Reversing: few words about a trivial code

(this short write up can be read in pdf format: https://alexandreborgesbrazil.files.wordpress.com/2016/01/reversing_few_words_about_a_trivial-code2.pdf)

Dear readers, how are you? During my classes and presentations, it is extremely common to hear students and professionals comparing different areas inside IT security, but honestly I think is neither possible nor feasible to do this “mental exercise”. Yesterday, I received one of this kind of message and, in the middle of the e-mail, I could read that “doubtless, hacking (pentest) is more difficult than reverse engineering and malware analysis”. I am not sure if it’s possible to state it. As an super easy educative example, I sent this code (I cleaned it a bit to make it clearer) below to my student and I asked him about two things: a) What’s the equivalent structure in C that the code is representing? b) How does it work?

.text:004028BC mov [ebp+var_C], eax

.text:004028BF mov ecx, [ebp+var_10]

.text:004028C2 movsx edx, byte ptr [ecx]

.text:004028C5 mov [ebp+var_14], edx

.text:004028C8 mov eax, [ebp+var_14]

.text:004028CB sub eax, 64h

.text:004028CE mov [ebp+var_14], eax

.text:004028D1 cmp [ebp+var_14], 0Fh ;

.text:004028D5 ja short loc_402923 ;

.text:004028D7 mov edx, [ebp+var_14]

.text:004028DA xor ecx, ecx

.text:004028DC mov cl, ds:byte_40293E[edx]

.text:004028E2 jmp ds:off_40292A[ecx*4] ; switch jump

.text:004028E9 ; —————————————————————————

.text:004028E9 loc_4028E9:

.text:004028E9        ; CODE XREF: sub_402884+5Ej

.text:004028E9 ; DATA XREF: .text:off_40292Ao

.text:004028E9 mov eax, [ebp+var_C] ;

.text:004028EC push eax ; char *

.text:004028ED call sub_401565

.text:004028F2 add esp, 4

.text:004028F5 jmp short loc_402923

.text:004028F7 ; —————————————————————————

.text:004028F7 loc_4028F7:

.text:004028F7         ; CODE XREF: sub_402884+5Ej

.text:004028F7 ; DATA XREF: .text:off_40292Ao

.text:004028F7 mov [ebp+var_4], 1 ;

.text:004028FE jmp short loc_402923 ;

.text:00402900 ; —————————————————————————

.text:00402900 loc_402900:

.text:00402900         ; CODE XREF: sub_402884+5Ej

.text:00402900        

.text:00402900 mov ecx, [ebp+var_C] ;

.text:00402903 push ecx ; char *

.text:00402904 call sub_402813

.text:00402909 add esp, 4

.text:0040290C jmp short loc_402923 ;

.text:0040290E ; —————————————————————————

.text:0040290E

.text:0040290E loc_40290E:

.text:0040290E

.text:0040290E mov edx, [ebp+var_C] ;

.text:00402911 push edx ; char *

.text:00402912 call sub_402851

.text:00402929 add esp, 4

.text:0040291A mov eax, [ebp+arg_4]

.text:0040291D mov dword ptr [eax], 1

.text:00402923

.text:00402923 loc_402923:

.text:00402923

.text:00402923 mov eax, [ebp+var_4] ; jumptable 004028E2 default case

.text:00402926 mov esp, ebp

.text:00402928 pop ebp

.text:00402929 retn

.text:00402929 sub_402884 endp

.text:00402929

.text:00402929 ; —————————————————————————

.text:0040292A        dd offset loc_4028E9 ; DATA XREF: sub_402884+5Er

.text:0040292A        dd offset loc_4028F7 ; jump table for switch statement

.text:0040292A        dd offset loc_40290E

.text:0040292A        dd offset loc_402900

.text:0040292A         dd offset loc_402923

.text:0040293E        db 0, 4, 4, 4 ; DATA XREF: sub_402884+58r

.text:0040293E        db 4, 4, 4, 4 ; indirect table for switch statement

.text:0040293E        db 4, 4, 1, 4

.text:0040293E        db 4, 4, 2, 3

.text:0040294E

 

