Logo
Overview
Git-based CTF

Git-based CTF

br0nzu br0nzu
December 25, 2025
15 min read

이번 포스팅에서는 KAIST SoftSec에서 나온 논문인 Git-based CTF: A Simple and Effective Approach to Organizing In-Course Attack-and-Defense Security Competition에 대해 포스팅하겠습니다.

Motivation

해당 논문을 읽게된 계기는 차상길 교수님 랩실에서 나온 논문이기도 하고 최재승 교수님이 참여하신 논문이라 예전부터 궁금했었습니다. 또한 HSpace 나이츠 프론티어 행사에서 Git-based CTF를 한다는 이야기를 듣고, Git-based CTF를 직접 운영하고자 해당 논문을 읽게 되었습니다.

Git-based CTF

이제, Git-based CTF: A Simple and Effective Approach to Organizing In-Course Attack-and-Defense Security Competition에 대한 논문 내용을 정리하겠습니다.

Abstract

기존 CTF를 만들고 관리하기 위해서는 상당한 시간과 인적 자원이 필요하여, 관리자에게 부담이 되었습니다. 그래서 관리자의 운영 부담을 최소화 하면서 A&D 방식의 Git-based CTF를 제안합니다.

1. Introduction

CTF Frameworks

기존 CTF 운영 문제점은 다음과 같습니다.

  • C1(상호작용 문제, Interactivity Challenge): 현실적이고 교육적으로 효과적인 CTF는 공격자와 방어자 간의 지속적인 상호작용이 포함되어야 하지만, 많은 공개형 CTF 프레임워크들은 이러한 상호작용 기능을 지원하지 않는 구조적 한계를 가지고 있습니다.
  • C2(환경 구성 문제, Configuration Challenge): CTF 환경을 구성하려면 상당한 시간과 기술적 역량이 필요합니다.
  • C3(모니터링 문제, Monitoring Challenge): CTF가 진행되는 동안 지속적으로 대회를 모니터링하고 관리할 인원이 필요합니다.
  • C4(콘텐츠 제작 문제, Contents Creation Challenge): 매번 대회를 개최할 때마다 새로운 문제(10~50개)를 직접 만들어야 하는데, 각 문제의 난이도 수준뿐만 아니라 문제 간의 다양성도 함께 고려해야 합니다.

그래서 Git-based CTF는 BIBIFI1의 설계에서 영감을 받고, 앞서 언급한 모든 문제(C1-C4)를 포괄적으로 해결합니다.

먼저, 상호작용 문제(C1)는 참여자들이 공격자와 방어자 두 역할을 모두 수행함으로 해당 문제가 해결됩니다. Git-based CTF에서 공격은 대상 팀의 GitHub 저장소(Repository)에 이슈(Issue)를 제출하는 행위를 의미하고, 방어는 자신의 팀에 있는 언인텐 취약점을 패치하는 행위를 의미합니다.

환경 구성 문제(C2)는 Git-based CTF에서 주로 Git과 Docker를 사용하여 비용이 적게 들고, 환경 설정이 완전히 분산형으로 구성되기 때문에, CTF 환경을 구축하는 데 부담이 크게 줄어듭니다.

모니터링 문제(C3)는 참여자 자신이 만든 어플리케이션에 직접 취약점을 삽입하고, 관리자는 참여자들의 공격을 패치된 버전과 취약한 버전 모두 실행함으로써 해당 공격이 실제로 취약점을 악용했는지를 손쉽게 판별할 수 있어 모니터링 문제를 해결합니다.

마지막으로 콘텐츠 제작 문제(C4)는 참여자들이 문제를 직접 제작하기 때문에, 관리자의 문제 제작 부담이 크게 줄어들어 콘텐츠 제작 문제를 해결할 수 있습니다.

Git-based CTF를 실제로 적용하기 위해, 2018년 봄학기 KAIST에서 진행된 한 과목의 수업 활동의 일환으로 CTF 대회를 운영했습니다. → KAIST-IS521 Github

2. Background

CTF(Capture The Flag)는 참가자들이 여러 과제를 해결했다는 증거로 플래그(Flag)를 획득(Capture)하는 방식의 대회입니다. CTF는 크게 두 가지 형태로 나뉩니다. Jeopardy(문제 풀이형)와 Attack-and-Defense(공격-방어형) 방식이 있습니다.

