Post

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

최근에 Git-based CTF에 대해 좀 공부해야 할 일이 있었는데, 관련해서 자료가 논문과 깃허브밖에 없어서 논문 번역을 오랜만에 좀 해 봤습니다. 혹시나, 이에 대한 내용이 필요했던 분들께 도움이 되었으면 하는 마음으로 내용을 공유합니다. 논문의 출처는 다음과 같습니다.

SeongIl Wi, Jaeseung Choi, and Sang Kil Cha. “Git-based CTF: A Simple and Effective Approach to Organizing In-Course Attack-and-Defense Security Competition”. In: ASE 2018 - 2018 USENIX Workshop on Advances in Security Education.

다음번에는 Git-based CTF를 진행하는 방법에 대해서 블로깅을 해도 괜찮을 것 같네요.

1. Introduction


이 논문에서는 Attack&Defense CTF를 교육 과정 내에서 주최하는 데 있어서 해결해야 하는 도전 과제들을 설명하고, 이런 도전 과제들을 Git-based CTF로 해결할 수 있다고 이야기합니다. 도전 과제의 예시는 다음과 같습니다:

  • C1 (Interactivity Challenge): attacker와 defender 사이의 지속적인 상호작용이 있어야 함.
  • C2 (Configuration Challenge): CTF 환경을 설정하는 것이 간편해야 함
  • C3 (Monitoring Challenge): CTF 수행 중에 이를 모니터링하고 관리하기가 쉬워야 함.
  • C4 (Contents Creation Challenge): 교수자가 새롭게 문제를 내는 어려움을 해결해야 함.

1.png

먼저, Git-based CTF에서 학생들은 attacker인 동시에 defender입니다. 전형적인 Attack&Defense CTF처럼 실시간 상호작용이 가능합니다. 이러한 방식이 익숙지 않은 뉴비를 위해서는 직접적인 가이드를 제공합니다.

둘째로, 환경 설정에 있어서 저렴하고 완전히 분산되어 있습니다. 학생들은 도커 컨테이너를 통해, 상대팀의 문제 환경을 빌드하고, 익스플로잇을 개발합니다. 익스플로잇을 완성한 이후에는, 이를 상대 레포지토리에 이슈를 남김으로써 공격을 수행할 수 있습니다. 이때, 이슈의 내용은 상대 팀과 교수자만 확인할 수 있도록 암호화됩니다.

셋째로, 교수자가 모니터링에 드는 노력을 줄였습니다. 취약점 삽입 단계에서 어떤 취약점이 익스플로잇 가능한지 쉽게 확인할 수 있고, 타겟 소프트웨어의 패치된 버전과 취약한 버전 모두에 익스플로잇을 돌려보면서, 이를 확인할 수 있습니다. 그 결과, 몇 주 동안 숙제로만 내줘도 나중에 한꺼번에 검사가 쉽게 가능한 것입니다.

마지막으로, Contents Creation의 부담을 학생에게 돌림으로써, 교수자의 부담은 줄이면서, 삽입된 취약점을 통해 학생의 실력과 경험을 파악할 수 있습니다. 학생들은 다른 팀의 취약점 패치 버전을 보면서 다시 익스플로잇하기 위해 코드를 점검하기 때문에, 공격자와 방어자 역할을 동시에 체험할 수 있습니다.

2. Background


Jeopardy-style CTF와 Attack&Defense-style CTF의 차이점에 관해 이야기합니다. 전자는 Defense는 고려하지 않은 공격만 있으며, 후자는 hands-on security skill을 체험할 수 있다는 점에서 교육적인 가치가 더욱 높지만 운영하기 어렵다는 단점이 있습니다.

깃허브를 CTF 환경으로 쓰려는 보안 교육적인 노력이 있었으나, Git-based CTF는 이에 더해 PGP 암호화를 사용함으로써 익스플로잇을 안전하게 전달할 수 있도록 합니다.

3. Git-based CTF


