// 플랫폼

인스턴스마다 microVM,운영은 저희가.

문제 이미지 빌드부터 인스턴스 격리, 리전 배치, 장애 대응, 대회 후 로그 분석까지 맡습니다. 운영진은 문제와 대회에만 신경 쓰면 됩니다.

01 동작 방식

compose 파일과 CTFd는지금 쓰는 그대로 씁니다.

  1. 01

    이미지 올리기

    challrun push 한 번이면 이미지를 빌드해서 고른 리전에 배포합니다. 로컬에서 테스트한 compose 파일 그대로입니다.

  2. 02

    플랫폼 연동

    CTFd는 플러그인만 설치하면 되고 다른 플랫폼은 REST API를 호출하면 됩니다. rCTF든 직접 만든 대회 사이트든 HTTP 요청만 보낼 수 있으면 붙일 수 있습니다.

  3. 03

    대회 당일

    참가자가 인스턴스를 켤 때마다 새 microVM이 뜨고 팀별 플래그가 들어갑니다. 서버 모니터링과 장애 대응은 저희가 맡습니다.

# sits next to your docker-compose.yml, nothing else changes
name: web/blog-v2
compose: ./docker-compose.yml
expose:
  - service: app
    port: 8080
    as: https   # https://<team>.blog-v2.inst.chall.run
  - service: pwnbox
    port: 31337
    as: tcp     # nc icn1.chall.run 40213
resources:
  memory: 512Mi
  cpu: 0.5
ttl: 45m
flag:
  env: FLAG       # unique per team, injected at spawn
  format: "acme{%s}"