JeopardyCTF는 일련의 문제 세트로 구성됩니다. 각 문제에는 특별히 설정된 서버가 존재하며, 그 서버에는 참가자가 성공적으로 공격했음을 증명하기 위한 비밀 문자열(Flag)이 저장되어 있습니다. 이러한 형태의 CTF는 일반적으로 방어 과정을 포함하지 않으며, 대부분 공격 중심(Attack-only)으로 진행됩니다.

반면, 공격-방어형(Attack-and-Defense) CTF는 각 참가자가 여러 서비스 어플리케이션을 실행하는 서버를 직접 운영합니다. 참가자들은 다른 팀 서버 어플리케이션에서 취약점을 찾는(Flag를 탈취하는) 동시에, 자신의 어플리케이션을 패치하여 플래그를 보호해야 합니다. 모든 팀의 서버가 서로 연결되어 있어야 하므로, 공격-방어형 CTF는 Jeopardy CTF보다 운영하기 훨씬 어렵습니다.

CTF는 참가자들에게 실질적인 보안 실습의 기회를 제공하며, 최근 들어 그 교육적 가치가 점점 더 주목받고 있습니다. 하지만, 기존 CTF의 프레임워크들은 서론(Introduction)에서 다룬 여러 문제들(C1–C4)이 있습니다. 따라서 본 논문은 이러한 한계를 극복하면서도, 수업 활동의 일부로 공격-방어형 CTF를 손쉽게 운영할 수 있는 새로운 방식을 제시합니다.

3. Git-based CTF

이 장에서는 Git-based CTF의 설계(Design)에 대해 설명합니다. Git-based CTF는 총 세 가지 단계(Phase)로 구성되어 있습니다.

  1. 준비 단계 (Preparation Phase)
  2. 취약점 주입 단계 (Injection Phase)
  3. 실습 단계 (Exercise Phase)

Git-based CTF Design

위 사진은 Git-based CTF의 전체적인 흐름을 도식화한 것입니다. 먼저, 각 팀은 서비스 어플리케이션을 준비해야 합니다. 그 다음으로, 참가자들은 자신의 팀 서비스 어플리케이션에 취약점을 직접 삽입합니다. 마지막으로, 참가자들은 다른 팀의 서비스 어플리케이션을 분석하고 공격(exploit) 하는 실습 단계를 수행합니다. 각 단계에서 관리자와 참여자는 Git을 적극적으로 활용하여, 관리자의 작업 부담을 최소화한다는 목표를 달성하도록 설계하였습니다.

Git-based CTF의 환경 설정은 다음과 같습니다.

  1. Git-based CTF를 설정하기 위해, 관리자는 먼저 각 팀별로 하나의 GitHub 저장소(Repository)를 생성하고 할당해야 합니다.

  2. 그 다음, 관리자는 PGP 키 쌍(Public/Private Key Pair)을 생성하고, 그 중 개인 키(Private Key)를 안전하게 (관리자끼리)공유합니다.

  3. 각 팀은 자신의 서비스 어플리케이션을 해당 저장소에서 관리하게 됩니다. 이 저장소는 단순히 소스 코드를 저장하는 공간일 뿐 아니라, 공격(Exploit)을 제출하는 인터페이스 역할도 수행합니다. 각 팀 역시 자신의 PGP 키 쌍을 개별적으로 생성해야 하며, 생성된 모든 공개 키(Public Key)는 관리자의 공개 키와 함께 모든 팀 간에 공유됩니다.

  4. 관리자는 스크립트를 실행하여 제출된 공격 정보를 자동으로 수집(Fetch) 하고, 이후 공격의 성공 여부를 자동으로 평가(evaluate) 할 수 있습니다. 또한 Git-based CTF에서는 별도의 CTF 서버를 운영할 필요가 없습니다. 즉, 모든 과정은 GitHub 기반의 분산 환경에서 처리됩니다.

3.1. Preparation Phase

이 단계에서 각 팀은 관리자가 지정한 포트 번호에 바인딩되는 서비스 어플리케이션을 준비해야 합니다. 어플리케이션이 실행되면, 클라이언트가 네트워크를 통해 해당 서비스에 접속할 수 있어야 합니다. 각 팀은 직접 개발 방식(Hands-on Development)과 오픈소스 소프트웨어 가져오기 방식(Importing Open-source Software) 중 하나를 선택하여 어플리케이션을 준비할 수 있습니다.