Git-based CTF는 세 가지 단계로 구성되어 있습니다: (1) 준비, (2) 삽입, (3) 실습. 학생들은 네트워크 서비스를 준비하고, 취약점을 삽입한 뒤, 다른 팀의 서비스를 분석하고 익스플로잇을 개발합니다.

2.png

설정

교수자는 레포지토리를 만들고 개별 팀마다 하나의 레포지토리를 배정합니다. 교수자들은 한 개의 PGP key 쌍을 만들고, 이를 교수자 사이에 공유합니다. 각 팀도 하나의 PGP 키 쌍을 만들고, 모든 공개키(교수자의 것을 포함)를 팀들 사이에 공유합니다. 교수자가 제출된 공격을 테스트하고 평가하기 위한 스크립트가 존재하며, CTF를 돌리기 위한 서버도 필요가 없습니다. 오로지 깃허브 상에서만 개발/패치 및 공격이 이루어지는 겁니다.

3.1 Preparation Phase

각 팀은 네트워크 서비스 애플리케이션을 준비해야 합니다. 이 애플리케이션은 교수자가 지정한 포트 번호에 바인딩 되어야 합니다. 애플리케이션이 돌고 있으면 클라이언트는 네트워크로 서비스에 접근할 수 있어야 하고, 각 팀은 두 가지 방법으로 앱을 개발합니다.

Hands-on Development.

학생들이 직접 자신만의 서비스를 개발합니다.

Importing Open-source Software.

학생들이 같은 종류의 서비스를 개발하는 걸 피하기 위해 오픈 소스를 가져와 사용한 것에 자유를 제공합니다. 또한, 교수자는 학생들이 import 한 소스 코드를 조사하고, 안전한 서비스인지 파악하길 권장합니다.

서비스가 개발이 완료되면, 각 팀은 자신들의 레포지토리에 코드를 푸시합니다. 이 단계에서 레포지토리는 각 팀과 교수자들만 볼 수 있습니다. 최종적으로 레포지토리에는 서비스 빌드를 위한 Makefile과 패키지 설치를 위한 Dockerfile까지 포함되어 있어야 합니다.

3.2 Injection Phase

이제 모든 팀이 자신의 레포지토리에 애플리케이션이 준비된 상태입니다. 이제 \(N\)개의 서로 다른 취약점을 각자의 앱에 삽입해야 하는데, 이때, \(N\)은 교수자가 강의 상황에 따라 결정합니다. 개별 팀은 \(N\)개의 구분된 브랜치를 만들어 취약점을 삽입합니다. 이때 삽입된 취약점을 의도된 취약점이라고 부릅니다.

취약점을 삽입한 이후에는 exploitable한 취약점인지 증명하기 위한 익스플로잇 코드를 생성하고 이를 PGP key로 암호화하여 푸시합니다. 이때, 익스플로잇 코드는 교수자에게만 보여야 하므로, 교수자의 공개키로 암호화함에 주의합니다.

Automated Exploit Verification.

두 개의 컨테이너를 띄우고, 익스플로잇 코드의 적절성을 판단합니다. 먼저, 취약한 어플리케이션을 포함하는 컨테이너에 교수자가 임의로 지정한 flag.txt 파일을 포함합니다. 다른 하나는 이에 상응하는 익스플로잇을 실행하고 반환받은 플래그가 이전 컨테이너에 포함된 flag.txt와 동일한 문자열인지를 판단합니다. 익스플로잇이 성공적이었다면, 타당한 플래그가 보여지게 되고, 이러한 로직이 3.3에서 attack의 적절성을 판단하는 데 사용됩니다.

Contents Creation.

이러한 취약점 삽입 과정을 통해, 교수자는 CTF에 사용될 문제를 얻어낼 수 있고, 더 나아가 자동으로 검사하고 평가할 수도 있습니다. 그러나, 중요한 것은 이렇게 만들어진 문제가 아주 다양하고 흥미로운가에 대한 것입니다. 4장에서 소개하겠지만, 학생들은 자신의 수준에 맞는 취약점을 삽입하기 때문에, 문제의 어려움과 취약점의 다양성은 학생들에 의해 가능해집니다.

Low Barriers to Entry.

