T1 easy_overflow
2023-01-14WP
Hgame week1 pwn 第二题
考点:简单栈溢出
0x01
file——64-bit,
checksec 开启NX
0x02
IDA看源码,先找/bin/sh,一路索引过去发现在一个后门函数中
然后我的第一反应是先记下call system的地址,结果一看,没找到?取而代之的是call sub_401060
于是我卡了一下,可能是第一次碰到这样的题的缘故,我没有意识到函数名称可以是不一样的
打开main函数伪代码也是这样……
越看越不对劲,搜索资料才发现这种题的风格就是去符号使原函数名字无法显示
这么说IDA无法解决了
0x03
我们转而动态调试试一下
我们假设文件带有system函数,又据题意应该是有gets或者read之类的函数的
运行文件测试一下确实如此
那么我们在这几个函数处试着打断点
我们可以看到,其中system的地址和后面函数中的call sub_401060的plt处地址对上了
read函数的地址和main函数中的 call sub_401080的plt处地址对上了
同时呢,gdb运行文件的时候还发现main函数中还有一个close函数,浏览一下main函数源码只有sub_401070了
查阅了一些资料得知,close(1)关闭了标准输出,详细见这篇文章
也就是有下面我们得到shell后无法在屏幕上看到flag的情况
这时候就要输入exec 1>&0重启标准输出
那么现在呢我们已经把文件里的几个主要函数分析好了,接下来就要找偏移量了
0x03
这一部分我发现一个很坑的地方,如果我们用ctf-wilki上的方法,那么我们在gdb调试设断点的时候就不能设
b read
这样设的话我们直接就进入到read函数里了,那就无法看到储存数据的寄存器(不管是什么)距rsp或者rbp的偏移了
并且,此时已经开始进入read子函数,即已经分配了新的栈帧了,rsp已经移动,再去计算rsp和rbp的差值则会不准确
b *0x4011be
我们应该这样设断点,这样就停止在进入read函数之前,不仅可以看到相对偏移,还能计算出rbp-rsp
得出rsp和rsi 0x7fffffffddd0,rbp为0x7fffffffdde0,计算得距rbp偏移量就为0x7fffffffdde0-0x7fffffffddd0
那么再加上rbp求得为0x10+8
还可以暴力求得 懒得计算偏移量的话
0x04
可以写exp
from pwn import *
p = remote("week-1.hgame.lwsec.cn", 30574)
system_addr = 000000000401176
payload = b ' a ' * 0x18 + p64(system_addr)
p.sendline(payload)
p.interactive()
0x05
好奇怪为什么官方的WP可以直接反汇编成正常的函数?
搜了一下好像可以手动添加标签,这篇文章教了一下这么回复库函数名,但是看不懂……
0x06
得到shell后发现并没有办法显示出flag,问题就在之前的那个close(1)因为汇编代码中有这样一句
mov edi, 1
所以认为close()括号里的参数时1
这时候需要使用命令让shell能够正常回显
exec 1>&0
累死了,终于拿到flag