서비스 어플리케이션이 완성되면, 각 팀은 자신의 GitHub 저장소에 코드를 푸시(push) 해야 합니다. 이 단계에서 각 저장소는 비공개로 설정되며, 팀 구성원과 관리자만 접근할 수 있습니다. 이 단계가 끝날 때쯤, 각 저장소에는 다음과 같은 파일들이 포함되어 있어야 합니다.

  • Dockerfile(필수): 어플리케이션 실행에 필요한 패키지를 자동으로 설치하는 dockerfile
  • Makefile(선택): 어플리케이션을 자동으로 빌드하기 위한 makefile

빌드 결과물로 생성된 바이너리(binary)는, 제공된 Dockerfile을 기반으로 구성된 Docker 컨테이너 내에서 정상적으로 실행되어야 합니다. 개발 과정을 좀 더 쉽게 지원하기 위해, Debian 기반 이미지 위에 구축된 템플릿 Dockerfile을 제공합니다. 이 Dockerfile은 관리자가 무작위로 생성한 문자열을 담은 flag.txt 파일 을 입력으로 받아, 해당 flag 파일을 컨테이너 내부의 /var/ctf/ 디렉터리에 복사합니다. 또한, 관리자가 각 팀의 저장소가 제대로 빌드되는지 확인할 수 있도록, 우리는 git clone, docker build, make 등의 명령어를 순차적으로 실행하여 각 저장소의 정상 동작 여부를 자동으로 점검하는 간단한 스크립트를 제공합니다.

준비 단계에서 준비된 어플리케이션들이 의도치 않은 취약점(Unintended Vulnerabilities)을 포함할 수 있음을 주목합니다. 이러한 취약점은 참여자들이 직접 서비스를 개발했는지, 혹은 오픈소스 소프트웨어를 가져와 사용했는지와 무관하게 존재할 수 있습니다. 일반적으로 오픈소스 소프트웨어는 단기간에 참여자들이 작성한 코드보다 취약점이 적을 가능성이 높지만, 그럼에도 여전히 제로데이 공격(Zero-Day Attack) 에 노출될 수 있습니다. 본 논문의 나머지 부분에서는 이러한 취약점을 의도치 않은 취약점(Unintended Vulnerabilities)으로 지칭합니다.

3.2. Injection Phase

모든 팀이 각자의 저장소에 어플리케이션을 준비한 이후, 각 팀은 자신의 서비스 어플리케이션에 N개의 서로 다른 취약점을 삽입해야 합니다. 여기서 N의 값은 관리자가 상황(ex: 참여자 수 등)에 따라 결정합니다. 각 팀은 저장소 내에 N개의 별도 브랜치(Branch) 를 생성하고, 각 브랜치마다 서로 다른 취약점 하나씩을 삽입합니다. 이 단계에서 의도적으로 삽입된 이러한 취약점들을 이전에 존재할 수 있었던 의도치 않은 취약점과 구분하기 위해, 의도적으로 삽입된 취약점을 의도된 취약점(Intended Vulnerabilities)이라고 지칭합니다.

참여자들이 주어진 N개의 취약점을 주입한 후, 각 팀은 삽입된 각 취약점이 실제로 공격 가능한지(Exploitable)를 증명하기 위해 각 취약점에 대한 익스플로잇을 작성해야 합니다. Git-based CTF에서 익스플로잇은 Docker 컨테이너에서 실행되는 프로그램이며, 입력으로 대상의 포트 번호를 받아, 그 포트 번호에서 실행 중인 서비스 컨테이너 내부의 flag 내용을 표준 출력으로 출력합니다. 각 익스플로잇 프로그램과 해당 Dockerfile은 저장소에 푸시 되기 전에 PGP 키를 사용해 서명(Sign) 및 암호화(Encrypt) 되어야 합니다. 이때, 관리자만이 익스플로잇의 내용을 볼 수 있도록, 익스플로잇은 교사의 공개 키로 암호화되어야 합니다. 이 단계에서 생성된 익스플로잇들은 각 의도된 취약점의 정답으로 간주할 수 있으며, 다음 단계에서 저장소가 공개되더라도 다른 팀이 접근할 수 없어야 합니다.

취약점 주입 단계(Injection Phase)는 다음과 같은 특징들이 있습니다.

자동화된 익스플로잇 검증(Automated Exploit Verification)

