|
DARPA AIxCC는 생성형 AI 기술을 활용해 보안 문제를 해결하려는 취지에서 탄생한 대회입니다. 삼성 리서치는 유수 대학의 연구원들과 연합 팀을 구성해 이 대회에 참가했으며, 준결선에서 우수한 성적을 거두어 내년 결선에 진출하게 되었습니다. 이 블로그에서는 AIxCC 대회를 소개하고 저희 팀이 구현한 CRS 디자인에 대해 설명합니다. |
DARPA AIxCC(AI Cyber Challenge)
DARPA AIxCC(AI Cyber Challenge)는 빠르게 발전하는 생성형 AI, 특히 LLM(Large Language Model)을 활용해 사회 기반 인프라를 구성하는 오픈 소스 프로젝트를 보호하고 보다 안전한 소프트웨어 환경을 조성하자는 취지로 마련된 대회입니다. 미국 백악관과 AI 선두주자인 Anthropic, Google, Microsoft, OpenAI 등이 후원하는 이 대회는 유례없는 규모의 DARPA Grand Challenge 행사로 자리매김했습니다.
Team Atlanta
삼성 리서치는 KAIST, POSTECH, Georgia Tech 등 세계 유수 대학의 연구원들과 연합하여 Team Atlanta라는 팀으로 AIxCC에 참가했습니다. 이번 블로그 포스팅에서는 AIxCC 대회와 Team Atlanta에서 디자인한 사이버 추론 시스템(Cyber Reasoning System, CRS)을 소개해 드리려고 합니다.
대회 미션
이번 대회에서 Team Atlanta는 CRS를 사용해 지정된 코드 리포지토리(git)에서 버그를 찾고 패치를 생성해 버그를 수정하는 미션을 수행했습니다. 준결선에서는 C/C++ 또는 Java로 구현된 총 5개의 오픈소스 프로젝트가 출제되었습니다. 각 오픈소스 프로젝트는 사회 기반 인프라를 구성하는 프로젝트로, Android 및 Tizen 커널로 쓰이는 Linux, Nginx 웹 서버, CI 툴인 Jenkins 등이 포함되었습니다.
해당 프로젝트에서 0-day(알려지지 않은 취약점) 또는 1-day(알려진 취약점) 버그를 찾아야 했으며, 각 버그는 Top20 CWE(Common Weakness Enumeration) 타입으로 구성되었습니다. 준결선에서는 총 8개 타입의 버그가 출제된 가운데 Team Atlanta는 5개 타입의 버그를 찾았고, 2개 타입의 버그에 대한 패치를 생성했습니다.
Linux의 예제로 주어진 CVE-2021-43267을 가지고 전체 CRS가 어떻게 구성되었는지 설명드리면, CVE-2021-43267은 TIPC(Transparent Inter-Process Communication)에 존재하는 버그로, 두 프로세스가 암호로 보호된 채널을 형성하는 과정에서 생긴 메모리 관련 버그입니다. 이 버그는 잘 문서화되어 있고 해당 공격코드도 공개되어 있어 CRS를 테스트하기 좋은 예제였습니다.
이 버그의 이면을 살펴보면 더욱 흥미로워집니다. 이 취약점은 한 보안 연구원이 CodeQL을 사용해 Linux 커널 소스 코드를 감사하던 중 발견되었습니다. 연구원은 메모리 할당을 위한 kmalloc() 함수에 16비트 크기 파라미터가 전달되는 경우를 찾고 있었고, 이를 위해 데이터 흐름 기반의 CodeQL 쿼리를 사용했습니다. 그는 16비트 크기 파라미터가 할당된 객체에 접근할 때 정수 오버플로우가 쉽게 발생할 수 있을 것이라고 직감했습니다. 하지만 실제로 발견된 버그는 정수 오버플로우가 아니라, 크기와 관련된 입력 값에 대한 적절한 검증이 누락되어 발생한 힙 오버플로우였습니다.
`skey`는 사용자 제공 `hdr`을 기반으로 크기가 할당되었지만, `skey->key`는 `skey->keylen`까지 복사되었으며 이 값 또한 사용자가 제어할 수 있어 크기와 일치하지 않을 수 있었습니다. 커널에서 이 두 값에 대해 검사(sanity check)를 수행하지 않기 때문에 Out-of-bound 접근이 가능했습니다.
LLM을 활용하여 CVE-2021-43267을 탐지할 수 있을까요? 대회에서 사용이 허가된 GPT-4/GPT-4o 모델의 경우 약 64k 토큰을 사용할 수 있습니다. 하지만 Linux 커널의 경우 30m 정도의 라인으로 구성된 프로젝트이다 보니 LLM만으로는 버그를 탐지하기가 쉽지 않았습니다. 그래서 주최측에서는 Input space를 축소시켜 Harness라고 하는 User space 프로그램을 제공했고, 이를 통해 도달할 수 있는 코드의 숨겨진 버그를 찾는 과제를 냈습니다. Harness는 바이너리 Input을 받고 CRS를 대신하여 시스템콜들을 호출하게 됩니다. TIPC의 예에서는 CRS가 소켓을 생성하고, 소켓을 설정하고, 보안 키를 셋업하는 절차를 하나하나 정확하게 수행할 수 있도록 Harness의 Input을 찾는 것이 목표였습니다.
다양한 방법으로 해당하는 Input을 생성할 수 있었지만, 저희가 주로 선택한 방법은 전통적인 버그 탐지 기술인 Fuzzing, Symbolic Execution, Concolic Execution에서 사람이 수행하는 작업을 LLM으로 Augment하면서 기존 방식을 자동화하고 성능을 개선하는 것이었습니다. 일명 LLM-in-the-loop라고 하는 이 방법으로 1) Seed를 만들고 Fuzzing의 Dictionary를 생성, 2) Input을 수정하는 알고리즘 구현, 3) Git Commit 분석 등에 LLM을 사용했습니다.
CRS로 버그를 탐지한 후에는 자동으로 해당 버그를 수정할 수 있는 패치를 생성해야 했습니다. CVE-2021-43267의 경우 버그를 수정하기 위해 두 가지 검사를 추가했습니다. 크기가 최소 키 크기보다 큰지 확인하고, `keylen`이 크기와 일치하는지 확인하여 할당된 메모리에 대한 접근을 방지했습니다.
Team Atlanta의 CRS에서는 패치를 생성하는 과정을 LLM으로 구성된 멀티 에이전트(Multi Agent) 방식으로 해결했습니다. 각 에이전트는 다양한 프롬프트와 사용이 허락된 자동 툴을 통해 다양한 패치를 생성하고 이를 직접 실행하면서 검증하게 되며, 이러한 과정을 거쳐 최종 패치를 선택하게 됩니다. AIxCC 대회에서는 버그를 유발하는 Input, 이를 차단하는 패치, 그리고 버그가 발생한 Commit ID를 함께 제출해야 합니다. 이후 내부 테스트를 거쳐 Input 및 패치가 검증되고 점수가 매겨집니다.
대회가 진행되는 동안 저희 CRS는 SQLite3에서 0-day 버그를 찾았습니다. 많은 분들께서 AIxCC가 프로덕션 환경에서 어떻게 돌아갈지 의문을 제기했는데 짧은 대회 중에도 CRS로 알려지지 않은 버그를 발견하고 수정하여 CRS의 큰 가능성을 보여주었던 것 같습니다. 특히 여러 참가팀 중 유일하게 운영진이 설정한 취약점이 아닌 실제 0-day 취약점을 찾아내어 대회 관계자들로부터 호평을 받았습니다.
마치며
준결선에서 사용된 CRS는 C/C++ 및 Java 언어를 지원하도록 설계되었습니다. 남은 일 년 동안 결선을 준비하면서 10개 이상의 언어와 언어 조합을 지원하도록 시스템을 확장하며, 좀 더 특화된 ML 기술과 LLM에 보다 중점을 둔 기술을 기반으로 CRS를 업데이트할 계획입니다.
단기적으로는 DARPA AIxCC 결선을 잘 준비해 세계적인 무대에서 다른 유수의 팀들과 당당히 겨루어 좋은 성적을 낼 수 있도록 최선을 다하겠습니다. 관심을 가지고 지켜봐 주세요!
|
|