team -- https / nc --> edge.icn1   sni + port map
                          |
          +---------------+---------------+
          v                               v
   host epyc-07                    host epyc-11
   |- fc-7f3a  b4ckd00r          |- fc-c0de  r3kt
   |  `- compose: app, db          |  `- compose: pwnbox
   |- fc-91ab  null_ptr          `- fc-0b5e  0xfe
   `- ...                             `- ...

02 리전

참가자와 가까운 곳에인스턴스를 띄웁니다.

오픈 대회는 전 세계에서 참가합니다. 서울에 띄운 인스턴스에 유럽 팀이 붙으면 왕복 지연만 250ms가 넘습니다. chall.run은 한 대회의 인스턴스를 여러 리전에 나눠 띄울 수 있습니다.

  • fra1 프랑크푸르트 DE
  • ams1 암스테르담 NL
  • atl1 애틀랜타 US
  • icn1 서울 KR
  • nrt1 도쿄 JP
  • sin1 싱가포르 SG
  • gru1 상파울루 BR 준비 중
  • +가까운 리전에 자동 배치

    참가자가 인스턴스를 켜면 접속 위치를 보고 가장 가까운 리전에 띄웁니다. 같은 문제라도 한국 팀은 서울, 유럽 팀은 프랑크푸르트에서 받습니다.

  • +리전 고정도 가능

    결선처럼 모든 팀이 같은 조건이어야 하는 대회는 문제별로, 또는 대회 전체를 한 리전에 고정할 수 있습니다.

  • +이미지는 모든 리전에

    올린 이미지는 쓰기로 한 모든 리전의 서버에 미리 빌드됩니다. 어느 리전에서 켜도 기다리는 시간은 같습니다.

  • +요금은 띄운 리전 기준

    인스턴스마다 실제로 뜬 리전의 배율과 트래픽 단가가 붙습니다. 리전별 단가는 요금 페이지에 있습니다.

03 안정성

09:00에 터지지 않게시작 전에 준비합니다.

CTF 운영진들이 올린 인프라 회고 글을 보면 장애는 대부분 시작 후 30분 안에 납니다. 그래서 준비는 대회가 열리기 전에 끝내 둡니다.

$ challrun preflight acme-26
[ok] hosts     12 in icn1, instances spread across all
[ok] images    14/14 challenges prebuilt on every host
[ok] testrun   900 parallel starts, p99 boot 0.8 s
[ok] failover  pulled icn1-07, 61 instances redeployed in 4 s
[ok] isolation scoreboard p95 41 ms during the rush
[ok] on-call   24/7, #acme-26-infra
ready. good luck, have fun.
예시 출력
  • +이미지는 미리 빌드해 둡니다

    이미지는 모든 서버에 미리 빌드되어 있습니다. 대회 시작 후 이미지 빌드를 위해 기다리지 않아도 됩니다. 마지막으로 쓴 뒤 일정 기간이 지난 이미지는 자동으로 지웁니다.

  • +대회 전에도 언제든 테스트

    대회 시작 전에도 언제든지 인스턴스를 띄워 테스트할 수 있습니다. 쓴 만큼만 크레딧이 나가니 참가 팀 수만큼 한꺼번에 띄워 보는 부하 테스트도 직접 해 보시면 됩니다.

  • +서버 한 대에 몰지 않습니다

    인스턴스는 여러 서버에 분산되어 배포됩니다. 서버 한 대에서 장애가 발생하더라도, 즉시 다른 서버에 같은 인스턴스를 배포하고 사용자에게 안내합니다.

  • +스코어보드와 분리

    인스턴스 요청은 대회 CTFd 서버가 아니라 저희 컨트롤 플레인이 받습니다. 인스턴스 요청이 몰려도 스코어보드는 느려지지 않습니다.

  • +엔지니어 24시간 대기

    장애에 대응하는 엔지니어가 24시간 대기합니다. 새벽에 시작하는 대회든 주말 대회든 똑같이 대응합니다.

  • +실시간 대시보드와 사후 리포트

    대회 중에는 실행 중인 인스턴스, 대기열, 서버 상태를 실시간으로 볼 수 있습니다. 끝나면 사용량과 장애 내역을 정리해서 보내 드립니다.

04 로그 분석

플래그 공유와 AI 사용,로그로 확인합니다.

인스턴스는 팀마다 따로 뜨고, 동적 플래그를 쓰면 플래그도 팀마다 달라집니다. 그래서 어떤 요청과 플래그가 어느 팀 것인지 추적할 수 있습니다. 대회 중이든 끝난 뒤든 이 로그를 분석해서 운영진에게 넘겨 드립니다.

$ challrun audit acme-26
[flag]  0x1f submitted a flag issued to 0x3a
        web/blog-v2 · 10:41:12
[flag]  0x1f, 0x77 same /24, 4 solves <40 s apart
[agent] 0x52 web/notes 1,840 req in 6 min
        scripted path walk, no idle gaps
[agent] 0x0c pwn/heap 94 connects
        payload rewritten every ~8 s
[ok]    808 teams, no signals
report: audit/acme-26.html (organizers only)
예시 출력
  • +플래그 공유

    다른 팀에 발급된 플래그를 내면 그 자리에서 잡힙니다. 단, 문제가 동적 플래그(dynamic flag)를 지원해야 합니다. 인스턴스를 띄울 때 팀별 플래그를 FLAG 환경 변수로 넣어 드리니 문제에서 이 값을 읽도록 만들면 됩니다. 한 인스턴스에 여러 팀 IP가 붙거나, 여러 팀이 몇 초 차이로 같은 문제를 풀거나, 페이로드가 똑같은 경우처럼 잘 안 드러나는 흔적도 찾습니다.

  • +AI 사용 감사

    AI 에이전트는 사람과 푸는 방식이 다릅니다. 요청 속도, 경로를 훑는 순서, 재시도 패턴, 도구가 남기는 흔적이 다르게 찍힙니다. 자동화로 보이는 팀을 표시하고 근거가 된 요청도 함께 보여 드립니다.

  • +판단은 운영진이

    AI를 허용할지는 대회 규칙이 정합니다. 저희는 아무도 실격시키지 않고 팀별 근거만 드립니다. AI를 허용하는 대회라면 같은 데이터로 팀들이 AI를 어떻게 썼는지 볼 수 있습니다.

  • +팀별 타임라인

    어떤 팀이 언제 어떤 인스턴스를 켜고 무엇을 보냈는지 내려받을 수 있어서 이의 제기나 사후 검토에 바로 쓸 수 있습니다. 로그는 해당 대회 운영진만 볼 수 있고 대회 종료 30일 뒤에 지웁니다.

05 자주 묻는 질문

Q.왜 컨테이너가 아니라 microVM인가요?
CTF 참가자는 원래 샌드박스를 탈출하려는 사람들입니다. 컨테이너는 같은 서버에 올라간 다른 인스턴스와 커널을 함께 쓰지만 microVM은 인스턴스마다 커널이 따로 있습니다. VM이 1초 안에 부팅되기 때문에 격리를 높여도 참가자가 기다릴 일은 거의 없습니다.
Q.기존 문제를 고쳐야 하나요?
대부분은 고칠 필요가 없습니다. 로컬에서 docker compose up으로 돌아가는 문제라면 여기서도 그대로 돌아갑니다. 다만 privileged 컨테이너와 host 네트워크 모드는 쓸 수 없습니다.
Q.CTFd를 안 써도 연동할 수 있나요?
REST API로 붙이면 됩니다. 시작·연장·중지·상태 조회 엔드포인트 네 개가 전부이고 CTFd 플러그인도 같은 API를 씁니다.
Q.AI 쓴 팀을 자동으로 실격시키나요?
아니요. 저희는 로그에 나온 내용을 전달하고 판단은 대회 규칙에 따라 운영진이 합니다. 탐지 결과는 정황일 뿐 증거는 아니라서, 표시한 팀마다 근거가 된 요청을 같이 드립니다.
Q.참가자가 인프라를 공격하면요?
VM마다 트래픽 제한이 걸려 있고 다른 팀 VM이나 컨트롤 플레인으로 가는 경로는 막혀 있습니다. VM 탈출 같은 취약점을 찾으면 알려 주세요. 제대로 된 제보에는 사례합니다.

사전 신청 일시 중단문의는 메일로 부탁드립니다.

$ 문의

베타를 준비하는 동안 사전 신청은 받지 않고 있습니다. 대회 일정이나 궁금한 점은 아래 주소로 메일 보내 주세요.

support@quickmetal.kr 메일 보내기 →