이 시점에서 각 의도된 취약점이 실제로 공격 가능한지를 확인하기 위해, 해당 취약점에 대응하는 익스플로잇을 단순히 실행해보면 됩니다. 먼저, 무작위로 생성된 flag.txt 파일을 포함한 취약한 어플리케이션을 Docker 컨테이너 내에서 실행합니다. 그 다음, 별도의 Docker 컨테이너에서 익스플로잇 프로그램을 실행하여, 그 출력 결과가 flag.txt 파일에 저장된 무작위 문자열(즉, 올바른 flag 값)과 일치하는지를 검증합니다. 익스플로잇이 성공했을 경우에만, 프로그램은 올바른 flag 문자열을 출력하게 됩니다. 이와 같은 자동화된 검증 절차는 이후 Exercise Phase에서 설명되는 제출된 공격 평가 과정에서도 동일하게 사용됩니다.

콘텐츠 생성(Contents Creation)

취약점 주입 단계(Injection Phase)를 통해, 관리자는 별도의 문제 제작 노력 없이 CTF 문제로 활용 가능한 취약한 서비스를 확보하게 됩니다. 또한, 이러한 문제들에 대한 공격 시도 역시 자동으로 검사 및 평가할 수 있습니다. 한 가지 우려는, 이렇게 생성된 문제들이 충분히 다양하고 흥미로운 문제 구성을 가질 수 있을지 여부입니다. 그러나 Evaluation에 따르면, 참여자들은 자신의 기술 수준에 따라 취약점을 주입하는 경향이 있었습니다. 그 결과, 참여자들이 만든 CTF 문제들은 취약점 유형과 난이도 수준 모두에서 상당히 다양하게 분포된 것으로 나타났습니다.

낮은 진입 장벽(Low Barriers to Entry)

각 브랜치의 커밋 기록(Commit History)에는 원본 프로그램과 비교하여 어떤 변경이 이루어졌는지 명확히 보입니다. 이러한 정보는 다음 단계(Exercise Phase)에서 CTF 초보자들이 어플리케이션의 취약점을 분석하고 공격할 때 유용한 힌트가 됩니다. 즉, Git-based CTF에서는 경험이 부족한 참여자라도 단순히 diff 명령어를 실행해 취약 코드의 위치를 쉽게 찾아낼 수 있습니다. 이는 Git-based CTF의 핵심적인 특징 중 하나입니다. 왜냐하면 참여자들이 다양한 수준의 보안 지식과 경험을 가지고 있다고 가정하기 때문에, 모든 수준의 학습자들이 공격-방어형 CTF를 함께 즐기고 참여할 수 있어야 하기 때문입니다.

3.3. Exercise Phase

마지막 단계의 주요 목적은 공격과 방어를 실제로 수행하며 학습하는 것입니다. 각 팀은 다른 팀의 서비스 어플리케이션을 분석하고, 그 안에서 취약점을 찾아내어 공격을 수행합니다. 이 단계에서 관리자는 모든 팀의 서비스 저장소를 공개로 전환하여, 모든 참가자가 소스 코드에 접근할 수 있도록 합니다. 대회를 진행하는 방법은 취약점 주입 단계(Injection Phase)에서 만들어진 커밋을 분석하여 의도된 취약점을 찾는 방법과 서비스 어플리케이션 내에서 존재하는 의도치 않은 취약점을 직접 찾아내는 방법이 있습니다.

참가자가 다른 팀의 서비스에서 취약점을 발견하면, 그 취약점을 공격하기 위한 익스플로잇을 작성해야 합니다. 앞서 Injection Phase에서 언급했듯이, Git-based CTF에서의 익스플로잇은 다른 Docker 컨테이너에서 실행 중인 타겟 서비스에 연결하여 컨테이너 내부에 저장된 flag를 획득하는 프로그램입니다. 이 단계에서 생성되는 모든 익스플로잇은 관리자와 취약 서비스의 소유 팀의 공개 키로 암호화되어야 합니다. 즉, 두 당사자만이 해당 익스플로잇의 내용을 확인할 수 있습니다. 참가자는 대상 어플리케이션의 GitHub 저장소에 이슈(Issue)를 생성하는 방식으로 익스플로잇을 제출합니다.

관리자는 참여자들이 이 과정을 간편하게 수행할 수 있도록, 명령줄 도구(Command-line Tool)를 제공하여 대상 저장소에 손쉽게 이슈를 생성하도록 지원합니다. 또한 관리자용으로는, 제출된 이슈를 자동으로 수집(Fetch) 하고 앞선 단계(Injection Phase)와 동일한 방식으로 익스플로잇의 유효성을 검증할 수 있는 별도의 명령줄 도구를 제공합니다.

