본문 바로가기

시스템

pwntools ( +드림핵 문제 푸는 법)

얼마 전에 처음 드림핵(http://dreamhack.io)을 접하고 문제를 풀어 보려고 했는데 아예 접근조차 못하겠어서 고생을 했다. 그래서 여기저기 찾아보다가 알게 된 게 pwntool이라는 거였다. pwntool을 먼저 설명하기 전에 드림핵 문제를 푸는 법을 설명해야겠다.

 

가장 먼저 드림핵에서 플래그를 얻어내기 위해서는 드림핵의 서버에 접속해야 하는데 이때 nc 명령어를 이용한다.

nc는 TCP 또는 UDP 프로트콜을 사용하는 네트워크 연결에서 데이터를 읽고 쓸 수 있는 간단한 명령어이다. 드림핵 워게임에서 접속 정보를 확인하면 어디로 들어가야 하는지 알 수 있다.

nc host1.dreamhack.games 포트번호 

터미널에서 이렇게 치면 해당 문제의 서버로? 접속이 가능해진다. 접속하고 나면 로컬에서 내가 실행한 프로그램과 동일하므로 답을 입력해 주면 된다. 답을 입력하면 플래그를 던져 준다. 이 플래그를 워게임에 쳐 넣으면 문제를 맞힐 수 있다.

 

여기서 pwntool이 편리한 역할을 해준다. 문제의 서버로 접속해서, 답을 입력하는 것까지의 과정을 파이썬 코드로 작성하고, 이 파이썬 파일을 실행하기만 하면 플래그를 얻을 수 있게 되는 것이다.

 

 

그럼 pwntool을 가지고 어떻게 파이썬 코드를 쓸까? 이 분을 참고하였다. 감사합니다 (https://tekiter.tistory.com/4)

from pwn import *

pwn 모듈을 임포트 해온다. 만약 pwn이 설치되어 있지 않다면 파일 실행 시 오류가 난다. 이때에는 pip install pwn 해서 설치해주고 파일을 다시 실행해주면 된다.

r=remote("host1.dreamhack.games", 포트번호)

리모트를 통해서 해당 문제 서버에 접속해 준다. nc 명령어와 동일한 역할을 한다고 보면 될 것 같다.

r.send("hello world") # stdin에 "hello world" 넣음
r.sendline("hello world") # stdin에 "hello world\n" 넣음

둘 다 input을 입력할 때 보통 쓴다. 그러니까 C로 치면 scanf에서 우리가 입력하는 부분이다. send와 sendline의 다른 점은 뒤에 \n가 들어가는지 들어가지 않는지이다. 이 차이가 문제를 맞추고 틀리고에 좀 큰 영향을 주기도 한다.

r.recvuntil('AAA')

이거는 AAA까지 반환한다, 이렇게 나와있는데 그냥 약간 until을 봐서 AAA가 나올 때까지 ~~~ 이렇게 생각하면 된다. 그래서 보통은 r.recvutil('AAA')이랑 r.send('BBB')를 같이 써서 AAA가 나올 때까지 기다렸다가 BBB를 보낸다 이렇게 생각하면 될 것 같다. 조금 더 찾아보니 sendlineafter('AAA', 'BBB')이라는 함수가 또 있다! 이게 AAA가 출력되면 BBB를 입력하는 함수라고 한다.

r.interactive()

이 함수를 맨 마지막에 무조건 써 주는 것 같았다. 프로그램에 입출력 조작이 직접 필요할 때 이걸 쓴다고 한다. 쉘 접속, 익스플로잇에 필수라고 한다. 익스플로잇 파일과 프로세스의 연결을 stdin/stdout에서 process로 바꿔준다고 한다.