web-dev-qa-db-ja.com

バッファオーバーフロー-シェルコードのアドレスを検索

私は SEEDのバッファオーバーフローの脆弱性ラボラボの説明とタスク )に取り組んできました。環境はUbuntu 12.04 32ビットです。次のコードを検討してください:

/* stack.c */
/* This program has a buffer overflow vulnerability. */
/* Our task is to exploit this vulnerability */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int bof(char *str)
{
    char buffer[24];
    /* The following statement has a buffer overflow problem */
    strcpy(buffer, str);
    return 1;
}
 int main(int argc, char **argv)
{
    char str[517];
    FILE *badfile;
    badfile = fopen("badfile", "r");
    fread(str, sizeof(char), 517, badfile);
    bof(str);
    printf("Returned Properly\n");
    return 1;
}

戻りアドレスを上書きするために、24バイト(配列のサイズ)に4バイト(前のフレームポインタ用)に8バイトをジャンプする必要があるため、配列を36位から上書きする必要があることがわかりました。一部のコンパイラデータ(目的は指定されていません)。これはEBPとバッファーのアドレスの差(デバッガーを使用)で計算しました。

悪意のあるコードにジャンプするには、NOPスレッドの任意のアドレスにジャンプできることに気付きました。十分に大きな値の場合、攻撃は成功しました。可能な限り最小の住所を計算してみました。ロジック(および講師)は、戻りアドレスと前のフレームポインター(それぞれ4バイト)の両方を渡したかったため、EBP + 8であると述べました。残念ながら、その値で実行しようとしたときに攻撃は成功しませんでした。徹底的な検索の結果、可能な最小アドレスは0xBFFFF168、これはEBP + 48であり、理由がわかりません。私は、NOPスレッドなしで攻撃を実行しようとしても、問題が発生しました。

誰かが説明できますか?以下は、オーバーランの前後のスタックの説明といくつかの追加の値です。

事前にどうもありがとうございました。

14        strcpy(buffer, str);
(gdb) x/20x $sp
0xbffff100:    0x0804b008    0xbffff157    0x00000205    0xb7e34374
0xbffff110:    0xb7fc4ff4    0xb7fc4ff4    0x00000000    0xb7e1f900
0xbffff120:    0xbffff368    0xb7ff26b0    0x0804b008    0xb7fc4ff4
0xbffff130:    0x00000000    0x00000000    0xbffff368    0x080484ff
0xbffff140:    0xbffff157    0x00000001    0x00000205    0x0804b008
(gdb) next
16        return 1;
(gdb) x/20x $sp
0xbffff100:    0xbffff118    0xbffff157    0x00000205    0xb7e34374
0xbffff110:    0xb7fc4ff4    0xb7fc4ff4    0x90909090    0x90909090
0xbffff120:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff130:    0x90909090    0x90909090    0x90909090    0xbffff168
0xbffff140:    0x90909090    0x90909090    0x90909090    0x90909090
(gdb) p &buffer
$1 = (char (*)[24]) 0xbffff118
(gdb) p $ebp
$2 = (void *) 0xbffff138
(gdb) p $sp
$3 = (void *) 0xbffff100
10
alond22

スタックの実際のサイズはコンパイラの最適化に大きく依存し、デバッガの存在によって影響を受けます。この場合、スタックをebp + 8に最小化する必要はないので、考えすぎません。

スタックの編成を同じ実行であると見なすことは、現実的なエクスプロイトシナリオではなくなったことに留意してください。より現実的なシナリオでは、Nxbit/depとASLRをバイパスする必要があるため、エクスプロイトコードを特定の場所に置くことで、とにかくそれを切り抜けることができます。

NOPスレッドの無料バージョンの攻撃が必要な場合は、代わりに、プログラムをクラッシュさせずにアドレスを開示する方法を見つけることに焦点を当てます。そのような小さな例では、それは不可能かもしれません。

1
baordog