Git-based CTF의 방어(Defense in Git-based CTF)

다른 팀의 공격으로부터 방어하기 위해, 각 팀은 자신의 서비스 어플리케이션에서 발견된 의도치 않은 취약점을 수정할 수 있습니다. 의도된 취약점은 이미 원본 코드를 통해 해결책이 존재하므로, Git-based CTF에서의 방어는 항상 의도치 않은 취약점에 대해서만 수행됩니다. 서비스에서 새로운 의도치 않은 취약점이 발견되면, 해당 어플리케이션의 소유 팀은 그 취약점을 수정하고, 변경 사항을 저장소의 master 브랜치에 푸시 할 수 있습니다.

모든 저장소가 공개되어 있기 때문에, 다른 팀들은 이러한 패치 내역을 실시간으로 모니터링할 수 있습니다. 따라서 패치가 잘못되었거나 불완전한 경우, 다른 팀은 동일한 취약점을 다시 공격할 수 있습니다.

또한 Git-based CTF에서는 의도치 않은 취약점을 성공적으로 공격한 팀에게 그 취약점이 방어팀(Defending Team)에 의해 수정될 때까지 주기적으로 점수를 부여합니다. 이로 인해 모든 참가자는 다른 팀의 패치를 지속적으로 모니터링해야 합니다. 이는 관리자가 직접 수정 내역을 검증해야 하는 BIBIFI와의 중요한 차별점입니다.

자동 점수 시스템(Automated Scoring System)

Git-based CTF의 설계는 자동 점수 산정(Automated Scoring)을 가능하게 합니다. 예를 들어, 참여자가 하나의 프로그램 pk개의 의도된 취약점 v₁, v₂, …, vₖ을 주입했다고 가정합니다. 이때, pᵢvᵢ만 포함된 수정된 버전의 프로그램이라고 합니다. 의도된 취약점에 대한 공격을 평가하기 위해, 관리자는 공격 프로그램을 p₁, p₂, …, pₖ, 그리고 원본 프로그램 p에 모두 실행합니다. 그 결과, 어떤 버전에서 올바른 flag가 반환되는지를 관찰합니다.

익스플로잇이 오직 하나의 수정된 버전에서만 작동할 경우, 해당 공격이 어떤 취약점을 겨냥했는지를 즉시 식별할 수 있습니다. 익스플로잇이 오직 원본 프로그램에서만 작동할 경우, 이는 의도치 않은 취약점에 대한 공격으로 간주합니다.

의도치 않은 취약점에 대한 공격이 발생할 때마다, 피해 팀(Victim)의 점수는 M분마다 차감(Deduct) 됩니다. 여기서 M은 관리자가 설정할 수 있는 조정 가능한 매개변수입니다. 이는 학생들이 신속히 취약점을 수정하도록 유도하기 위함입니다. 또한, 공격자와 방어자 간의 실시간 상호작용을 유지하기 위해 하나의 어플리케이션 내에서 서로 다른 두 개의 의도치 않은 취약점은 그중 하나가 master 브랜치에서 수정되기 전까지는 구분하지 않습니다. 모든 공격(즉, GitHub 이슈)이 발생할 때마다, 관리자는 공격 시점 직전에 커밋된 프로그램 버전을 가져와(fetch), 그 시점의 프로그램을 기준으로 평가합니다. 이를 통해 참가자들은 공격자와 방어자의 실시간 상호작용을 실제 공격-방어형 CTF처럼 경험할 수 있습니다.

결과적으로, Git-based CTF는 Jeopardy와 Attack-and-Defense의 특성을 모두 지닙니다. 즉, 의도된 취약점은 Jeopardy형처럼 공격만 가능한 형태이고, 의도치 않은 취약점은 Attack-and-Defense의 공격-방어 전투를 가능하게 하는 형태입니다.

점수판(Scoreboard)

Git-based CTF는 완전히 분산형 구조의 CTF 프레임워크이기 때문에, 점수를 표시하기 위한 전용 웹 서버를 별도로 운영하지 않습니다. 대신, 참여자와 관리자 모두 제공된 스크립트를 실행하여 현재의 점수판을 확인할 수 있습니다. 이 스크립트는 공격 로그(Attack Log)를 자동으로 가져와, 각 팀의 시간별 점수 변화를 시각화한 HTML 파일을 생성합니다. 이렇게 만들어진 그래프는 일반적인 CTF 대회와 동일한 형태로, 시간에 따른 각 팀의 점수 변동 추이를 한눈에 확인할 수 있습니다.

