본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 06. 11:47

나의 AI 에이전트가 스스로의 시스템에서 버그를 발견했다

요약

침투 테스트 자동화를 위한 AI 에이전트 AEGIS 구축 경험을 다룹니다. 모델 업그레이드(Sonnet에서 Opus로)를 통해 에이전트의 자율성이 향상되었으며, 사고 흔적(thinking traces)을 기록하는 지속성 계층의 중요성을 강조합니다.

핵심 포인트

  • 침투 테스트 자동화를 위한 AEGIS 에이전트 개발
  • 모델 성능 향상에 따른 엄격한 규칙(scaffolding)의 필요성 감소
  • 사고 흔적(thinking traces) 저장을 위한 지속성 계층 구축의 중요성
  • 에이전트의 자율적 버그 발견 사례

나는 침투 테스트 (penetration tests)를 수행하는 AI 에이전트를 구축하는 데 두 학기를 보냈다. 해커가 아닌 분들을 위해 설명하자면, 침투 테스트는 기본적으로 다른 누군가가 시스템을 공격하기 전에 취약점을 찾기 위해 시스템에 침입을 시도하는 보안 평가를 의미한다. 내 프로젝트의 목표는 이 과정을 자동화하는 것이다. 이 에이전트는 명령어를 제안하고, SSH를 통해 격리된 가상 머신(virtual machine)에서 이를 실행하며, 인간 테스터가 하는 것과 동일한 방식으로 다단계 공격 워크플로우 (attack workflows)를 체인 형태로 연결한다. 모든 동작은 대상에 영향을 미치기 전에 안전 및 승인 게이트를 통과한다. 핵심은 통제된 자율성 (governed autonomy)이다. 에이전트가 작업을 수행하지만, 시스템이 에이전트가 정직하고 안전하게 행동하도록 유지한다.

이 프로젝트의 이름은 A.E.G.I.S.이며, 프로젝트가 끝날 무렵 에이전트는 Hack The Box 실험실 타겟을 대상으로 심각한 SQL 인젝션 (SQL injection, 사용자 입력을 통해 데이터베이스를 조작하는 방식)을 자율적으로 확인했다. 하지만 에이전트가 했던 가장 유용한 일은 타겟의 취약점을 찾는 것과는 전혀 상관없는 것이었다. 그것은 바로 자기 자신 내부에서 버그를 찾아낸 것이었다.

에이전트 시스템 (agentic systems) 구축에 대해 아무도 말해주지 않는 것

AI 에이전트가 무언가 잘못했을 때, 본능적으로 규칙을 추가하고 싶어진다. 에이전트가 정적 자산 (static assets)을 curl로 가져온다? 정적 자산을 절대 curl 하지 말라는 규칙을 추가한다. 에이전트가 중요한 경로를 건너뛴다? 이를 반드시 확인하도록 강제하는 필수 작업 큐 (action queue)를 추가한다. 에이전트가 우선순위 시스템을 따르지 않는다? 우선순위에 P0부터 P7까지 번호를 매기고 타협 불가능하게 만든다.

그것이 정확히 내가 했던 방식이었다. 그리고 효과가 있었다. 한동안은 말이다.

AEGIS의 초기 버전은 Claude Sonnet 4에서만 작동했다. 그 버전은 그 모든 스캐폴딩 (scaffolding)이 필요했다. 엄격한 규칙과 필수 큐가 없었다면, 에이전트는 이미 수행한 작업을 놓치거나, 동작을 반복하거나, 혹은 그냥 방황했을 것이다. 구조가 에이전트의 일관성을 유지해 주었다.

그러다 나는 적응형 사고 (adaptive thinking) 기능이 있는 Claude Opus 4.6으로 업그레이드했고, 모든 것이 변했다.

세션 01: 마침내 내가 볼 수 있게 되었을 때

Opus와의 첫 세션은 4월 2일에 진행되었습니다. 에이전트는 18개의 명령을 완료하고 ANALYSIS (분석) 단계에 도달했습니다. 외부에서 보기에는 Sonnet 4에 비해 확실히 개선된 모습이었습니다. 더 많은 명령을 수행했고, 진행 과정이 더 매끄러웠으며, 도구 선택 (tool selection) 또한 더 나았습니다.

하지만 Opus는 Sonnet이 결코 보여주지 않았던 것, 즉 thinking traces (사고 흔적)를 저에게 제공했습니다. 매 턴마다 에이전트는 현재 상태를 추론하고, 옵션을 검토하며, 다음에 무엇을 할지 결정하는 내부적인 숙고 (internal deliberation) 과정을 생성합니다.

