Skip to content

Commit e15563b

Browse files
committed
post: add BroncoCTF 2025 Writeup
1 parent 0c75557 commit e15563b

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
---
2+
author: "UmmIt"
3+
title: "Bronco CTF 2025 Writeup"
4+
tags: ["Bronco CTF", "2025", "Writeup", "CTF"]
5+
date: 2025-02-17T10:16:30+0800
6+
lastmod: 2025-03-02T04:37:15+0800
7+
---
8+
9+
# Introduction
10+
11+
Bronco CTF 2025 began on Sunday, February 16, 2025, at 3:00 AM and concluded on Monday, February 17, 2025, at 3:00 AM. The event was organized by the Santa Clara University Cybersecurity Club. Fortunately, the timing of the event worked well for me, as I tend to stay up late. I spent about 10 hours solving challenges and managed to complete around 4 of them. This competition was quite guess-based and non-technical, so I ended up skipping several challenges.
12+
13+
> Event Website: [Bronco CTF](https://ctfd.broncoctf.xyz/)
14+
15+
## Delayed Announcement
16+
17+
Bronco CTF 2025 experienced an unexpected delay due to server issues caused by a high volume of participants trying to access the site. As a result, the competition was postponed for about 6 hours. The organizers provided a Google Drive link to download the challenges, allowing us to work on them while the server was down. Once the server was back up, we could submit our flags through the platform.
18+
19+
## Break the Battalion
20+
21+
This challenge involved simple reverse engineering. We were given a binary file `a.out` and tasked with finding the flag within it.
22+
23+
### Solution
24+
25+
Upon examining the file, I identified it as a `.out` file, which indicated it was compiled with g++ or gcc. I opened it to see what it does.
26+
27+
```bash
28+
┌──(leon㉿localhost)-
29+
└─$ ./a.out
30+
What is ze passcode monsieur?
31+
232
32+
bcb
33+
wrong password
34+
```
35+
36+
It appeared to be a password-protected file, and I needed to discover the actual password to retrieve the flag. After some guessing, I decided to use `strings` to analyze the binary file.
37+
38+
```bash
39+
┌──(leon㉿localhost)-
40+
└─$ strings a.out
41+
...
42+
Debugger detected! Exiting...
43+
What is ze passcode monsieur?
44+
%255s
45+
brigade
46+
correct password
47+
wrong password
48+
;*3$"
49+
GCC: (GNU) 14.2.1 20240910
50+
new.c
51+
...
52+
```
53+
54+
From the `strings` output, I could see that it was a GCC-compiled file, with the original file name being `new.c`. The password input was identified as `brigade`. This was enough information to retrieve the flag, but I decided to analyze the file further using radare2.
55+
56+
Using radare2, I disassembled the binary to find the flag.
57+
58+
```bash
59+
┌──(leon㉿localhost)
60+
└─$ r2 a.out
61+
WARN: Relocs has not been applied. Please use `-e bin.relocs.apply=true` or `-e bin.cache=true` next time
62+
[0x000010b0]> iz
63+
[Strings]
64+
nth paddr vaddr len size section type string
65+
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
66+
0 0x00002004 0x00002004 29 30 .rodata ascii Debugger detected! Exiting...
67+
1 0x00002022 0x00002022 29 30 .rodata ascii What is ze passcode monsieur?
68+
2 0x00002040 0x00002040 5 6 .rodata ascii %255s
69+
3 0x00002046 0x00002046 7 8 .rodata ascii brigade
70+
4 0x0000204e 0x0000204e 16 17 .rodata ascii correct password
71+
5 0x0000205f 0x0000205f 14 15 .rodata ascii wrong password
72+
```
73+
74+
I confirmed that `brigade` was indeed the password, so I tried it.
75+
76+
```bash
77+
┌──(leon㉿localhost)-
78+
└─$ ./a.out
79+
What is ze passcode monsieur?
80+
brigade
81+
2"97145
82+
wrong password
83+
```
84+
85+
This time, I received an interesting hint: `2"97145`. I decided to try this input.
86+
87+
```bash
88+
┌──(leon㉿localhost)-
89+
└─$ ./a.out
90+
What is ze passcode monsieur?
91+
2"97145
92+
brigade
93+
correct password
94+
```
95+
96+
This time, I received the output `correct password`, and the flag was `bronco{brigade}`.
97+
98+
![break-the-battalion](https://dl.ummit.dev/BroncoCTF.2025/Break%20the%20Battalion.png)
99+
100+
## Inspector Requestor
101+
102+
For this challenge, we were given a link to a Google Form, but it said, `unfortunately, it was too late for us to retrieve the flag. It felt like a trick.`
103+
104+
### Solution
105+
106+
The solution was straightforward: I simply browsed the source code of the page, and there it was—the flag.
107+
108+
```
109+
Since you are here, here is the flag! Inspect element is fun.
110+
bronco{why_does_google_still_expos3_th1s_wh3n_i_stopped_accepting_submissions_101}
111+
```
112+
113+
The flag is `bronco{why_does_google_still_expos3_th1s_wh3n_i_stopped_accepting_submissions_101}`.
114+
115+
## Mary's Lamb is a Little Phreak
116+
117+
This challenge was quite guess-based. We were given a link to input some text, and we had to guess the flag. No technical skills were required for this challenge.
118+
119+
### Solution
120+
121+
I searched through a search engine using the phrase `mary had a little lamb in DTMF`, and the first website that appeared in the results contained the flag.
122+
123+
and the flat is `bronco{32123332223333212333223211}`
124+
125+
![Mary's Lamb is a Little Phreak](https://dl.ummit.dev/BroncoCTF.2025/Mary's%20Lamb%20is%20a%20Little%20Phreak.png)
126+
127+
## Rahhh-Sh
128+
129+
This challenge was a cryptography task where we had to decrypt the given text to obtain the flag.
130+
131+
### Solution
132+
133+
I used Python to decrypt the message.
134+
135+
```python
136+
import math
137+
138+
e = 65537
139+
p = -811
140+
n = 3429719
141+
142+
q = n // p
143+
144+
phi_n = (p + 1) * (q + 1)
145+
146+
def extendedEuclideanAlgo(e, phi_n):
147+
A1, A2, A3 = 1, 0, phi_n
148+
B1, B2, B3 = 0, 1, e
149+
150+
while True:
151+
if B3 == 0:
152+
return -1
153+
if B3 == 1:
154+
return B2
155+
156+
Q = A3 // B3
157+
T1, T2, T3 = A1 - (Q * B1), A2 - (Q * B2), A3 - (Q * B3)
158+
A1, A2, A3 = B1, B2, B3
159+
B1, B2, B3 = T1, T2, T3
160+
161+
d = extendedEuclideanAlgo(e, phi_n)
162+
163+
def decrypt(c, d, n):
164+
return [pow(ci, d, n) for ci in c]
165+
166+
c = [-53102, -3390264, -2864697, -3111409, -2002688, -2864697, -1695722, -1957072, -1821648, -1268305, -3362005, -712024, -1957072, -1821648, -1268305, -732380, -2002688, -967579, -271768, -3390264, -712024, -1821648, -3069724, -732380, -892709, -271768, -732380, -2062187, -271768, -292609, -1599740, -732380, -1268305, -712024, -271768, -1957072, -1821648, -3418677, -732380, -2002688, -1821648, -3069724, -271768, -3390264, -1847282, -2267004, -3362005, -1764589, -293906, -1607693]
167+
168+
decrypted_message = decrypt(c, d, n)
169+
170+
flag = ''.join(chr(m) for m in decrypted_message if 0 <= m < 256)
171+
print("Decrypted Message:", decrypted_message)
172+
print("Flag:", flag)
173+
```
174+
175+
flag: `bronco{m4th3m4t1c5_r34l1y_1s_qu1t3_m4g1c4l_raAhH!}`.
176+
177+
## Conclusion
178+
179+
Overall, Bronco CTF 2025 was too guess-based, Personally, I prefer technical challenges. but unfortunately, almost all the challenges were guess-based. I hope the next CTF will be more technical and challenging.

0 commit comments

Comments
 (0)