TsukuCTF 2022 writeup
TsukuCTF 2022にチームDCDCで参加し3位でした。
OSINT力はそこまでないのですが、普段出すことのできないOSINT力を発揮できるTsukuCTFはとても楽しかったです。

- [Tushkushi] Welcome
- [OSINT] inuyama082
- [OSINT] station
- [OSINT] Gorgeous Interior Bus
- [OSINT] Flash
- [OSINT] Bus POWER
- [OSINT] what_time_is_it
- [OSINT] uTSUKUSHIi
- [Reversing] GrandpaMemory
[Tushkushi] Welcome
Tushkushi 2022のDiscordサーバの🚩-welcome-to-tsukuctfチャンネルにフラグがありました

[OSINT] inuyama082

店名は分からないけど抹茶の画像から犬山市の抹茶屋さんであることは予想できたので、"犬山市 抹茶"とGoogle検索し画像を眺めました。
犬山カフェよあけや というお店に行ったブログ記事の写真が配布画像と似ていたので、犬山カフェよあけやのメニューを調べました。
メニューを一通り調べた結果、答えはTsukuCTF22{和チーズケーキ ver.煎茶パウダー}でした。
検索結果を見ると犬山市には抹茶屋などお茶に関係する店が多いことが気になり犬山市とお茶の関係について調べると、犬山城下有楽苑にある如庵という茶室が 国宝茶席三名席であったりと、犬山市はお茶の歴史がある地域なのだと勉強になりました。 osintしている途中で雑学知識が増えていくのはosintの魅力だなぁと思いました。
[OSINT] station

東豊線という文字と写真の雰囲気から札幌市の地下鉄の駅だと分かります。 札幌市の地下鉄
は、南北線・東西線・東豊線と3つの路線があるらしいのですが、東豊線には女性専用車両がないそうなので、東豊線の駅は除外できまた。また、youtubeで札幌市営地下鉄の動画を見たところ、飛び込み防止柵の黄色は東西線を表していることが分かったので東西線の駅と絞れました。
東西線の駅の路線図を見ながらもう一度画像を見てると、画像中の柱の案内は西11丁目の新さっぽろ方面へ行く人向けの案内ではないかと気づきました。
撮影場所が西11丁目駅だとすると、新さっぽろ方面の次の駅は南北線と東豊線も通っている大通駅であり南北線と東豊線の文字が書いてあることに納得できます。
答えはTsukuCTF22{西11丁目}でした。
[OSINT] Gorgeous Interior Bus

バス先頭のモニタを見ると次の次の停車駅は〜スパあたみ駅であることが分かります。
Google検索はサジェストが得意なので"スパあたみ"で検索すると、マリンスパあたみという建物があることが分かりました。マリンスパあたみの近くにはバス停があるのでしょう。
このバスは豪華なので熱海駅は経由してるだろうと思い、熱海駅からマリンスパあたみへの行き方を調べると、このバスは熱海駅→〜→銀座→親水公園→マリンスパあたみ のルートのバスと分かりました。なのでこのバスの次の停車駅は銀座のようです。
Google mapで静岡県の銀座付近の交差点を調べると、東海岸町交差点という交差点がありました。
答えはTsukuCTF22{東海岸町}でした。
[OSINT] Flash
マイコンのフラッシュメモリから読み出したデータから、プログラムが動いていたホテル名と部屋番号を特定する問題です。
最初にrand0mさん(@crypt_3n)がデータの中のapa-316-2428という怪しい文字列を見つけてくれました。
アパホテルは部屋ごとにSSIDが分けられていることを聞いたことがあったので、この文字列に部屋番号が含まれていると思いました。
数字で管理したい人って色々な物を数字で管理するよな(偏見)と思い、アパホテルの建物ごとに番号が与えられてないかと調べると、アパホテルは建物ごとに3桁の数字がNo.数字という形で割り当てられていることが分かりました。
site:www.apahotel.com "No. 316"などとGoogle検索すると、No. 316はアパホテル&リゾート〈両国駅タワー〉だそうです。
部屋番号は2428であってくれと思いながら、答えを提出すると
答えはTsukuCTF22{アパホテル&リゾート〈両国駅タワー〉_2428}で正解でした。
[OSINT] Bus POWER
撮影場所付近の交差点の名前を当てる問題です。

