문제 생성하기
문제를 만들기 위해 가장 먼저 해야 할 일은 문제에 사용할 Git Repository의 이름을 선택하는 것입니다. 웹사이트 상에서 문제 생성하기 버튼을 클릭하여 문제가 사용할 Repository 이름을 입력해 주세요.
Repository 이름에는 Hypen(-), underscore(_), a-z0-9의 char-set만을 사용해 주세요.
이 페이지에서 입력하는 문제 이름은 Repository 이름을 자동으로 추천하기 위한 도우미입니다. 최종적으로 보여질 문제 이름은 업로드한 버전에 따라 자유롭게 변경할 수 있습니다.
난이도는 여러분이 생각하는 문제의 난이도입니다. 이 난이도에 따라 문제의 점수가 결정됩니다.
난이도를 변경하는 기능은 현재 지원하지 않습니다.
파일 업로드하기
워게임 문제에 사용될 파일은 두가지 방법으로 업로드할 수 있습니다.
문제 테스트하기
문제를 업로드에 성공한 경우 업로드된 파일이 정상인지 검증합니다. 검증에 성공한 버전에 한해서 배포할 수 있으므로, 문제 검증을 성공해야 합니다.
업로드한 버전을 선택한 뒤 설정 검사 버튼을 클릭하면 검사가 진행됩니다.
검증 여부는 각 문제 설정 페이지의 Tasks 페이지를 통해 확인할 수 있습니다. 만약 검증에 실패하는 경우 실패 사유가 표시됩니다.
Web API를 통해 파일을 업로드 했다면 자동으로 문제 파일 검증이 진행되고, 재검증이 필요할 경우 재검증 요청 없이 새로운 버전을 업로드하면 됩니다.
문제 배포하기
검증에 성공한 버전을 현재 버전으로 설정할 수 있습니다. 설정된 버전의 설명과 공개 파일 등이 사용자에게 공개됩니다.
VM을 사용하는 문제의 경우 의도한 대로 작동하는지 테스트 접속 환경을 통해 확인해볼 수 있습니다.
모든 것이 원하는 대로 작동하여 이 문제를 공개해도 좋은 상태라면, 문제 공개하기 버튼을 클릭하여 모든 사람들이 문제에 접근하여 문제를 풀 수 있도록 공개할 수 있습니다.
한 번 공개한 문제는 다시 비공개로 전환할 수 없습니다.
Web API
문제를 업로드 하기 위해서는 다음과 같은 정보를 입력해야 합니다.
- 문제 제목
- 문제를 대표하는 제목입니다.
- 정해진 서식이 없으며 자유롭게 설정할 수 있습니다.
- 설명
- 문제에 대한 설명입니다. Markdown 포맷으로 작성합니다.
- 문제에 대한 정보나 문제를 해결하기 위해 필요한 단서를 기술하는 등의 문제와 관련된 내용을 적을 수 있습니다.
- 플래그
- 문제를 해결한 뒤 획득 할 수 있는 Flag입니다.
- 정해진 형식은 없지만 유추하기 어렵게 작성하는 것이 이상적입니다.
- 태그
- 문제에 해당하는 분야를 태그합니다. 모든 문제는 하나 이상의 태그가 지정되어야 합니다.
- 다음과 같은 태그들을 사용할 수 있으며, 이외에도 적절한 태그를 사용할 수 있습니다.
pwnable
reversing
web
crypto
forensics
cloud
misc
VM 설정
만약 문제를 해결하기 위해 별도의 서버를 필요로 하는 경우 VM 사용하기를 통해 VM을 추가할 수 있으며 세부 사항을 설정 할 수 있습니다.
- 운영체제
- VM에서 사용하는 운영체제의 종류를 지정합니다.
- 다음과 같은 운영체제를 사용할 수 있습니다.
- Linux
- VM 메모리
- VM 인스턴스가 사용하는 최대 메모리 크기를 지정합니다.
- VM 디스크 크기
- VM 인스턴스가 사용하는 최대 디스크 크기를 지정합니다.
- VM Expose 포트
- 외부에서 VM으로 접근할 수 있는 포트를 지정합니다.
- comma(
,
)로 구분된[port]/[protocol]
형태의 쌍 목록을 사용하여야 합니다.- protocol로는
tcp
와udp
를 사용할 수 있습니다.
- protocol로는
- 지정하지 않을 경우 어떤 포트도 개방하지 않습니다.
필요한 메모리 및 디스크 크기는 실제로 Docker를 사용해 image를 생성하고 container를 실행하는 것으로 필요한 크기를 확인할 수 있습니다.
Image의 크기는docker image
명령어를, 메모리의 크기는docker stats
명령어를 통해 확인할 수 있습니다.
필요한 공간의 최소화를 위해 Base image는
slim
혹은alpine
버전을 사용하는 것을 권장합니다. 빌드하는 시간을 단축시킬 수 있으며, 디스크 크기 문제로 인한 에러를 크게 줄일 수 있습니다.
파일 업로드
폴더를 업로드 할 때는 다음과 같은 조건을 만족해야 합니다.
- 반드시
public/
폴더를 포함해야 합니다.- 이 폴더는 문제를 푸는데 필요한 파일들을 포함하는 폴더입니다.
- 이 폴더의 파일들은 문제에 접근하는 모든 사용자가 자유롭게 다운로드할 수 있습니다.
- Git을 통한 업로드에 필요한
Specfile
,Description.md
등의 파일은 필요하지 않습니다. - VM을 필요로 하는 경우
Dockerfile
이 최상위 경로에 존재해야 합니다.- Docker 컨테이너를 만들기 위한 설정을 기술한 파일입니다.
- 자세한 내용은 Dockerfile Reference를 참조해 주세요.
웹사이트를 통해 문제를 업로드 한 경우
upload-1
과 같은 태그가 자동으로 부여됩니다.
다음 예제 파일들을 이용해 필요한 파일 구조를 확인할 수 있습니다.
문제 테스트, 배포
git을 이용한 파일 업로드를 위해서는 기본적인 Git 사용법의 숙지가 필요합니다.
SSH 공개키 등록하기
생성된 문제를 Git으로 접근하려면 먼저 SSH 키를 서버에 등록해야 합니다. SSH 키를 생성한 적이 없다면 다음 링크를 통해 자세히 알아볼 수 있습니다.
SSH 키는 마이 페이지 내 워게임 설정 항목에서 추가하거나 삭제할 수 있으며, 워게임 페이지 상단의 워게임 설정 버튼을 통해 바로 이동할 수 있습니다.
등록을 정상적으로 마쳤다면, 다음 쉘 명령어를 통해 SSH 키가 등록되었는지 확인할 수 있습니다.
$ ssh -T git@git.dreamhack.io
Welcome to DreamHack, @userid!
Repository clone하기
문제 생성을 통해 만들어진 서버 Repository를 복사합니다. Repository 복사는 다음 명령어를 통해 수행할 수 있습니다.
git clone git@git.dreamhack.io:[repository-name].git
Cloning into '[repository-name]'...
현재 git init을 통해 직접 생성한 Repository를 워게임 시스템에 복사해 넣는 것은 지원되지 않습니다.
문제 파일 구성하기
하나의 문제에는 다음과 같은 파일과 폴더를 필수적으로 업로드해야 합니다.
Specfile
- 문제에 대한 자세한 설정을 기술한 파일입니다.
- 아래의 예제 파일을 복사하여 문제에 필요한 형태로 설정을 작성합니다.
Description.md
- 문제에 대한 설명을 작성하는 파일입니다. Markdown 포맷으로 작성합니다.
- 문제에 대한 정보나 문제를 해결하기 위해 필요한 단서를 기술하는 등의 문제와 관련된 내용을 적을 수 있습니다.
public/
- 문제를 푸는데 필요한 파일들을 포함하는 폴더입니다.
- 이 폴더의 파일들은 문제에 접근하는 모든 사용자가 자유롭게 다운로드할 수 있습니다.
만약 VM을 필요로 하는 문제라면 추가적으로 다음과 같은 파일을 필수적으로 업로드해야 합니다.
Dockerfile
- Docker 컨테이너를 만들기 위한 설정을 기술한 파일입니다.
- 자세한 내용은 Dockerfile Reference를 참조해 주세요.
- Docker version을 명시할때는,
FROM ubuntu:22.04
보다는FROM ubuntu:22.04@sha256:b6b83d3c331794420340093eb706a6f152d9c1fa51b262d9bf34594887c2c7ac
- sha256 hash는
docker inspect [Image Name]
이후RepoDigests
값을 사용하면 됩니다.
e.g)docker inspect ubuntu:22.04
- libc file은 익스플로잇 과정에서 필요하다면 public/ 에 넣어주는 것을 권장합니다.
Specfile
모든 Specfile
에는 [wargame]
section이 필수적으로 포함되어야 하고, VM을 필요로 하는 문제라면 [vm]
section이 추가적으로 포함되어야 합니다.
[wargame] section
[wargame]
section에는 다음과 같은 속성들이 필수적으로 작성되어야 합니다.
- title
- 문제를 대표하는 제목입니다.
- 정해진 서식이 없으며 자유롭게 설정할 수 있습니다.
- flag
- 문제를 해결한 뒤 획득 할 수 있는 Flag입니다.
- 정해진 형식은 없지만 유추하기 어렵게 작성하는 것이 이상적입니다.
- tags
- 문제에 해당하는 분야를 태그합니다. 모든 문제는 하나 이상의 태그가 지정되어야 합니다.
- 다음과 같은 태그들을 사용할 수 있으며, 이외에도 적절한 태그를 사용할 수 있습니다.
pwnable
reversing
web
crypto
forensics
cloud
misc
[vm] section
[vm]
section에는 다음과 같은 속성들이 필수적으로 작성되어야 합니다.
- os
- VM에서 사용하는 운영체제의 종류를 지정합니다.
- 다음과 같은 운영체제를 사용할 수 있습니다.
linux
- memory
- VM 인스턴스가 사용하는 최대 메모리 크기를 MB 단위로 지정합니다.
- disk
- VM 인스턴스가 사용하는 최대 디스크 크기를 MB 단위로 지정합니다.
- ports
- 외부에서 VM으로 접근할 수 있는 포트를 지정합니다.
- comma(
,
)로 구분된[port]/[protocol]
형태의 쌍 목록을 사용하여야 합니다.- protocol로는
tcp
와udp
를 사용할 수 있습니다.
- protocol로는
- allow_outgoing
- VM이 외부 네트워크에 접근할 수 있는지 여부를 지정합니다.
true
또는false
의 값을 사용할 수 있습니다.
- docker_compose
docker-compose
를 활용하여 이미지를 빌드합니다.- 해당 옵션을 지정하는 경우
Dockerfile
이 아닌docker-compose.yml
파일을 요구합니다.
필요한 메모리 및 디스크 크기는 실제로 Docker를 사용해 image를 생성하고 container를 실행하는 것으로 필요한 크기를 확인할 수 있습니다.
Image의 크기는docker image
명령어를, 메모리의 크기는docker stats
명령어를 통해 확인할 수 있습니다.
필요한 공간의 최소화를 위해 Base image는
slim
혹은alpine
버전을 사용하는 것을 권장합니다. 빌드하는 시간을 단축시킬 수 있으며, 디스크 크기 문제로 인한 에러를 크게 줄일 수 있습니다.
예제
Docker Version
[wargame]
title = My challenge
flag = flag{my_challenge}
tags = web
[vm]
os = linux
memory = 128
disk = 256
ports = 80/tcp, 443/tcp
allow_outgoing = false
docker_compose = false
Docker Compose Version
[wargame]
title = Compose challenge
flag = flag{compose_challenge}
tags = misc
[vm]
os = linux
memory = 128
disk = 1024
ports = 5000/tcp
allow_outgoing = false
docker_compose = true
Commit, Tag, Push
문제에 필요한 파일들을 모두 준비한 뒤 이 파일들을 서버에 업로드하기 위해서는, 먼저 현재 상태를 commit해야 합니다.
Git의 기초 - 수정하고 저장소에 저장하기
https://git-scm.com/book/ko/v2/Git의-기초-수정하고-저장소에-저장하기
$ git add -A
$ git commit -m "commit message"
[master f2b6efd] commit message
(...)
commit이 만들어진 후, 해당 commit에 tag를 추가해야 합니다. 이 tag가 해당 문제의 버전 구분에 해당합니다.
$ git tag [tag-name]
tag한 결과물을 push하여 서버에 버전을 올릴 수 있습니다.
$ git push origin master --tags
Total 8 (delta 1), reused 0 (delta 0)
(...)
* [new tag] [tag-name] -> [tag-name]
문제 테스트, 배포
공식 분야
드림핵은 점수 체계의 신뢰도 및 공정성 유지를 위해 분야 별로 문제 수가 적절히 확보된 분야에 대해서만 점수를 집계하고 있습니다. 이에 따라 아직 문제 수가 적절히 확보되지 않은 분야들에 대하여 공식적으로 점수를 집계하고 있지 않습니다. 현재 공식 분야로 선정된 분야는 다음과 같습니다.
- 시스템해킹 (System Hacking, Pwnable)
- 리버스 엔지니어링 (Reverse Engineering, Reversing)
- 암호학 (Cryptography, Crypto)
- 웹해킹 (Web Hacking, Web)
점수 시스템
워게임의 레이팅은 다음과 같은 기준으로 산정됩니다.
워게임 레이팅 = (공식 분야 점수들의 합)
워게임 레이팅 = (시스템 해킹 점수) + (리버스 엔지니어링 점수) + (암호학 점수) + (웹해킹 점수)
분야별 점수 = 문제 상수 * 가중치(0.0 ~ 1.0)의 합
가중치 = 0.95 ^ (난이도 순 정렬했을 때 순서)
문제의 난이도마다 산정되는 고유 점수는 다음과 같습니다. (100% 가중치 기준 획득할 수 있는 최대 점수입니다.)
- UNRANKED: 0
- 레벨 1: 20
- 레벨 2: 40
- 레벨 3: 75
- 레벨 4: 130
- 레벨 5: 200
- 레벨 6: 300
- 레벨 7: 435
- 레벨 8: 610
- 레벨 9: 830
- 레벨 10: 1100
투표 시스템
문제 풀이자는 자신이 해결한 문제의 난이도를 투표할 수 있습니다. 정해진 레벨에 투표하기 위해서는 기준 점수를 만족해야 합니다.
- 레벨 1: 500
- 레벨 2: 500
- 레벨 3: 500
- 레벨 4: 500
- 레벨 5: 500
- 레벨 6: 1000
- 레벨 7: 1000
- 레벨 8: 1500
- 레벨 9: 1500
문제의 난이도는 투표된 모든 난이도의 중앙값으로 선정되며, 짝수 개의 투표가 존재하는 경우 가장 가운데 두 투표의 산술평균을 난이도로 사용합니다.
예외로 레벨 10은 투표할 수 없으며, 드림핵 관리자가 가장 가치 있고 도전적인 문제를 임의로 선택하여 선정됩니다.
워게임 구조
Dreamhack 워게임은 만약 문제를 동작시키기 위해 별도의 서버를 필요로 하는 경우(예: 리모트 서버, 웹 서버) 해당 문제를 해결하기 위해 각 유저를 대상으로 별도의 가상 환경을 제공합니다. 해당 가상 환경을 공격하여 사용자는 Flag를 획득하고, 문제에 따른 점수를 획득합니다.
- 사용자가 VM을 필요로 하는 문제를 도전하려고 할 때 새로운 VM 인스턴스가 생성되며 각 유저에게 독자적으로 제공됩니다.
- 이를 통해 문제를 도전 중인 여러 사용자의 상태가 간섭되는 것을 방지합니다.
- 워게임 서버의 임의의 포트가 배정되며,
Specfile
에 정의된 포트로 포워딩됩니다.- 포트는 TCP와 UDP를 지원합니다.
- 각 문제는 여러 개의 포트를 Expose 할 수 있지만, 워게임 서버에서 순차적인 포트를 배정하지 않을 수 있습니다.
예를 들어,Specfile
에서 Expose 하기로 지정한 포트가8080/tcp,8081/tcp
과 같은 연속된 포트여도, 시스템에서 배정하는 포트는10254/tcp,10532/tcp
와 같이 연속적이지 않을 수 있습니다.
서버 설정
Dreamhack 문제가 제공하는 서버는 아래의 설정을 기반으로 동작하며, 문제는 해당 환경 아래에서 반드시 호환성을 테스트해야 합니다.
- 모든 문제 VM은 Firecracker microVM 아래에서 동작합니다.
- 문제를 만든 사람이 제공한 image를 빌드한 container가 문제의 VM으로 사용됩니다.
- Container는 문제를 만든 사람이 명시한
Dockerfile
를 기반으로 생성됩니다. - 문제의 Repository 내
Specfile
에 문제 VM이 필요로 하는 최소의 CPU, 메모리, 디스크 크기가 설정되어야 합니다.- 문제를 만드는 사람의 별도 요청에 따라 변경될 수 있습니다.
- 문제 VM은 CPU 사용량 제한이 걸려 있습니다. (전체 서버의 CPU 사용량 중 약 10% 규모)
- 부팅 과정은 예외로 CPU 사용량 제한이 해제됩니다.
- VM 자체의 메모리 사용량에 의해 최소 메모리 필요 용량은 128MB입니다.
- 디스크 크기는 image를 빌드하기 위한 공간을 포함해야합니다.
- 문제를 만드는 사람이 직접
Dockerfile
을 테스트하여 필요한 공간의 크기를 알고 있어야 합니다. docker images
명령어를 통해 Docker image의 크기를 알 수 있습니다.
- 문제를 만드는 사람이 직접
문제 구성 관리
Dreamhack은 문제의 버전 관리의 용이함을 위해 Git을 내부적으로 사용하고 있습니다.
- 문제가 생성됨과 동시에 실제 Git Repository가 서버에 생성되며 관리됩니다.
- 문제 출제자가 문제를 개발하는 과정 중 원하는 상태의 커밋을 tag하고 웹페이지를 통해 Deploy할 수 있습니다.
- 이 과정을 통해 문제 출제자와 Dreamhack 스탭들이 쉽게 기록을 통해 발생한 서버 문제를 해결할 수 있습니다.
- Git Repository는 현재 128MB의 크기 제한이 있습니다.
- Git을 사용하지 않고 웹페이지만을 사용하여 문제의 버전을 업로드 할 수 있습니다.
- 웹페이지를 사용하여 업로드하는 경우 전송된 파일을 자동으로 커밋한 후
upload-1
과 같은 태그를 부여합니다. - 웹페이지를 통해 커밋하는 것과 Git을 통해 커밋하는 것은 차이가 없으며, Dreamhack 내부에서 동일하게 관리합니다.
- Deploy를 요청하기 전에 반드시 설정된 값이 정상적인지 검사해야 하며, 웹페이지에서 검사를 요청할 수 있습니다.
- Test 과정이 완료되면
Dockerfile
을 포함한 문제인 경우 image를 빌드합니다. - 만약 image를 재생성 및 재배포해야 하는 경우 새로운 Tag를 부여하여 빌드해야 합니다.
- Test 과정과 image 빌드 과정이 모두 끝나면 "Live" 버전으로 배포할 수 있게 됩니다.
- 유저가 문제의 정보를 요청하는 경우 문제를 만든 사람이 기술한 문제의 "Live" 버전의 정보를 받게 됩니다.