4. Evaluation

2018년 KAIST에서 진행된 대학원 수준의 한 과목에서 Git-based CTF를 실제로 운영했습니다. 이 과목의 대부분의 학생들은 정보보안 전공자였으며, 암호학과 수학 등 다양한 배경을 가지고 있었습니다. 총 21명의 학생 중 11명은 보안 대회에 참여한 경험이 전혀 없었습니다. 먼저 학생들을 6개 팀으로 나누고, 약 3주간에 걸쳐 단순하지만 안전한 메시지 어플리케이션을 개발하도록 요구하였습니다. 관리자는 어플리케이션의 동작을 명확히 설명한 구체적인 명세서를 제공했으며, 학생들이 보다 흥미로운 취약점을 만들어낼 가능성을 높이기 위해 C 또는 C++ 언어만 사용하도록 제한하였습니다.

첫 번째 단계가 끝난 뒤, 각 학생에게 자신이 만든 어플리케이션에 최소 하나 이상의 취약점을 삽입하도록 요청하였습니다. 그 결과, 학생들은 총 6개의 서로 다른 어플리케이션에 28개의 취약점을 주입하였습니다. 비록 2018년에 수행된 Git-based CTF는 예비 수준의 시도였지만, 이후 진행한 사후 분석을 통해 여러 가지 의미 있는 교훈과 결과를 얻을 수 있었습니다. 이 절의 나머지 부분에서는 그 주요 결과들을 순서대로 기술합니다.

주입된 취약점의 다양성(Diversity of Injected Vulnerabilities)

학생들이 삽입한 취약점들에서 논리적 오류(Logic Errors)와 전통적인 메모리 손상(Memory Corruption) 오류 등 다양한 유형의 취약점이 존재함을 관찰하였습니다. 가장 흔한 유형은 잘못된 프로그램 로직에서 비롯된 논리적 오류였습니다. 예를 들어, 전체 논리적 오류의 약 절반은 프로토콜 설계상의 결함 때문이었습니다. 또한, 버퍼 오버플로(Buffer Overflow), 버퍼 오버리드(Buffer Overread), Use-After-Free, 타입 혼동(Type Confusion)과 같은 다양한 형태의 메모리 손상 취약점도 발견하였습니다.

The distribution of different kinds of injected vulnerabilities

위 그림은 이러한 결과를 요약한 것입니다. 이 결과는 Git-based CTF가 관리자가 직접 문제를 제작하지 않고도 다양한 유형의 CTF 문제를 준비할 수 있도록 돕는다는 점을 보여줍니다.

난이도 수준(Difficulty Levels)

학생들이 삽입한 각 취약점을 추가적으로 분석한 결과, 학생의 경험 수준과 삽입된 취약점의 난이도 사이에 의미 있는 상관관계가 존재함을 발견하였습니다. 즉, 학생들은 자신의 기술 수준에 따라 취약점을 삽입하는 경향이 있었습니다. 이 관계는 아래 그림에 시각적으로 나타나 있습니다.

Vulnerability Type.png

분석의 단순화를 위해, 한 번이라도 CTF 대회에 참여한 적이 있는 학생은 경험자(Experienced)로 분류했습니다. 경험이 없는 학생들은 메모리 공격(Memory Exploitation) 기술에 익숙하지 않기 때문에, 주로 논리적 오류(Logic Error)에 초점을 맞추는 경향이 있었습니다. 실제로, 수업에 참여한 모든 암호학 전공 학생들은 논리 오류를 삽입하였습니다. 반면, 해킹 기법에 대한 고급 지식을 가진 학생들은 보다 복잡한 형태의 취약점을 삽입하였습니다. 이들 중 네 명은 복수의 취약점(Multiple Vulnerabilities)-예를 들어, 메모리 누수(Memory Leak)와 메모리 손상(Memory Corruption)을 함께 삽입하였으며, 이러한 취약점들을 ASLR(Address Space Layout Randomization)과 DEP(Data Execution Prevention) 같은 방어 기법을 우회하여 원격 셸(Remote Shell)을 획득할 수 있도록 체이닝(Chaining)해야 했습니다. 이러한 결과는 학생들이 만든 CTF 문제들이 균형 잡힌 난이도 분포를 가지게 된다는 사실로 이어집니다.

