|
| 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 | + |
| 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 | + |
| 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