security/포너블 - dreamhack

Dockerfile을 이용해 CTF 문제 환경 구성하기

민사민서 2023. 6. 19. 03:41

참고한 사이트

https://yenua.tistory.com/100

https://www.n1net4il.kr/posts/how-to-run-docker-for-ctf

https://juntheworld.tistory.com/94

 

우리는 단일 dockerfile과 단일 container만 있으면 된다.

따라서 Image를 빌드할 때 docker-compose를 사용할 필요가 없고, docker-compose.yml 파일도 따로 생성할 필요가 없다

(여러 컨테이너들을 동시에 관리해야 하는, CTF 서버에서나 필요)

 

Step1. Docker Image를 빌드한다

- Dockerfile이 존재하는 directory로 이동한다

sudo docker build -t my_docker_image .

- t옵션을 이용해 my_docker_image라는 이름의 Docker Image를 생성한다

- docker build context는 current directory로 지정한다

Step1-1. 생성한 Docker Image를 확인한다

sudo docker images

- ls -l로 확인 불가능하다. docker 이미지는  docker 내부 저장소에 따로 저장된다

Step1-2. 생성한 Docker Image를 삭제한다

sudo docker rmi <IMAGE_ID>

Step 2. 생성한 이미지를 바탕으로 Docker container를 생성/실행한다

sudo docker run -d -p 7182:7182 --name my_docker_container my_docker_image

- '-d' 옵션을 이용해 컨테이너를 백그라운드에서 실행하도록 한다

- '-p' 옵션을 이용해 host의 7182 포트를 container의 7182 포트에 mapping 한다

- '--name' 옵션을 이용해 컨테이너에 이름을 부여한다

- 'rm' 옵션을 주면 컨테이너 종료 시 컨테이너가 자동으로 제거된다

Step2-1. 실행중인 컨테이너를 확인한다

sudo docker ps (-a)

- '-a' 옵션을 주면 현재 중지되어있는 컨테이너까지 표시해준

Step 3. 실행중인 컨테이너에 접속한다

sudo docker exec -it my_docker_container /bin/bash

- '-it' 옵션을 이용해 대화형(interactive) 터미널을 연다

- 접속 후 /bin/bash 혹은 /bin/sh 쉘을 실행한다

Step 3-1. 컨테이너에 접속하여 패키지를 다운받고 싶을 때

sudo docker exec -u root -it my_docker_container /bin/bash

- root로 접속한다 (각종 다운로드 및 접근 권한 확보 위해)

apt-get update
apt-get install gdb -y

apt-get install -y python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh

- gdb 및 pwndbg를 다운받아서 바이너리를 분석한다

Step 4. 실행중인 컨테이너를 종료한다

sudo docker stop my_docker_container

Step 4-1. 실행 종료된 컨테이너의 실행을 재개한다

sudo docker start my_docker_container

Step 4-2. 정지한 컨테이너를 제거한다

sudo docker rm my_docker_container

Step 0. gdb/pwndbg가 깔린 환경의 Docker Image를 생성하고 싶다면

- dockerfile에 내용을 추가한 후 Docker Image를 빌드하면 된다

RUN apt-get update 아래에 
RUN apt-get -y install gdb python3 python3-pip python3-dev git libssl-dev libffi-dev build

RUN git clone https://github.com/pwndbg/pwndbg && cd pwndbg && ./setup.sh

- 수정 후 새로운 이미지를 build하면 된다

- gdb ./mc_thread 해서 기본 gdb 연 후 'source /pwndbg/gdbinit.py' 을 입력해 pwndbg 로드하면 된다

 

 

thnks to Gaurdian 정재영 회장님... 내용추가...

컨테이너에서 실행중인 바이너리를 호스트에서 분석

- dockerfile을 수정해서 이미지에 gdb/pwndbg를 설치하거나

- 컨테이너에서 gdb/pwndbg 패키지 다운받을 필요 없다

=> 번거롭기도 하고 패키지 설치 과정에서 libc 마이너 버전이 달라지면서 바이너리 상태에 영향 줄 수 있음

=> 서버와 동일한 환경을 구축하고자 하는 목적성 해칠 수 있음

이렇게 컨테이너에서 프로세스 실행시켜놓고

호스트에서 ps -ef 명령어를 통해 PID를 확인하고 // 도커 안에서 실행되는 프로세스는 호스트에서도 보인다

sudo gdb -p <PID>

gdb -p 옵션을 이용해 해당 프로세스에 gdb 붙인다 (sudo 필수)

root 계정으로 실행하는거라 gdb에 pwndbg가 안깔려있을 것

soucre /home/minseo/pwndbg/gdbinit.py   (설치 경로 적절히) 입력하여 pwndbg를 사용해서 분석한다

컨테이너의 ip를 확인하는 법

- 도커를 설치하면 호스트의 eth0 네트워크 인터페이스와 도커 컨테이너를 연결하는 네트워크 인터페이스인 docker0가 자동으로 생성된다

- 172.17.0.x 대역이 생성된다!!

- 컨테이너 -> 호스트 방향의 ip는 172.17.0.1 이다

sudo docker inspect [container_name]

- docker inspect 명령어를 통해 컨테이너의 세부 정보 확인 가능, 각 컨테이너의 ip는 172.17.0.2 부터 순서대로 부여

컨테이너 생성 시 포트포워딩?

- 호스트의 port X를 자동으로 해당 컨테이너의 port Y로 forwarding / 연결 시켜주는 것

- docker run 옵션으로 "-p X:Y"를 주면, localhost:X 로 접속 시 [container ip]:Y 로 연결시켜줌

sudo docker run -d --name container1 my_docker_image
sudo docker run -d -p 1234:7182 container2 my_docker_image

이렇게 컨테이너를 생성 및 실행시켰더니

PORTS 상황을 보라!

포트포워딩이 안 된 컨테이너는 개인 ip + 포트번호로만 접속이 가능한데

포트포워딩 된 컨테이너는 localhost / 개인 ip 에서 특정 포트번호로 접속이 모두 가능하다