당신의 AI가 해킹대회(CTF) 문제를 못 푸는 이유: 웹해킹 편
당신의 AI가 해킹대회(CTF) 문제를 못 푸는 이유: 웹해킹 편
AI Agent에게 별다른 지침 없이 CTF 웹 문제를 맡겨도 꽤 잘 풀 때가 있습니다. 페이지를 둘러보며 어떤 기술을 썼는지 살펴보고, ffuf나 sqlmap 같은 도구도 돌려봅니다. SQL Injection이나 SSRF, LFI 같은 취약점을 찾아보다가 요청 몇 번 만에 flag를 가져오기도 합니다.
그런데 한참을 돌려도 풀지 못하는 문제도 있습니다. 같은 로그인 form만 계속 테스트하거나, 앞서 사용하던 웹 세션을 잃어버립니다. 파일을 읽는 데 성공하고도 정작 flag는 가져오지 못하기도 합니다. 대화 기록만 길어질 뿐, 문제는 풀지 못합니다.
지난 글에서는 Agent가 리버싱 문제를 풀 때 어디에서 막히는지 살펴봤습니다. 이번에는 웹 문제를 다뤄보겠습니다. 2025년부터 2026년 사이에 공개된 논문과 발표 자료, 오픈소스 구현을 참고해 Agent가 잘 푸는 웹 문제의 특징과, 풀지 못하는 문제에서는 무엇이 문제가 되는지 정리했습니다.
참고: 모델이 빠르게 발전하고 있어, 자료에 나온 성능이나 실패 사례가 현재(2026년 9월 기준)의 프론티어 모델에도 그대로 적용되지는 않을 수 있습니다. 이 글에서는 각 자료의 주요 내용과 저희가 최근 최근 Agent를 사용하여 저희가 최근 Agent로 웹 문제를 풀면서 겪었던 어려움을 중심으로 다룹니다.
목차
- Agent가 웹 문제를 푸는 방식
- Agent가 잘 푸는 문제
- attack surface 탐색의 한계
- session과 상태 추적의 어려움
- 취약점 발견과 flag 획득 사이
- 틀린 가설, 반복되는 시도
- 모델 밖의 문제: 도구의 관찰과 기록
- 성공 판정의 함정
- 마무리
- 참고한 글과 자료
Agent가 웹 문제를 푸는 방식
Agent는 먼저 공격 대상을 살펴보고 취약점이 있을 만한 지점을 찾습니다. 포트와 서비스를 확인하고, 엔드포인트와 파라미터를 모으며, 페이지 소스와 JavaScript bundle도 읽습니다. 필요하면 directory fuzzing이나 스캐너를 활용해 조사 범위를 넓힙니다. 이렇게 모은 정보를 바탕으로 의심스러운 입력에 요청을 보내고, status code, response body, redirect, 응답 시간의 차이를 비교하면서 실제 취약점이 있는지 확인합니다.
취약점을 찾았다고 작업이 끝나는 것은 아닙니다. CTF에서는 flag를 확보해 제출해야 하고, 별도의 공격 목표가 있는 벤치마크에서는 그 목표를 달성했는지 검증받아야 합니다. 따라서 Agent는 취약점 발견 이후에도 필요한 작업을 이어가고, 최종 판정까지 확인해야 합니다.
CVE-Bench의 SQL Injection 성공 사례에서는 이 작업을 여러 Agent가 나누어 수행했습니다. 먼저 한 Agent가 엔드포인트를 확인하고 sqlmap으로 boolean-blind injection을 찾아 데이터를 추출합니다. 이어 별도 Agent가 추출한 값을 evaluator에 제출해 최종 검증을 받습니다 [7]. 앞 단계에서 얻은 결과가 다음 Agent에게 전달되면서, 취약점 탐색부터 검증까지 이어진 것입니다.
CVE-Bench는 심각도가 Critical인 web application CVE 40개를 다루는 벤치마크입니다. 취약한 application을 컨테이너에서 실행하고, 파일 접근/database 접근/관리자 로그인 같은 목표를 달성했는지 타겟 쪽 evaluator가 확인합니다. 논문은 한 번 시도했을 때의 성공률과, 각 문제를 5번씩 시도해 한 번 이상 성공한 문제의 비율을 함께 보고합니다 [7].
이처럼 여러 단계에 걸친 작업을 이어가려면, 앞서 보낸 요청뿐 아니라 현재 작업 상태도 남겨야 합니다. 어떤 session을 사용했고 어디까지 확인했으며 무엇이 아직 남아 있는지 알아야 다음 행동을 결정할 수 있습니다. 브라우저를 사용하는 문제라면 cookie와 storage, DOM의 상태 변화도 여기에 포함됩니다. 이런 정보가 대화 기록에만 흩어져 있으면, 기록이 길어지거나 요약되는 과정에서 빠져 이후 작업에 필요한 맥락을 잃을 수 있습니다.
Agent가 잘 푸는 문제
Agent가 상대적으로 잘 푸는 문제는 조사 범위가 좁고, 시도한 결과가 분명하게 드러나는 문제입니다. 테스트할 파라미터가 보이고 입력을 바꿨을 때 응답이 어떻게 달라지는지 바로 확인할 수 있다면, 어디서부터 시작하고 다음에 무엇을 확인할지 판단하기 쉽습니다. 복잡한 session 상태까지 유지할 필요가 없다면 작업을 이어가는 부담도 줄어듭니다.
관찰한 결과에서 취약점의 원인까지 쉽게 연결할 수 있다면 더 유리합니다. 에러 메시지에 입력을 처리하는 함수가 드러나거나, 소스 코드에서 입력이 취약한 함수로 전달되는 경로가 짧고 명확한 경우입니다. 여기에 모델이 익숙하게 다루는 취약점 유형이라면 다음에 확인할 내용을 정하기도 수월합니다.
반대로 입력의 처리 흐름이 복잡하면 겉으로 보이는 값만으로는 판단하기 어렵습니다. Stress-Testing SAST and LLMs on Modern Web Backends 발표에는 middleware가 query의 값을 검사하지만 handler는 같은 이름의 값을 JSON body에서 읽는 사례가 나옵니다. 입력을 검증하는 코드가 있어도 실제로 사용한 값은 다를 수 있으므로, 어느 단계에서 어떤 값을 다루는지 추가로 추적해야 합니다 [10].
Stress-Testing SAST and LLMs on Modern Web Backends는 현대적인 웹 backend의 복잡한 데이터 처리에서 생기는 취약점을 기존 SAST와 LLM이 얼마나 찾아낼 수 있는지 살펴본 Black Hat Europe 2025 발표입니다. 실제 개발 관행을 본뜬 취약한 application 사례 모음인 Unsafe Code Lab을 사용했습니다 [10].
Agent에게 유리한 문제는 조사할 대상과 입력의 처리 흐름이 분명하고, 유지해야 할 상태의 부담이 적은 문제입니다. 필요한 동작을 도구로 수행할 수 있다는 전제에서, 응답의 차이를 해석하기 쉽고 다음 단계까지 이어가야 할 맥락이 적을수록 풀이를 진행하기 수월합니다.
attack surface 탐색의 한계
이제부터는 Agent가 웹 문제를 풀 때 어떤 한계에 부딪히고, 어떤 상황에서 풀이가 막히는지 살펴보겠습니다.
웹 Agent는 공격 방법을 고르기 전에, 어디를 테스트할지부터 놓치기도 합니다.
CVE-Bench에서 가장 자주 나온 실패 유형은 Insufficient Exploration이었습니다. Agent 실행을 분석한 표에서 탐색 부족의 빈도는 설정에 따라 37.5~80.0%였습니다. 첫 화면의 로그인 form에 집중하다가 다른 엔드포인트를 놓쳤습니다. 반대로 타겟 포트가 적혀 있는데도 다른 포트를 전부 훑거나, 타겟 대신 외부 사이트와 evaluator를 분석하는 경우도 있었습니다 [7].
CyberEvolver의 cookie_injection 사례를 보면 이 문제가 좀 더 분명합니다. Agent는 홈페이지와 소스를 읽고, URL 파라미터와 form, directory까지 테스트했습니다. 그런데 실제 injection point는 cookie에 있었습니다. 여러 곳을 확인하면서 정작 필요한 입력 지점은 건너뛴 것입니다. 응답에 Welcome back이 있는지를 boolean oracle로 활용하지 못한 점도 실패 원인이었습니다 [6].
CyberEvolver는 Agent의 실패 기록을 분석하고, 다음 실행에 사용할 지침과 도구 구성 등의 scaffold를 수정하는 보안 Agent 연구입니다. 같은 Agent를 단순히 반복 실행하는 방식과 실패 원인을 반영해 구성을 개선하는 방식을 여러 보안 벤치마크에서 비교하며, cookie_injection처럼 Agent가 취약한 입력 위치나 응답의 단서를 놓친 사례도 분석합니다 [6].
요청을 몇 번 보냈는지만으로는 이런 누락을 알기 어렵습니다. 무엇을 테스트했는지 나눠서 적으면 차이가 보입니다.
POST /login × username × SQLi → 실패
POST /login × password × SQLi → 미시험
GET /profile × id × IDOR → 재현 필요
GET /dashboard × session cookie → 미시험
이런 기록을 같은 대화 세션 안에서만 관리하면 compaction 등에 의해 같은 요청을 반복하면서도 미시험 항목을 놓칠 수 있습니다. PentesterFlow는 이를 줄이기 위해 endpoint × parameter × 취약점 유형별 상태를 저장하고, 아직 기록되지 않은 조합을 미시험 목록으로 반환하는 방식을 사용합니다 [1]. 다만 이 상태는 Agent가 직접 기록하므로, 잘못 분류된 항목까지 찾아주는 것은 아닙니다. 이 기능은 탐색 범위를 관리하는 데 도움을 주지만, 실제 테스트가 제대로 수행됐는지까지 보장하지는 못하기에 완벽한 대응책은 아닙니다.
PentesterFlow는 웹 모의해킹용 오픈소스 Agent입니다. HTTP 요청, browser traffic capture, coverage, skill, 발견 사항 저장 기능을 제공합니다. 코드 주석에서도 같은 지점을 반복해서 테스트하면서 다른 조합을 빠뜨리는 문제를 주요 한계로 지적합니다 [1].
탐색의 한계 문제를 해결하기 위해서 Agent는 요청을 보낼 때마다 새로 발견한 엔드포인트와 입력 위치를 목록에 반영하고, 실패로 기록한 항목도 실제로 충분히 확인했는지 다시 살펴보도록 해야 합니다. 그래야 눈에 잘 띄는 입력만 반복해서 테스트하거나, 아직 확인하지 않은 공격 지점을 이미 살펴본 것으로 오인하는 일을 줄일 수 있습니다.
session과 상태 추적의 어려움
웹에서는 같은 URL에 같은 값을 보내도 항상 같은 결과가 나오지는 않습니다. 로그인 여부나 앞서 보낸 요청에 따라 server와 browser의 상태가 달라지기 때문입니다. cookie, CSRF token, redirect, DOM, browser storage가 모두 다음 요청의 결과에 영향을 줄 수 있습니다. WebSocket처럼 별도의 통신 방식을 사용한다면 연결 과정과 message 순서까지 이어서 처리해야 합니다. Agent는 요청 하나만 만드는 것이 아니라, 이전 요청에서 만들어진 상태를 다음 요청까지 가져가야 합니다.
From Assistance to Autonomy의 평가 대상 가운데 웹 문제 두 개는 network protocol 분석과 여러 단계의 환경 상호작용이 필요했습니다. 같은 Claude Sonnet 4.5를 사용했을 때, terminal과 대화형 도구를 유연하게 사용할 수 있었던 비공개 범용 Agent는 두 문제를 모두 풀었고 Claude Code는 한 개를 풀었습니다. 반면 CTF 풀이용 NYU Agent와 Cybench Agent는 한 문제도 풀지 못했습니다. 저자들은 session 유지, 여러 단계의 작업 처리, 달라지는 응답에 대한 대응을 도구가 충분히 지원하지 못한 점을 주요 원인으로 봤습니다. 다만 두 문제만의 비교이고 실행 환경도 달랐으므로 특정 도구의 효과를 분리할 수는 없습니다 [5].
From Assistance to Autonomy: An Empirical Study of AI Use in a Live Capture-the-Flag (CTF) Competition은 USENIX Security 2026에 발표된 연구 논문입니다. 현장 CTF에서 참가자 41명의 AI 활용을 관찰하고, 같은 17개 문제에서 네 가지 자율 Agent framework와 세 가지 모델을 조합한 12개 구성의 성과를 인간 팀과 비교했습니다. NYU Agent와 Cybench Agent는 평가에 사용된 CTF 풀이용 framework입니다 [5].
CyberEvolver가 분석한 securinotes는 숨겨진 관리자 note에서 flag를 가져오는 웹 CTF 문제입니다. 취약점은 notes.count method에 전달되는 조건을 이용한 NoSQL Injection이었지만, 일반적인 HTTP 요청으로는 해당 method를 호출할 수 없었습니다. 처음 받은 페이지에는 Meteor의 기본 화면과 JavaScript bundle만 있었고, 실제 데이터는 WebSocket 위에서 동작하는 DDP(Distributed Data Protocol)를 통해 오갔기 때문입니다. 초기 Agent는 이 구조를 파악하지 못한 채 form, URL parameter, cookie, JSON POST를 계속 시험했습니다. 이후 실행에서는 DDP 연결을 유지하는 script를 사용해 해당 method와 상호작용했고, 관리자 note를 추출했습니다 [6].
Meteor는 JavaScript로 웹 애플리케이션의 client와 server를 함께 개발할 수 있는 framework입니다. client와 server 사이의 데이터를 실시간으로 동기화하며, 이를 위해 주로 WebSocket 기반의 DDP를 사용합니다.
이 사례에서 풀이를 가른 것은 요청에 넣을 값을 고르는 능력만이 아니었습니다. 애플리케이션이 사용하는 통신 방식으로 연결을 이어가고, 앞선 상호작용에서 만들어진 상태를 유지할 수 있어야 했습니다. 따라서 session과 상태 추적의 문제를 줄이려면 Agent의 요청 생성뿐 아니라, 도구가 필요한 상호작용을 지원하고 그 상태 변화를 다음 요청까지 반영할 수 있는지도 함께 살펴봐야 합니다.
취약점 발견과 flag 획득 사이
웹 CTF에서 취약점을 재현한 것과 문제를 푼 것은 같은 의미가 아닙니다. 파일을 읽거나 명령을 실행할 수 있게 되더라도, 목표 데이터를 찾아 flag를 제출해야 풀이가 끝납니다. 이 사이에서 Agent는 확보한 기능을 남은 목표에 어떻게 사용할지 판단해야 합니다.
CyberEvolver가 분석한 apb-vm2는 LFI 취약점으로 /root/flag.txt를 읽는 문제였습니다. Agent는 절대 경로를 이용한 파일 읽기에 성공했지만, 이를 목표 파일에 적용하지 않고 다른 접근 방식과 경로 제한 우회 기법을 다시 시험했습니다. 풀이에 필요한 기능을 확보하고도 목표 데이터 확보로 이어가지 못한 것입니다 [6].
CTFExplorer에서는 여러 서비스를 거치는 문제에서 이러한 실패가 나타났습니다. The Silent Corridor와 The Glass Atrium은 공개 서비스에서 얻은 접근 권한을 이용해 내부 서비스를 찾고, 숨겨진 데이터에 접근해야 하는 문제였습니다. 두 문제에는 합계 다섯 개의 flag가 있었지만, 평가한 여섯 모델은 각각 한 개 또는 두 개만 회수했습니다. 첫 서비스의 취약점을 공격한 뒤에도 내부 서비스로 탐색과 공격을 이어가는 작업이 남아 있었습니다 [4].
CTFExplorer는 취약한 웹 service 40개를 하나의 network에 배치한 benchmark와 이를 탐색하는 Agent 구조, 실행 과정을 평가하는 CTFExplorerEval을 함께 제안한 연구입니다. The Silent Corridor와 The Glass Atrium은 이 benchmark에서 여러 단계의 공격을 살펴보기 위해 분석한 사례입니다 [4].
두 연구는 앞서 얻은 결과를 다음 작업에 반영하도록 서로 다른 방식을 사용했습니다. CyberEvolver는 실패 기록을 바탕으로 작업 지침을 수정해, 확인한 기능을 남은 목표에 적용하고 목표 데이터를 얻으면 불필요한 변환으로 제출을 미루지 않도록 했습니다 [6]. CTFExplorer는 각 Agent의 발견 사항과 실패 기록을 공유하고, 관리 역할의 Supervisor Agent가 다음 작업을 조정하도록 했습니다. 실패가 반복되면 검토 역할의 Critic에이전트가 기록을 살펴보고 접근 방향을 바꾸도록 개입했습니다 [4].
CyberEvolver의 후속 실행에서는 목표 파일을 읽고 flag를 제출했습니다. 확보한 문자열을 해석하려는 시도도 있었지만, 의미 있는 결과가 나오지 않자 추가 변환을 멈추고 원래 문자열을 제출해 정답으로 인정받았습니다. 이전 실행은 파일 읽기에 성공하고도 30단계 동안 flag를 얻지 못했지만, 지침을 수정한 후속 실행은 17단계 만에 확보와 제출을 완료했습니다 [6].
CTFExplorer도 논문 부록 D의 별도 웹 문제에서 협업을 통해 flag를 획득했습니다. 각 Agent가 짧은 실행 예산 안에 독립적으로 끝내지 못한 풀이를 기록 전달과 Supervisor Agent와 Critic Agent의 개입으로 이어간 결과였습니다. 다만 앞선 두 다단계 문제에서는 이 구조를 사용하고도 다섯 개 중 한두 개만 회수했습니다. 일부 풀이를 완료하는 데는 도움이 되었지만, 복잡한 문제의 남은 작업까지 모두 해결하지는 못했습니다 [4].
취약점 발견을 flag 획득으로 이어가려면, 확보한 기능과 남은 목표를 기준으로 다음 작업을 선택해야 합니다. 작업 지침을 수정하거나 Agent 사이에 기록을 전달하는 것도 이 판단이 이어지도록 하기 위한 방법입니다. 실행이나 담당 Agent가 바뀌더라도 이미 얻은 성과를 활용해 목표 데이터를 확보하고, 제출까지 마쳐야 풀이가 완료됩니다.
틀린 가설, 반복되는 시도
Agent가 계속 명령을 실행한다고 해서 풀이가 진전되는 것은 아닙니다. 처음 세운 가설이 틀렸다면 입력 문자열을 바꾸거나 실행 시간을 늘려도 같은 실패가 반복될 수 있습니다. 다른 Agent가 작업을 이어받더라도 앞선 판단을 그대로 받아들이면 출발점은 달라지지 않습니다.
CTFExplorer의 설정 비교 실험에서는 실행 예산과 Agent 수 제한을 달리해도 해결률이 꾸준히 높아지지 않았습니다. 진전 없이 끝난 실행은 성공한 실행보다 더 많은 Agent를 사용했습니다. 연구진은 짧게 활동하는 Agent들이 비슷한 탐색을 반복하고, 문맥이 자주 초기화되면서 앞선 추론을 발전시키기 어려웠다고 해석했습니다. 두 모델과 세 가지 설정에 한정된 결과이지만, Agent를 추가하는 것만으로는 막힌 풀이가 진전되지 않는 모습을 보여줍니다 [4].
XBOW는 오래 이어진 실행에 오해와 잘못된 가정이 쌓이는 문제에 주목했습니다. 기술 블로그에서는 문제를 푸는 Agent인 solver가 행동하고 결과를 확인하는 과정을 최대 80회로 제한했다고 설명합니다. 그 이후에도 성공하는 경우는 있었지만, 누적된 오해를 안고 실행을 연장하기보다 새 solver로 시작하는 편이 효율적이었다는 자체 관찰입니다 [8].
두 사례는 각각 맥락이 사라지는 문제와 잘못된 가정이 누적되는 문제를 보여줍니다. 확인한 사실을 다음 작업에 전달하는 것과, 그 사실에 대한 앞선 해석을 그대로 받아들이는 것은 구분해야 합니다. 기록을 유지하더라도 기존 판단이 틀릴 수 있고, 새 실행을 시작하더라도 앞선 실패를 반영하지 않으면 같은 시도가 반복될 수 있습니다.
CyberEvolver는 실패한 실행을 분석해 다음 시도의 구성을 바꾸는 방식을 사용했습니다. 실행 기록에서 확인된 사실과 실패 원인을 정리하고, 이를 바탕으로 작업 지침/도구 사용 규칙/관찰 결과 처리 방식 등 Agent의 실행 구성인 scaffold를 수정했습니다. 앞선 시도가 왜 막혔는지를 다음 실행에 반영하도록 한 것입니다. 연구에서는 이 방식과 초기 Agent의 구성을 유지한 채 반복 실행하는 방식을 비교했습니다 [6].
비교 결과, 같은 구성을 더 실행했을 때보다 실패에 맞춰 구성을 수정했을 때 개선 폭이 컸습니다. 네 모델과 네 평가 조건에서, 초기 Agent의 실행 결과로 추정한 4회와 16회 누적 해결률의 차이는 평균 1.4%였습니다. 반면 CyberEvolver의 해결률은 초기 Agent의 16회 누적 해결률보다 평균 13.6% 높았습니다. 웹 문제만을 평가한 결과는 아니지만, 이 실험에서는 실패 분석을 반영한 구성 변경이 반복 실행으로 풀지 못했던 문제를 추가로 해결했습니다 [6].
틀린 가설에서 벗어나는 데 중요한 것은 실행을 이어갈지 새로 시작할지만이 아닙니다. 앞선 기록에서 확인된 사실은 이어받되, 실패를 반복하게 만든 해석과 작업 방식은 수정할 수 있어야 합니다. 재시도가 의미를 가지려면 앞선 실패가 다음 판단에 무엇을 바꾸었는지가 드러나야 합니다.
모델 밖의 문제: 도구의 관찰과 기록
필요한 상호작용을 수행할 수 있어도, 그 결과가 모델에 충분히 전달된다는 보장은 없습니다. 도구가 응답의 일부만 보여주거나 대화 요약에서 판단 근거가 빠지면, Agent는 실제로 일어난 일을 불완전하게 파악할 수 있습니다. 앞서 다룬 상태 유지와 함께, 도구가 무엇을 관찰하고 어떤 기록을 남기는지도 살펴봐야 합니다.
이 글에서 검토한 pentestkit의 HTTP 도구는 href, src, action에서 링크를 수집하고, 응답 본문 앞부분 최대 4,000자를 모델에 전달합니다. 파일에는 최대 24,000자를 저장하므로 모델에게 전달되지 않은 내용 일부를 다시 확인할 수 있지만, 그 파일도 전체 응답을 보장하지는 않습니다. 또한 이 HTTP 도구만으로는 브라우저에서 JavaScript가 실행된 뒤의 화면 변화를 직접 관찰할 수 없습니다 [2].
기록을 남기더라도 결과를 성공과 실패로만 압축하면 status code, body 길이, redirect, 오류 유형에 나타난 차이가 사라질 수 있습니다. parser 오류와 도구 자체의 오류를 구분하지 못하면 server의 반응도 잘못 해석하게 됩니다. 도구가 관찰한 내용과 모델이 전달받은 내용 사이의 차이가 이후 판단에 영향을 주는 것입니다.
Strix는 작업 환경과 기록을 유지하기 위한 방식을 마련했습니다. 여러 Agent가 기본 브라우저를 공유하면 서로의 화면 상태를 바꿀 수 있으므로, Agent마다 별도 브라우저 세션을 사용하도록 지침을 둡니다. 큰 도구 출력을 파일에 저장하고 대화에는 일부와 저장 경로를 전달하는 기능도 제공합니다. 문맥이 길어지면 오래된 기록은 요약하되 최근 기록은 원문으로 유지합니다 [3].
Strix는 여러 전문 Agent가 역할을 나누어 보안 테스트를 수행하는 오픈소스 도구입니다. browser/shell/proxy를 통한 환경 상호작용과 발견 사항 및 테스트 진행 상태의 기록을 지원합니다 [3].
이렇게 하면 대화에 담는 정보량을 줄이면서도 저장된 출력을 다시 확인할 경로를 남길 수 있습니다. 다만 요약 자체가 원본을 대신하지는 않습니다. PentesterFlow는 요약을 앞선 작업을 찾아보기 위한 불완전한 색인으로 취급하도록 명시합니다. 정확한 주소나 응답 내용, 이전에 확인한 결과가 필요하면 요약만으로 단정하지 말고 현재 세션의 새 도구 호출로 재확인하도록 합니다 [1].
도구의 관찰과 기록이 충분한지는 다음 판단에 필요한 근거를 확인할 수 있는지로 살펴봐야 합니다. 출력 보관과 요약은 긴 작업을 이어가는 데 도움을 주지만, 처음부터 관찰하지 않았거나 저장 과정에서 빠진 내용을 복원해주지는 않습니다. Agent가 무엇을 직접 확인했고 무엇을 요약이나 일부 출력에 의존해 판단했는지 구분할 수 있어야, 도구의 제약에서 비롯된 오해를 줄일 수 있습니다.
성공 판정의 함정
목표에 도달하기 위한 작업을 수행하는 것과, 실제로 도달했는지 판정하는 것은 별개의 문제입니다. Agent가 명령을 실행하고 결과를 출력했더라도, 그 결과가 어디에서 나왔고 무엇을 입증하는지 확인해야 합니다.
Black Hat USA 2025의 AI Agents for Offsec with Zero False Positives 발표에는 Agent가 command injection을 검증하다 따옴표 처리를 잘못해 자기 환경의 /etc/passwd를 읽은 사례가 나옵니다. 대상 서버의 파일을 가져온 것이 아닌데도 성공으로 받아들인 것입니다 [9]. 반대 방향의 오판도 있었습니다. CTFExplorer에서는 flag가 이미 수락됐는데, 검토 역할의 Critic Agent가 이를 환각이라고 판단했습니다 [4]. 성공을 선언하는 Agent와 이를 검토하는 Agent 모두 실제 결과와 다른 판단을 내릴 수 있었습니다.
AI Agents for Offsec with Zero False Positives는 Agent의 취약점 발견 주장을 비-AI 검증 코드로 확인해 오탐을 줄이는 방법을 다룬 발표입니다. 취약점 유형별 증거 검사 방식과 검증기를 잘못 설계했을 때 생기는 문제를 함께 다룹니다 [9].
정해진 flag가 있는 평가에서는 출력된 문자열을 정답과 대조할 수 있습니다. XBOW 공개 벤치마크를 사용하는 pentestkit은 미리 정한 flag를 문제 환경에 넣고, 실행이 끝난 뒤 Agent의 실행 출력이나 결과 파일에 그 문자열이 그대로 포함되어 있는지 확인합니다 [2]. CVE-Bench는 타겟 쪽 평가 서버가 파일 또는 데이터베이스 접근 등 미리 정의한 목표를 검사하고, /done 응답의 status에 성공 여부를 반환합니다 [7]. 두 방식 모두 Agent의 성공 선언과 별도로 정해진 조건의 충족 여부를 확인합니다.
XBOW 벤치마크는 XBOW가 2024년에 공개한 웹 보안 평가용 CTF 문제 104개입니다. 각 문제는 Docker 기반으로 실행하며 숨겨진 flag를 찾는 것이 목표입니다. 하나의 목표를 달성하는 데 여러 취약점이나 풀이 단계가 포함될 수 있습니다. 다만 공식 저장소는 2026년 중반 기준으로 이 문제들이 포화되어 모델이나 Agent framework의 성능 차이를 구분하기 어렵다고 안내하고 있습니다 [11].
정해진 flag가 없는 평가 환경에서도 검증용 데이터를 마련할 수 있습니다. 앞선 Black Hat 발표는 원래 접근할 수 없어야 하는 서버 파일이나 데이터베이스에 추측하기 어려운 문자열인 canary를 두고, Agent가 제출한 값과 일치하는지 비-AI 코드로 검사하는 방식을 제안했습니다. 파일처럼 보이는 출력을 제시하는 것과 목표 데이터에 실제로 접근하는 것을 구분하기 위한 방법입니다 [9].
직접적인 응답에 결과가 드러나지 않는 동작은 OAST(Out-of-Band Application Security Testing)로 확인할 수도 있습니다. OAST는 별도 서버에 도착한 통신 기록으로 애플리케이션의 동작을 확인하는 보안 테스트 방식이며, 이때 관측하는 통신을 callback이라고 부릅니다 [12]. 다만 통신이 관측됐다는 사실이 무엇을 입증하는지는 해당 문제의 목표와 함께 판단해야 합니다.
검증 코드가 있다고 오판이 모두 사라지는 것은 아닙니다. 같은 Black Hat 발표에서는 URL 형식이나 브라우저의 실행 환경을 충분히 제한하지 않아 의도하지 않은 동작이 검증을 통과한 사례를 소개했습니다. 단순한 console 출력도 XSS의 증거로 허용했다가 잘못된 결과를 받아들였습니다. 특정 신호가 발생했는지만 검사하면, 대상의 취약점 때문에 발생한 신호인지 놓칠 수 있다는 뜻입니다 [9].
성공 판정은 실제 대상에서 나온 증거가 정해진 목표를 충족했는지를 기준으로 해야 합니다. 실제 웹 서비스에서는 그 동작이 원래 허용된 것인지도 확인해야 합니다. 특히 다른 사용자의 데이터에 대한 접근 권한이나 업무 규칙을 다루는 문제는 값의 획득만으로 취약점을 단정하기 어렵습니다 [9]. Agent의 설명과 별도로 결과의 출처, 목표 달성 여부, 허용된 동작의 범위를 확인할 수 있어야 성공처럼 보이는 출력과 실제 성공을 구분할 수 있습니다.
마무리
이제 글을 마무리하겠습니다. Agent가 웹 문제를 풀 때는 문제의 구조뿐 아니라, 도구로 어떤 작업을 할 수 있고 앞선 결과를 얼마나 활용할 수 있는지도 영향을 미쳤습니다. 앞서 살펴본 풀이에 유리한 조건과 풀이가 막히는 상황을 함께 정리하면 다음과 같습니다.
| 항목 |
풀이에 유리한 조건 |
풀이가 막히는 상황 |
| 탐색 범위 |
경로와 입력 지점이 드러나 있어 조사할 대상을 정하기 쉽습니다 |
중요한 입력 지점을 놓친 채 익숙한 경로만 반복해서 조사합니다 |
| 상태와 단계 |
유지해야 할 상태가 단순하고 목표까지의 단계가 적습니다 |
여러 연결 상태와 중간 결과를 유지하지 못하거나, 확보한 기능을 다음 단계에 활용하지 못합니다 |
| 도구와 관찰 |
필요한 동작을 수행하고 응답의 차이를 확인할 수 있습니다 |
도구가 필요한 동작을 지원하지 않거나, 일부 출력만 보고 판단합니다 |
| 기록과 작업 선택 |
실제 요청과 응답을 다시 확인하고, 이미 확인한 항목과 남은 작업을 구분할 수 있습니다 |
기록이 사라지거나 요약에서 근거가 빠져 같은 작업을 반복합니다 |
| 실패와 판단 수정 |
앞선 실패를 바탕으로 가설과 작업 방식을 바꿀 수 있습니다 |
실행을 늘리거나 담당 Agent가 바뀌어도 잘못된 가정을 그대로 이어받습니다 |
풀이가 잘 진행되는 것과 실제로 문제를 풀었는지는 구분해야 합니다. 분명한 성공 기준과 외부 검증은 목표 달성 여부를 확인하는 데 필요합니다. 다만 검증기를 갖추더라도 검사 조건이 잘못되면 결과를 오판할 수 있으므로, 성공 판정에서는 다음 내용을 따로 살펴봐야 합니다.
| 성공 판정에서 확인할 것 |
확인이 필요한 이유 |
| 증거의 출처 |
출력된 값이나 관측된 신호가 실제 대상에서 나온 것인지 확인해야 합니다 |
| 목표와 검증 기준 |
취약점 후보 발견, 재현, 목표 달성, 최종 수락을 구분하고, 목표에 맞는 증거를 Agent의 설명과 별도로 검사해야 합니다 |
| 허용된 동작의 범위 |
실제 웹 서비스에서는 데이터를 얻었다는 사실만으로 취약점을 단정할 수 없습니다. 원래 허용된 접근이나 동작인지도 확인해야 합니다 |
기록 보관, 작업 조정, 실행 구성 수정, 외부 검증은 이런 어려움을 줄이려는 시도였습니다. 다만 기능을 갖췄는지만으로는 충분하지 않았습니다. 남긴 기록이 다음 판단에 쓰이고, 실패가 작업 방식의 수정으로 이어지며, 증거가 목표에 맞게 검증되는지까지 확인해야 합니다.
이 글에서 살펴본 실패에는 이런 공통점이 있었습니다. 취약점을 알아보더라도 필요한 입력 지점을 놓쳤고, 사용할 수 있는 기능을 확보하고도 목표 데이터까지 도달하지 못했으며, 결과를 얻고도 성공 여부를 잘못 판단했습니다.
각 단계의 결과를 다음 행동과 최종 검증으로 이어가지 못하는 것, 이것이 당신의 AI Agent가 웹 CTF 문제를 못 푸는 이유입니다.
참고한 글과 자료
[1] PentesterFlow/agent: https://github.com/PentesterFlow/agent
[2] lordx64/pentestkit: https://github.com/lordx64/pentestkit
[3] usestrix/strix: https://github.com/usestrix/strix
[4] Nanda Rani et al., “CTFExplorer: Evaluating LLM Offensive Agents Through Multi-Target Web CTF Benchmarking”: https://arxiv.org/abs/2602.08023v3
[5] Tingxuan Tang et al., “From Assistance to Autonomy: An Empirical Study of AI Use in a Live Capture-the-Flag (CTF) Competition”: https://www.usenix.org/system/files/usenixsecurity26-tang-tingxuan.pdf
[6] Yihe Fan et al., “CyberEvolver: Structured Self-Evolution for Cybersecurity Agents on the Fly”: https://arxiv.org/abs/2605.26195v2
[7] Yuxuan Zhu et al., “CVE-Bench: A Benchmark for AI Agents' Ability to Exploit Real-World Web Application Vulnerabilities”: https://arxiv.org/abs/2503.17332
[8] Albert Ziegler, XBOW, “Agents Built From Alloys”: https://xbow.com/blog/alloy-agents
[9] Brendan Dolan-Gavitt, Black Hat USA 2025, “AI Agents for Offsec with Zero False Positives”: https://i.blackhat.com/BH-USA-25/Presentations/US-25-Dolan-Gavitt-AI-Agents-for-Offsec-with-Zero-False-Positives-Thursday.pdf
[10] Andrew Konstantinov and Irina Iarlykanova, Black Hat Europe 2025, “Stress-Testing SAST and LLMs on Modern Web Backends”: https://i.blackhat.com/BH-EU-25/eu-25-Konstantinov-UnsafeCodeDetectionBenchmark.pdf
[11] XBOW, “XBOW Validation Benchmarks”: 공식 저장소와 문제 구성/flag 주입 방식. 2026-09-06 확인. README의 벤치마크 포화 및 변별력 관련 고지 포함.
[12] PortSwigger, “Out-of-band application security testing (OAST)”: OAST 개념 설명, Burp Collaborator의 통신 관측 방식.