任意コード実行の脆弱性がどうとか言われてもピンとこない。
バッファオーバーフローもただアプリ落ちるだけじゃんと思っている。
そんな人向けに何故騒がれるのか説明してみようという記事です。
任意コード実行ってなに?
簡単に言うと「PCやスマホであなたが出来ること大体全部を他人がやれてしまう穴」が見つかったという意味です。
SNSにあなたのふりして投稿したり、アカウント自体消したり、保存してある画像を全部消したり、あなた名義で好き放題課金したり、あなたの名義でウイルスをばらまいたりできます。
こういう何でもできる所が"任意"なわけですね。
何でもできるということは、ウイルス.exeを複製してそこら中に仕込むこともできます。
任意コード実行で攻撃されたら再インストールか捨てるしかないのも恐ろしいところです。
業務中に穴を突かれて会社のサーバーにも広がって大変な目に合う人もいます。
なにすると任意コード実行になるの?
色々ありますが代表的な原因にバッファオーバーフローがあります。
セキュリティの世界では、バッファオーバーフローが見つかる=任意コード実行を警戒して使用を控える、って空気感です。
バッファオーバーフローが危険と言われるのはそのせいだったんですね。
バッファオーバーフローがどうなって任意コード実行に?
「メモリに次に実行するアドレスがメモしてありますが、バッファオーバーフローで好きに上書きできてしまうから」です。
って言われてもピンとこないと思うので順に説明します。
まずは説明用C言語のコードをドン!
#include <stdio.h>
#include <limits.h>
#include <string.h>
void hoge() {
printf("Hoge!");
}
int main() {
char b = 'A';
char a[4];
fgets(a, INT_MAX, stdin);
printf("%c\n", b);
return 0;
}
※本来ならfgetsした内容を使ってなんか処理するんですが省略。
※hoge()が呼ばれていないのも同上。
このままだと単に入力受け付けてから「A」と出力して終わるだけです。
しかしfgetsがaのサイズではなくINT_MAX(※巨大な数)で受けているためバッファオーバーフローが発生しています。
なので適当にガチャガチャ入力してやると。
こうなります。
さて、ではここから任意コード実行を試みます。
レッツ任意コード実行!
まずメモリーをexcelに例えます!
「そうはならんやろ」って言われそうですがExcelに例えるんです!
とりあえず今回のアプリを当てはめるとこんな感じ。
fgets呼び出しは「この図の上から順に入力で埋めていく処理」と言えるでしょう。
並び順は、変数aが居て、よくわからないものが3byteいて、変数bがいて、また何かが~って感じですね。
1文字1byteで、途中のprintfは変数bを表示しているのだから。
fgetsに8文字入力したら表示変わりそうじゃないですか?やってみましょう。
無事出力が8文字目に変化しました!
※よく見ると以前の例外している画像でも8文字目が出力されてたりします。
メモリー図に反映させるとこんな感じ。
こうしてみると"mainの次に実行するアドレス"を上書きしてみたくなりませんか?なりますよね?
ところでhoge()関数のアドレスは0x2044D420で、これは文字であらわすと「 ヤD 」なんですよ。
えいっ
おぉ、hoge()関数が実行されたではないですか!
この時のメモリー。
解説
あんな感じで"○○したら実行するアドレス"は実はメモリー上にたくさんあります。
- 関数呼び出しが終わったら戻る先のアドレス
- 今回のはこれ
- 例外したら実行するアドレス
- そのインスタンスのメソッドのアドレス
- 関数ポインターの中身
などなど。
それらを1つでも上書きされると好きな関数を呼ばれてしまい、ファイル作られたり外部と通信されて好き放題されます。
つまりメモリーを好きに書き換えられると、それだけで攻撃には十分ということなんです。
もちろんこれらへの対策もいくつもあって、対策を回避するための攻撃もいっぱいあるのですが、そういう話はまた今度ということで。