0

DVL (いまいましい脆弱な Linux) という名前の Linux ディストリビューションをインストールし、バッファ オーバーフローのエクスプロイトを実行しています。私は、bof に対して脆弱な 2 つの実質的に同一のプログラムを作成しました。

//bof_n.c
#include <stdio.h>
void bof() {
  printf("BOF");
}

void foo(char* argv) {
  char buf[10];
  strcpy(buf, argv);
  prinf("foo");
}

int main(int argc, char* argv[]) {
  if (argc >= 1) {
    foo(argv[1]);
  }
  return 0;
}

//bof.c
#include <stdio.h>
void bof() {
  printf("BOF!\n");//this is the only change
}

void foo(char* argv) {
  char buf[10];
  strcpy(buf, argv);
  prinf("foo");
}

int main(int argc, char* argv[]) {
  if (argc >= 1) {
    foo(argv[1]);
  }
  return 0;
}

その後、両方をコンパイルし、両方のケースで bof() 関数のアドレスを取得しました (例: objdump -d bof.o | grep bof)。このようなアドレスを 4 バイトのアドレス ADDR と名付けましょう。

また、buf 変数に 32 バイトを書き込むと、EIP レジスタが完全に上書きされることもわかりました (gdb の出力は仮想マシン上にあるため、ここではコピーできません)。

今、もしそうなら:

./bof `perl -e 'print "\x90"x28 . "ADDR"'`

私は得る:

fooBOF!
Segmentation fault

代わりに、bof_n を使用して同じアプローチを試みると、「セグメンテーション違反」メッセージのみが表示されます。したがって、ADDR 値が繰り返される回数をインクリメントしようとしましたが、少なくとも 350 回繰り返されていれば、目的の結果が得られることがわかりました。しかし、上記の出力を正確に取得する代わりに、「BOF」メッセージの長いリストを次々に取得します。「BOF」メッセージを 1 つだけ取得しようとしましたが、どうやらそれはできません (取得したかゼロか、またはそれらの長いリスト)。なぜこれが起こっているのですか?何か案が?

gcc 3.4.6 で DVL を使用しています

4

2 に答える 2

0

私は解決策を見つけました。問題はメッセージの出力に関するものであり、バッファ オーバーフローのエクスプロイト自体ではありません。実際、レジスタ eip は bof_n の例でも正しく上書きされ、プログラム フローは bof() 関数で正しくリダイレ​​クトされていました。問題は、明らかに、セグメンテーション違反の前に stdout がフラッシュされなかったため、メッセージが表示されなかったことです。

代わりに、を使用するfprintf(stderr, "BOF");と、最終的に「BOF」メッセージが表示されます。

于 2013-08-29T10:35:49.977 に答える