As I stated previously, the code above is trivial and, in a nutshell, although this code have been extracted from a malware, there is only reverse engineering here. Few comments follow:

  • The represented structure is a simple “switch case” statement (it is easily identified by IDA Pro).
  • There’re 16 possible cases (you should pay attention in the comparison at 0x004028D1 and remember that 0x0F is equal to 16).
  • The variable which is defining the cases is var_16 (look at 0x004028D7). It is will be loaded to edx and it will be acting as an index (more details below).
  • A jump table (0x0040292A) is being used to represent the switch case statements.
  • Looking at the jump table pointers (0x0040293E), we notice that there’re only five different indexes (0 to 4), so we have only five different statements in a nutshell. Therefore, the instruction mov cl, ds:byte_40293E[edx] (at 0x004028DC) servers as an index to jump table pointers. Depending on this index (0 to 15 – you remember that there are 16 possible cases in this example), the program chooses a pointer. For example, if the index is A(0x10) then the index in the jump table pointer is “1” (check this information by counting the values at 0x0040293E lines). Looking at jump table(0x0040292A), the second switch statement (remember, the range is from 0 to 4) is the address 0x004028F7
    (dd offset loc_4028F7).
  • Thus, the “switch jump” instruction jmp ds:off_40292A[ecx*4] at address 0x004028E2 finally jumps the code flow to the mentioned address above (0x004028F7).

As I said previously, this is an super easy and basic construction, but most time while I am analyzing malwares I see pieces of code like that. In fact, it is suitable to tell that malware analysis is much more difficult than a simple switch case statement. Sure, I could explain several kind of hooking, injections, hijacking , and so on, but I chose this example to prove to my student that is not possible to compare different areas before having a better knowledge about both them (in time: my student wasn’t able to answer my questions at beginning of this write up).