기본적으로 API는 에이전트의 응답과 함께 이러한 thinking blocks (사고 블록)를 반환하지만, 이를 어디에도 저장하지는 않습니다. 그 부분은 제 책임이었습니다. 저는 제가 'vault (금고)'라고 부르는 곳에 이 모든 것을 JSON artifact (JSON 아티팩트)로 캡처하는 persistence layer (지속성 계층)를 구축했습니다. 이것이 없다면, 추론 과정은 각 API 호출 후에 사라져 버리며 결코 확인할 수 없게 됩니다.

제가 실제로 세션 01의 traces (흔적)를 읽었을 때, 외부에서 보기에는 괜찮아 보였던 출력물들 아래에는 심각한 문제들이 숨겨져 있었습니다.

7턴의 루프 (The seven-turn loop)

가장 최악이었던 것은 9번째 턴과 16번째 턴 사이에서 발생한 7턴 동안의 루프였는데, 에이전트가 /images를 curl 하라는 명령을 계속해서 거부하는 상황이었습니다. 9번째 턴에서 에이전트가 생각하고 있었던 내용은 다음과 같습니다:

"운영자(operator)가 나에게 /images를 curl 하라고 요청하고 있다. 하지만 나의 규칙에는 'CSS, JS, 이미지 파일 또는 기타 정적 자산(static assets)을 절대 curl 하지 마시오'라고 명시되어 있다. /images/는 curl 해서는 안 되는 정적 자산 경로로 명시적으로 나열되어 있다."

4턴 뒤인 13번째 턴에서도 정확히 똑같은 논리였습니다:

"운영자가 나에게 /images를 curl 하라고 명시적으로 말하고 있다. 하지만 나의 규칙에는 '8. CSS, JS, 이미지 파일 또는 기타 정적 자산을 절대 curl 하지 마시오'라고 되어 있다. /images는 내가 절대 curl 해서는 안 되는 정적 자산 경로로 명시적으로 나열되어 있다."

에이전트는 기술적으로 거부하는 것이 맞았습니다. 하지만 여기서 '운영자(operator)'는 사람이 아니었습니다. 그것은 시스템 프롬프트 (system prompt)에 내장된 우선순위가 지정된 다음 작업 목록인 저의 필수 작업 큐 (mandatory action queue)였습니다. 큐는 계속해서 /images를 밀어넣었고, 에이전트는 이를 거부하기 위해 규칙 8번을 계속 인용했으며, 어느 쪽도 이 루프를 깨뜨릴 수 없었습니다. AI 에이전트가 아무것도 성취하지 못한 채 자신의 규칙을 두고 스스로와 논쟁하며 보낸 7턴의 시간이었습니다.

사고 흔적 (thinking traces)이 없었다면, 저는 이런 일이 일어나고 있다는 사실을 전혀 알지 못했을 것입니다. 에이전트의 가시적인 출력물은 정상적으로 보였습니다. 다른 명령어를 제안하고 있었고, 다른 측면에서는 진전을 보이고 있었습니다. 외부에서 보기에는 이 루프가 완전히 보이지 않았습니다.

에이전트가 나의 버그를 발견하다

하지만 사고 흔적은 6번째 턴에서 훨씬 더 흥미로운 것을 보여주었습니다. 에이전트는 제가 미처 알아차리지 못했던 제 시스템 프롬프트 (system prompt) 내의 모순을 포착했습니다.

저는 ffuf (숨겨진 페이지를 브루트 포스 방식으로 찾아내는 데 사용되는 웹 퍼징 도구)를 Phase 3 도구 목록(즉, EXPLOITATION 단계에서만 사용 가능해야 함)과 RECON 기본 우선순위 목록(즉, 시스템이 에이전트에게 즉시 사용하도록 제안함) 양쪽 모두에 기재해 두었습니다. 제 설정의 두 부분이 에이전트에게 서로 반대되는 행동을 하라고 지시하고 있었던 것입니다.

에이전트는 이 모순을 통해 추론하여 Phase 3 도구의 사용을 올바르게 연기했습니다. 스스로 올바른 판단을 내린 것입니다. 하지만 여기서 중요한 점은 이것입니다. 이것은 에이전트가 타겟에서 취약점 (vulnerability)을 찾아낸 것이 아닙니다. 그것은 에이전트가 제 시스템에서 버그를 찾아낸 것입니다.

사고 흔적이 실제로 보여준 것

제가 사고 흔적을 단순한 호기심이 아닌 진단 데이터 (diagnostic data)로서 읽기 시작하자, 명확한 패턴이 나타났습니다. 에이전트는 보안에 대해 추론하고 있는 것이 아니었습니다. 에이전트는 준수 (compliance)에 대해 추론하고 있었습니다.

에이전트는 다음에 무엇을 하는 것이 실제로 타당한지 생각하는 대신, 저의 우선순위 라벨 어휘를 채택하고 시스템 프롬프트의 번호가 매겨진 규칙들을 인용하곤 했습니다. "운영자 명령은 P0이다"라거나 "nmap 미실행이 최우선 순위이다"와 같은 문구들이 끊임없이 등장했습니다. 에이전트는 침투 테스트 (penetration testing)를 수행하는 대신, 제 규칙 시스템을 가지고 '사이먼 가라사대 (Simon Says)' 게임을 하고 있었던 것입니다.

