angstromctf 2019 WriteUp
はじめに
angstromctfというワードがtwitterで流れてきたのでその勢いで登録しました。初心者にも解ける問題があるよって言われたので、、、ctfの勉強なんてしようと思っててずっとしてこなかった感じなので、これを機に始めようかななんて思っています。なので、このWriteupは初心者がたまたま解けた問題を乗っけているだけなので詳しいことを知りたい方は別の方のページに飛んでくださいねっ!
REV
One Bite
ctfのサーバに実行ファイルがあるのでその対話に答えてフラグ取得するやつ。elfファイルをもらえるので解析します。radare2
を使いました。
・1つ目の入力はstrcmp
で比較されている文字列okrrrrrrr
。
・2つ目は足して0x88
(136)、かけて0xec7
(3783)、になる2つの数字の小さい順39
と97
。
actf{okrrrrrrr_39_97}
MISC
The Mueller Report
pdf
string target_file.pdf | grep actf
actf{no0o0o0_col1l1l1luuuusiioooon}
Blank Paper
firefoxでそのままファイルを開いたら、普通に開けました。著者の部分にフラグがかいてあります。
actf{knot_very_interesting}
Paper Bin
.dat
ファイルが入手できます。ストーリー仕立てみたいになっていて、先ほどのpdfファイルが消えたからリカバリしてくれみたいな感じです。GUIからダブルクリックでPDFは開けるのですが、著者の部分は空欄です。hexdump -C target.dat
で一度開いてみると先頭からしばらく00で埋まっていたので、データの一部分ごっそり抜いてきたみたいなファイルかと。
https://qiita.com/forestsource/items/15933888466ba9c3f048
ファイル抽出してみようと思いforemost
で抜いてみると20個PDFファイルが出てきました。しかしstrings
で"actf"をgrep
回してみたけど見つからず..(これで見つかるなら元ファイルにgrep
かけただけで見つかるはずだし..)
foremost
の出力ファイルがあるのでそれをみると、411KBの若干他より重いファイルと、コメントがついたファイルに当たりをつけて開いてみると、後者の著者欄にフラグがありました。
actf{proof_by_triviality}
Paper Trail
pcapng
ファイルが入手できるので、TCPStream
をFollow. 「ランダムに生成するよ:(」って言ってますが、辿ってみるとa
,c
,t
,f
となるのでそのまま追って行きました。
actf{fake_math_papers}
WEB
No Sequels
以下のフォームを通す。最初はJWT
かなと思っていたのですが、MongoDB
でした。
router.post('/login', verifyJwt, function (req, res) { // monk instance var db = req.db; var user = req.body.username; var pass = req.body.password; if (!user || !pass){ res.send("One or more fields were not provided."); } var query = { username: user, password: pass } db.collection('users').findOne(query, function (err, user) { if (!user){ res.send("Wrong username or password"); return } res.cookie('token', jwt.sign({name: user.username, authenticated: true}, secret)); res.redirect("/site"); }); });
Burp
をかませて、jsonを送信します。
- Content-Type: application/x-www-form-urlencoded + Content-Type: application/json - username=hoge&password=hoge + { + "username" : {"$gt": ""}, + "password" : {"$gt": ""} +}
ネットだとapplication/x-www-form-urlencoded
でのPoCが多いですが、一度パラメータの存在を確認しているので、username[$ne]=
のような事はできませんでした。
actf{no_sql_doesn't_mean_no_vuln}
CRYPTO
Classy Cipher
暗号苦手なので簡単ですが書きます。
問題文
from secret import flag, shift def encrypt(d, s): e = '' for c in d: e += chr((ord(c)+s) % 0xff) return e assert encrypt(flag, shift) == ':<M?TLH8<A:KFBG@V'
ord()
は文字を単語に、chr()
は数字を文字に変換します。なので、読み込んできているshift
の値が分かれば、比較している文字列を復号できそうです。
shift = 0 for i in range(257): e = '' e = chr((ord('a')+i) % 0xff) if (e==':'): shift = i l = ':<M?TLH8<A:KFBG@V' e = '' for c in l: e += chr((ord(c) -shift) % 0xff ) print(e)
python
のfor
文がわからなかった。。
actf{so_charming}
Really Secure Algorithm
RSA
は相変わらず苦手ですが、過去のスクリプトを引っ張ってきてそのまま利用しました。
#python2 def exgcd(m, n): if n>0: y,x,d = exgcd(n, m%n) return x, y-m/n*x, d else: return 1, 0, m def n_module(_p,_q): return _p*_q E = 65537 C = 7022848098469230958320047471938217952907600532361296142412318653611729265921488278588086423574875352145477376594391159805651080223698576708934993951618464460109422377329972737876060167903857613763294932326619266281725900497427458047861973153012506595691389361443123047595975834017549312356282859235890330349 p = 8337989838551614633430029371803892077156162494012474856684174381868510024755832450406936717727195184311114937042673575494843631977970586746618123352329889 q = 7755060911995462151580541927524289685569492828780752345560845093073545403776129013139174889414744570087561926915046519199304042166351530778365529171009493 N = n_module(p,q) d = exgcd(E, (p-1)*(q-1))[0] % ((p-1)*(q-1)) P = pow(C, d, N) print ("%x"%P).decode("hex")
actf{really_securent_algorithm}
Half and Half
解けたのですが正攻法ではないと思うので詳しくは書きません...
from secret import flag def xor(x, y): o = '' for i in range(len(x)): o += chr(ord(x[i])^ord(y[i])) return o assert len(flag) % 2 == 0 half = len(flag)//2 milk = flag[:half] cream = flag[half:] assert xor(milk, cream) == '\x15\x02\x07\x12\x1e\x100\x01\t\n\x01"'
フラグ文字列を半分に分けて1文字ずつ取り出してXOR
してます。先頭の文字列と末尾はわかっているので、actf{
と_taste
と}
がわかります。あとは総当たりかなと思ったのですが、組み合わせパターン多すぎて諦めました。問題文がMm, coffee. Best served with half and half!
だったので、coffee
かなと決め打ちでやってみたら当たりました。下は最後にフラグを出したコード。ちゃんとした答えが知りたい。
targets = '\x15\x02\x07\x12\x1e\x100\x01\t\n\x01"' # 全部で24文字 # answer = 'actf{000000}' # e = '' # for i in range(len(targets)): # e += chr(ord(targets[i])^ord(answer[i])) # print(e) => "taste 19:1_" x = 'actf{coffee_' mid11_16 = '_taste' e = '' for i in range(len(targets)): e+= chr(ord(targets[i])^ord(x[i])) print(x + e)
actf{coffee_tastes_good}
最後に
いくつか省略していますが、簡単な問題なので。結果は 359/1570位となりました。意外と上位に感じるかもですが、上の方は桁が違うので全然上位ではないです。ひとまずweb問に強くなりたいので頑張ろうと思います。以上。
【Rspec, Capybara】dt, dd要素を取得 ~ 隣の要素を取得
タイトル通りの内容です。 フィーチャーテストをする際に、dd, dt
の値を関連づけて取ることでテストをわかりやすく、書きやすくしたいと思いました。
問題
<dl> <dt id="family-name" class="label">f_name</dt> <dd class="data--string">family</dd> <dt id="given-name" class="label">g_name</dt> <dd class="data--string">given</dd> <dl>
上のfamily
と言う<dd>
の値をラベルf_name
経由で取得したい。Capybara
であれば、find("dd.data--string")
で取得可能ですが、該当するものが2つあり(更に表示が増える可能性も今後ある)、find_all("dd.data--string").first
とかで順番を指定して取るのも可読性が低いと思うので、f_name
ラベルの隣の要素として取得できないかと思いました。
解決
find("dt#family-name", text: "f_name").find("+dd").text # =>"family" find("dt#family-name", text: "f_name").first(:xpath, './following-sibling::dd').text # => "family"
上のどちらでも希望通りの値が取得可能です。
余談ですが、こちらで紹介した、Capybara
のJavaScriptのテスト時では前者の+
を用いた手法はエラーになって使えないので注意。
sibling()
sibling
と言うメソッドも用意されていて、find("dt#family-name", text: "f_name").sibling("dd")
といった形で使います。しかし、このメソッドはfind()
見つけた要素と横並びになっている(兄弟?)タグを探索します。ですので、今書いたコードを最初のhtmlに使用すると、dd
が2つ見つかってしまいエラーになるので注意。(find()
の仕様と同じ。詳しくはリファレンスで)
参考
【Capybara】vue.jsを使ったページのfeature test時に値が取れない
前提
Ruby On Rails
プロジェクト内vue.js
でフロントエンドを賄っています。Capybara
でfeatue
テストをする時、値がうまく取れずにコケた話です。
問題
ajax
を使い、並び順等を非同期で変更できるようなtable
を持つページに対してテストを書こうとしました。しかし、値をall()
やfind()
で取得しようとしても、find("hoge").text
や.value
の値は""
の空の文字列が帰ってきて、テストは失敗します。
binding.pry
をテスト中に挟んだところ、formが上手く描画しきれてないような気がしました。form
のvalueがresource.id
であったり、resource.title
のままだったので、vue.jsが走る前の状態なんだなと言うことはわかります。ググっていくうちに、JavaScriptがそもそも動いていない、もしくはCapybaraがデフォルトでJavaScriptをテストできないのでは?と思い始めました。
解決
初めにjs: true
を記述してあげれば、JavaScriptを使用する者に対しても、テストが実行できるようになります。ちなみに、chrome
が入っていないとエラー出るので入れておきましょう。(私はVivaldiしか入っていなかった..)
describe "HogePage", type: :feature, js: true do ... end
余談
とても時間を使ってしまいましたが、単純な知識不足。原因にあたりをつけるために、save_and_open_page
メソッドが役立ちました。これは、テスト中に挟むことで、その時のhtmlをブラウザで開いてくれます。今回ではform
のtbody
部分が<script>
タグで囲まれていて未実行状態のような感じだったので、あたりをつけられました。以上。
技術書典6に行ったお話
2019/4/14 技術書典
に行ってきました。それのただの日記です。
現地
には11:30に着きました。今年は11~13時の入場には1000円かかったのですが、それに負けずみなさん朝から並んでいました。30分開ければ流石に並ばずに入れるかと思っていたのですが、結局20~30分ほど並びました。12頃、中は人でごった返していて立ち読みとかしてると邪魔になってしまうほどで、あらかじめチェックしていた店を回るだけの作業になってしまいました。
僕が買っている最中にアナウンスで、待機列が解消され再入場が簡単にできるようになったとの連絡があったので、恐らく一番混んでいたタイミングだったと思います。13時前までには一通り買い終えたのでそのまま帰りましたが、残念ながら2冊ほど印刷分は売り切れしていて、PDF版になりました。
買った本
ハッキングラボの育てかた~ミジンコでもわかるBadUSB~
OWASP ZAPではじめるウェブアプリ脆弱性診断
コードで理解するwebフレームワークの脆弱性
ファイアウォール ログ分析の基礎
セキュリティ畑でつかまえて
Radare2で学ぶバイナリ解析入門
ワールドマップ自動生成読本
ハニーポットと秘密のファイル
ハッキングラボに関しては別途機材が必要になるので、早めにAmazonでポチりました。シェル芸の本も買おうとは思っていたのですが、物理本が先に売り切れていたので、今回は諦めました。ワールドマップ自動生成は単純に気になっちゃったので、その場で買いました!(とても安かったし)
次の技術書典
も、気になった本があったら行くと思います。Twitterで本の情報が流れてくるというのが、購買意欲を上げるために大事な気がしました。主催者ページの出店サークル一覧では本が全て並んでいるわけではないので、ふつーにスルーしていた本が結構ありましたし。僕自身は表紙とタイトルだけで買うか決めていたので、もう少しホームページの改善を期待したいです。 以上。
T-pot止めます
話題
タイトル通りです。別にシリアスな内容でもないです。
最後に観察する
T-pot全体の過去30日間のデータです。
全体を通して5900番へのアクセス多め。おそらくVNCのポート(PC遠隔操作系のやつ)。次に思うのは3/25~3/30あたりにかけて色々とアクセスが増えていること。逆に、選挙のあった4/7前後はその周辺と比べても特に目立つような変化は見られない。ではCowrieのアクセス記録を見てみる。
ピーク日は違えど、三月の終わりに大量sshを飛ばしてきたのは、いつものアメリカ中国ロシアさん。その辺りに何か大きな出来事あったかなと考えましたが、元号発表が4月の頭にあったくらいですね。それを狙っていたわけでもなさそう。
なぜやめるのか
多機能すぎる
たくさんデータが取れるのは面白いのですが、知識が追いついていないと何を見ればいいのか分からない。変化にも気づきにくい。結局モチベーションも上がらないし、知識も増えないし、電気代もかかるし。特に、あらかじめカスタマイズされているので初めから自分の手をつけず、愛着もそれほど湧きませんでしたし、手をつけ始めるタイミングも難しかったです。再設定とかも上手く出来なかったし、初めから自分でやれればもう少し続いたのかなと思います。結局ねT-potの中の3割程度しか使わなかったと思うんです。というより使いこなせなかった。。
新しく始めたい
WOWHoneypotに興味を惹かれています。何やら自分でいじれる部分がありそうですし、ハニポの責務も限定的なので。
うるさい
ラップトップにLinux乗っけて動かしていたのですが、画面開きっぱなし(閉じても動くように設定できなかった)、ファン周りっぱなしでちょっと気になります。これくらいは大丈夫なのですが、負荷がかかるタイミングは結構大きな音が続きました。でもこれは後付けの理由です。
T-potを植えようとしている初心者の方へ
今もまだ初心者ではありますが、T-potはオススメしません。 * 情報量が多すぎてよく分からない * 可視化もほぼされていて、初めからあまり手を動かさない * きっと自分に不要な部分がある * 地味にスペック要求されたような..?!
最後に
何はともあれ、半年程度お世話になっていたと思います。ずっと動いていたので、ちょっと休んでもらいましょう。(また植えるけどね笑)