1. socat을 이용한 문제 구성
[필요한 파일]
1 - 문제파일(바이너리, *.py등)
2 - Dockerfile, docker-compose.yml
3 - README.md
1-1. socat이란?
:다목적 소켓 터널링을 위한 유명한 유닉스 소켓 프로그램
(socat 설치)
apt-get install socat
1-2. 문제파일 준비
(1) 입출력이 가능한 문제파일을 작성
ex) test.c
# test.c
#include <stdio.h>
#include <string.h>
#define FLAG "RD{welldone_you_found_the_flag}"
void check_input(char *input) {
if (strcmp(input, "1234") == 0) {
printf("%s", FLAG);
printf("Correct!\n");
} else {
printf("Wrong!\n");
}
}
int main() {
char input[100];
printf("Enter the flag: ");
fgets(input, sizeof(input), stdin);
// Remove newline character from input
input[strcspn(input, "\n")] = 0;
check_input(input);
return 0;
}
1-3. Dockerfile, docker-compose.yml 작성
(바이너리만 제공하는 경우)
FROM ubuntu:22.04@sha256:b6b83d3c331794420340093eb706a6f152d9c1fa51b262d9bf34594887c2c7ac
ENV PROB test
ENV PORT 8888
RUN apt-get update -y
RUN apt-get install -y socat
RUN adduser $PROB
WORKDIR /home/$PROB
COPY ./flag ./flag
COPY ./deploy/prob ./prob
RUN chmod 644 ./flag
RUN chmod 755 ./prob
USER $PROB
EXPOSE 8888
CMD socat TCP-LISTEN:$PORT,reuseaddr,fork EXEC:./prob,stderr
ex) docker-compose.yml
version: '3'
services:
socat:
image: socat_test
ports:
- "38888:8888"
=> docker-compose는 관리용으로써 문제제공시 compose파일은 제공하지 않는다.
실행 : docker-compose up -d
종료 : docker-compose down
1-4. README.md 작성
[나만의 README 작성 프레임]
# Title :
# Author :
# Desc
asdf
---
(flag)
RD{test}
(익스 원리)
(익스플로잇 코드)
1-5. 환경 구축 테스트
(폴더구성)
> tree
.
├── Dockerfile
├── deploy
│ └── prob
├── docker-compose.yml
└── flag
docker build -t {이미지 이름} .
docker run --rm -it -p {외부포트}:{내부포트} {이미지 이름}
nc localhost {외부포트}
주의사항
(1) - 권한 에러
(base) Greedun 😁 > ~/Downloads/test
> docker run --rm -p 38888:8888 socat_test
2024/06/30 07:28:43 socat[9] E execvp("./prob", "./prob"): Permission denied
2024/06/30 07:28:43 socat[8] E waitpid(): child 9 exited with status 1
=> 해당 에러는 flag, prob파일에 작업하려는데 올바른 권한이 없어서 생기는 에러이다.
-> 이 에러를 해결하기 위해서는 dockerfile에서 권한을 부여하는 명령어를 작성해야한다.
(2) - docker run시 취소 불가 상황
(문제 원인)
[chatgpt왈]
- 컨테이너가 포그라운드 프로세스로 실행되지 않거나
- 신호를 적절하게 처리하지 않는 경우
=> chatgpt왈 이런 문제로 종료가 안되는거라고 답변이 왔다.
그래서 다음와 같은 방법을 나열해봤다.
1 - Docker 컨테이너 종료 명령 사용
2 - SIGINT 신호 전달
3 - Docker compose 사용(V)
4 - 직접 SIGINT 신호 보내기
이제 하나씩 방법을 알아보고 그중 적당히 간편한 것으로 방법을 찾고자 한다.
(1) Docker 컨테이너 종료 명령 사용
docker ps
docker stop {container_id}
(2) SIGINT 신호 전달
docker run 명령어로 실행할때 -it옵션으로 TTY를 할당하여 표준 입력이 연결됨
-> Ctrl+C신호를 전달하여 컨테이너 종료가 가능
(3) Docker compose 사용 - 채택
=> compose로 컨테이너를 관리시 더 쉽게 종료할 수 있음
ex) docker-compose.yml
version: '3'
services:
socat:
image: socat_test
ports:
- "38888:8888"
ex) docker 실행
실행 : docker-compose up -d
=> -d옵션 : 백그라운드으로 실행
종료 : docker-compose down
(4) 직접 SIGINT 신호 보내기
docker kill --signal=SIGINT {container_id}
참고링크
(socat)
(1) https://minpeter.xyz/blog/use-socat-nc-ctf-challenge
(2) https://dhna.tistory.com/334
=> socat명령어와 관련된 옛날자료