이것은 모델의 잘못이 아니라 제 잘못이었습니다. P0부터 P7까지의 경직된 결정 계층 구조와 필수 작업 큐 (action queue)는 그 정도 수준의 가이드가 필요했던 Sonnet 4를 위해 설계된 것이었습니다. 적응형 사고 (adaptive thinking)를 갖춘 Opus 4.6은 이미 발견한 내용을 바탕으로 추론하고 스스로 다음 단계를 계획할 수 있었습니다. 에이전트가 궤도를 벗어나지 않게 유지해주던 가드레일 (guardrails)이 이제는 에이전트의 발목을 잡는 요소가 되어 있었습니다.

해결 방법

문제를 파악하고 나니 변경 사항은 간단했습니다.

경직된 우선순위 계층 구조 (priority hierarchy)를 원칙 기반의 프롬프트 (principles-based prompts)로 교체했습니다. "P0: nmap을 먼저 실행할 것, P1: 경로를 두 번째로 열거할 것" 대신, 이제 시스템은 "제안된 다음 작업: 당신의 판단을 사용하십시오"와 같이 말합니다.

강제적인 작업 대기열 (action queue)은 권고 사항으로 변경되었습니다. 에이전트가 반드시 따라야 하는 명령 대신, 다른 것이 더 합리적이라고 판단될 경우 에이전트가 스스로 평가하고 무시할 수 있는 제안이 되었습니다.

에이전트가 이전 정찰 데이터 (reconnaissance data)에 나타난 URL만 요청하도록 제한하던 엄격한 가드 (guard)를 완전히 제거했습니다. 볼트 (vault)가 이미 에이전트가 수행한 작업을 추적하고 있었기 때문에, 중복 탐지 (duplicate detection) 기능이 에이전트의 옵션을 인위적으로 제한하지 않으면서도 동일한 문제를 처리할 수 있었습니다.

결과

이러한 변경 사항을 적용하여 동일한 대상을 상대로 세션 02를 실행했습니다. 31개의 명령, 낭비된 턴 0회로 침투 (exploitation) 단계에 도달했습니다. 사고 추적 (thinking traces) 결과, 순응 지향적 추론 (compliance-oriented reasoning) 대신 증거 기반 추론 (evidence-driven reasoning)의 흔적이 나타났습니다. 에이전트는 모든 것을 맹목적으로 플래그 (flagging)하는 대신 가치에 따라 스스로 평가할 수 있었기에, 가치가 낮은 취약점 제안들을 독립적으로 기각했습니다. 단계 전환 (phase transitions)은 매끄러웠습니다. 에이전트는 인간 테스터가 수행할 법한 자율적인 우선순위 지정 (autonomous prioritization) 능력을 보여주었습니다.

자동 SQL 인젝션 (SQL injection) 스캐너는 10번 실행되었지만 취약점을 놓쳤습니다. 에이전트는 로그인 양식의 싱글 쿼트 (single-quote) 문자가 인증된 페이지로의 리다이렉트 (redirect)를 유발하는 간단한 HTTP 요청을 통해 스스로 취약점을 찾아냈습니다. 스캐너는 놓쳤지만, 추론 (reasoning)은 이를 잡아냈습니다.

참고로, 7개의 모든 평가 세션에 걸친 총 API 비용은 약 19달러였습니다.

이것이 보안 너머에서 중요한 이유

여기서 얻을 수 있는 교훈은 침투 테스트 (penetration testing) 그 이상이라고 생각합니다. 만약 여러분이 어떤 종류의 에이전트형 AI (agentic AI) 시스템을 구축하고 있다면, 에이전트가 무엇을 출력하는지뿐만 아니라 어떻게 생각하는지도 볼 수 있어야 합니다. 출력 중심의 평가 (Output-only evaluation)는 에이전트가 정답을 맞혔는지 여부만을 알려줍니다. 반면 추론 가시성 (Reasoning visibility)은 에이전트가 올바른 이유로 정답에 도달했는지, 아니면 단 하나의 엣지 케이스 (edge case)만으로도 무너질 상황인지를 알려줍니다. 제 에이전트는 제가 작성한 규칙 하나를 두고 스스로와 논쟁하며 7번의 턴 (turns)을 소모하는 동안, 겉보기에는 그럴싸한 출력을 내놓고 있었습니다. 만약 그랬다면 저는 그대로 제품을 출시했을 것입니다.

만약 에이전트의 추론이 블랙박스 (black box)라면, 여러분은 눈을 가린 채 비행하는 것과 같습니다. 그리고 문제가 정말 중요해지는 시점이 되어서야 그 사실을 알게 될지도 모릅니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0