개별 브랜치에 반영된 커밋이 본 프로그램에서 어떤 코드가 달라졌는지를 알려줍니다. 이는 CTF 입문자에게 큰 힌트가 될 수 있습니다. Git-based CTF에서는 CTF에 익숙지 않은 초심자라도 diff를 사용해서 타겟 프로그램에서 취약한 부분이 어디인지 쉽게 발견할 수 있습니다.

3.3 Exercise Phase

마지막 단계의 주목표는 attack과 defense를 실습하는 것입니다. 각 팀은 다른 팀들의 서비스를 분석하고 취약점을 발견한 뒤, 이를 익스플로잇합니다. 이 단계에서야 비로소 모든 레포지토리는 public하게 공개됩니다. CTF에 참여하는데 두 가지 방법이 존재합니다: (1) 삽입 단계에서 만들어진 커밋을 분석하고 의도된 취약점을 발견하는 것, (2) 시스템 내에서 의도하지 않은 취약점을 발견하는 것.

CTF 플레이어들은 다른 팀의 서비스에서 취약점을 찾고 익스플로잇 코드를 작성합니다. 이때, exploit은 도커 컨테이너 내부에서 실행되며, 다른 취약한 컨테이너에 요청을 보내고 플래그를 읽어올 수 있는 프로그램을 의미합니다. 모든 익스플로잇 코드는 공개키로 암호화되어, 교수자와 해당 익스플로잇 이슈를 받은 팀만 볼 수 있어야 합니다.

우리는 타겟 레포지토리에 쉽게 이슈를 생성하는 간단한 스크립트, 제출된 이슈를 가져와 exploitable한지 증명하는 스크립트 등을 제공합니다.

Defense in Git-based CTF.

Git-based CTF에서 Defense는 오직 의도하지 않은 취약점을 패치하는 것을 의미합니다. 의도된 취약점은 원래 소스 코드를 사용하면 존재하지 않는, 이미 패치가 존재하는 취약점이기 때문입니다. 의도하지 않은 취약점이 발견되면, 그 팀은 애플리케이션에 대한 패치를 master branch에 반영합니다. 이러한 패치는 다른 팀에서도 확인할 수 있기 때문에, 패치가 잘못됐거나, 불완전하다면 똑같은 류의 취약점을 다시 익스플로잇할 수 있게 됩니다.

우리는 취약점이 패치될 때까지 의도하지 않은 취약점을 발견한 참가자에게 주기적으로 점수를 제공했습니다. 이에 따라, 모든 참가자는 패치를 모니터링하고 있어야 했습니다.

Automated Scoring System.

한 팀이 레포지토리에 \(k\)개의 취약점 \(v_1\), \(v_2\), …, \(v_k\)를 프로그램 \(p\)에 삽입했다면, 프로그램은 \(p_i\)개의 수정된 버전(브랜치)이 존재하게 됩니다. 이때, 특정 의도한 취약점에 대해 평가를 하려면, 모든 \(p_i\)와 \(p\)에 익스플로잇을 테스트해보고, 유효한 플래그를 반환하는지 확인합니다. 특정 수정된 버전의 프로그램에서만 동작한다면, 해당 의도한 취약점이 익스플로잇되었음을 알 수 있습니다. 만약, 원본 프로그램 \(p\)에서만 익스플로잇이 동작한다면, 이는 의도하지 않은 취약점임을 알 수 있습니다. 의도하지 않은 취약점이 익스플로잇되었을 때, 매 \(M\) 분마다 defender 팀의 포인트를 차감합니다. 공격을 평가할 때마다, 가장 최근 버전의 커밋을 가져와 사용하기 때문에, 참가자들은 일반적인 Attack&Defense CTF처럼 실시간 상호작용을 경험할 수 있습니다.

Scoreboard.

Git-based CTF는 분산된 CTF 프레임워크라서, 스코어를 보여주는 웹 서버가 따로 없습니다. 대신에, 학생들은 로컬에서 스크립트를 돌려서, 현재 스코어 보드를 확인할 수 있습니다. 스크립트는 attack log를 fetch하고 자동적으로 HTML file을 생성합니다.

