この大会は2019/4/2 14:00(JST)~2019/4/4 14:00(JST)に開催されました。
今回もチームで参戦。結果は3536点で681チーム中4位でした。
自分で解けた問題をWriteupとして書いておきます。
sanity check (Misc 1)
ルールのページにフラグが書いてあった。
Thanks for reading rules here's your free flag: encryptCTF{L3t5_H4CK}
encryptCTF{L3t5_H4CK}
ham-me-baby (Misc 100)
$ nc 104.154.106.182 6969 Welcome To ____ __ _______________ / __/__ __________ _____ / /_ / ___/_ __/ __/ / _// _ \/ __/ __/ // / _ \/ __/ / /__ / / / _/ /___/_//_/\__/_/ \_, / .__/\__/ \___/ /_/ /_/ ___/___/_/_____ |_ |/ _ < / _ \ / __// // / /\_, / /____/\___/_//___/ you will be receiving hamming(7,4) codes. your job is to send data bits from a 7 bit hamming code. ___________________________________________________________________ | | | DO YOUR RESEARCH : https://en.wikipedia.org/wiki/Hamming(7,4) | | FLAG WILL BE PRINTED AFTER YOU SEND CORRECT DATA BITS 100 TIMES | |___________________________________________________________________| and come back here. remember somebits could be flipped. you need to send correct data bits. [*] CODE: 1011101 [*] DATA: 1101 [*] CODE: 1100010 [*] DATA: 0010 [*] CODE: 1011100 [*] DATA: 1100 [*] CODE: 1001110 [*] DATA:
Hamming(7,4)の問題。訂正せずにCODEから一部を取り出せばよいだけ。
import socket def recvuntil(s, tail): data = '' while True: if tail in data: return data data += s.recv(1) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('104.154.106.182', 6969)) data = recvuntil(s, 'bits.\n').strip() print data data = recvuntil(s, '\n').strip() print data data = recvuntil(s, '\n').strip() print data for i in range(100): print 'Round %d' % (i+1) data = recvuntil(s, '\n').strip() print data if data == 'CODE VALIDATED': data = recvuntil(s, '\n').strip() print data code = data.split(': ')[1] d = code[2] + code[-3:] data = recvuntil(s, ': ') print data + d s.sendall(d + '\n') data = recvuntil(s, '\n').strip() print data
encryptCTF{hummmmm_hummmmmm}
ham-me-baby-2 (Misc 100)
ham-me-babyの問題の訂正らしい。CODEから必要に応じて訂正し、データ部分のみ返す必要がある。
import socket def recvuntil(s, tail): data = '' while True: if tail in data: return data data += s.recv(1) def check_bit(code): d = map(int, [code[2], code[4], code[5], code[6]]) p = map(int, [code[0], code[1], code[3]]) if (d[0] + d[1] + d[3]) % 2 != p[0]: return False elif (d[0] + d[2] + d[3]) % 2 != p[1]: return False elif (d[1] + d[2] + d[3]) % 2 != p[2]: return False return True def correct(code): if check_bit(code): try_code = code else: for i in range(len(code)): if code[i] == '0': try_code = code[:i] + '1' + code[i+1:] else: try_code = code[:i] + '0' + code[i+1:] if check_bit(try_code): break return try_code[2] + try_code[-3:] s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('104.154.106.182', 6969)) data = recvuntil(s, 'bits.\n').strip() print data data = recvuntil(s, '\n').strip() print data for i in range(100): print 'Round %d' % (i+1) data = recvuntil(s, '\n').strip() print data code = data.split(': ')[1] correct_data = correct(code) data = recvuntil(s, ': ') print data + correct_data s.sendall(correct_data + '\n') data = recvuntil(s, '\n').strip() print data data = recvuntil(s, '\n').strip() print data
encryptCTF{1t_w4s_h4rd3r_th4n_1_th0ught}
Sweeeeeet (Web 50)
CookieのFLAGに以下がセットされている。
encryptCTF%7By0u_c4nt_U53_m3%7D →encryptCTF{y0u_c4nt_U53_m3}
これはフラグとして通らない。
CookieのUIDに以下がセットされている。
f899139df5e1059396431415e770c6dd
md5逆変換すると、"100"になる。
以下の"0"のmd5をセットしてみる。
cfcd208495d565ef66e7dff9f98764da
CookieのFLAGが以下に変わった。
encryptCTF%7B4lwa4y5_Ch3ck_7h3_c00ki3s%7D%0A
encryptCTF{4lwa4y5_Ch3ck_7h3_c00ki3s}
It's a WrEP (Forensics 50)
無線通信のcapファイルが添付されている。
$ aircrack-ng encryptCTFWEP.cap Opening encryptCTFWEP.cap Read 546320 packets. # BSSID ESSID Encryption 1 58:D7:59:79:61:34 MCSP No data - WEP or WPA 2 40:31:3C:E6:CA:3C Malik’s WPA (1 handshake) 3 14:CC:20:F5:32:FE encryptCTF WEP (88648 IVs) 4 0C:D2:B5:72:3C:D4 home WPA (0 handshake) 5 E4:6F:13:80:82:99 prime2 No data - WEP or WPA 6 04:95:E6:05:50:60 Letzpay1 WPA (0 handshake) 7 C4:B8:B4:BF:5B:C8 foresightinn No data - WEP or WPA 8 B4:EF:FA:51:EC:53 Le 2 No data - WEP or WPA 9 72:B7:AA:33:56:23 vivo 1802 None (0.0.0.0) 10 78:D3:8D:E4:E5:8C Sarovar None (172.16.168.188) 11 50:5D:AC:94:3D:E4 Webnyxa_airtel_12G No data - WEP or WPA 12 C4:B8:B4:4D:93:74 Webnyxa_airtel_first No data - WEP or WPA 13 C8:D7:79:A7:E0:0A Unknown 14 B0:C1:9E:A3:18:BA Airtel-Hotspot-18BA WPA (0 handshake) 15 C4:B8:B4:A8:92:20 sanchez No data - WEP or WPA 16 74:DA:DA:D8:86:77 Orium WPA (0 handshake) 17 AC:EE:9E:91:D3:43 AndroidAP No data - WEP or WPA 18 AE:56:2C:96:57:C9 Unknown 19 84:FE:DC:DC:8C:06 password No data - WEP or WPA 20 04:B1:67:C2:3D:87 Redmiamit No data - WEP or WPA 21 70:5A:AC:92:B9:BC Ritesh mobile No data - WEP or WPA Index number of target network ? 3 Opening encryptCTFWEP.cap Attack will be restarted every 5000 captured ivs. Starting PTW attack with 88648 ivs. Aircrack-ng 1.2 beta3 [00:00:00] Tested 837 keys (got 85909 IVs) KB depth byte(vote) 0 0/ 17 57(107520) 84(99840) 71(97536) B5(97536) D0(96512) 1 0/ 1 C4(116992) DD(98816) 1A(97792) 3A(96768) 59(94720) 2 2/ 2 3E(101632) 4D(98816) 9B(97536) 2B(96256) 5E(96000) 3 13/ 3 C5(93952) B6(93440) 63(93184) 72(93184) B8(92928) 4 0/ 1 98(121344) F8(98048) C2(97536) C1(97280) D4(96000) KEY FOUND! [ 57:34:35:5F:31:37:5F:52:33:34:4C:3F:21 ] (ASCII: W45_17_R34L?! ) Decrypted correctly: 100%
WEPキーが見つかった。
encryptCTF{W45_17_R34L?!}
Journey to the centre of the file 1 (Forensics 75)
zipとgzで何重にも圧縮しているので、スクリプトで解凍する。
import subprocess import os cmd_file = 'file flag' cmd_zip = 'unzip flag.zip' cmd_gzip = 'gzip -d flag.gz' i = 1 while True: print 'Round %d' % i i += 1 if os.path.exists('flag.zip'): cmd = cmd_zip ret = subprocess.check_output( cmd.split(" ") ) os.remove('flag.zip') elif os.path.exists('flag.gz'): cmd = cmd_gzip ret = subprocess.check_output( cmd.split(" ") ) ret = subprocess.check_output( cmd_file.split(" ") ) if 'Zip archive' in ret: os.rename('flag', 'flag.zip') else: ret = subprocess.check_output( 'cat flag'.split(" ") ) print ret break else: break
encryptCTF{w422up_b14tch3s}
Wi Will H4CK YOU!! (Forensics 100)
無線通信のcapファイルが添付されている。
$ aircrack-ng -w dict/rockyou.txt encryptCTFWPA.cap Opening encryptCTFWPA.cap Read 4790 packets. # BSSID ESSID Encryption 1 14:CC:20:F5:32:FE encryptCTF WPA (1 handshake) 2 0C:D2:B5:72:3C:D4 home No data - WEP or WPA 3 40:31:3C:E6:CA:3C Malik’s WPA (0 handshake) 4 00:00:00:00:00:00 Unknown Index number of target network ? q Index number of target network ? 1 Opening encryptCTFWPA.cap Reading packets, please wait... Aircrack-ng 1.2 beta3 [01:41:30] 7049164 keys tested (1210.81 k/s) KEY FOUND! [ ThanckYou ] Master Key : 48 89 DD 32 53 9E A7 49 1E 63 3D F7 06 CD CD 4F 0E 1E 22 56 BD DA 8B 10 ED 80 6D 8E 20 3C 7B D3 Transient Key : F0 F9 59 E0 EA 24 01 AC B4 B9 CE 01 F3 04 60 A9 C9 84 6F 2A 59 0A 24 9E 3E 5E 87 36 64 EC D8 8D C3 2C AA FA E7 02 D0 D1 D2 64 96 2E A7 A8 D5 29 4B FF A3 EB AB 16 D9 11 F7 2F F3 6B 2D F8 61 31 EAPOL HMAC : EC F7 55 70 56 9E 7B AE 18 BB 39 6E 88 C6 F3 F2
WPAキーが見つかった。
encryptCTF{ThanckYou}
yhpargonagets (Steganography 25)
Pythonライブラリを使う。
from steganography.steganography import Steganography flag = Steganography.decode('encode.jpg') print flag
encryptCTF{pip_in5t411_5teg4n0graphy}
Stressed out? (Steganography 100)
wavファイルのプロパティを見ると、タイトルは以下のようになっている。
1_4M_Str3ss3d_0ut
wavを対応しているsteghideを試してみる。
$ steghide extract -sf dontstressoutkiddo.wav Enter passphrase: ★先ほどのタイトルを指定 wrote extracted data to "flag.jpg".
flag.jpgを取り出せて、そこにフラグが書いてあった。
encryptCTF{tyl3r_j0s3ph_is_4_g0d}
Hard Looks (Cryptography 75)
"-"を1、"_"を0にして考える。暗号文の長さは8の倍数でないので、先頭に不足分0をつけて、デコードする。
enc = '--_--___--_-_-__--_--__--__-_-__--_--___--__--__--_---__--__-___--_---__---__-__--_---__--______--_---__--_-____--_-____--__--__--_-_-__--_-____--_-____--_--___--_---_--___-___--_-_-__--_---__--__--__--_-____--__--__--_-_-__--_-_-_--__--___--__--__--___-__--__--__--_---__--_-_-_--__--___--_-____---_____--__--__--_-____--_-_-__--__-___--_-____--_-____--_-_-_--__--___--__--__--__--__--_-___--__-_-__--__--__--______--_-_-__--_-_-__--_-____--_---__--_-____---_____--__--_--__--___--__-___--___-__--_---_--__-__' enc = enc.replace('-', '1') enc = enc.replace('_', '0') while True: if len(enc) % 8 == 0: break enc = '0' + enc msg = '' for i in range(0, len(enc), 8): msg += chr(int(enc[i:i+8], 2)) flag = msg.decode('hex') print flag
encryptCTF{W45_17_H4RD_3N0UGH?!}
RSA_Baby (Cryptography 100)
qとnが分かっているので、pは算出できる。あとはそのまま復号する。
from Crypto.Util.number import * e = 65537 q = 9896984395151566492448748862139262345387297785144637332499966426571398040295087125558780121504834847289828037371643927199404615218623314326851473129699891 with open('flag.enc', 'r') as f: data = f.read() c = int(data.split('\n')[1], 16) n = int(data.split('\n')[2].split(': ')[1]) p = n / q phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(c, d, n) flag = long_to_bytes(m) print flag
encryptCTF{74K1NG_B4BY_S73PS}
Julius,Q2Flc2FyCg== (Cryptography 150)
Base64デコードして、シフトしたら復号できた。
enc = 'fYZ7ipGIjFtsXpNLbHdPbXdaam1PS1c5lQ' while True: if len(enc) % 4 == 0: break enc += '=' dec = enc.decode('base64') flag = '' for i in range(len(dec)): code = ord(dec[i]) - 24 flag += chr(code) print flag
encryptCTF{3T_7U_BRU73?!}
AEeeeeS (Cryptography 200)
AESキーは2進数になっているが、バイナリに変えると16バイトになる。あとはそのままAES復号を行う。
from Crypto.Cipher import AES with open('AEeeeeS.key', 'r') as f: data = f.read().strip() while True: if len(data) % 8 == 0: break data = '0' + data key = '' for i in range(0, len(data), 8): key += chr(int(data[i:i+8], 2)) enc = 'c68145ccbc1bd6228da45a574ad9e29a77ca32376bc1f2a1e4cd66c640450d77' cipher = AES.new(key, AES.MODE_ECB) flag = cipher.decrypt(enc.decode('hex')) print flag
encryptCTF{3Y3S_4R3_0N_A3S_3CB!}
(TopNOTCH)SA (Cryptography 300)
nをfactordbで素因数分解する。
57891041571118599917733172578294383243762455810797917992757930072844611988433 = 194038568404418855662295887732506969011 * 298348117320990514224871985940356407403
あとはそのまま復号する。
from Crypto.PublicKey import RSA from Crypto.Util.number import * with open('pubkey.pem', 'r') as f: pub_data = f.read() pubkey = RSA.importKey(pub_data) n = pubkey.n e = pubkey.e p = 194038568404418855662295887732506969011 q = 298348117320990514224871985940356407403 assert n == p * q with open('flag.enc', 'r') as f: data = f.read() c = int(data.split('\n')[1], 16) phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(c, d, n) flag = long_to_bytes(m) print flag
encryptCTF{1%_0F_1%}