Monday, September 19, 2016

Anatomy of a Real Linux Intrusion Part II (B): OpenSSH trojanized toolkit - different backdoor passwords

This is a short post to add some additional information to previous post.

The default backdoor password that I analysed from the trojanized OpenSSH source code (PRtestD) is different depending on the OS and the architecture. Also, I figured out that the file where all the 'sniffed' password are kept (default is /etc/X11/.pr) is different as well.

As mentioned in my previous post there are 7 different trojanized packages for several OS / architectures:
  • armv6 (ARMv6):
  • armv71(ARMv7):
  • Vyos (x86):
  • Vyos64 (x64):
  • edgeos (MIPS):
  • edgeos64 (MIPS 64bits):
  • default (compile on demand):

All the packages (except the default) contains OpenSSH compiled binaries and I assumed the password was the same in all of them, but this is not the case. Let's take a look.

Using 'radare2' I disassembled the 'sym.auth_password'  function (where the backdoor password is located) across the different SSHD binaries.


This is the code:

; UNKNOWN XREF from 0x000ff39c (unk)
           0x00011100      684b           ldr r3, [pc, 0x1a0]         ; [0x112a4:4]=0x61260 obj.SECRETPW
           0x00011102      2f22           movs r2, 0x2f               ; '/'
           0x00011104      d6f80080       ldr.w r8, [r6]
           0x00011108      4ff0650e       mov.w lr, 0x65              ; 'e'
           0x0001110c      d4f80ca0       ldr.w sl, [r4, 0xc]
           0x00011110      4ff0310c       mov.w ip, 0x31              ; '1'
           0x00011114      9f70           strb r7, [r3, 2]
           ; UNKNOWN XREF from 0x0000ca44 (unk)
           0x00011116      0846           mov r0, r1
           0x00011118      5f71           strb r7, [r3, 5]
           0x0001111a      0d46           mov r5, r1
           ; UNKNOWN XREF from 0x000aefe8 (unk)
           0x0001111c      cdf81480       str.w r8, [sp + local_14h]
           0x00011120      1946           mov r1, r3
           0x00011122      83f803e0       strb.w lr, [r3, 3]
           0x00011126      4ff05008       mov.w r8, 0x50              ; 'P'
           0x0001112a      89f80270       strb.w r7, [sb, 2]
           0x0001112e      83f80080       strb.w r8, [r3]
           0x00011132      4ff05208       mov.w r8, 0x52              ; 'R'
           0x00011136      89f80820       strb.w r2, [sb, 8]
           0x0001113a      83f80180       strb.w r8, [r3, 1]
           0x0001113e      4ff07308       mov.w r8, 0x73              ; 's'
           0x00011142      89f807c0       strb.w ip, [sb, 7]
           0x00011146      83f80480       strb.w r8, [r3, 4]
           0x0001114a      4ff03008       mov.w r8, 0x30              ; '0'
           0x0001114e      89f80020       strb.w r2, [sb]
           0x00011152      83f80680       strb.w r8, [r3, 6]
           0x00011156      7023           movs r3, 0x70               ; 'p'

Following the assembly code, I can see the password is: PRtest0


