Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
PE(exe)ファイルのRev問を解いてみよう<公開版>
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Xcyba17her
August 10, 2019
Technology
2.7k
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
PE(exe)ファイルのRev問を解いてみよう<公開版>
Xcyba17her
August 10, 2019
More Decks by Xcyba17her
See All by Xcyba17her
SECCON_quals_2019_follow_me.pdf
xcyba17her
0
200
CCCamp_CTF__ALLES_CTF__2019.pdf
xcyba17her
0
230
Other Decks in Technology
See All in Technology
AWS Security Hub CSPMの成功・失敗体験
cmusudakeisuke
0
310
FPGAの開発コンペでZephyrを使ってみた
iotengineer22
0
150
GitHub Copilot 最新アップデート – 「一歩先」の実践活用術
moulongzhang
5
1.5k
AI駆動開発を通して感じた、 AI時代のデザイナーの役割変化
whisaiyo
4
2.3k
エラーバジェットのアラートのタイミングを考える.pdf
kairim0
0
180
Lightning近況報告
kozy4324
0
210
Android の公式 Skill / Android skills
yanzm
0
160
20260619 私の日常業務での生成 AI 活用
masaruogura
1
230
小さく始める AI 活用推進 ― 日経電子版 Web チームの事例/nikkei-tech-talk47
nikkei_engineer_recruiting
0
310
Agile and AI Redmine Japan 2026
hiranabe
3
350
Kiro Ambassador を目指す話
k_adachi_01
0
110
2026TECHFRESH畢業分享會 - 原生還是跨平台? App 開發踩坑實錄
line_developers_tw
PRO
0
1.3k
Featured
See All Featured
Accessibility Awareness
sabderemane
1
140
Git: the NoSQL Database
bkeepers
PRO
432
67k
The browser strikes back
jonoalderson
0
1.3k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Are puppies a ranking factor?
jonoalderson
1
3.6k
Un-Boring Meetings
codingconduct
0
320
WENDY [Excerpt]
tessaabrams
11
38k
Statistics for Hackers
jakevdp
799
230k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.6k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
How to Talk to Developers About Accessibility
jct
2
240
Transcript
PE(exe)ファイルの Rev問を解いてみよう <公開版> Ciruela(@__Xcyba17her_)
目次 問題解説 Binary 2 (NeverLAN CTF 2019)
Crack me (InnoCTF 2019) Left 5 Seconds (Victor of Cyberists) Gacha (Victor of Cyberists) 完全版ではksnctfの3問のWriteupと,問題ファイルやソルバを 用意しています.色々と考慮すべきことがあるので,完全版の 配布はTwitter DMにより個人的に行うことにします. 完全版からksnctfの部分のwriteupを抜いただけなので,ツー ルのある機能の説明が省かれているにもかかわらず,その後の 問題で既知の機能として扱われている可能性があります. 2
Binary 2 (NeverLAN CTF 2019) 3
どんな問題? 認証システムのユーザーネームとパスワードを忘れてしまった… Employee_Payroll.exe(32bit)というファイルが渡される 実行すると,UsernameとPasswordが要求される 4
ファイルの種類を識別する WindowsではTrIDNetが便利(シグネチャデータが大きいが我慢) 画像から,exeファイルの可能性が高い 5
dnSpyで逆コンパイル dnSpyは,.NET製かつシンボル情報が多ければバイナリから ソースコードに復元する超優秀なツール exeファイルはまずこいつに突っ込んでみる! exeファイルが32bitか64bitかで32bit版と64bit版のdnSpyを使 い分ける必要がある 6
怪しいbtnLogin_Click関数 “OK”ボタンを押すと実行されると予想 UsernameとPasswordが正し ければ実行される 文字列を作った後,それを ウィンドウで表示する ログイン試行が3回を超えたら 実行される… UsernameとPasswordのいずれ
かが誤っていれば実行される … 7
checkUsername関数とcheckPassword関数 直接文字列を比較している… Usernameは”admin” Passwordは ”dGhpc19pc19ub3RfdGhlX2ZsYWdfeW91X3NlZWtfa2VlcF9sb29raW5n” 8
見つけたUsernameとPasswordを入れる flag{ST0RING_STAT1C_PA55WORDS_1N_FIL3S_1S_N0T_S3CUR3} 2ページ前のthis.r1~this.r53にはflagが平文で入っていた 9
Crack me (InnoCTF 2019) 10
Crack_me.exe(32bit)が渡される “Enter the key:”と表示され,何か入力するとウィンドウが閉 じる 11 どんな問題?
dnSpyを使えない セクション情報などしか表示されない 12
IDA Freewareで眺める 文字入力関数のcinやscanfを探す Importsタブ → Ctrl+Fで検索機能を表示 → cinで検索
1件だけ表示されるので,ダブルクリックでその場所へ移動 13
IDA Freewareで眺める cinはsub_403630関数で呼ばれている “sub_403630”の部分をダブルクリック 14
IDA Freewareで眺める “Enter the key:”の表示と入力の処理がある ここがメインの処理のようだ 15
IDA Freewareで眺める cinの入力処理後,分岐でsub_4032F0関数が呼ばれることが多い 入力後の文字列の検証でダメだった場合の処理と予想 16
IDA Freewareで眺める 17 “Invalid key!”と表示 exit(0)のような処理 sub_4032F0関数は検証でダメだった場合の処理でよさそう “Invalid
Key”の表示やexit(0)的な処理がある
IDA Freewareで眺める sub_4032F0関数に名前”wrong_exit”と名付けておく sub_4032F0をクリック→Nキーを押す→Nameに”wrong_exit”と入力 18
IDA Freewareで眺める 一つ目の分岐を見る sub_403310関数の返り値が0xFFFFFFFF(=-1)以外ならよさそうだが… 19
IDA Freewareで変数に名前をつける [ebp+var_28]は,cinの引数であり,入力文字列へのポインタが 入っていると考えられる var_28に”input_string”と名前をつけてみる var_28をクリック →
Nキーを押す → 名前を付ける 20
IDA Freewareで眺める 読むのが非常に面倒くさい… さらに関数を呼んでいる デバッグしてみよう Strという第一引数に”_”を
指定していることから入力に おける”_”に関する関数と 予想 デバッグ時には入力文字列に “_”を含ませてみる 21
(x64dbgに付属する)x32dbgを使う x64dbgとx32dbgは,x32とx64のPEファイルをデバッグできる Ollydbgは32bitしかデバッグできないのでこちらのほうが便利 Ollydbgよりカラフルでよさそう(小並感) 22
x32/x64dbgで関数を探す CPUタブ内で左クリック → 検索 → 全モジュールを検索 → 外部 関数呼び出し
→ 関数名cinで検索 → 結果をダブルクリックし て移動 23
x32/x64dbgでグラフ表示 CPUタブ内で左クリック→グラフ 関数全体が表示されない場合は,左クリック→全体図 24
x32/x64dbgでブレークポイントを設置 左の灰色の点をクリックするとブレークポイントを設置できる IDAでsub_403310関数に相当する関数を探し,その直後にブレーク ポイントを置く IDAでsub_403310関数に相当する関数の返り値をeaxの値から調べ ることができる 25
sub_403310の返り値を検証する “_”の入力の有無や位置を変えて返り値(eax)の変化を調べる “_”を入れないとeaxは0xffffffff(=-1)に,入れると”_”のイン デックスがeaxに入ることがわかる 関数直前には入力文字列へのポインタがecxに格納されるため,入 力文字列も扱う関数だと予想できる
sub_403310は,指定文字列から指定文字か文字列を検索しイン デックスを返し,見つからなければ-1を返す,strstrのような 関数だと予想できる 分岐前に返り値(eax)が0xffffffffならwrong_exitに移動するこ とになっていた 入力文字列に”_”が含まれていればwrong_exitに移動しない! 26
x32/x64dbgで関数に名前を付ける sub_403310に”sub_strstr”という名前をつけてみる 該当命令で左クリック→ラベル→ラベル00E53310を選択し,名前 を付ける 27
2つめの分岐を調べる またもやsub_strstrを呼んでいる ebp+var_30には以前のsub_strstrで見つかった”_”のインデッ クス(厳密にはアドレス)が入っており,それに1を加えたものを 引数として渡している つまり入力文字列にはアンダーバー’_’が2つ以上必要 28
3つめの分岐を調べる sub_4033F0の返り値(eax)が0x0fであればよい 入力にアンダーバー’_’が2つ入るようにしながら,入力文字列 を変えてみる eaxには入力文字列の長さが入ることが分かる sub_4033F0の機能はstrlenと同じ
入力すべき文字列は15文字 29
4つめの分岐を調べる sub_402850の返り値(eax)が指すアドレスに入っている1バイト の値が0x72(=‘r’)であればよい cmp命令の前にブレークポイントを置き,eaxの値を調べる eaxは入力文字列の先頭のアドレス 入力する文字列の1文字目は’r’
30
5つめの分岐を調べる エスパーできる 1文字目の’r’に平文で見 れる”everse”が続くので はないか 実際に1文字目から ”reverse”とすると
exit_wrongに分岐しない 31
6つめの分岐を調べる sub_402850は4つめの分岐に出てきた 4つめの分岐のsub_402850では,0を引数とし,返り値は入力文字 列の1文字目のアドレスだった 今回は8を引数としていて,今回は返り値が入力文字列の9文字目の アドレスであると予想する.すなわち,9文字目が’i’(=0x69)であ ると予想する
32
7つめの分岐を調べる 9文字目のASCIIコードと10文字目のASCIIコードを加えると 0xdcになる 9文字目は’i’(=0x69)だった → 10文字目は’s’(=0x73) 33
8つめの分岐を調べる これまでの情報から,1文字目 から11文字目は確定し, ”reverse_is_????” と考えられる “fine”が見えるので, “reverse_is_fine”かと 思いきや通らない
34
8つめの分岐を調べる ごめんなさい,これは完全に勘です(m´・ω・`)m 実は,sub_403090を通るとeaxには入力文字列の12~15文字目を前に3 だけシフトした文字列が入る 例えば,入力の12~15文字目が”abcd”だと返り値eaxには”^_`a”が 入る
では,入力の12~15文字目を前に3だけシフトして”fine”だったら いい,すなわち”ilqh”だったらいいのではと考えた これでだめだったら諦めるか地道に読んでいくつもりだった 35
偶然の正解 ”reverse_is_ilqh”が正解だった しかし,フラグ文字列では’e’が’3’に改変されていた 恐らく最後の分岐以降がその処理 36
Left 5 Seconds (Victor of Cyberists) 37
どんな問題? left_five_seconds.exeとGameLogic.dllが渡される 1から30のマスを5秒以内で順にクリックする マウスで30回すべてのマスをクリックしていくブルートフォースの ようなスクリプトを書いても解けそう 38
dnSpyが使える クリア条件が見つからないが,時間計測とそれに応じexitする Form1.Timer1_Tick関数が見つかる exitしてしまう条件の500という値は5.00秒を示していそう この値を大きくすれば1~30までクリックする十分な時間を確保できそう 39
dnSpyでプログラムを書き換える dnSpyでは,逆コンパイルしたソースコードを書き換えて再コン パイルすることができる! if (this.time_count == 500)をif (this.time_count
== 50000)に書き換えたい ソースコード上で左クリック → Edit Method → 該当部分を書き換 える → 右下のCompileボタン → ソースコード画面のFile → save All… → left_five_seconds_edited.exeなどと保存 40
うまく起動しない left_five_seconds_edited.exeを起動してみる “Invalid Hash!”と表示されて起動しない ハッシュ値の検証をして改造の検知をしている? 41
どこでハッシュ値の検証を行っているか left_five_minutes.exeとGameLogic.dllの両方で”Invalid Hash!”という文字列を探す IDAでView → Open subviews →
stringsでバイナリ内の文字列が 表示される 42
どこでハッシュ値の検証を行っているか GameLogic.dllで”Invalid Hash!”が見つかる それに加え,”77777f298dba696637adfadf59a5630f”という文 字列が見つかる left_five_seconds.exeのハッシュ値とこれを比較し,合ってい なければ起動しない可能性がある
43
Windowsで,ハッシュ値を算出する HashSumやHashCalcが使える left_five_minutes.exeのMD5ハッシュ値 が”77777f298dba696637adfadf59a5630f”に一致 GameLogic.dllのMD5ハッシュ値照合用の文字 列”77777f298dba696637adfadf59a5630f”を, left_five_seconds_edited.exeのMD5ハッシュ値に変えてしまえ
ばハッシュ値による改造検知を通過できそう 44
ハッシュ値の検査を回避する left_five_seconds_edited.exeのハッシュ値を算出する f97402713388f91420ad583e679df8b9 45
ハッシュ値の検査を回避する GameLogic.dllのハッシュ値検査用文字列を改ざんする Stirlingで改ざんする 検索・移動 → 検索 →
検索文字列入力 (データ種別は文字列・検 索範囲はデータ全体) 46
ハッシュ値の検査を回避する 右のASCII文字列からハッシュ値検査用文字列を変更する 書き換えたら,ファイル → 上書き保存 47
ハッシュ値の検査を回避する left_five_minutes_edited.exeを起動する ハッシュ値検査を回避できている 残り時間を示す文字列が0:00になっても終了しない 1~30をクリックし終わるとフラグが表示される 48
別解 Form1.Button_Clickといういかにもボタンが押されたら呼ば れそうな関数がある さて,プログラムが終了してしまう条件は,time_countが500 を超えてしまうことだった つまり,Form1.Button_Clickにブレークポイントを置いて実 行し,ボタンを押す
→ プログラムがブレークポイントで一時停 止する → time_countの値を編集して0に戻す → プログラムを 進めるというのを繰り返せば解ける time_countはunsignedの変数のようであり,負数には設定できな い.つまり,プログラムを動かしてボタンを押すまでを5秒でやら なければいけないので少し不安があり,そして30回もやるのはめん どくさい 49
Gacha (Victor of Cyberists) 50
どんな問題? Gacha.exe(64bit)と使用画像のフォルダが渡される 12回のガチャで12種類の誕生石を集めなければならない 51
dnSpyで開ける しかし,難読化処理されておりほぼコードを読めない 52
IDAで眺める 難読化データばかりで処理がわからない 難読化手法も不明 53
CheatEngineを使ってみる CheatEngineは,ゲームチーター御用達?のオープンソースソ フトウェアであり,条件を指定してメモリアドレスの検索を 行ったり,メモリの書き換えを行うことができる Gacha.exeを起動してからCheatEngineを起動し,左上のコン ピュータのアイコンをクリック,プロセスの一覧からGachaを選択 し,Openをクリック 54
未知数検索 未知数検索とは,ゲーム内でのアクションごとに値が変化した メモリアドレスを絞っていき,重要な機能を持つアドレスを特 定すること Gacha.exeにおいては,ガチャを引くごとに残り回数が減るた め,残り回数や資金を格納しているアドレスを特定できる可能 性がある
アドレスを特定したら,あとは内容を好きなように書き換える 55
未知数検索 まずScan Typeを”Unknown Initial Value”,Value Type を”4 Bytes”にし,First Scanをクリック
以降は,ガチャを引いた後,Scan Typeを”Changed Value”と してNext Scanをすることを繰り返す 残念ながらこの方法では絞り込めない 56
特定の値の配列の検索 Gachaでは,これまでに出た誕生石を1,出ていない誕生石を0と する12要素の配列を作成し,12種類の誕生石が全て排出された か判断している可能性がある 例えば,1月,4月,6月の誕生石が既出であったら,内容が [1,0,0,1,0,1,0,0,0,0,0,0]となっている配列が存在する可能性 がある
配列の検索にあたり,現在2,3,4,5,9,11,12の誕生石が排出されて いる場合を例にやりかたを示す 57
特定の値の配列の検索(1byte単位) 配列の各要素が1バイトである場合と4バイトである場合の2通り で検索してみる.まずは1バイト単位で検索 New Scan → Value Type:
Array of Byte → Valueのテキス トボックスに”00 01 01 01 01 00 00 00 01 00 01 01”を入 力 → 全てのメモリを調べるためにWritable, Executable, CopyOnWriteのチェックを全て▪にする → First Scan しかし結果は1件もない 58
特定の値の配列の検索(4byte単位) New Scan → Value Type: Grouped → Valueのテキストボッ
クスに”4:0 4:1 4:1 4:1 4:1 4:0 4:0 4:0 4:1 4:0 4:1 4:1”を入力(4:0は4バイトの値が0の意) → 全てのメモリを調べ るためにWritable, Executable, CopyOnWriteのチェックを 全て▪にする → First Scan 1件だけ結果が出る 59
CheatEngineでメモリを書き換える 結果のアドレスをダブルクリック → Valueが0である各アドレ スのValueをダブルクリックして1を入力 60
CheatEngineでメモリを書き換える 次にガチャを引くと,フラグが表示される 本来ならサーバ側に処理を隠すし,わかりやすく連続したアドレスに格納し ないが,それだと初心者は絶対に解けないのでこうしたとのこと 61
解説終了! お疲れさまでした(o^―^o) 62