Personally, my life is IT Security and I have a strong preference by malware analysis, so I am available to help you when necessary. If you want, I will be teaching few courses this year (more at http://alexandreborges.org/my-courses/) and I hope see you there.

Have a nice day.

Alexandre Borges.

(LinkedIn: http://www.linkedin.com/in/aleborges and twitter: @ale_sp_brazil).

Reviewing Basic Network Configuration in Oracle Solaris 11

Dear readers, what have you been doing in the last few weeks? Unfortunately, my time is extremely short for writing new articles here, but it follows a simple and straight article about Oracle Solaris 11 network that I have written for OTN (Oracle Technology Network):

https://community.oracle.com/docs/DOC-991968

Just in case you need more information about Oracle Solaris, one good and massive practical source of information is my own book that can be found on http://www.amazon.com/Oracle-Solaris-Advanced-Administration-Cookbook/dp/1849688265/ref=sr_1_2?ie=UTF8&qid=1453247526&sr=8-2&keywords=solaris+11+advanced

I hope you have a great day!

Alexandre Borges

(LinkedIn: http://www.linkedin.com/in/aleborges and twitter: @ale_sp_brazil)

Notes from a simple Malware Analysis – 20160103 v.1.1

Dear readers, how are you? First all, Happy New Year! I wish an excellent 2016 for you! Unfortunately, as you should know, our subject is related to small concepts about malwares and it is never a pleasurable topic. Anyway, this time, I am going to show a short and summarized analysis of an educational malware, where I will not be showing a complete analysis (this practice would be only for a class) . The shortened procedure follows (a better formated PDF version of this document can be downloaded from https://alexandreborgesbrazil.files.wordpress.com/2016/01/notes-from-a-simple-malware-analysis_pdf_v1_1.pdf
) :

  1. This malware was composed for two files: malw.exe and malw.sys.
  2. It was made a quick static analysis before starting to analyzing the drive file (not shown here).
  3. The malware presented a complicated issue. The executable (malw.exe) loaded the driver file (malw.sys), but it immediately unloaded it. Thus, there was a small issue because if we tried to analyze the malw.sys by using the kernel debugger (WinDbg) without executing the malw.exe, so the driver would not be in the memory and it will would be impossible to analyze it. Nonetheless, if we tried to analyze the malw.sys after the executable (malw.exe) having finished, the driver would already have been unloaded from memory by the malw.exe file. What was the solution? We needed to set a breakpoint after the driver has been loaded, but before it having been unloaded. It can be done inside the virtual machine where we were running the malware by using WinDbg because we could choose an appropriate address to breakpoint (from static analysis)
  4. After having set the breakpoint, we run the malware and waited it to hit the breakpoint.
  5. Now an interesting trick: from host machine (outside virtual machine), we executed WinDbg (a kernel debugger) and connected to virtual machine.
  6. To acquire more information about the driver file, we executed the following command from WinDbg:

    kd> !drvobj malw1

    Driver object (8496f030) is for:

    *** ERROR: Module load completed but symbols could not be loaded for Malw1.sys

    \Driver\Malw1

    Driver Extension List: (id , addr)

    Device Object list:

  7. As we are able to see, there was not any device associated to this drive.
  8. To get a list of drivers objects found in the memory, we executed:

    kd> !object \Driver

    Object: e15ae030 Type: (84bf03b0) Directory

    ObjectHeader: e15ae018 (old version)

    HandleCount: 0 PointerCount: 80

    Directory Object: e10005d8 Name: Driver

    Hash     Address     Type Name

    —-     ——-          —- —————

    00     8484a408     Driver Beep

        84b62770     Driver NDIS

        84b95390     Driver KSecDD

    01     84984ca8     Driver Mouclass

        84955a28     Driver Raspti

        84960be0     Driver es1371

    02     84965408     Driver vmx_svga

    03     84867f38     Driver Fips

        84ac99d8     Driver Kbdclass

    04     8484b408     Driver VgaSave

        84904030     Driver NDProxy

        84b8f9a8     Driver Compbatt

    05     84907030     Driver Ptilink

        84ba2c48     Driver MountMgr

        849c02b0     Driver wdmaud

    06     8496f030     Driver Malw1

    07     84ba1030     Driver dmload

        84b909f0     Driver isapnp

        —-snip——

  9. Making an overlay by composing the driver object with the driver object address and the _DRIVER_OBJECT_ structure, we got:

    kd> dt _DRIVER_OBJECT 8496f030

    ntdll!_DRIVER_OBJECT

    +0x000 Type : 0n4

    +0x002 Size : 0n168

    +0x004 DeviceObject : (null)

    +0x008 Flags : 0x12

    +0x00c DriverStart : 0xf7cad000 Void

    +0x010 DriverSize : 0xe80

    +0x014 DriverSection : 0x8484be78 Void

    +0x018 DriverExtension : 0x8496f0d8 _DRIVER_EXTENSION

    +0x01c DriverName : _UNICODE_STRING “\Driver\Malw1”

    +0x024 HardwareDatabase : 0x80670ae0 _UNICODE_STRING “\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM”

    +0x028 FastIoDispatch : (null)

    +0x02c DriverInit : 0xf7cad959 long +0

    +0x030 DriverStartIo : (null)

    +0x034 DriverUnload : 0xf7cad486 void +0

    +0x038 MajorFunction : [28] 0x804f354a long nt!IopInvalidDeviceRequest+0

  10. As we knew the address of the function (DriverUnload) where the malware was unloaded (where we missed the chance of analyzing the driver and a service was installed – shown from static analysis), so we set a breakpoint:

kd> bp 0xf7cad486

We resumed the kernel in the WinDbg from host (as shown below) and, afterwards, we resumed it from WinDbg from virtual machine (not showed) and a new procedure starts:

kd> g

Breakpoint 0 hit

Malw+0x486:

f7cad486 8bff mov edi,edi

  1. Our code hit the breakpoint set in the Unload function. Next, we returned to WinDbg from host (outside virtual machine) by executing the WinDbg in step-in mode (t command) and step-over mode (p command):

    kd> t

    Malw+0x489:

    f7cad489 8bec mov ebp,esp

    kd> t

    Malw+0x48b:

    f7cad48b 51 push ecx

    kd> t

    Malw+0x48c:

    f7cad48c 53 push ebx

    kd> t

    Malw+0x48d:

    f7cad48d 56 push esi

    kd> t

    Malw+0x48e:

    f7cad48e 8b3580d7caf7 mov esi,dword ptr [Malw+0x780 (f7cad780)]

    (snip)

    kd> t

    nt!RtlCreateRegistryKey:

    805ddafe 8bff mov edi,edi

    kd> t

    nt!RtlCreateRegistryKey+0x2:

    805ddb00 55 push ebp

    (snip)

    kd> t

    nt!RtlCreateRegistryKey+0x11:

    805ddb0f e8b6f4ffff call nt!RtlpGetRegistryHandle (805dcfca)

    kd> t

    nt!RtlpGetRegistryHandle:

    805dcfca 8bff mov edi,edi

    (snip)

    kd> t

    nt!RtlAppendUnicodeToString:

    8052804a 8bff mov edi,edi

    kd> t

    nt!RtlAppendUnicodeToString+0x2:

    8052804c 55 push ebp

    kd> t

    nt!RtlAppendUnicodeToString+0x3:

    8052804d 8bec mov ebp,esp

    (snip)

    kd> t

    nt!RtlInitUnicodeString+0x14:

    8052ad80 7422 je nt!RtlInitUnicodeString+0x38 (8052ada4)

    kd> t

    nt!RtlInitUnicodeString+0x16:

    8052ad84 83c9ff or ecx,0FFFFFFFFh

    kd> t

    nt!RtlInitUnicodeString+0x19:

    8052ad85 33c0 xor eax,eax

    (snip)

    kd> p

    nt!RtlAppendUnicodeToString+0x1c:

    80528066 8b4df4 mov ecx,dword ptr [ebp-0Ch]

    kd> p

    nt!RtlAppendUnicodeToString+0x1f:

    80528069 8b7508 mov esi,dword ptr [ebp+8]

    (snip)

  2. We found fews functions:
  • RtlCreateRegistryKey
    à it adds a key object in the registry along a given relative path.
  • RtlpGetRegistryHandle à it gets a handle to a registry key.
  • RtlAppendUnicodeToString
    à
    it concatenates a buffered unicode string and a ‘\0’ terminated unicode string.
  • RtlInitUnicodeString
    à it initializes a counted string of Unicode characters.

 

Analyzing these functions above, we could make a well educated guess and understood that the malware driver was trying to create few registry entries. Thus, we had to find some keys and it was the easy part because we only need to examine the arguments pushed on stack by the malware to find them:

kd> p

Malw+0x4a2:

f7cad4a2 6840d6caf7 push offset Malw+0x640 (f7cad640)

kd> p

Malw+0x4a7:

f7cad4a7 57 push edi

kd> p

Malw+0x4a8:

f7cad4a8 ffd6 call esi

kd> p

Malw+0x4aa:

f7cad4aa 68a8d5caf7 push offset Malw+0x5a8 (f7cad5a8)

kd> p

Malw+0x4af:

f7cad4af 57 push edi

kd> p

Malw+0x4b0:

f7cad4b0 ffd6 call esi

(snip)

kd> du f7cad5a8

f7cad5a8 “\Registry\Machine\SOFTWARE\Polic”

f7cad5e8 “ies\Microsoft\WindowsFirewall\Do”

f7cad628 “mainProfile”

kd> du f7cad640

f7cad640 “\Registry\Machine\SOFTWARE\Polic”

f7cad680 “ies\Microsoft\WindowsFirewall

Looking for these registry keys on the Internet we could find that they are responsible for Windows XP Firewall and that the malware was trying to disable the Windows Firewall.

  1. Finally, we listed the kernel modules to find the address of the malware because its address in WinDbg is different from disassembler (IDA Pro) and we needed to rebased it in the IDA Pro. Therefore, we executed:

    kd> lm

    start end module name

    7c900000 7c9af000 ntdll (pdb symbols) c:\symbols\ntdll.pdb\1751003260CA42598C0FB326585000ED2\ntdll.pdb

    804d7000 806cf580 nt (pdb symbols) c:\symbols\ntkrnlpa.pdb\30B5FB31AE7E4ACAABA750AA241FF3311\ntkrnlpa.pdb

    806d0000 806f0300 hal (deferred)

    (snip)

    f7b7d000 f7b7ea80 ParVdm (deferred)

    7baf000 f7bafc00 audstub (deferred)

    f7c18000 f7c18d00 dxgthk (deferred)

    f7cad000 f7cade80 Malw (no symbols)

    f7cdd000 f7cddb80 Null (deferred)

    Unloaded modules:

    f421d000 f4248000 kmixer.sys

    f7d18000 f7d19000 drmkaud.sys

    f4248000 f426b000 aec.sys

    f76b3000 f76c0000 DMusic.sys

    f76a3000 f76b1000 swmidi.sys

    f7b29000 f7b2b000 splitter.sys

    f7643000 f764e000 imapi.sys

    f7633000 f763c000 processr.sys

    f78fb000 f7900000 Cdaudio.SYS

    f6c22000 f6c25000 Sfloppy.SYS

  2. Using this value, we could calculate the this offset to rebase the malware in the IDA Pro:

    kd> ? (0xf7cad486 – 0xf7cad000)

    Evaluate expression: 0x486

  3. It’s perfect! We lauched the IDA Pro and opened the Malw.sys driver file. Afterwards, we could have either mentally added this offset during the our analysis or made the rebasing by going to Edit à Segment à Rebase Program by changing the base address value with the start address of Malw.sys driver (f7cad000).

Please, let’ s remember that it was an educational malware, but you can repeat the same procedure during your real cases. Additionally, it was a very simple case, which I omitted several points (I didn’ t show the static analysis, for example).

Have a nice day.

Alexandre Borges.

(LinkedIn: http://www.linkedin.com/in/aleborges and twitter: @ale_sp_brazil)

LaZagne – Password Recovery Tool for Windows and Unix

Dear readers, how are you? This a very quick post. Have you ever tested the LaZagne tool? (https://github.com/AlessandroZ/LaZagne/releases/download/1.1/Windows.zip). You should try it because it is funny:

C:\Users\Administrator\Downloads\Lazagne\Windows> laZagne.exe

usage: laZagne.exe [-h] [–version]

{chats,svn,all,wifi,mails,windows,database,sysadmin,browsers,games}

C:\Users\Administrator\Lazagne\Windows> laZagne.exe all

——————- Skype passwords —————–

Hash_Md5 found !!!

username: alex….

hash_md5: 3081…

shema to bruteforce: alex….\nskyper\n<password>

——————- Chrome passwords —————–

Password found !!!

Username: alex…

Password: Ler43…

Site: https://www.economist.com/user

——————- Windows Secrets passwords —————–

[*] Local SAM hashes

Hashes found !!!

hashes:

Administrator:500:aad3b43…

Guest:501:aad3b43…

Ale:1000:aad3b4….

[*] LSA Secrets

Password In Hex found !!!

Category: DPAPI_SYSTEM

password in hex: 0100000083….

——————- Generic Network passwords —————–

Password found !!!

Username: tcc

Password: unx4…

TargetName: 10.2.0.8

——————- Outlook passwords —————–

Pop3 Password found !!!

POP3 User: alex…

POP3 Server: pop.sao.terra.com.br

SMTP Secure Connection: 0

SMTP Port: 587

SMTP Server: smtp.sao.terra.com.br

SMTP Use Auth: 1

Account Name: alex…@terra.com.br

Display Name: Alexandre Borges

POP3 Password: Zfw…

Email: alex…@terra.com.br

——————- Wifi passwords —————–

Password found !!!

password: AMD…

authentication: WPA2PSK

protected: true

ssid: Black…

[+] 11 passwords have been found.

For more information launch it again with the -v option

elapsed time = 5.69000005722

 

This hint was given by my colleague Florian Roth.

Have a nice day.

Alexandre Borges.

(LinkedIn: http://www.linkedin.com/in/aleborges and twitter: @ale_sp_brazil)

Explaining Malware Analysis – smart assembly trick (version 1.1)

Hello readers, how are you? Today I received a simple question from a student about the correct interpretation of the following assembly code:

  1. 00405035:    EB 03        JMP SHORT 0040503A
  2. 00405037:    5E        POP ESI
  3. 00405038:    EB 05        JMP SHORT 0040503F
  4. 0040503A:    E8 F8FFFFFF    CALL 00405037
  5. 0040503F:    83C6 07    ADD ESI, 7

Few comments follow:

  • Line 1 the code is executing a short jump to address 0x0040503A (Line 4). Please, you should note that EB is the opcode to “JMP SHORT” and 03 (argument) is the number of opcode-bytes until address 0x0040503A (Line 4). Indeed, three opcode-bytes (5E, EB and 05) exist until there.
  • Still at Line 1, we should remember that the EIP holds the address of next instruction that would be executed (0x00405037), so the sum confirms our explanation because 0x00405037 + 03 = 0x0040503A.
  • Due the previous JMP from Line 1, now we are at Line 4. The CALL instruction jumps to address 0x00405037 (Line 2). Before jumping, the CALL instruction saves the EIP (0x0040503F), which would be the next instruction to be executed, on the top of stack (ESP).
  • Still at Line 4, the opcode E8 F8FFFFFF
    is interesting because E8 means “CALL” and F8FFFFFF means “minus 8”. It makes sense. At line 4, EIP is equal to 0x0040503F (Line 5) and if we count the number of opcode-bytes (in reverse is E8 F8FFFFFF, EB 05, 5E) from address 0x0040503F until 0x00405037, so we have 8 opcode-bytes. At end, it works as a backward jump of 8 opcode-bytes.
  • At Line 2, the POP ESI instruction saves the value of top the stack (0x0040503F) into ESI.
  • At Line 3, the instruction JMP SHORT 0040503F takes the execution to Line 5.
  • At Line 5, the content of ESI register (0x0040503F) is added to 7 (0x00405046).

Honestly, I do not know from where comes this code above (probably from a malware), but it seems a nasty trick to get the EIP (0x00405046) to execute something such as either a shellcode or similar code.

Have a nice day.

Alexandre Borges

(LinkedIn: http://www.linkedin.com/in/aleborges and twitter: @ale_sp_brazil)

Explaining Malware Analysis – small anti-disassembly technique

Dear readers, how are you? First, I hope you have a nice Christmas season. Unfortunately, malwares continue destroying the world (even today, DEC/25/2015 – 03:12 AM) and stealing your information (password, credit cards, keys, and so on). Thus, I will show you an extremely simple (almost naïve) anti-disassembly technique used by malwares as a distractor during your analysis:

.text:0044203C

.text:0044203C push ebp

.text:0044203D mov ebp, esp

.text:0044203F sub esp, 4

.text:00442045 push 440000h

.text:0044204A add [esp+8+var_8], 2057h

.text:00442055 retn

.text:00442055 sub_44203C endp

.text:00442055

.text:00442055 ; —————————————————————————

.text:00442056 dw 8BE9h

.text:00442058 ; —————————————————————————

.text:00442058 inc ebp

.text:00442059 or [eax+756C0178h], al

.text:0044205F push ds

.text:00442060 push offset dword_4420D0

.text:00442065 call sub_441444

.text:0044206A add esp, 4

.text:00442070 push dword ptr [ebp+8]

.text:00442073 call loc_4420A6

.text:00442078 add esp, 4

.text:0044207E add esp, 4

.text:00442084 pop ebp

.text:00442085 retn

The three highlighted lines contain a small trick. Indeed, they represent a simple jump to address 0x00442057. Why? Because the address 0x00440000 is pushed into stack and in next line the same value is added to 0x2057 resulting to 0x00442057. You should remember that result it kept on top of stack (ESP). Then, when the retn instruction is called, the result (0x00442057) is popped from stack into EIP and the flow is redirected to it. Sure, you need to change some data to code and vice versa during the analysis, but this time I only want to focus on this simple anti-disassembly technique.

It was extremely easy, was not it?

During next days I will show other small and nasty tricks used by malwares to make your analysis harder.

Have a nice day.

Alexandre Borges.

(LinkedIn: http://www.linkedin.com/in/aleborges and twitter: ale_sp_brazil)

Oracle 12c Transportable Tablespace on OTN (Oracle Technology Network)

Dear readers, how are you? It follows my article about Oracle 12c Transportable Tablespace on OTN (Oracle Technology Network):

https://community.oracle.com/docs/DOC-922240

I hope you have a nice day.

Alexandre Borges.

(LinkedIn: http://www.linkedin.com/in/aleborges and Twitter: @ale_sp_brazil)