web-dev-qa-db-ja.com

このバッファオーバーフローを悪用する方法。返品先はどこですか?

バッファオーバーフローの練習をしていますが、奇妙なことに、いくつかは実行できますが、他は実行できません。理由は不明です。次にコード例を示します。

助けが必要なコード:

#include <stdio.h>
int main(int argc, char * argv[]) {
    char buf[256];
    if(argc == 1) {
        printf("Usage: %s input\n", argv[0]);
        exit(0);
    }
    strcpy(buf,argv[1]);
    printf("%s", buf);
}

このコードをgcc -z exestack -fno-no-stack-protectorでコンパイルします

質問:

  1. 一般的な手法は、次の命令レジスタがメモリ内で検索する場所を上書きするようにバッファに書き込むことであることを理解しています。だから私の質問は、どこに上書きするかを判断するためにこのコードにどこにブレークポイントを挿入するのですか?私がメインでdisasを実行すると、次のようになります。

    0x080497b1 <+60>:$ 0x10、%espを追加

    0x080497b4 <+63>:サブ$ 0xc、%esp

    0x080497b7 <+66>:$ 0x0をプッシュ

    0x080497b9 <+68>:0x804fd50を呼び出します

    0x080497be <+73>:mov 0x4(%eax)、%eax

    0x080497c1 <+76>:$ 0x4、%eaxを追加

    0x080497c4 <+79>:mov(%eax)、%eax

    0x080497c6 <+81>:サブ$ 0x8、%esp

    0x080497c9 <+84>:%eaxをプッシュ

    0x080497ca <+85>:lea -0x108(%ebp)、%eax

    0x080497d0 <+91>:%eaxをプッシュ

    0x080497d1 <+92>:0x8049028を呼び出します

    0x080497d6 <+97>:$ 0x10、%espを追加

    0x080497d9 <+100>:サブ$ 0x8、%esp 0x080497dc <+103>:lea -0x108(%ebp)、%eax

* main + 97にブレークポイントを追加してからAAAAAAを実行すると、次のようになります。

Breakpoint 1, 0x080497d6 in main ()
(gdb) info registers
eax            0xbffff1f0   -1073745424
ecx            0xbffff575   -1073744523
edx            0xbffff1f0   -1073745424
ebx            0x80da000    135110656
esp            0xbffff1e0   0xbffff1e0
ebp            0xbffff2f8   0xbffff2f8
esi            0x80da000    135110656
edi            0x80481e8    134513128
eip            0x80497d6    0x80497d6 <main+97>
eflags         0x246    [ PF ZF IF ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x33 51

このオーバーフローを解決するために、ブレークポイントを適切な場所に配置していますか? strcpyを呼び出した直後ですか?また、ebpはxbffff2f8にあることがわかります。これは、このすぐ隣の0xbffff2fcのアドレスを上書きしてバッファー内を指すようにしたいということですか?それは機能していないようです:私のバッファーはNOPスレッドとシェルコードです。

助けてくれてありがとう!

1
wussavennell

訂正..もう一度見ますが、EIPを上書きするには、buf + whateverIsAboveItOnStack + EBP(4bytes)+ whateverYouWantEIPtoBeであるバッファーを入力する必要があります。 gdbでプログラムを実行し、disass strcpy()と入力すると、オーバーフローが発生した場所とバッファーが配置されている場所を確認できます。お役に立てれば。

    (gdb) run $(python -c 'print "a" * 270')
Starting program: /home/bob/C/Disassembler_Fun/SE_Vuln/se_vuln $(python -c 'print "a" * 270')

Program received signal SIGSEGV, Segmentation fault.
0x0040068b in main (argc=<error reading variable: Cannot access memory at address 0x61616161>, 
    argv=<error reading variable: Cannot access memory at address 0x61616165>) at se_vuln.c:10
10  }
(gdb) i r
eax            0x0  0
ecx            0x61616161   1633771873
edx            0xb7fbc870   -1208235920
ebx            0x61616161   1633771873
esp            0x6161615d   0x6161615d
ebp            0x61616161   0x61616161
esi            0x2  2
edi            0xb7fbb000   -1208242176
eip            0x40068b 0x40068b <main+139>
eflags         0x10286  [ PF SF IF RF ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x33 51

どこかで実行を返す脆弱な関数(main())を持つプログラムでバッファをオーバーフローすると、EIPを上書きできます

    #include <string.h>

void vuln(char *arg) {
    char buffer[10];
    strcpy(buffer, arg);
}  

int main( int argc, char** argv ) {
    vuln(argv[1]);
    return 0; 
}

    (gdb) run $(python -c "print ('a' * 22) + ('b' * 4)")
Starting program: /home/bob/C/Disassembler_Fun/overflow $(python -c "print ('a' * 22) + ('b' * 4)")

Program received signal SIGSEGV, Segmentation fault.
0x62626262 in ?? ()
(gdb) i r
eax            0xbffff286   -1073745274
ecx            0xbffff520   -1073744608
edx            0xbffff296   -1073745258
ebx            0x61616161   1633771873
esp            0xbffff2a0   0xbffff2a0
ebp            0x61616161   0x61616161
esi            0x2  2
edi            0xb7fbb000   -1208242176
eip            0x62626262   0x62626262
eflags         0x10282  [ SF IF RF ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x33 51
(gdb) 

B(0x42はbの16進数)がEIPを上書きしていることに注意してください。これは、DOS攻撃に使用できる種類のオーバーフローの一種だと思いますが、必ずしもコード実行ではありません。バッファにnopスレッドとシェルコードを格納することを含むテストに使用する場合は、この例のバッファを大きくすることをお勧めします。がんばって楽しんでね!これがお役に立てば幸いです。

1
Bobby Bushay