4. Evaluation


2018년, KAIST에서 일부 학부 졸업생들을 대상으로 강의를 진행했습니다. 21명의 학생 중 11명은 CTF 경험이 없는 상태였고, 이들을 6개의 팀으로 나누어 3주 동안 안전한 메시지 앱을 만들기를 요청했습니다. 메시지 앱의 상세 스펙을 제공하였고, C와 C++로 개발하도록 하였습니다. 최소 1개의 취약점을 삽입하라고 하였고, 학생들은 6개의 서로 다른 앱에 총 28개의 취약점을 삽입하였습니다. 비록 예비적인 CTF였으나, 이를 통해 다음과 같은 교훈을 얻을 수 있었습니다.

Diversity of Injected Vulnerabilities.

프로토콜 설계의 결함에 의한 로직 에러부터, 메모리 오염 취약점까지 다양하게 삽입되었습니다. 이러한 과정에서 교수자의 부담이 거의 없다시피 한 것에 주목해야 합니다.

Difficulty Levels.

학생들의 자신의 기술 수준을 기반으로 취약점을 삽입한다는 것을 알게 되었습니다. CTF 경험이 한 번도 없는 학생들은 대개 로직 에러에 집중했고, 이러한 활동에 익숙한 학생들은 메모리 에러를 기반으로 쉘을 띄우는 문제를 제출하기도 했습니다. 이로 인해, 학생의 수준에 따라 적절한 난이도의 CTF 문제들이 생성되었습니다.

Unintended Vulnerabilities.

14개의 취약점이 18개의 기능 문제가 CTF 진행 중에 발견할 수 있었습니다. 학생들은 12개의 버그를 해결했고, 한 개의 버그를 고치는데 평균적으로 10시간이 소요되었습니다. 의도하지 않은 취약점은 대부분 해킹과 보안에 대해 고인물인 친구들이 풀 수 있었습니다. 따라서, 학생들의 수준을 적절히 섞어 진행하는 것이 중요함을 알게 되었습니다. 경험이 적은 학생들이 의도된 취약점을 찾고, 경험이 많은 학생들이 의도하지 않은 취약점을 찾기 때문입니다.

5. Discussion


Diverse Challenges.

3.1에서 2번째 방법(오픈소스를 끌어다 사용하는 방법)을 사용하면 좀 더 다양한 문제를 볼 수 있을 겁니다. 우리의 선행 연구에서는 모두가 1번째 방법(직접 개발하는 방법)을 사용했지만, 이를 활용하면 어떤 팀은 웹을 기반으로 한 공격도 가능했겠죠.

Unintended Scoring.

3.3에서 보았듯이, Git-based CTF에서는 자동으로 의도한 취약점이 공격에 의해 익스플로잇되는지 확인할 수 있습니다. 그러나, 특정 버전에서 의도한 취약점 \(v_1\)이 존재할 때, 공격자가 의도하지 않은 취약점으로 해당 버전을 익스플로잇해도, 이는 취약점 \(v_1\)을 익스플로잇했다고 판단합니다. 그러나, 우리는 이것이 정당한 방법이라고 봐도 괜찮은 것이, 보통 의도하지 않은 취약점이 더 익스플로잇하기 어려우며, Git-based CTF 자체가 의도된 취약점만 익스플로잇할 경우 제한된 점수를 가질 수 있는데, 의도치 않은 취약점으로 훨씬 더 많은 점수를 얻을 수 있게 되기 때문입니다.

Cheating.

익스플로잇 코드를 공유하는 부정행위가 학생들 사이에서 발생할 수 있습니다. 그러나, MOSS 전통적인 표절 탐지 툴을 사용해서 익스플로잇 코드를 비교해 볼 수 있고, 문제에 대한 솔루션과 제출한 답에 대해 정확히 비교할 수 있으므로, 안티 치트 솔루션을 결합할 수 있다는 장점이 있습니다. 이는 future work로 남겨 놓았습니다.

This post is licensed under CC BY 4.0 by the author.