くらっかーの落書き帳

くらっかーの落書き帳

Ubuntuについて扱っています。時々セキュリティとプログラミング

Amebaでブログを始めよう!

 はいどーもお久しぶりです、くらっかーですよっと。久しぶりに内容のあるブログを頑張って書こうと思います。

 今回は書式文字列攻撃(print format attack)について扱っていこうと思います。なんだか物騒ですねえ。実際に攻撃とかはしませんが(技量がたり無さすぎ問題)ちょっと説明するだけです。他にこれについて扱ってるわかりやすいブログがあるんだからそれでいいじゃんってなりそうですが、出来るだけ自分なりに噛み砕いて説明するのでよろしくおねがいしますね。

 

 書式文字列攻撃とは、printf関数の脆弱性をついた攻撃方法で、ユーザーが入力した内容がそのまま出力されるプログラムなどに有効です。C言語とかをかじったことのある人なら必ず知ってると思います。その攻撃を受けるサンプルコードがこれです。

#include<stdio.h>
int main(void){
    char str[128];
    fgets(str, 128, stdin);
    printf(str); //ここに脆弱性
    return 0;
}

char型でstr[128]を宣言し、fgetsで文字を受け取ります。(fgetsについて分からない方はこちらへ→https://bituse.info/c_func/28)

printfを見てもらうと分かるんですけど、printf("%s",str)とならずにprintf(str)とそのまま出力するようになっていることがわかりますが、これが危険なんですね、ええ。もちろんccでコンパイルすると警告が出て怒られます。

 

 前項で書いたガバプログラムに実際にちょっと手をかけてみましょう。

$ echo -e "aaaa %x %x %x %x %x %x %x"|./a.out

%xは16進数で表示させる書式指定子です。このように命令すると書式指定子が与えられprintf(str)がprintf("%x")のようになりスタックの中身を表示してしまうそうです。実行結果を見てみましょう。

$ echo -e "aaaa %x %x %x %x %x %x %x"|./a.out
aaaa 1adae890 bb501d40 fbad2088 f98127a f981260 61616161 25207825

'a,b,c,d...'は16進数で「61,62,63,64...」です。ここではaaaaを除いて左から6つ目に61616161とあります。これが'aaaa'であり、ここではスタックの6番目のローカル領域に変数strが格納されているということになりますね。aaaaをabcdに変えてみるとabcdを除いてここでは左から6つ目に64636261と出力されます(スタックは反転で出力される)。これがなんやねんということなのですが、コレを言い換えるとコードの与え方(←読者様はそれが知りたいんだろ!いい加減にしろ!)によってはメモリを自由に書き換えてしまうことが可能です。プログラムを強制的に書き換えることが出来たりします。

 今回はこんなんで以上です。頑張って色々勉強しますのでよろしくおねがいします_(:3」∠)_