セキュリティ系の勉強・その他開発メモとか雑談. Twitter, ブログカテゴリ一覧
本ブログはあくまでセキュリティに関する情報共有の一環として作成したものであり,公開されているシステム等に許可なく実行するなど、違法な行為を助長するものではありません.

angstromctf 2019 WriteUp

はじめに

angstromctfというワードがtwitterで流れてきたのでその勢いで登録しました。初心者にも解ける問題があるよって言われたので、、、ctfの勉強なんてしようと思っててずっとしてこなかった感じなので、これを機に始めようかななんて思っています。なので、このWriteupは初心者がたまたま解けた問題を乗っけているだけなので詳しいことを知りたい方は別の方のページに飛んでくださいねっ!

REV

One Bite

ctfのサーバに実行ファイルがあるのでその対話に答えてフラグ取得するやつ。elfファイルをもらえるので解析します。radare2を使いました。
f:id:thinline196:20190421012101p:plain f:id:thinline196:20190421011839p:plain ・1つ目の入力はstrcmpで比較されている文字列okrrrrrrr
・2つ目は足して0x88(136)、かけて0xec7(3783)、になる2つの数字の小さい順3997
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の若干他より重いファイルと、コメントがついたファイルに当たりをつけて開いてみると、後者の著者欄にフラグがありました。 f:id:thinline196:20190420233820p:plain 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)

pythonfor文がわからなかった。。
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"

上のどちらでも希望通りの値が取得可能です。
余談ですが、こちらで紹介した、CapybaraJavaScriptのテスト時では前者の+を用いた手法はエラーになって使えないので注意。

sibling()

siblingと言うメソッドも用意されていて、find("dt#family-name", text: "f_name").sibling("dd")といった形で使います。しかし、このメソッドはfind()見つけた要素と横並びになっている(兄弟?)タグを探索します。ですので、今書いたコードを最初のhtmlに使用すると、ddが2つ見つかってしまいエラーになるので注意。(find()の仕様と同じ。詳しくはリファレンスで)

参考

stackoverflow.com

www.rubydoc.info

【Capybara】vue.jsを使ったページのfeature test時に値が取れない

前提

Ruby On Railsプロジェクト内vue.jsでフロントエンドを賄っています。Capybarafeatueテストをする時、値がうまく取れずにコケた話です。

問題

ajaxを使い、並び順等を非同期で変更できるようなtableを持つページに対してテストを書こうとしました。しかし、値をall()find()で取得しようとしても、find("hoge").text.valueの値は""の空の文字列が帰ってきて、テストは失敗します。
binding.pryをテスト中に挟んだところ、formが上手く描画しきれてないような気がしました。formvalueresource.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をブラウザで開いてくれます。今回ではformtbody部分が<script>タグで囲まれていて未実行状態のような感じだったので、あたりをつけられました。以上。

技術書典6に行ったお話

2019/4/14 技術書典

に行ってきました。それのただの日記です。

現地

には11:30に着きました。今年は11~13時の入場には1000円かかったのですが、それに負けずみなさん朝から並んでいました。30分開ければ流石に並ばずに入れるかと思っていたのですが、結局20~30分ほど並びました。12頃、中は人でごった返していて立ち読みとかしてると邪魔になってしまうほどで、あらかじめチェックしていた店を回るだけの作業になってしまいました。

f:id:thinline196:20190414224339j:plain

僕が買っている最中にアナウンスで、待機列が解消され再入場が簡単にできるようになったとの連絡があったので、恐らく一番混んでいたタイミングだったと思います。13時前までには一通り買い終えたのでそのまま帰りましたが、残念ながら2冊ほど印刷分は売り切れしていて、PDF版になりました。

買った本

  • ハッキングラボの育てかた~ミジンコでもわかるBadUSB~

  • OWASP ZAPではじめるウェブアプリ脆弱性診断

  • コードで理解するwebフレームワークの脆弱性

  • ファイアウォール ログ分析の基礎

  • セキュリティ畑でつかまえて

  • Radare2で学ぶバイナリ解析入門

  • ワールドマップ自動生成読本

  • ハニーポットと秘密のファイル

    ハッキングラボに関しては別途機材が必要になるので、早めにAmazonでポチりました。シェル芸の本も買おうとは思っていたのですが、物理本が先に売り切れていたので、今回は諦めました。ワールドマップ自動生成は単純に気になっちゃったので、その場で買いました!(とても安かったし)

次の技術書典

も、気になった本があったら行くと思います。Twitterで本の情報が流れてくるというのが、購買意欲を上げるために大事な気がしました。主催者ページの出店サークル一覧では本が全て並んでいるわけではないので、ふつーにスルーしていた本が結構ありましたし。僕自身は表紙とタイトルだけで買うか決めていたので、もう少しホームページの改善を期待したいです。 以上。

T-pot止めます

話題

タイトル通りです。別にシリアスな内容でもないです。

最後に観察する

T-pot全体の過去30日間のデータです。 f:id:thinline196:20190410234657p:plain f:id:thinline196:20190410234702p:plain f:id:thinline196:20190410234705p:plain

全体を通して5900番へのアクセス多め。おそらくVNCのポート(PC遠隔操作系のやつ)。次に思うのは3/25~3/30あたりにかけて色々とアクセスが増えていること。逆に、選挙のあった4/7前後はその周辺と比べても特に目立つような変化は見られない。ではCowrieのアクセス記録を見てみる。 f:id:thinline196:20190410235422p:plain f:id:thinline196:20190410235425p:plain

ピーク日は違えど、三月の終わりに大量sshを飛ばしてきたのは、いつものアメリカ中国ロシアさん。その辺りに何か大きな出来事あったかなと考えましたが、元号発表が4月の頭にあったくらいですね。それを狙っていたわけでもなさそう。

なぜやめるのか

多機能すぎる
たくさんデータが取れるのは面白いのですが、知識が追いついていないと何を見ればいいのか分からない。変化にも気づきにくい。結局モチベーションも上がらないし、知識も増えないし、電気代もかかるし。特に、あらかじめカスタマイズされているので初めから自分の手をつけず、愛着もそれほど湧きませんでしたし、手をつけ始めるタイミングも難しかったです。再設定とかも上手く出来なかったし、初めから自分でやれればもう少し続いたのかなと思います。結局ねT-potの中の3割程度しか使わなかったと思うんです。というより使いこなせなかった。。

新しく始めたい
WOWHoneypotに興味を惹かれています。何やら自分でいじれる部分がありそうですし、ハニポの責務も限定的なので。

うるさい
ラップトップにLinux乗っけて動かしていたのですが、画面開きっぱなし(閉じても動くように設定できなかった)、ファン周りっぱなしでちょっと気になります。これくらいは大丈夫なのですが、負荷がかかるタイミングは結構大きな音が続きました。でもこれは後付けの理由です。

T-potを植えようとしている初心者の方へ

今もまだ初心者ではありますが、T-potはオススメしません。 * 情報量が多すぎてよく分からない * 可視化もほぼされていて、初めからあまり手を動かさない * きっと自分に不要な部分がある * 地味にスペック要求されたような..?!


最後に

何はともあれ、半年程度お世話になっていたと思います。ずっと動いていたので、ちょっと休んでもらいましょう。(また植えるけどね笑)