だから私はバッファオーバーフローの演習を完了しようとしています。私が利用しようとしているコードは以下のとおりです。私ができることは、オーバーフロー攻撃によって自分の印刷ステートメントを挿入することです。私がやりたいのは、$ catファイルで攻撃を実行することです。 code.c
#include <stdio.h>
#include <string.h>
#define INPUT_BUFFER 256 /* maximum name size */
/*
* read input, copy into s
*/
void getl(char *s)
{
int c;
while ((c=getchar()) != EOF)
*s++ = c;
*s = '\0';
}
void removenl(char *s)
{
int l;
l = strlen(s);
while (l--)
if (s[l] == '\n')
s[l] = '\0';
}
int main()
{
char target[INPUT_BUFFER];
getl(target);
if (strlen(target) < INPUT_BUFFER) {
removenl(victim);
printf("%s is the target\n", target);
}
return 0;
}
「char target [INPUT_BUFFER];」で攻撃が行われることを知っています。ポイント。たとえば257 'a'とすると、BOFが生成されます。
現時点での分解はこんな感じ。
0x0000000000400673 <+0>: Push %rbp
0x0000000000400674 <+1>: mov %rsp,%rbp
0x0000000000400677 <+4>: sub $0x100,%rsp
=> 0x000000000040067e <+11>: lea -0x100(%rbp),%rax
0x0000000000400685 <+18>: mov %rax,%rdi
0x0000000000400688 <+21>: callq 0x4005ed <getline>
0x000000000040068d <+26>: lea -0x100(%rbp),%rax
0x0000000000400694 <+33>: mov %rax,%rdi
0x0000000000400697 <+36>: callq 0x4004b0 <strlen@plt>
0x000000000040069c <+41>: cmp $0xff,%rax
0x00000000004006a2 <+47>: ja 0x4006cc <main+89>
0x00000000004006a4 <+49>: lea -0x100(%rbp),%rax
0x00000000004006ab <+56>: mov %rax,%rdi
0x00000000004006ae <+59>: callq 0x400623 <removenewlines>
0x00000000004006b3 <+64>: lea -0x100(%rbp),%rax
0x00000000004006ba <+71>: mov %rax,%rsi
0x00000000004006bd <+74>: mov $0x400764,%edi
0x00000000004006c2 <+79>: mov $0x0,%eax
0x00000000004006c7 <+84>: callq 0x4004c0 <printf@plt>
0x00000000004006cc <+89>: mov $0x0,%eax
0x00000000004006d1 <+94>: leaveq
0x00000000004006d2 <+95>: retq
バッファが満たされていないスタックは次のようになります。
0x7fffffffded0: 0xf7ffe1c8 0x00007fff 0xf7de4961 0x00007fff
0x7fffffffdee0: 0x00000000 0x00000000 0xf7ff7a10 0x00007fff
0x7fffffffdef0: 0x00000001 0x00000000 0x00000000 0x00000000
0x7fffffffdf00: 0x00000001 0x00007fff 0xf7ffe1c8 0x00007fff
0x7fffffffdf10: 0x00000000 0x00000000 0x00000000 0x00000000
0x7fffffffdf20: 0x00000000 0x00000000 0x00000000 0x00000000
0x7fffffffdf30: 0x00000000 0x00000000 0xf7ffe520 0x00007fff
0x7fffffffdf40: 0xffffdf70 0x00007fff 0xffffdf60 0x00007fff
0x7fffffffdf50: 0xf63d4e2e 0x00000000 0x00400391 0x00000000
0x7fffffffdf60: 0xffffffff 0x00000000 0xffffe0c8 0x00007fff
0x7fffffffdf70: 0xf7a251f8 0x00007fff 0xf7ff74c0 0x00007fff
0x7fffffffdf80: 0xf7ffe1c8 0x00007fff 0x00000000 0x00000000
0x7fffffffdf90: 0x00000001 0x00000000 0x0040072d 0x00000000
0x7fffffffdfa0: 0xffffdfd0 0x00007fff 0x00000000 0x00000000
0x7fffffffdfb0: 0x004006e0 0x00000000 0x00400500 0x00000000
0x7fffffffdfc0: 0xffffe0b0 0x00007fff 0x00000000 0x00000000
0x7fffffffdfd0: 0x00000000 0x00000000 0xf7a36f45 0x00007fff
0x7fffffffdfe0: 0x00000000 0x00000000 0xffffe0b8 0x00007fff
0x7fffffffdff0: 0x00000000 0x00000001 0x00400673 0x00000000
0x7fffffffe000: 0x00000000 0x00000000 0x5f571179 0x81bce2d3
0x7fffffffe010: 0x00400500 0x00000000 0xffffe0b0 0x00007fff
バッファがいっぱいになると、次のようになります。
0x7fffffffded0: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdee0: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdef0: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdf00: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdf10: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdf20: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdf30: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdf40: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdf50: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdf60: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdf70: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdf80: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdf90: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdfa0: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdfb0: 0x61616161 0x61616161 0x61616161 0x61616161
0x7fffffffdfc0: 0x61616161 0x61616161 0x61616161 0x37636161
0x7fffffffdfd0: 0x30343630 0x00003030 0xf7a36f45 0x00007fff
0x7fffffffdfe0: 0x00000000 0x00000000 0xffffe0b8 0x00007fff
0x7fffffffdff0: 0x00000000 0x00000001 0x00400673 0x00000000
0x7fffffffe000: 0x00000000 0x00000000 0x5f571179 0x81bce2d3
0x7fffffffe010: 0x00400500 0x00000000 0xffffe0b0 0x00007fff
私はこの攻撃を機能させるために知っている、戻りアドレスを上書きするために動作する必要があり、そこに自分のシェルコードを配置する。
シェルコードのペイロードと思われるものをGDBに入れて、それのシェルコード表現を取得しました。
#include <stdio.h>
void main() {
printf("Now i've pwn your computer");
return 0;
}
\xff\x25\x12\x0c\x20\x00\x68\x00\x00\x00\x00\xe9\xe0\xff\xff\xff\x55\x48\x89\xe5\xbf\xa4\x05\x40\x00\xb8\x00\x00\x00\x00\xe8\xe6\xfe\xff\xff\x90\x5d\xc3\x0f\x1f\x00
実際にこのシェルコードを取得して悪用するにはどうすればよいですか?入力する場所と、プログラムを自然に実行させる方法に戸惑っていると思います。何か見えたら、または正しい方向に役立つヒントを教えていただけませんか。
ありがとう。
これは一般にかなり広範な質問ですが、一般的なアプローチで回答してみます。
通常の容疑者(スタックカナリア、ASLR、no-exec-bitなど)を無効にした場合の一般的なアプローチは次のとおりです。
バッファがオーバーランする前に埋める必要があるスペースの量を確認し、そのスペースを任意の入力で埋めます(念のため、私は個人的にNOPを使用してNOPスライドを作成します)。
NOPスライドの最後で、戻りアドレスを上書きする前に、必ずペイロードを用意してください。
たとえば、戻りアドレスが1000バイトの最後の4バイトで、ペイロードが100バイトの場合、896 NOPの後にペイロードを置き、その後にNOPスライド内のアドレスを置きます。
オンラインで使用しているアーキテクチャの16進数値を調べることができます。
私は個人的に次のいずれかを好みます:
あなたが尋ねたように2番目のオプションを使用するには、次を使用して必要なバイナリファイルを生成できます
xxd -r -p textfile > file
ここで、textfile
は、次のような16進値の文字列を含むファイルです。
aaaaaaaaaaaaaaaff25…
バッファオーバーフローの実行を考えるときは常に、最初に実行ポインタ(EIP/RIP)を制御する方法を考える必要があります。
関数が実行されるたびに、実行ポインタがスタックフレームに保存されます。関数が戻ると、スタックから実行ポインタを取得して実行を再開します(さらに多くの機能がありますが、私は単純化しすぎているため、一般的なアイデアを得ることができます)。
スタックだけを調べることはできません。スタックポインタ、ベースポインタ、命令ポインタのレジスタを調べる必要があります。これにより、EIPが正常に上書きされたかどうか、および期待される値で通知されます。
また、EIPをペイロードのアドレスでオーバーライドする必要がありますが、そのためには、ペイロードの場所を知る必要があります。この場合、それは単純なバッファオーバーフローであるため、スタックにあります。ただし、事前にスタックのアドレスを知っている必要がありますOR JMPを検索するESPコードで命令をそこに置く。
要約すると: