2

これはこれに関連している可能性がありますが、同じボートに乗っているかどうかはわかりません。

そこで、Hacking: The Art of Exploitation を読み直しましたが、この本の C コードのいくつかについて質問があります。

私たちが 2000 年まで戻ってきて、スタック Cookie と ASLR を実際には持っていないと仮定しましょう (おそらく持っているかもしれませんが、実装されていないか、普及していません)、または現在私たちが持っている他のタイプの保護-日。

彼は、単純なスタックベースのオーバーフローを悪用する次のコードを示しています。

#include <stdlib.h>

char shellcode[] = "..." // omitted

unsigned long sp(void) 
{ __asm__("movl %esp, %eax); }

int main(int argc, char *argv[]) {
int i, offset;
long esp, ret, *addr_ptr;
char *buffer, *ptr;

offset = 0;
esp = sp();
ret = esp - offset;

// bunch of printfs here...

buffer = malloc(600);

ptr = buffer;
addr_ptr = (long *) ptr;
for(i = 0; i < 600; i+=4)
{ *(addr_ptr++) = ret; }

for(i = 0; i < 200; i++)
{ buffer[i] = '\x90'; }

ptr = buffer + 200;
for(i = 0; i < strlen(shellcode); i++)
{ *(ptr++) = shellcode[i]; }

buffer[600-1] = 0;

execl("./vuln", "vuln", buffer, 0);

free(buffer);

return 0;
}

彼がやりたいことは、ESP のアドレスを取得し、保存された EIP をそのアドレスで上書きすることです。これにより、プロセッサはメモリ内の NOP スレッドにジャンプし、スタック内のシェルコードを実行します。

私が理解していないのは、sp() から取得した特定の ESP 値を、呼び出した時点でどのように使用できるかということです。

私が理解していることから、スタックは次のような「何か」に見えます。

...
saved ebp <-- execl
saved eip
"./vuln"
"vuln"
buffer
0
*ptr <-- sp() returns this address?
*buffer
*addr_ptr
ret
esp
offset
i
saved ebp <-- main
saved eip
argc
argv
...

彼は (関数ポインタであることはわかっているので、完全に正確な言い回しではないと思いますか?) sp() をエクスプロイトの早い段階で呼び出すので、悪い ESP アドレスを与えるべきではありませんか? さらに言えば、彼がここでその手法をどのように使用できるかさえわかりません。なぜなら、彼は脆弱なプログラム内のバッファーの先頭を指す ESP を決して取得しないからです。

ありがとう。

4

3 に答える 3

0

:) 私は実際に何が起こっているのかを見つけようとして、何日もこれにいました。その過程で、この投稿も発見しました。何が起こっているのかを垣間見たので、「私」のような他の人もこれが役立つと思うように、私が理解したことを共有する必要があると思いました.

unsigned long getesp()
{
__asm__("movl %esp, %eax");
}

この関数は、実際に戻りアドレスを推測するために使用されます。脆弱なプログラムの ESP 値ではなく、シェルコード インジェクション プログラムの ESP 値を返します。しかし、スタックはほぼ同じアドレスで開始されるため (ASLR が有効になっていないシステムの場合)、また aleph one が彼の記事で述べているように、「ほとんどのプログラムは一度に数百または数千バイトをスタックにプッシュすることはありません。したがって、スタックが開始する場所を知ることで、オーバーフローしようとしているバッファがどこにあるかを推測しようとすることができます", シェルコードがどこにあるべきかのアイデアを得ることができます. 説明させてください。

このテスト プログラムでは、スタックが 1000 から始まるとします。このアドレスは、実行時に上記のコードによって実際に返されます。脆弱なプログラムについて考えてみましょう。挿入しようとしているバッファがアドレス 970 にあり、戻りアドレスが 1040 に格納されているとします。

[バッファ 970][RETURN_ADDRESS 1070]

Ok?これで、バッファーは前半まで NOPS でファイルされ、次にシェルコードで、次に戻りアドレスでファイルされます。

[NOP SLED][SHELL_CODE][RETURN_ADDRESS]

このように埋めましょう

NOPS [970-1010] SHELLCODE[1010-1050] RETURN_ADDRESS[1050-1070]

getesp() によって返される値は、スタックがどこにあるかを示します。そのため、getesp() によって返された 1000 でリターン アドレスを書き換えると、1000 のアドレスが nops でファイルされているため、エクスプロイトが引き続き機能することがわかります。実行はシェルコードにスライドダウンします!

于 2014-06-18T19:32:36.593 に答える