自分は京都に住んだことがあったので、バスの先頭の座席が使用禁止であることやバスの運賃、道路の雰囲気から京都市内で撮影された写真であることがすぐに分かりました。
また、この通りは歩いたこともあり今出川通の雰囲気を感じ取れたので、Google mapのストリートビューで今出川通を歩きました。
信号機や画像右端に写っているクロネコヤマトの看板を目安に探していると、
答えはTsukuCTF22{千本今出川}と分かりました。
[OSINT] what_time_is_it
手前の電車の発車時刻を当てる問題です。

この問題はv1enettaさんと考えて解いてました。
まず、赤い電車がJR四国の特急うずしおであることはすぐに分かりました。
また、特急うずしおの停車駅とGoogle Mapの3Dビューを使うと、この画像はJR四国の徳島駅の2番ホームから撮影されたものだと分かりました。
次に、徳島駅の時刻表からこの画像の特急うずしおの発車時刻を特定するのですが、その前にやっておかなければならないことがあります。
それは時刻表の特定です。
鉄道会社は、鉄道の時刻表を顧客の需要や収益を基にダイヤを改正(時刻表を変更)をすることがあります。
このことから、まずは画像が撮影された年月をおおよそ特定し時刻表を手にいれた後、(その頃の車両に関する公式の資料や鉄道有識者が収集したデータから)電車の発車時刻を特定します。
画像の手前の方が半ズボンを履いていたり木の緑の感じから撮影時期は夏です。また、向かいのホームにマスクした方が元気よく歩いてる姿が見えるのでコロナ期以降の2020年夏 or 2021年夏 or 2022年夏 と予想できます。
2020年夏はコロナが未知のウイルスと恐れられていた時期で2021年夏は緊急事態宣言が発令されている時期なので、消去法により2022年夏に撮影されたと予想しました。
2022年夏の徳島駅の時刻表は、2022年3月12日に改定されて現在も使われているこのページのものです。
画像は手前から2番線、3番線、4番線と3本の電車が並んでます。数字が蜜に並んでいない時刻表を見ると分かるように、徳島駅においてこのように電車が3本並んでいるのはかなり珍しい時間帯です。
なので、時刻表から2番線、3番線、4番線の電車の発車時刻が近い組み合わせを探すと次のような組み合わせが見つかりました。
2番線:15:23発 (うずしお20号) 3番線:15:30発 4番線:15:30発
Twitterでうずしお20号についての投稿を検索すると、このツイートやこのツイートのように、徳島駅にうずしお20号が発車準備をしている時間帯に3本の電車が並んでいることを確認できました。
答えはTsukuCTF22{15:23}でした。
電車についてたくさん調べていると鉄道オタクになりかけました。 時刻表に車両番号書いてほしいと思いました😥
[OSINT] uTSUKUSHIi
写真に写っている猫の誕生日を当てる問題です。

この猫は猫カフェなどの店で飼ってる猫だろう(日当たりが良く、部屋に広さを感じて部屋が高そうなので )
猫が座っている丸い台がオシャレでかわいい(リビングに丸い台置きますか?店なのでしょう)
黄色いソファのようなものが置いてある(角が傷が付いてパッチを当てたのか分からないが角の色が違う)
鼻の根本が少し黒い(猫カフェの猫の鼻はピンク色していることが多そうだったので特徴的だと思った)
右耳が切れている(喧嘩したのかな?)
この猫はかわいい(かわいい猫なので見つけやすいはず...)
これらの特徴から猫カフェについて調べていると、猫カフェMOCHAという日本全国に展開している猫カフェの店舗は丸いオブジェクトをたくさん使っていて写真と雰囲気が似ていると思いました。
次に、猫カフェMOCHAのホームページには全ての猫の名前と写真と誕生日が乗っていたので、全店舗の全ての猫と比較しました(1回目😹)。
配布画像の猫と見比べ続けた結果、(本当はいたのですが見逃していて)猫を見つけることができませんでした。
そこで、Google検索で猫カフェ 黄色 ソファと調べていると、このブログに写っているソファの黄色の変色具合が問題画像と似ていることに気づき、撮影場所は猫カフェMOCHA京都河原町店ではないか?と考えました。
もう一度猫カフェMOCHA京都河原町店の猫を注意深く見てみる(2回目)と、問題の猫はそっくす君と気づくことができました。