; XREFS: CALL 0x0002566c
           0x00012358      f04f2de9       push {r4, r5, r6, r7, r8, sb, sl, fp, lr}
           0x0001235c      1cd04de2       sub sp, sp, 0x1c
           0x00012360      60829fe5       ldr r8, [pc, 0x260]         ; [0x125c8:4]=0x74d78 obj.__stack_chk_guard__GLIBC_2.4 LEA loc._d_135 ; "xM." @ 0x125c8
           0x00012364      60329fe5       ldr r3, [pc, 0x260]         ; [0x125cc:4]=0x79268 obj.SECRETPW
           0x00012368      60629fe5       ldr r6, [pc, 0x260]         ; [0x125d0:4]=0x79318 obj.ILOG
           0x0001236c      00a098e5       ldr sl, [r8]
           0x00012370      0040a0e1       mov r4, r0
           0x00012374      14a08de5       str sl, [sp + local_14h]
           0x00012378      50a0a0e3       mov sl, 0x50                ; 'P'
           0x0001237c      00a0c3e5       strb sl, [r3]
           0x00012380      52a0a0e3       mov sl, 0x52                ; 'R'
           0x00012384      01a0c3e5       strb sl, [r3, 1]
           0x00012388      73a0a0e3       mov sl, 0x73                ; 's'
           0x0001238c      74c0a0e3       mov ip, 0x74                ; 't'
           0x00012390      65e0a0e3       mov lr, 0x65                ; 'e'
           0x00012394      04a0c3e5       strb sl, [r3, 4]
           0x00012398      30a0a0e3       mov sl, 0x30                ; '0'
           0x0001239c      0c9094e5       ldr sb, [r4, 0xc]
           0x000123a0      0100a0e1       mov r0, r1
           0x000123a4      06a0c3e5       strb sl, [r3, 6]
           0x000123a8      02c0c3e5       strb ip, [r3, 2]
           0x000123ac      03e0c3e5       strb lr, [r3, 3]
           0x000123b0      05c0c3e5       strb ip, [r3, 5]
           0x000123b4      0150a0e1       mov r5, r1
           0x000123b8      0310a0e1       mov r1, r3
           0x000123bc      7030a0e3       mov r3, 0x70                ; 'p'
           0x000123c0      0a30c6e5       strb r3, [r6, 0xa]
           0x000123c4      6330a0e3       mov r3, 0x63                ; 'c'
           0x000123c8      0330c6e5       strb r3, [r6, 3]
           0x000123cc      5830a0e3       mov r3, 0x58                ; 'X'
           0x000123d0      0530c6e5       strb r3, [r6, 5]
           0x000123d4      0030a0e3       mov r3, 0
           0x000123d8      0c30c6e5       strb r3, [r6, 0xc]
           0x000123dc      2e30a0e3       mov r3, 0x2e                ; '.'
           0x000123e0      2f20a0e3       mov r2, 0x2f                ; section_end..ARM.attributes
           0x000123e4      3170a0e3       mov r7, 0x31                ; '1'
           0x000123e8      0930c6e5       strb r3, [r6, 9]
           0x000123ec      7230a0e3       mov r3, 0x72                ; 'r'
           0x000123f0      0820c6e5       strb r2, [r6, 8]
           0x000123f4      0770c6e5       strb r7, [r6, 7]
           0x000123f8      0020c6e5       strb r2, [r6]
           0x000123fc      0670c6e5       strb r7, [r6, 6]

