NITAC miniCTF2 解説
自分は全23問中の10問の作問を担当したのでそれらの解説・想定解法を載せておきます。
Binary200 mosa1c
htmlが渡されます
何やら白黒のタイルがたくさん出てきます、ソースコードを見てみましょう
https://gyazo.com/8ac52e1d550368d47b2c6ea6f3d7ce82
これはあるファイルのバイナリを16進数でRGBに変換したものです
このページのタイトル「Look at the signature」で気づいた方も多いと思いますが、このファイルには50 4b 03 04というシグネチャがあるのでZIPファイルだとわかります
あとはここからバイト列を取り出してファイルに固めなおしてやるとFLAGの入ったZIPファイルが出てきます
先にファイルに固めてからflag.pngなどの文字列を見て気づいた参加者もいるみたいです
最初は100点問題だったのですが、直前に200点に引き上げられました
Binary300 xipher
「さいふぁー」って読んでほしい
ELFバイナリが渡されます、objdumpなどで逆アセンブルして読みましょう
暗号化する処理があるので、それを読んで暗号文を復号すればOK
平文を5文字ずつ区切ってコロコロ入れ替えてます
元のコードです
code:xipher.c
void swap(char *str, int a, int b) {
}
int main(int argc, char **argv) {
printf("Put your plaintext: ");
fgets(plain, 27, stdin);
printf("And your key: ");
fgets(keystr, 10, stdin);
int key = (int)strtoul(keystr, NULL, 10);
if (!key || strlen(plain) != 25) {
printf("Invalid parameters!\n");
return 0;
}
for (int i = 0; i < 25; i++) {
}
swap(plain, 1, key % 5);
swap(plain, 0, 3);
swap(plain, 4, 3);
printf("Here's encrypted flag: %s\n", plain);
return 0;
}
もともとはWebAssemblyで出力して渡したら楽しいかな〜とも思ったのですが結局x86でスタンダードに出題しました
Binary300 easyBIOS
以下のようなヒントからPBR/MBRを切り出してきたバイナリとわかります
「USBのデータの一部」
ファイル名「problem_pbr」
バイナリ末尾の55 AA
BIOSはここを16bitモードで読むということだけに注意して逆アセンブルすれば処理がわかります
FLAGの文字列をXORしてBIOSの機能で画面に表示しています
QEMUで動かした人もいましたね
元のアセンブラです
code:problem_pbr.asm
org 0x7c00
jmp short entry
nop
times 0x3e - ($ - $$) db 0
entry:
mov ax, 0
mov ss, ax
mov sp, 0x7c00
mov ds, ax
mov es, ax
mov ax, 0x0013
int 0x10
mov bl, 0xf
mov si, msg
call puts
fin:
hlt
jmp fin
puts:
inc si
cmp al, 0
je puts_end
xor al, 3
mov ah, 0x0e
mov bh, 0
int 0x10
jmp puts
puts_end:
ret
msg:
db "MJWB@xlaplofwf\ajlp~", 0
times 510 - ($ - $$) db 0
db 0x55, 0xaa
Binary100 Don't Feel Look
画像としてLookしてみましょう
https://gyazo.com/37c9b64416bb0bbe7f14eb9ba0eadc3d
GIMPで30秒で作った僕のアートが見られます
NITTCの人ごめんなさい
バイナリとしてLookしてみましょう
code:bash
$ xxd look_at_this.png | head -n 10
0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
0000010: 0000 0280 0000 0190 0806 0000 003e f3d1 .............>..
0000020: 2500 0000 0662 4b47 4400 ff00 ff00 ffa0 %....bKGD.......
0000030: bda7 9300 0000 0970 4859 7300 000b 1300 .......pHYs.....
...
00015f0: 0000 0840 0000 0420 0000 0210 0000 0108 ...@... ........
0001600: 00c0 56ff 0f79 e2d6 cb42 0e73 e800 0000 ..V..y...B.s....
0001610: 0049 454e 44ae 4260 824e 4954 4143 7b79 .IEND.B`.NITAC{y
0001620: 6573 5f79 6f75 5f6c 6f6f 6b5f 7468 6973 es_you_look_this
0001630: 7d0a }.
文字列だけをLookしてみましょう
code:bash
$ strings -n 10 look_at_this.png
...
NITAC{yes_you_look_this}
前回と同じネタです
Web100 leaking
アクセスするとすぐ戻されてしまいますね〜
ページ内のscriptでhistory.back()を使って即時戻しているみたいです
それに抗いつつ(JavaScriptを無効化するなど)Cookieを見てみるとsecretというキーにTklUQUN7bm90YWdhMW5fYWc0aW59Cg==という値が入っています
base64デコードするとFLAGです
こんな処理を書いてました
code:main.py
from flask import Flask, request, render_template, make_response
app = Flask(__name__)
@app.route('/')
def index():
resp = make_response(render_template("index.html"))
resp.set_cookie('secret', 'TklUQUN7bm90YWdhMW5fYWc0aW59Cg==')
return resp
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
Web200 Above the Cloud
途中から動かなくなりましたが、Solvedがいたので解説します
いくつかファイルがあるので見てみましょう
https://gyazo.com/5267f8a41c02d1294410759f006e0d3c
「雲の上」=cloudディレクトリの上にあるsecret.dbを読めということですね
今考えたらNext to the Cloudか?高専生なので英語はゆるしてください
/?f=../secret.dbのようにして上げると見えます
https://gyazo.com/a5205724d595b1b7af8b1e6ea34f59ed
「ディレクトリトラバーサル」という有名な脆弱性です
Web200 Chocolate Cookie Easy
クッキーっぽいなにかをポチポチすると下の文字が変化しますね
ソースを見てもらえばわかりますが、JavaScriptは使わずCSSのcounter系プロパティを乱用して実装しています
https://gyazo.com/ac5fa41bd426781b4f40da57414a495b
PPC的解法: 16個のcheckboxのオンオフをスクリプトなどで全通り試すとFLAGが出てきます
rev的解法: CSSのrules.cssを読み解くとNITAC{が出る組み合わせが1つに定まります
みんな総当りするやろとか思ってたんですが、会場ではほとんどのチームが後者の解法をとっていて驚きでした
Crypto100 Intro to AES
スクリプトが渡されるのでそれをちょっと書き換えるとうまくいきます
code:encrypt.rb
require 'openssl'
flag = "NITAC{??????????????????}"
key = "MozcSenpaiOhayou"
cipher = OpenSSL::Cipher.new 'AES-128-CBC'
cipher.encrypt
cipher.key = key
p cipher.update(flag) + cipher.final
# 実行結果
# $ ruby encrypt.rb
# "b{/\tb\xE37`\xB2\x91L\xFD\xD0\x84\xB7\x1C\xFF\xE8\x84\xEE\x99\x95\xB0\a\xB0B\x9E\x11a\x8A\x17\xA4"
これを…
code:decrypt.rb
require 'openssl'
key = "MozcSenpaiOhayou"
cipher = OpenSSL::Cipher.new 'AES-128-CBC'
cipher.decrypt
cipher.key = key
p cipher.update(flag) + cipher.final
# => NITAC{r1jnda4l_symm3tric}
Network100 itadakimasu
前日になってNetwork問がないことに気づいたので入れてみました
pcapファイルが渡されるのでWiresharkでいただいてください
HTTPの通信が入ってます
クライアント側が定期的に/readyを送って(polling)、サーバからの応答によってコマンドを実行して/exec_resultから結果を送り返す形式です
https://gyazo.com/607c474de94dc052d426dfd2d6b130ec
stringsへのせめてもの抵抗としてxxd flag.txtにしたんだなあと笑っていただければ嬉しいです(?)
Network500 gochisosama
マルウェアの通信を模したpcapファイルです
ただpollingとコマンドを実行する形式はitadakimasuと同じです
逆に違うのは通信がAESで暗号化されている点です、まず/initで暗号化キー、アルゴリズムを交換します
そこからは/data/(id)-(encrypted message)という形式でやりとりを繰り替えします
一定回数ごとに鍵を変更する処理が入っているのでそれに気をつければ最後にcat flag.txtが実行されて出てきます