そっくす君の誕生日をを入力すると、
答えはTsukuCTF22{2021/09/16}で正解でした。
[Reversing] GrandpaMemory
PDP-11のプログラムファイルが与えられて計算結果を答えるという問題です。
$ file ./a.out a.out: PDP-11 old overlay
配布されたファイルはPDP-11のプログラムで、PDP-11何も分からなんと思ったのですがファイルサイズがたった52byteだったので解けそう(読み切れそう)だと思いました。
まずPDP-11の逆アセンブラを探すと、https://github.com/caldwell/pdp11dasmが見つかりました。
これを使ってファイルのプログラムの部分を逆アセンブルしたものが以下になります。
000014: 005001 clr r1 ; .. 000016: 005002 clr r2 ; .. 000020: 005201 inc r1 ; .. 000022: 005202 inc r2 ; .. 000024: 006301 asl r1 ; A. 000026: 006301 asl r1 ; A. 000030: 006301 asl r1 ; A. 000032: 006301 asl r1 ; A. 000034: 006302 asl r2 ; B. 000036: 060102 add r1,r2 ; B` 000040: 000777 br 40 ; ..
wikipediaのPDP-11の命令セットについての説明を見ながら逆アセンブル結果を読むと、計算結果は18になることが分かりました。
答えはTsukuCTF22{18}でした。
seccamp全国大会2022 オンライン 参加記(Z7チューター)
はじめに
ブログでは久方ぶりです。pr0xyです。
セキュリティ・キャンプ全国大会2022にZ7のチューターとして参加させていただきました。 チューターは担当の講義(自分の場合はZ7)のサポートやグループワークの補助など、様々な場面で潤滑油になることが求められていました。 この記事ではチューター視点でseccamp2022を簡単に振り返りたいと思います。
講義
自分のサポート担当の講義はZ7のマルウェアサンドボックス強化ゼミで、講義+開発を行いました。
マルウェアサンドボックスにはマルウェアの振る舞いからマルウェアの種類を特定するシグネチャという機能が付いています。 マルウェアは日々種類が増え続けているため、既存のシグネチャで検知できないマルウェアは結構存在します。(既存のシグネチャの作りが甘いこともありますが...) この講義の目的はシグネチャを開発することで既存のシグネチャで検知できなかったマルウェアを検知できるようにすることです。
シグネチャを書くためにはマルウェアの振る舞いをコードに落とし込むことが必要で、マルウェアの振る舞いについての理解が十分でないとシグネチャを書くことは難しいです。 そのため受講者の方々には事前学習として、マルウェアの一般的な振る舞いを理解してもらう目的でマルウェアをサンドボックスで解析したレポートやマルウェア解析のブログなどを読んでもらいました。
マルウェアの振る舞いについて理解できるようになった後は、シグネチャを書けるようにするためにサンドボックス環境の仕組みやシグネチャとサンドボックスとの関係を理解してもらいました。 講義ではCAPEv2というOSSのサンドボックス環境を使用していたので、CAPEv2の構造やCAPEv2の既存のシグネチャを理解しました。
ここまで来るとマルウェアを検知するシグネチャを開発できるようになっていました。解析対象のマルウェアから特徴的な振る舞いを見つけて、振る舞いを検知するようなシグネチャコードを作成しました。 自分が書いたシグネチャコードが今までサンドボックスに検知されなかったマルウェアを検知できた時は嬉しいです!(自分も受講生と一緒に作成して楽しんでました!)
自分は今回チュータの立場で講義に参加したのですが、普段からマルウェアと触れ合っているという人ではないのでマルウェア関係の講義でサポートできるのかと不安がありました。 今振り返ってもサポートできていたかは微妙ではありますが、受講者視点で講義に参加して受講者の方々と一緒に疑問点を解決したり課題に取り組めた点は良かったと思っています。 またオンライン開催では講師やチュータ側は受講生の反応が無いと進めることが難しいので、受講生の方々には積極的にリアクションをもらえて助かりました。🙇
LT大会
期間内にLT大会が開催されました。LTは短時間で興味がある話がたくさん流れてくるので楽しすぎますね!
自分は今回ELFファイルのデバッグ関連について発表をしましたが、LT制限時間が5分のところを盛大にオーバーしてしまいました。ネタ選び、スライド作成など慣れていないと難しいですね。。
その他
受講者/チュータ/講師/運営が期間中に改善できそうな点を見つけては随時改善して、皆でイベントをより良いものにしていてとても良かったと思いました。
今年もオンライン開催でオフライン開催の時よりはやり辛さを感じることも多かったですが、オンラインベースなのでログが残されていることが多く後で振り返りがしやすい(講義資料がまとまっていたりする)などオンライン開催だからこその良い点もあり、seccamp事業はオンライン開催を経てより良いイベントになっているのではないかと思いました。
最後にseccampの関係者のみなさま、ありがとうございました!
ContrailCTFの担当した問題について
12/31~1/3に開催されたContrailCTFに作問者として参加しました。
私が担当した問題は
[misc]Lets_Connctと[rev]DownloaderLog
です。サクッと気持ちよく解いてもらえるような問題を目指していた(他のメンバが難しい問題を作ることは軽く予想できていた)ので、結果的に両問共にsolve数が多い問題となって良かったと思っています。
Lets_Connecct
問題名の通りアクセスするだけなので気軽に取り組める問題です。
ncで指定のアドレスに接続するとdocker上のbashに接続できます。bashに接続した後lsコマンドを実行するとflagファイルが見えるのですが、catコマンドでflagの中身を確認しようとすると、catコマンドがないと言われてしまいます。そして何の外部コマンドを使用できるか知るために/bin/の中身を表示させてみるとlsしかないことがわかります。 bashで使えるコマンドは2種類あり、一つは/bin/や/usr/bin/、/usr/local/bin/などにインストールされている外部コマンドであり、二つ目はbashが持っている機能である組み込みコマンドです。この問題環境においては外部コマンドはlsしかないので、このあとは組み込みコマンドで問題を解いていくことになります。
0:0:~ pr0xy$ nc 114.177.250.4 2999 bash: cannot set terminal process group (-1): Inappropriate ioctl for device bash: no job control in this shell bash-4.4$ pwd pwd / bash-4.4$ ls -al ls -al total 1132 drwxr-x--- 1 0 1000 4096 Dec 30 08:53 . drwxr-x--- 1 0 1000 4096 Dec 30 08:53 .. -rwxr-x--- 1 0 1000 220 Apr 4 2018 .bash_logout -rwxr-x--- 1 0 1000 3771 Apr 4 2018 .bashrc -rwxr-x--- 1 0 1000 807 Apr 4 2018 .profile -rwxr-x--- 1 0 1000 1113504 Dec 30 04:53 bash drwxr-x--- 1 0 1000 4096 Dec 30 08:53 bin drwxr-x--- 1 0 1000 4096 Dec 30 04:54 dev -rwxr----- 1 0 1000 44 Dec 30 05:14 flag drwxr-x--- 1 0 1000 4096 Dec 30 04:54 lib drwxr-x--- 1 0 1000 4096 Dec 30 04:54 lib32 drwxr-x--- 1 0 1000 4096 Dec 30 04:54 lib64 bash-4.4$ cat flag cat flag bash: cat: command not found bash-4.4$ ls -al /bin/ ls -al /bin/ total 140 drwxr-x--- 1 0 1000 4096 Dec 30 08:53 . drwxr-x--- 1 0 1000 4096 Dec 30 08:53 .. -rwxr-x--- 1 0 1000 133792 Dec 30 08:53 ls
bashにおいてhelp組み込みコマンドで組み込みコマンド一覧を確認できます。
bash-4.4$ help
help
GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
These shell commands are defined internally. Type `help' to see this list.
Type `help name' to find out more about the function `name'.
Use `info bash' to find out more about the shell in general.
Use `man -k' or `info' to find out more about commands not in this list.
A star (*) next to a name means that the command is disabled.
job_spec [&] history [-c] [-d offset] [n] or hist>
(( expression )) if COMMANDS; then COMMANDS; [ elif C>
. filename [arguments] jobs [-lnprs] [jobspec ...] or jobs >
: kill [-s sigspec | -n signum | -sigs>
[ arg... ] let arg [arg ...]
[[ expression ]] local [option] name[=value] ...
alias [-p] [name[=value] ... ] logout [n]
bg [job_spec ...] mapfile [-d delim] [-n count] [-O or>
bind [-lpsvPSVX] [-m keymap] [-f file> popd [-n] [+N | -N]
break [n] printf [-v var] format [arguments]
builtin [shell-builtin [arg ...]] pushd [-n] [+N | -N | dir]
caller [expr] pwd [-LP]
case WORD in [PATTERN [| PATTERN]...)> read [-ers] [-a array] [-d delim] [->
cd [-L|[-P [-e]] [-@]] [dir] readarray [-n count] [-O origin] [-s>
command [-pVv] command [arg ...] readonly [-aAf] [name[=value] ...] o>
compgen [-abcdefgjksuv] [-o option] [> return [n]
complete [-abcdefgjksuv] [-pr] [-DE] > select NAME [in WORDS ... ;] do COMM>
compopt [-o|+o option] [-DE] [name ..> set [-abefhkmnptuvxBCHP] [-o option->
continue [n] shift [n]
coproc [NAME] command [redirections] shopt [-pqsu] [-o] [optname ...]
declare [-aAfFgilnrtux] [-p] [name[=v> source filename [arguments]
dirs [-clpv] [+N] [-N] suspend [-f]
disown [-h] [-ar] [jobspec ... | pid > test [expr]
echo [-neE] [arg ...] time [-p] pipeline
enable [-a] [-dnps] [-f filename] [na> times
eval [arg ...] trap [-lp] [[arg] signal_spec ...]
exec [-cl] [-a name] [command [argume> true
exit [n] type [-afptP] name [name ...]
export [-fn] [name[=value] ...] or ex> typeset [-aAfFgilnrtux] [-p] name[=v>
false ulimit [-SHabcdefiklmnpqrstuvxPT] [l>
fc [-e ename] [-lnr] [first] [last] o> umask [-p] [-S] [mode]
fg [job_spec] unalias [-a] name [name ...]
for NAME [in WORDS ... ] ; do COMMAND> unset [-f] [-v] [-n] [name ...]
for (( exp1; exp2; exp3 )); do COMMAN> until COMMANDS; do COMMANDS; done
function name { COMMANDS ; } or name > variables - Names and meanings of so>
getopts optstring name [arg] wait [-n] [id ...]
hash [-lr] [-p pathname] [-dt] [name > while COMMANDS; do COMMANDS; done
help [-dms] [pattern ...] { COMMANDS ; }
この中から使えそうなものを探すと、readコマンドが使えそうです。 readコマンドを使うと以下のような感じでflagを表示できます。 flagには172.17.0.5の3000portに本当のflagが移動したと書いてあります。
bash-4.4$ while read line; do echo $line; done < flag while read line; do echo $line; done < flag Flag has moved to 3000 port on 172.17.0.5.
しかし172.17.0.5はローカルipアドレスの範囲内なので外部からnc 172.17.0.5 3000とすることはできないですし、114.177.250.4 2999のbashにはncコマンドがありません。よって、ここでもbashの機能を使って接続します。 bashには/dev/tcp/[ip]/[port]でtcp通信が行える機能があります。 以下はこの機能を使ってファイルディスクリプタ7番でコネクションを張って、readコマンドでファイルディスクリプタ7番の内容を読み取っています。
bash-4.4$ exec 7<> /dev/tcp/172.17.0.5/3000
exec 7<> /dev/tcp/172.17.0.5/3000
bash-4.4$ while read line; do echo $line; done <&7
while read line; do echo $line; done <&7
ctrctf{b4sh_1s_a_mul7ifuncti0n_sh3ll}
bash-4.4$
標準入力(ファイルディスクリプタ0番)を172.17.0.5:3000にするという方法もあります。
bash-4.4$ exec 0<> /dev/tcp/172.17.0.5/3000
exec 0<> /dev/tcp/172.17.0.5/3000
bash-4.4$ ctrctf{b4sh_1s_a_mul7ifuncti0n_sh3ll}
bash: ctrctf{b4sh_1s_a_mul7ifuncti0n_sh3ll}: command not found
bash-4.4$ exit
CTF開催中にサーバが変更されたことが/flagに反映されていなくて申し訳なかったです。🙇♂️ この記事を作成中に反映されていないことに気づきました。
DownloaderLog
この問題は、malware感染後にmalware(downloader)がインターネットから何やら怪しげなファイルをダウンロードしていた様子がログに残っていたという問題設定です。 log.pcapファイル(https://www.dropbox.com/s/losftwhw7w0718d/log.pcap?dl=0)がログに該当します。
log.pcapファイルをwireshark等で開くとhttp通信でファイルを二つダウンロードしてきていることがわかります。 http通信の内容を詳しくみると、まずhttp://file.io/k7zg2B(アップロード時のファイル名はsuspicious)からELFファイルのようなファイルをダウンロードし、次にhttp://file.io/7GNqHT(アップロード時のファイル名はonetime_secret.key)からunixタイムのようなものが書かれているテキストファイルをダウンロードしてきていることがわかります。
wiresharkの[File]->[Exports Objects]->[HTTP]でk7zg2Bを抽出します。
ここからk7zg2B(認証+flag表示プログラム)というファイルの解析を行なっていきます(後ろに認証プログラムのソースコードを貼っていますので参考にしてください)。
ghidraでk7zg2Bを開くと0x00400716からmain関数があります。
ghidraで処理を見ると分かると思いますが、main関数では引数に与えられたファイルの中身の数字が(現在時刻-6000)~(現在時刻+6000)の場合、0x6010bdから始まる関数を呼び出します。この関数はcheck_func.S 内に書いてある_check_func関数です。
(gdbでステップ実行をしていると0x6010bdに入った瞬間デバッグが終了してしまうかもしれません。その際は少し先の部分にbreakpointを張って実行してみてください。 detect_debuggerが始まる0x601081にbreakpointを張るとうまくいくかもしれません。)
_check_func関数では、0x601081から始まるdetect_debuggerを呼んでます。これはデバッガを検知する関数です。gdb等のデバッガを使ってプログラムを走らせるとdetect_debugger内のsyscall後、raxレジスタに-1 が入ってしまうのでsyscall後、set $rax=0 とすることでデバッガ検知を回避することができます。 _check_funcに戻った後、0x601060から始まるdecode_xorを呼んでます。これはdataセクションのあるpack_start~ pack_endの部分をdecodeして実行できるようにしている関数です。
detect_debugger終了後の_check_func関数ではファイルの数字が(現在時刻-60)~(現在時刻) かつ 53の倍数の時のみflagを出力するという処理になっています。
余計な命令が入らないように最小限のアセンブリでプログラムを作成したので、アセンブリを追いかけることのできるレベルかなと思っています。
現実的にはmalwareがhttp通信を行なっていることはあまりなく、httpsやdnsのレコード取得を使ってファイルや司令のやりとりをすることかと思います。 ctf仕様の問題になりましたが、file.ioという一見怪しくないようなサービスを利用している点など雰囲気を感じ取ってもられば良いなと思って作問しました。
最後にバイナリの作成手順を書いておきます。
$ gcc main.c check_func.S -no-pie $ strip a.out
そしてa.outのdataセクションに入っているpack_startラベルからpack_endラベルに該当する部分をxor 25 でエンコードしました。
// main.c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<time.h>
extern void _check_func(int key_time,int now_time);
char *filename;
void cleanup(){
char *cmd[] = {"/bin/rm",filename,NULL};
execv("/bin/rm",cmd);
}
int main(int argc,char **argv){
filename = argv[0];
if(argc != 2){
puts("key required :(");
cleanup();
return 1;
}
FILE *fp;
if((fp = fopen(argv[1],"r")) == NULL){
return 2;
}
char t[11] = {0};
fread(t,sizeof(char),10,fp);
int key_time = atoi(t);
int now_time = time(NULL);
if(key_time - 6000 < now_time && now_time < key_time + 6000){
_check_func(key_time,now_time);
}else{
puts("invalid :|");
cleanup();
return 3;
}
return 0;
}
check_func.Sの中でxorでエンコードする処理を入れたいと思ったのでw(書き込み)権限のあるdataセクションに配置しています。(textセクションをmprotectしたり、新しい領域をrwxで確保するという方法もあります)
check_func.Sに書いてあるflag文字列が散らばっているのは、xor25でデコード後dataセクションの部分をメモリダンプされるとflagが丸見えになることを避けたかったからです。 かといって複雑で面倒な処理を加えると解く側が嫌になってしまうと思ったので、単純にjmp命令を多用するスパゲティコードに仕上げました。 ctfdのflag提出状況を見ていると散らばっている文字列を色々つなぎ合わせているflag(ctrctf{3inary_a4na1yst}など)があったので少しは効果があったのかなと思っています。
# check_func.S
.data
.global _check_func
decode_xor:
mov $pack_start,%eax
xor %ecx,%ecx
mov $pack_end,%ecx
sub $pack_start,%ecx
dec %ecx
next_byte:
xor $25,(%ecx,%eax,1)
loop next_byte
xor $25,(%ecx,%eax,1)
ret
detect_debugger:
mov $101,%rax
mov $0,%rdi
mov $0,%rsi
mov $1,%rdx
mov $0,%r10
syscall
cmp $0xffffffffffffffff,%rax
jne ok
mov $60,%rax
mov $255,%rdi
syscall
ok:
ret
_check_func:
push %rbp
mov %rsp,%rbp
sub $0x10,%rsp
mov %edi,-0x4(%rbp)
mov %esi,-0x8(%rbp)
call detect_debugger
call decode_xor
pack_start:
mov -0x4(%rbp),%eax
cmp %eax,-0x8(%rbp)
jle bye
mov -0x4(%rbp),%eax
add $0x3c,%eax
cmp %eax,-0x8(%rbp)
jge bye
jmp L5end
L5: .ascii "4na1yst"
L5end:
mov -0x4(%rbp),%eax
mov $0,%rdx
mov $53,%rbx
div %rbx
cmp $0,%rdx
jne bye
mov $1,%rax
mov $1,%rdi
mov $flag_msg,%rsi
mov $21,%rdx
syscall
jmp wL1s
flag_msg: .ascii "Nice :) Flag is here\n"
L4: .ascii "3inary_"
wL6s:
mov $1,%rax
mov $L6,%rsi
mov $2,%rdx
syscall
jmp succes_end
wL6e:
L3: .ascii "are_"
wL3s:
mov $1,%rax
mov $L3,%rsi
mov $4,%rdx
syscall
jmp wL4s
wL3e:
L6: .ascii "}\n"
wL4s:
mov $1,%rax
mov $L4,%rsi
mov $7,%rdx
syscall
jmp wL5s
wL4e:
L2: .ascii "{u_"
wL2s:
mov $1,%rax
mov $L2,%rsi
mov $3,%rdx
syscall
jmp wL3s
wL2e:
L1: .ascii "ctrctf"
succes_end:
mov $60,%rax
mov $0,%rdi
syscall
wL5s:
mov $1,%rax
mov $L5,%rsi
mov $7,%rdx
syscall
jmp wL6s
wL5e:
bye:
mov $1,%rax
mov $2,%rdi
mov $err_msg,%rsi
mov $20,%rdx
syscall
mov $60,%rax
mov $41,%rdi
syscall
wL1s:
mov $1,%rdi
mov $1,%rax
mov $L1,%rsi
mov $6,%rdx
syscall
jmp wL2s
wL1e:
err_msg: .ascii "invalid time_key :}\n"
pack_end:
最後に
ContrailCTFに参加していただきありがとうございました!!