의도치 않은 취약점(Unintended Vulnerabilities)

Git-based CTF에 참여한 학생들은 의도된 취약점 뿐만 아니라, 그 과정에서 의도치 않은 취약점도 발견하였습니다. 활동 기간 동안 총 14개의 취약점과 18개의 기능적 버그(Functionality Bugs)가 보고되었으며, 결과적으로 모든 팀이 최소 한 개 이상의 의도치 않은 취약점을 포함하고 있었습니다. 학생들은 총 12개의 버그를 수정 하였으며, 버그 하나를 수정하는 데 평균 약 10시간이 소요되었습니다. 가장 오래 걸린 경우에는 24시간이 소요되었습니다. 흥미롭게도, 이러한 의도치 않은 취약점의 대부분은 보안 및 해킹에 대한 높은 배경지식을 가진 학생들에 의해 발견되었습니다.

따라서 서로 다른 경험 수준을 가진 학생들이 혼합된 팀 구성이 교육적으로 매우 중요하다고 판단하였습니다. Git-based CTF는 각 의도된 문제에 대해 비교적 명확한 힌트를 제공하기 때문에, 보안 경험이 적은 학생들은 이러한 문제를 중심으로 학습할 수 있고, 더 숙련된 학생들은 의도치 않은 취약점을 찾아내는 활동에 집중할 수 있었습니다.

5. Discussion

다양한 문제 유형(Diverse Challenges)

앞서 Prepare Phase에서 언급했듯이, Git-based CTF의 각 팀은 직접 어플리케이션을 개발 하거나, 기존 프로젝트를 가져오기 방식 중 하나를 선택하여 준비할 수 있습니다. 본 연구에서는 직접 개발 방식만을 적용하였습니다. 그러나 기존 프로젝트 가져오기을 병행한다면, 더욱 다양한 형태의 문제와 공격 시나리오가 등장할 것으로 기대됩니다. 예를 들어, 팀마다 서로 다른 유형의 어플리케이션을 준비할 수 있으며, 특히 일부 팀이 웹 어플리케이션을 선택할 경우, SQL 인젝션, XSS, CSRF 등의 웹 기반 공격도 실험적으로 관찰될 수 있을 것입니다.

의도치 않은 점수 산정(Unintended Scoring)

앞서 Exercise Phase에서 설명했듯이, Git-based CTF는 자동으로 공격이 어떤 의도된 취약점을 공격했는지를 식별할 수 있습니다. 하지만, 만약 공격자가 의도치 않은 취약점을 이용하여 대상 프로그램의 버전을 식별하는 익스플로잇을 제작한다면, 시스템이 그 공격을 의도된 취약점 공격으로 잘못 판단할 가능성이 생깁니다. 예를 들어, 프로그램 p에 하나의 의도된 취약점 v₁이 존재한다고 가정 합니다. 공격자가 p₁ 버전에서만 flag를 출력하도록 익스플로잇을 제작한 경우, 비록 실제로는 v₁을 이용하지 않았더라도, 시스템은 이 공격을 v₁에 대한 유효한 공격으로 인식하여 공격자에게 점수를 부여하게 됩니다. 그러나 이러한 의도치 않은 점수 부여를 크게 우려할 필요가 없다고 생각합니다. 그 이유는 다음과 같습니다.

  1. 의도치 않은 취약점을 공격하는 것은 의도된 취약점을 공격하는 것보다 훨씬 어렵습니다. 따라서 이러한 경우의 점수는, 오히려 더 어려운 문제를 해결한 학생에게 추가 보상으로 간주할 수 있습니다.

  2. Git-based CTF에서는 의도된 취약점에 대한 점수가 고정된 반면, 의도치 않은 취약점은 수정되지 않는 한 무제한 점수를 획득할 수 있습니다.

결과적으로, 의도치 않은 취약점을 통해 얻을 수 있는 점수는 의도된 취약점보다 훨씬 크기 때문에 의도치 않은 점수 부여를 크게 우려할 필요 없습니다.

부정행위(Cheating)

