I've got a pretty tricky flag that I have been beating my head against for a while now and would love an explanation for how something like this would be possible. I have a program that when run, seemingly immediately cancels itself. File returns: file.exe: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=60e0255339eac5de5c216aed54d2b55cfa3d7dda, not stripped
and
Checksec returns:
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
As you can see, it has a canary enabled which is a problem considering the program accepts no input after running it. Usually I would either brute force the canary or grab it when it leaks then pass it to be input, but I don't see how it's possible to grab the leak and then put it in as an arg after the fact - but since the canary changes on execution you clearly have to do that. Everything looks like you'd expect when disassembling it in ghidra - except for the no input part. Here's the main func:
0x000000000040060e <+0>: push rbp
0x000000000040060f <+1>: mov rbp,rsp
0x0000000000400612 <+4>: sub rsp,0x10
0x0000000000400616 <+8>: mov DWORD PTR [rbp-0x4],edi
0x0000000000400619 <+11>: mov QWORD PTR [rbp-0x10],rsi
0x000000000040061d <+15>: mov rax,QWORD PTR [rbp-0x10]
0x0000000000400621 <+19>: add rax,0x8
0x0000000000400625 <+23>: mov rax,QWORD PTR [rax]
0x0000000000400628 <+26>: mov rdi,rax
0x000000000040062b <+29>: call 0x4005a7 <evil>
0x0000000000400630 <+34>: mov eax,0x0
0x0000000000400635 <+39>: leave
0x0000000000400636 <+40>: ret
and here's the evil func:
0x00000000004005a7 <+0>: push rbp
0x00000000004005a8 <+1>: mov rbp,rsp
0x00000000004005ab <+4>: sub rsp,0x70
0x00000000004005af <+8>: mov QWORD PTR [rbp-0x68],rdi
0x00000000004005b3 <+12>: mov rax,QWORD PTR fs:0x28
0x00000000004005bc <+21>: mov QWORD PTR [rbp-0x8],rax
0x00000000004005c0 <+25>: xor eax,eax
0x00000000004005c2 <+27>: mov DWORD PTR [rbp-0x54],0x0
0x00000000004005c9 <+34>: mov rdx,QWORD PTR [rbp-0x68]
0x00000000004005cd <+38>: lea rax,[rbp-0x50]
0x00000000004005d1 <+42>: mov rsi,rdx
0x00000000004005d4 <+45>: mov rdi,rax
0x00000000004005d7 <+48>: mov eax,0x0
0x00000000004005dc <+53>: call 0x4004b0 <sprintf@plt>
0x00000000004005e1 <+58>: mov eax,DWORD PTR [rbp-0x54]
0x00000000004005e4 <+61>: cmp eax,0xdeadbeef
0x00000000004005e9 <+66>: jne 0x4005f7 <evil+80>
0x00000000004005eb <+68>: lea rdi,[rip+0xd6] # 0x4006c8
0x00000000004005f2 <+75>: call 0x400490 <puts@plt>
0x00000000004005f7 <+80>: nop
0x00000000004005f8 <+81>: mov rax,QWORD PTR [rbp-0x8]
0x00000000004005fc <+85>: xor rax,QWORD PTR fs:0x28
0x0000000000400605 <+94>: je 0x40060c <evil+101>
0x0000000000400607 <+96>: call 0x4004a0 <__stack_chk_fail@plt>
0x000000000040060c <+101>: leave
0x000000000040060d <+102>: ret
there's clearly some pretty suspect stuff going on here, but I can't seem to make heads or tails of it.
edit: I've found this video which is exactly this problem but with a buffer of 72 and I can not for the life of me figure out how to get this to work. Could someone explain to me where he gets the numbers from in his fuzzing script?
edit2: Here's an asciinema recording of me replicating that video ^