web-dev-qa-db-ja.com

ROPチェーンを構築できません

私の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ガジェットを選択して0xcafebabe0x0badf00dadd esp,8からポップアウトし、次にpop ebxを介してガベージの参照されていない値をポップアウトしてからret exec_stringに。まったく機能すると思いますか?私が間違っていたら訂正してください。

さらに、デバッグを開始すると、次のような結果になります。

かっこいい、私は命令ポインタを所有しているように見えます。それにジャンプしてROPチェーンを開始するには、それをadd_bin関数アドレスに置き換える必要があります。

だが... -

0x91c2b1c2のSIGSEGV?正しいadd_binアドレスを入力しました。ASLR、PIEとカナリアが無効になっています。多分vulnerable_functionが取得する文字列への未定義の参照があると思いましたが、上記のリンクのプライマーでは無視されたため、非常に混乱しました。

2
Asm .

問題は実際にはPython 3にありました。これは、Python 2.のような単純な方法で生のバイトを出力できませんでした。また、add esp, 8; pop ebx; retガジェットは正しいです:)これはROPチェーンを構築する代替方法です(ガベージ値はadd_sh関数によって参照されないため、セグメンテーション違反に陥る危険なしにそれを行うことができ、特に非常に便利になる場合があります)バイナリに完璧なガジェットが少ない場合)。これがエクスプロイトです:

1
Asm .

この問題を修正すれば、成功すると思います。

gef➤  ropper --search pop
[...]
0x0804901e: pop ebx; ret; 
0x080491c4: pop edi; pop ebp; ret; 
[...]

この場合、これらのガジェットはスタックを「混乱させる」ことはありません。オーバーフローの後で少しクリーンアップして、チェーン内の次の関数に戻ることができるようにします。代わりに選択したガジェットはcloseですが、8ではなくadd esp, 4にするか、追加のpopを使用しないでください。デバッガーでステップ実行すると、その理由がわかります。

したがって、代わりに上記のpop; pop; retを使用してください。

1
multithr3at3d