Git-based CTF에서는 참여자들이 공모할 가능성이 있습니다. 예를 들어, 학생들이 서로 익스플로잇 코드를 공유할 수 있습니다. 그러나 Git-based CTF의 관리자는 모든 익스플로잇 코드를 직접 다운로드하여 기존의 표절 탐지 도구인 MOSS와 같은 시스템으로 검증할 수 있습니다. 이는 기존의 CTF 대회와는 다르기 때문입니다. 전통적인 CTF에서는 주최 측이 참가자의 익스플로잇 코드에 접근할 수 없지만, Git-based CTF는 관리자는 참가자의 익스플로잇 코드를 확인할 수 있습니다. 향후 연구에서는, 이러한 점을 보완하기 위해 기존의 반부정행위 CTF 솔루션을 Git-based CTF와 통합하는 방안을 모색할 예정입니다.

CTF 기반 교육을 개선하기 위한 다양한 시도가 존재합니다. 하지만, 본 포스팅에서는 해당 절을 생략하겠습니다.

7. Conclusion

본 논문에서는 Git-based CTF 라는 새로운 형태의 Attack-and-Defense CTF 플랫폼을 제안하였습니다. 이 플랫폼은 수업 내 활동으로도 손쉽게 운영할 수 있도록 설계되었습니다. 기존 CTF 플랫폼이 직면하고 있는 네 가지 주요 문제(C1-C4)를 정의하고, Git-based CTF가 이 모든 문제를 효과적으로 해결할 수 있음을 보였습니다. 또한, Git-based CTF를 운영하기 위한 소스 코드는 GitHub에 공개되어 있습니다.

Git-based CTF(with HSpace)

Git-based CTF를 이번년도 11월 HSpace 나이츠 프론티어 행사에 적용시켰습니다. 기존 Git-based CTF에서 스크립트 부분을 개선하고, 서비스 어플리케이션 명세서 부분만 다르게 진행하였습니다.

기존 스크립트는 python2 버전의 문법이여서, python3 문법에서 동작할 수 있도록 개선하였습니다. 서비스 어플리케이션 명세서를 따로 제한하지 않고, 주제(HSPACE에 실제로 존재하면 좋을 웹 서비스 개발 / HSPACE에 있으면 재미있을 웹 서비스 개발)만 제시 했습니다.

짧은 기한 안에서 스크립트를 개선하고 Git-based CTF를 운영하다 보니 미숙한 부분들이 많았습니다.. 서비스 어플리케이션 명세에 따로 제한을 두지 않아서, 참여자들이 만든 서비스를 빌드하는 데 시간이 많이 걸렸습니다. 또한, 스크립트가 정상적으로 동작하지 않은 경우도 있었습니다. 다시한번 미숙한 운영으로 참여했던 분들께 사죄의 말씀을 올립니다..ㅠㅠ

Git-based CTF를 하면서 느낀점은 부정행위를 방지하는 스크립트와 언인텐 취약점 판단하는 스크립트가 있으면 좋을거 같습니다. Discussion에서 부정행위와 관련된 논의가 나왔지만, 해당 부분이 구현되어 있지는 않았습니다. 그래서 Future Work로 부정행위를 판단하는 스크립트를 만들어볼 계획입니다. 또한, 2018년도 KAIST Git-based CTF에서 언인텐 취약점 부분을 살펴 보려고 했는데, 언인텐 취약점 부분은 보이지 않았고, 논문에서도 애매하게 설명하여 언인텐 취약점을 판단하는 스크립트를 개발해야한다고 느꼈습니다.

부정행위를 방지하는 스크립트와 언인텐을 판단하는 스크립트가 있으면, 관리자의 운영 부담을 기존 Git-based CTF보다 훨씬 줄어들거 같아서 Future Work로 개발하여 후속 논문까지 작성해볼 계획입니다.

Conclusion

평소에 궁금했던 Git-based CTF 논문을 읽어서 좋았고, 운영 기회를 준 HSpace에 감사합니다.

또한, 같이 운영해준 hy30nq, Ark3a, koreant에 감사합니다.

마지막으로, 미숙한 운영에도 잘 따라와주신 HSpace 나이츠 프론티어분들께도 감사합니다.

References

[1] Git-based CTF: A Simple and Effective Approach to Organizing In-Course Attack-and-Defense Security Competition

[2] GitCTF Github

[3] KAIST-IS521 Github

Footnotes

  1. BIBIFI(Build it, break it, fix it): 관리자가 제공한 명세서에 따라 참가자는 어플리케이션을 만들어야 하고, 다른 팀의 어플리케이션에 대해 공격을 하는 CTF