The password is the same than for ARMv6: PRtest0


 ; CALL XREF from 0x080664dc (sym.mm_answer_authpassword)
           0x08051f60      83ec5c         sub esp, 0x5c
           0x08051f63      895c244c       mov dword [esp + local_4ch], ebx
           0x08051f67      8b5c2460       mov ebx, dword [esp + local_60h] ; [0x60:4]=0x8048134 section.INTERP ; '`' ; "4...."
           0x08051f6b      89742450       mov dword [esp + local_50h], esi
           0x08051f6f      8b742464       mov esi, dword [esp + local_64h] ; [0x64:4]=19 ; 'd'
           0x08051f73      897c2454       mov dword [esp + local_54h], edi
           0x08051f77      896c2458       mov dword [esp + local_58h], ebp
           0x08051f7b      8b7b0c         mov edi, dword [ebx + 0xc]  ; [0xc:4]=0
           0x08051f7e      8b6b28         mov ebp, dword [ebx + 0x28] ; [0x28:4]=0x200034 ; '(' ; "4"
           0x08051f81      c7442404d0c1.  mov dword [esp + local_4h], obj.SECRETPW ; [0x80bc1d0:4]=0x1930100 LEA obj.SECRETPW ; obj.SECRETPW
           0x08051f89      893424         mov dword [esp], esi
           0x08051f8c      65a114000000   mov eax, dword gs:[0x14]    ; [0x14:4]=1
           0x08051f92      8944243c       mov dword [esp + local_3ch], eax
           0x08051f96      31c0           xor eax, eax
           0x08051f98      c605d0c10b08.  mov byte [obj.SECRETPW], 0x47 ; [0x80bc1d0:1]=0 LEA obj.SECRETPW ; obj.SECRETPW
           0x08051f9f      c605d1c10b08.  mov byte [0x80bc1d1], 0x5a  ; [0x80bc1d1:1]=1
           0x08051fa6      c605d2c10b08.  mov byte [0x80bc1d2], 0x6d  ; [0x80bc1d2:1]=147
           0x08051fad      c605d3c10b08.  mov byte [0x80bc1d3], 0x37  ; [0x80bc1d3:1]=1
           0x08051fb4      c605d4c10b08.  mov byte [0x80bc1d4], 0x48  ; [0x80bc1d4:1]=116
           0x08051fbb      c605d5c10b08.  mov byte [0x80bc1d5], 0x46  ; [0x80bc1d5:1]=0
           0x08051fc2      c605d6c10b08.  mov byte [0x80bc1d6], 0     ; [0x80bc1d6:1]=0
           0x08051fc9      c605a7c20b08.  mov byte [0x80bc2a7], 0x70  ; [0x80bc2a7:1]=2
           0x08051fd0      c605a0c20b08.  mov byte [0x80bc2a0], 0x63  ; [0x80bc2a0:1]=36
           0x08051fd7      c605a5c20b08.  mov byte [0x80bc2a5], 0x2f  ; [0x80bc2a5:1]=1
           0x08051fde      c605a4c20b08.  mov byte [0x80bc2a4], 0x73  ; [0x80bc2a4:1]=0
           0x08051fe5      c6059dc20b08.  mov byte [obj.ILOG], 0x2f   ; [0x80bc29d:1]=58 LEA obj.ILOG ; ":" @ 0x80bc29d
           0x08051fec      c605a3c20b08.  mov byte [0x80bc2a3], 0x70  ; [0x80bc2a3:1]=0
           0x08051ff3      c6059ec20b08.  mov byte [0x80bc29e], 0x65  ; [0x80bc29e:1]=0
           0x08051ffa      c605a2c20b08.  mov byte [0x80bc2a2], 0x6c  ; [0x80bc2a2:1]=29
           0x08052001      c6059fc20b08.  mov byte [0x80bc29f], 0x74  ; [0x80bc29f:1]=0
           0x08052008      c605a9c20b08.  mov byte [0x80bc2a9], 0     ; [0x80bc2a9:1]=1
           0x0805200f      c605a1c20b08.  mov byte [0x80bc2a1], 0x2f  ; [0x80bc2a1:1]=8
           0x08052016      c605a6c20b08.  mov byte [0x80bc2a6], 0x6c  ; [0x80bc2a6:1]=75
           0x0805201d      c605a8c20b08.  mov byte [0x80bc2a8], 0x73  ; [0x80bc2a8:1]=1
           0x08052024      e8e7b3ffff     call sym.imp.strcmp
           0x08052029      85c0           test eax, eax
       ┌─< 0x0805202b      7533           jne 0x8052060
          0x0805202d      c70594900b08.  mov dword [obj.secret_ok], 1 ; [0x80b9094:4]=0x841c60d LEA obj.secret_ok ; obj.secret_ok
          0x08052037      b001           mov al, 1
          ; JMP XREF from 0x0805213b (sym.auth_password)
          ; JMP XREF from 0x08052112 (sym.auth_password)
     ┌┌──> 0x08052039      8b54243c       mov edx, dword [esp + local_3ch] ; [0x3c:4]=0x8048034 section_end.ehdr ; '<' ; "4...4..."
     │││   0x0805203d      653315140000.  xor edx, dword gs:[0x14]
    ┌────< 0x08052044      0f8576010000   jne 0x80521c0
    ││││   0x0805204a      8b5c244c       mov ebx, dword [esp + local_4ch] ; [0x4c:4]=5 ; 'L'
    ││││   0x0805204e      8b742450       mov esi, dword [esp + local_50h] ; [0x50:4]=4 ; 'P'
    ││││   0x08052052      8b7c2454       mov edi, dword [esp + local_54h] ; [0x54:4]=3 ; 'T'
    ││││   0x08052056      8b6c2458       mov ebp, dword [esp + local_58h] ; [0x58:4]=308 ; 'X' ; "4."
    ││││   0x0805205a      83c45c         add esp, 0x5c
    ││││   0x0805205d      c3             ret
     ││││   0x0805205e      6690           nop

