#4の仕組みを理解する為に、リバースエンジニアリングっぽいことをして手元で試してみたかった記録です。attack(書式文字列攻撃)。簡単に言うと、printfのフォーマット文字列の文字列ごと外部から変更可能なコードだと、アセンブラを覗いて好きなデータを覗いたり実行したり出来ちゃうよ!って話です。以下にアクセスした直下にq4というバイナリがあります。q60SIMpLlej9eq49こちらのコードがfgetsで取得した値をそのままprintfにぶち込んでる⇒その後に呼ばれるputcharのjmp先を本来呼ばれないはずのfopenに書き換えて、アクセス権の無いファイルを開いてしまおう!という問題でした。実際にポイントとなるアドレスはこちら。printfが0x80499f0。入力で使われるのはfgetsなので、そのアドレス+6バイトのところにprintfで参照しているレジスタのアドレスが来る計算となります。そこに"putcharの参照するレジストリを0x80499f0から別の場所にを書き換える処理"の文字列をぶち込むようにすればいいという理解でいます。ksnctfの問題に対してリバースエンジニアリング的なことをしてみる。作成コードksnctfの問題で出ていたオブジェクトのobjdump結果を元に作ってみました。コメントのアドレスは元ネタのq4バイナリをobjdumpした際のアドレス。fgetsの後のprintfで書式文字列攻撃をしていたからこんな感じだと思うんですよね。通常はfopenが絶対呼べないコードですが、なるほど確かにメモリ配置を把握出来て、最初のfgetsで入力した文字列を使ってそこにアクセスできるなら、fopenの実行が可能になりそう。}※投稿してから思ったけどfopen処理後にbreakしてないな(笑)コンパイルしてみる。動作環境はUbuntu18.04、gccのバージョンは7.3.0です。コンパイルオプションやカーネル設定も重要になります。コンパイラで制御が入っているから。gccのstack-protectorオプションでスタック破壊を検出する仕組み(カナリアというそうです)が入っています。運用環境における防御というわけでこんな感じでコンパイル。q4randomize_va_spaceはASLRという機能に関する設定で、こちらはプログラムに展開されるデータの配置をランダムにする設定。無効⇒objdumpと同じ配置になるということですかね。execstackはスタック実行可能フラグを設定するもの。やって見るだけでも、色々な脆弱性対応がデフォルトで行われているんですね。attackが出来る脆弱コードには警告が出るようになっていました。printf(buf);動作を見てみる記事と同じ理屈で実験。私の手元でbuildした際は、printfとfgetsの参照しているレジスタアドレスの差は4バイトでした。fgetsの入力を%pした際の4番目が実際にfgetsで書き込まれる値となるはず。<.plt>試してみます。202c6948,0,0,3abbb4c0,0,f132f7f8,1f6573f8,2c200932うまく入力した中身が参照出来ていますね。...ってあれ?表示位置が8バイトだ。まあじゃあ8バイトずらすことになるのか。