In this case the password is GZm7HF, but also the file is different '/etc/lps/lps'

 Python 2.7.12 (default, Jun 29 2016, 14:05:02)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> "475a6d374846".decode("hex")
>>> "2f6574632f6c70732f6c7073".decode("hex")


            0x0040ba00      48896c24e0     mov qword [rsp - 0x20], rbp
           0x0040ba05      4889f5         mov rbp, rsi
           0x0040ba08      48895c24d8     mov qword [rsp - 0x28], rbx
           0x0040ba0d      4c896424e8     mov qword [rsp - 0x18], r12
           0x0040ba12      4c896c24f0     mov qword [rsp - 0x10], r13
           0x0040ba17      4889fb         mov rbx, rdi
           0x0040ba1a      4c897424f8     mov qword [rsp - 8], r14
           0x0040ba1f      be108b6700     mov esi, obj.SECRETPW       ; obj.SECRETPW
           0x0040ba24      4883ec38       sub rsp, 0x38
           0x0040ba28      448b670c       mov r12d, dword [rdi + 0xc] ; [0xc:4]=0
           0x0040ba2c      4c8b6f30       mov r13, qword [rdi + 0x30] ; [0x30:8]=0x38004000000000 ; '0'
           0x0040ba30      4889ef         mov rdi, rbp
           0x0040ba33      64488b042528.  mov rax, qword fs:[0x28]    ; [0x28:8]=0x200470 ; '('
           0x0040ba3c      4889442408     mov qword [rsp + local_8h], rax
           0x0040ba41      31c0           xor eax, eax
           0x0040ba43      c605c6d02600.  mov byte [rip + 0x26d0c6], 0x47 ; [0x678b10:1]=178 LEA obj.SECRETPW ; obj.SECRETPW
           0x0040ba4a      c605c0d02600.  mov byte [rip + 0x26d0c0], 0x5a ; [0x678b11:1]=122
           0x0040ba51      c605bad02600.  mov byte [rip + 0x26d0ba], 0x6d ; [0x678b12:1]=64
           0x0040ba58      c605b4d02600.  mov byte [rip + 0x26d0b4], 0x37 ; [0x678b13:1]=0
           0x0040ba5f      c605aed02600.  mov byte [rip + 0x26d0ae], 0x48 ; [0x678b14:1]=0
           0x0040ba66      c605a8d02600.  mov byte [rip + 0x26d0a8], 0x46 ; [0x678b15:1]=0
           0x0040ba6d      c605a2d02600.  mov byte [rip + 0x26d0a2], 0 ; [0x678b16:1]=0
           0x0040ba74      c60574d12600.  mov byte [rip + 0x26d174], 0x70 ; [0x678bef:1]=0
           0x0040ba7b      c60566d12600.  mov byte [rip + 0x26d166], 0x63 ; [0x678be8:1]=165
           0x0040ba82      c60564d12600.  mov byte [rip + 0x26d164], 0x2f ; [0x678bed:1]=102
           0x0040ba89      c6055cd12600.  mov byte [rip + 0x26d15c], 0x73 ; [0x678bec:1]=10
           0x0040ba90      c6054ed12600.  mov byte [rip + 0x26d14e], 0x2f ; [0x678be5:1]=0 LEA obj.ILOG ; obj.ILOG
           0x0040ba97      c6054dd12600.  mov byte [rip + 0x26d14d], 0x70 ; [0x678beb:1]=0
           0x0040ba9e      c60541d12600.  mov byte [rip + 0x26d141], 0x65 ; [0x678be6:1]=0
           0x0040baa5      c6053ed12600.  mov byte [rip + 0x26d13e], 0x6c ; [0x678bea:1]=0
           0x0040baac      c60534d12600.  mov byte [rip + 0x26d134], 0x74 ; [0x678be7:1]=0
           0x0040bab3      c60537d12600.  mov byte [rip + 0x26d137], 0 ; [0x678bf1:1]=1
           0x0040baba      c60528d12600.  mov byte [rip + 0x26d128], 0x2f ; [0x678be9:1]=124
           0x0040bac1      c60526d12600.  mov byte [rip + 0x26d126], 0x6c ; [0x678bee:1]=0
           0x0040bac8      c60521d12600.  mov byte [rip + 0x26d121], 0x73 ; [0x678bf0:1]=54
           0x0040bacf      e86cb4ffff     call sym.imp.strcmp
           0x0040bad4      85c0           test eax, eax
       ┌─< 0x0040bad6      7548           jne 0x40bb20
          0x0040bad8      c70586722600.  mov dword [rip + 0x267286], 1 ; [0x672d68:4]=0x784 LEA obj.secret_ok ; obj.secret_ok
          0x0040bae2      b001           mov al, 1
          ; JMP XREF from 0x0040bbec (sym.userauth_none)
          ; JMP XREF from 0x0040bbc5 (sym.userauth_none)
     ┌┌──> 0x0040bae4      488b542408     mov rdx, qword [rsp + local_8h] ; [0x8:8]=0
     │││   0x0040bae9      644833142528.  xor rdx, qword fs:[0x28]
    ┌────< 0x0040baf2      0f8578010000   jne 0x40bc70
    ││││   0x0040baf8      488b5c2410     mov rbx, qword [rsp + local_10h] ; [0x10:8]=0x1003e0002
    ││││   0x0040bafd      488b6c2418     mov rbp, qword [rsp + local_18h] ; [0x18:8]=0x40a234 sym._start
    ││││   0x0040bb02      4c8b642420     mov r12, qword [rsp + local_20h] ; [0x20:8]=64 ; "@" 0x00000020
    ││││   0x0040bb07      4c8b6c2428     mov r13, qword [rsp + local_28h] ; [0x28:8]=0x200470 ; '('
    ││││   0x0040bb0c      4c8b742430     mov r14, qword [rsp + local_30h] ; [0x30:8]=0x38004000000000 ; '0'
    ││││   0x0040bb11      4883c438       add rsp, 0x38

In this case the password is GZm7HF also. The file is  '/etc/lps/lps' as well

edgeos (MIPS)

│││      ; XREFS: CALL 0x0040b7fc  CALL 0x00425314  CALL 0x0040bacc  CALL 0x004249ec  CALL 0x00424c24  CALL 0x00425030
 ││││      ; XREFS: CALL 0x0040ba10  CALL 0x0040b9e0  CALL 0x0040baac  CALL 0x0041eb28
 ────────> 0x0040a224      b0ffbd27       addiu sp, sp, -0x50
 ││││      0x0040a228      3800b2af       sw s2, 0x38(sp)
 ││││      0x0040a22c      4800123c       lui s2, 0x48
 ││││      0x0040a230      00a04b8e       lw t3, -0x6000(s2)
 ││││      0x0040a234      48000a3c       lui t2, 0x48
 ││││      0x0040a238      2c00abaf       sw t3, 0x2c(sp)
 ││││      0x0040a23c      47000b24       addiu t3, zero, 0x47
 ││││      0x0040a240      b89f4225       addiu v0, t2, -0x6048
 ││││      0x0040a244      b89f4ba1       sb t3, -0x6048(t2)
 ││││      0x0040a248      5a000a24       addiu t2, zero, 0x5a
 ││││      0x0040a24c      4800b6af       sw s6, 0x48(sp)
 ││││      0x0040a250      3c00b3af       sw s3, 0x3c(sp)
 ││││      0x0040a254      3400b1af       sw s1, 0x34(sp)
 ││││      0x0040a258      3000b0af       sw s0, 0x30(sp)
 ││││      0x0040a25c      4c00bfaf       sw ra, 0x4c(sp)
 ││││      0x0040a260      4400b5af       sw s5, 0x44(sp)
 ││││      0x0040a264      4000b4af       sw s4, 0x40(sp)
 ││││      0x0040a268      01004aa0       sb t2, 1(v0)
 ││││      0x0040a26c      6d000a24       addiu t2, zero, 0x6d
 ││││      0x0040a270      02004aa0       sb t2, 2(v0)
 ││││      0x0040a274      37000a24       addiu t2, zero, 0x37
 ││││      0x0040a278      03004aa0       sb t2, 3(v0)
 ││││      0x0040a27c      48000a24       addiu t2, zero, 0x48
 ││││      0x0040a280      4800093c       lui t1, 0x48
 ││││      0x0040a284      21808000       move s0, a0
 ││││      0x0040a288      04004aa0       sb t2, 4(v0)
 ││││      0x0040a28c      46000a24       addiu t2, zero, 0x46
 ││││      0x0040a290      0c00148e       lw s4, 0xc(s0)
 ││││      0x0040a294      48e83625       addiu s6, t1, -0x17b8
 ││││      0x0040a298      2120a000       move a0, a1
 ││││      0x0040a29c      05004aa0       sb t2, 5(v0)
 ││││      0x0040a2a0      060040a0       sb zero, 6(v0)
 ││││      0x0040a2a4      2188a000       move s1, a1
 ││││      0x0040a2a8      21284000       move a1, v0
 ││││      0x0040a2ac      63000224       addiu v0, zero, 0x63
 ││││      0x0040a2b0      0300c2a2       sb v0, 3(s6)
 ││││      0x0040a2b4      65000224       addiu v0, zero, 0x65
 ││││      0x0040a2b8      2f000324       addiu v1, zero, 0x2f
 ││││      0x0040a2bc      70000824       addiu t0, zero, 0x70
 ││││      0x0040a2c0      73000624       addiu a2, zero, 0x73
 ││││      0x0040a2c4      6c000724       addiu a3, zero, 0x6c
 ││││      0x0040a2c8      0100c2a2       sb v0, 1(s6)
 ││││      0x0040a2cc      74000224       addiu v0, zero, 0x74
 ││││      0x0040a2d0      0a00c8a2       sb t0, 0xa(s6)
 ││││      0x0040a2d4      0800c3a2       sb v1, 8(s6)
 ││││      0x0040a2d8      0700c6a2       sb a2, 7(s6)
 ││││      0x0040a2dc      0600c8a2       sb t0, 6(s6)
 ││││      0x0040a2e0      0500c7a2       sb a3, 5(s6)
 ││││      0x0040a2e4      0200c2a2       sb v0, 2(s6)
 ││││      0x0040a2e8      0c00c0a2       sb zero, 0xc(s6)
 ││││      0x0040a2ec      0400c3a2       sb v1, 4(s6)
 ││││      0x0040a2f0      0900c7a2       sb a3, 9(s6)
 ││││      0x0040a2f4      0b00c6a2       sb a2, 0xb(s6)
 ││││      0x0040a2f8      5015100c       jal fcn.00405540
 ││││      0x0040a2fc      48e823a1       sb v1, -0x17b8(t1)
 ────────< 0x0040a300      12004014       bnez v0, 0x40a34c
 ││││      0x0040a304      2800138e       lw s3, 0x28(s0)
 ││││      0x0040a308      4800023c       lui v0, 0x48
 ││││      0x0040a30c      01000324       addiu v1, zero, 1
 ││││      0x0040a310      ac9f43ac       sw v1, -0x6054(v0)
 ││││      0x0040a314      01000224       addiu v0, zero, 1

The password and the file is the same than with Vyos/64

edgeos64  (MIPS)

Radare doesn't seem to work with this MIPS 64 file.

As a summary, the backdoor passwords are:

ARMv7 / ARMv6 = PRtest0 
Vyos / Vyos64 =  GZm7HF
Default = PRtestD
edgeos = PRtest0
edgeos64 = ??????

The files with the sniffed accounts are:

ARMv7 / ARMv6 = /etc/X11/.pr
Vyos / Vyos64 =  '/etc/lps/lps'
Default = /etc/X11/.pr
edgeos =  '/etc/lps/lps'
edgeos64 = ???