[LLM] LLM 활용 취약점 익스플로잇 검증 파이프라인 구성기

반응형

들어가며

최근 취약점 대응 업무에서 가장 부담스러운 부분은 “새 취약점이 나왔다”는 사실 자체보다, 그 취약점이 우리 환경에서 실제로 위험한지를 빠르게 판단하는 일입니다. 대규모 언어 모델(LLM, Large Language Model)의 발전으로 취약점 리서치, PoC 분석, 패치 diff 해석, 영향도 정리 속도는 빨라졌지만, 동시에 공개되는 취약점 정보와 PoC도 훨씬 빠르게 확산되고 있습니다.

대응하는 입장에서는 다음 업무를 한꺼번에 처리해야 합니다.

  • 새로운 CVE의 원인과 영향 범위 확인
  • 공개 PoC의 신뢰성 판단
  • 안전한 격리 환경에서 재현 가능성 검증
  • 운영 서버 중 실제 조치 대상 식별
  • 패치, 완화, 재부팅 계획 수립
  • 보고서 또는 티켓에 들어갈 근거 정리

이 글에서는 필자가 구성한 LLM 활용 취약점 익스플로잇 검증 파이프라인을 정리합니다. 대상 사례는 Linux Kernel 취약점인 CVE-2026-31431 Copy Fail입니다. 함께 조사된 CVE-2026-31635 DirtyDecrypt/DirtyCBC 자료도 영향 범위 점검 스크립트에 일부 반영했습니다.

이 글의 실습은 교육·연구 목적의 승인된 로컬 검증 환경에서만 수행했습니다. 운영 환경 또는 제3자 시스템에서의 무단 재현, 권한 상승 시도, 서비스 중단 유발 행위는 절대 수행하면 안 됩니다.

이번 글에서 다룰 흐름은 다음과 같습니다.

  1. 취약점 대응 업무가 왜 과도해지는지 정리합니다.
  2. Linux Kernel 취약점 CVE-2026-31431을 설명합니다.
  3. LLM 프롬프트와 에이전트 구조를 이용해 취약 커널 VM에서 PoC를 검증합니다.
  4. 검증 결과를 바탕으로 영향받는 서버 범위 확인 스크립트를 작성합니다.
  5. 이 방식이 대응 시간을 어떻게 줄이는지 정리합니다.

 

 

1. 이번에 다룬 Linux Kernel 취약점

이번 파이프라인의 주 검증 대상은 CVE-2026-31431, 별칭으로 공개된 Copy Fail입니다. 수집된 연구 자료 기준으로 핵심은 다음과 같습니다.

  • 대상: Linux Kernel
  • 주요 컴포넌트: crypto/algif_aead, authencesn, AF_ALG, splice 기반 page cache 경로
  • 공격 조건: 로컬 저권한 코드 실행 가능
  • 영향: page cache 변조를 통한 권한 상승 가능성
  • 공개 PoC: Theori/Xint의 copy-fail-CVE-2026-31431
  • 대응: Linux kernel 6.18.22, 6.19.12, 7.0 또는 배포판 벤더가 백포트한 보안 커널 업데이트

 

수집된 내부 연구 레코드에는 취약점 설명이 다음과 같이 정리되어 있었습니다.

Linux kernel의 crypto/algif_aead 처리에서 AEAD in-place 동작과 authencesn 처리,
splice 기반 page cache 참조가 결합돼 로컬 저권한 사용자가 page cache를 변조할 수 있는 취약점이 확인됨

조금 풀어서 설명하면, 이 취약점은 네트워크에서 바로 원격 코드 실행(RCE, Remote Code Execution)이 되는 유형은 아닙니다. 대신 이미 서버 안에서 일반 사용자 권한 또는 컨테이너 내부 코드 실행 권한을 얻은 공격자가 호스트 커널의 page cache 경로를 악용해 권한 상승을 시도할 수 있는 유형에 가깝습니다.

 

 

특히 다음 환경에서는 우선순위를 높게 봐야 합니다.

  • Kubernetes, Docker, Podman 등 컨테이너 실행 노드
  • 자체 운영 CI runner, 빌드 서버, 테스트 서버
  • Bastion, jump host, shell 제공 서버
  • 여러 사용자가 함께 쓰는 Linux 서버
  • 웹 RCE나 배포 계정 탈취 이후 로컬 권한 상승으로 이어질 수 있는 서버

이 취약점의 까다로운 점은 “파일 디스크 내용이 직접 변경되는 것”이 아니라 page cache가 변조될 수 있다는 점입니다. 일반적인 파일 무결성 점검만으로는 공격 흔적을 충분히 포착하기 어렵습니다.

 

 

함께 참고한 DirtyDecrypt 자료

같은 연구 묶음에는 CVE-2026-31635 DirtyDecrypt/DirtyCBC 자료도 포함되어 있었습니다. 이 취약점은 Linux Kernel rxrpc/RxGK 경로의 길이 검증 오류로, 조작된 RESPONSE authenticator 길이가 하위 복호화 경로로 전달되어 커널 BUG_ON 또는 시스템 장애로 이어질 수 있는 유형입니다.

이번 글의 주 재현 대상은 Copy Fail이지만, 운영 서버 영향 범위 점검 스크립트에는 DirtyDecrypt의 커널 버전·설정 확인도 함께 넣었습니다. 실제 대응 업무에서는 취약점 하나만 따로 보지 않고, 같은 기간에 공개된 커널 취약점 묶음을 같이 점검하는 경우가 많기 때문입니다.

 

2. 검증 파이프라인 설계

필자가 원한 것은 “LLM에게 취약점 설명을 요약해 달라” 수준에 멈추는 것이 아닙니다. 대응 업무에서 필요한 것은 다음에 더 가깝습니다.

  • 취약점 근거 수집
  • 공개 PoC 신뢰성 확인
  • 격리된 VM에서 재현
  • 실행 전제 조건 기록
  • 재현 성공/실패 로그 보존
  • 운영 서버 영향 범위 점검 스크립트 생성
  • 사람이 검토 가능한 형태로 최종 요약

 

이를 위해 다음과 같은 에이전트 구조를 사용했습니다.

[Vulnerability Research Agent]
  ├─ NVD / CVE.org / kernel.org / vendor advisory 확인
  ├─ 공개 PoC 저장소 및 commit 고정
  └─ 영향 버전, 패치 버전, 전제 조건 정리

[Lab Orchestrator Agent]
  ├─ Fedora 43 Cloud Base 기반 disposable VM 생성
  ├─ 취약 커널 / 커널 설정 확인
  ├─ SSH localhost forwarding으로만 접근 허용
  └─ 테스트 종료 후 overlay 폐기

[PoC Verification Agent]
  ├─ 언어별 검증 코드 준비
  │   ├─ Python: 공개 PoC 실행 및 결과 수집
  │   ├─ C: AF_ALG / AEAD 경로 접근 가능성 확인
  │   └─ Bash: 커널 버전·config·모듈 상태 점검
  ├─ 실행 전/후 권한 상태 기록
  └─ 로그와 파일 해시 저장

[Impact Triage Agent]
  ├─ 검증된 전제 조건을 운영 점검 항목으로 변환
  ├─ 서버별 커널 버전 및 config 확인 스크립트 작성
  └─ 취약 가능 / 벤더 확인 필요 / 제외 가능으로 분류

실제 지시 프롬프트는 다음 형태로 구성했습니다.

너는 취약점 검증 에이전트다.
대상 CVE는 CVE-2026-31431 Copy Fail이다.
목표는 공개 PoC를 무조건 실행하는 것이 아니라, 다음 순서로 검증 가능한 근거를 남기는 것이다.

1. NVD, CVE.org, kernel.org stable commit, 공개 PoC 저장소를 확인한다.
2. PoC 저장소는 commit hash를 고정하고, 실행 파일의 SHA-256을 기록한다.
3. 로컬 호스트가 아니라 disposable VM에서만 검증한다.
4. VM은 취약한 커널 버전을 가진 Fedora 43 Cloud Base 이미지를 사용한다.
5. VM 접근은 127.0.0.1로 포워딩된 SSH만 허용한다.
6. 실행 전 id, sudo 가능 여부, 커널 config, algif_aead 상태를 기록한다.
7. PoC 실행 후 id, whoami, 종료 코드를 기록한다.
8. 성공/실패 여부와 관계없이 재현 로그를 artifacts 디렉터리에 저장한다.
9. exploit payload 자체를 운영 서버에 배포하지 않는다.
10. 최종적으로 운영 서버 점검용 Bash 스크립트를 작성한다.

출력은 다음 JSON 필드를 포함한다.
- cve_id
- testbed
- poc_source
- preconditions
- execution_result
- artifacts
- limitations
- remediation

스크린샷으로 남겨둔 프롬프트 실행 및 결과 확인 화면은 아래와 같습니다.

Disposable VM 내에서 실행한 결과

 

Exploit 실행 결과 확인

 

3. 취약 커널 VM 구성과 검증

검증은 운영 서버가 아니라 테스트 서버 내부의 disposable VM에서 수행했습니다. 에이전트가 직접 재사용 가능한 Fedora 43 QEMU/KVM 랩 하네스를 준비하고 검증까지 마친 것입니다.

 

VM 실행 스크립트

랩 스크립트의 핵심은 다음과 같습니다.

#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
OVERLAY="$ROOT/lab/vms/cve-2026-41651-fedora43.overlay.qcow2"
SEED="$ROOT/lab/vms/cve-lab-seed.iso"
LOG="$ROOT/lab/vms/cve-2026-41651-fedora43.console.log"
SERIAL_SOCK="$ROOT/lab/vms/cve-2026-41651-fedora43.serial"
ACCEL="${QEMU_ACCEL:-tcg}"
CPU="${QEMU_CPU:-max}"
SERIAL_MODE="${QEMU_SERIAL_MODE:-file}"

if [[ "$SERIAL_MODE" == "socket" ]]; then
  SERIAL_ARG="unix:$SERIAL_SOCK,server,nowait"
  rm -f "$SERIAL_SOCK"
else
  SERIAL_ARG="file:$LOG"
fi

exec qemu-system-x86_64   -name cve-2026-41651-fedora43   -accel "$ACCEL"   -cpu "$CPU"   -smp 4   -m 4096   -drive "if=virtio,file=$OVERLAY,format=qcow2"   -drive "if=virtio,file=$SEED,format=raw,readonly=on"   -netdev user,id=net0,hostfwd=tcp:127.0.0.1:2222-:22   -device virtio-net-pci,netdev=net0   -display none   -serial "$SERIAL_ARG"   -monitor "unix:$ROOT/lab/vms/cve-2026-41651-fedora43.monitor,server,nowait"

다만 실제 테스트용 서버에는 여러가지 진단용 VM도 같이 동작하고 있어 포트는 재매핑 수행했습니다.

  • qemu-system-x86_64가 PATH에 없고, /usr/libexec/qemu-kvm는 사용 가능했습니다.
  • 127.0.0.1:2222는 기존 Kali relay가 사용 중이어서 임시 검증에는 2322 포트를 사용했습니다.

따라서 실제 부팅 확인은 다음과 같이 수행했습니다.

/usr/libexec/qemu-kvm   -name cve-31431-fedora43-check   -accel kvm   -cpu host   -smp 4   -m 4096   -drive if=virtio,file=/tmp/[Redacted]/fedora43-check.overlay.qcow2,format=qcow2   -drive if=virtio,file=/home/[Redacted]/lab/vms/cve-lab-seed.iso,format=raw,readonly=on   -netdev user,id=net0,hostfwd=tcp:127.0.0.1:2322-:22   -device virtio-net-pci,netdev=net0   -display none   -serial file:/tmp/[Redacted]/console.log

실행 환경 확인 결과는 다음과 같이 기록되었습니다.

hostname=cve-lab-fedora43
kernel=6.17.1-300.fc43.x86_64
os=Fedora Linux 43 (Cloud Edition)
gcc=/usr/bin/gcc
python3=/usr/bin/python3
git=/usr/bin/git
crypto_config:
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_USER_API_AEAD=y
modules:
name:           algif_aead
filename:       (builtin)
description:    AEAD kernel crypto API user space interface

이 결과는 Copy Fail 검증에 필요한 AF_ALG, algif_aead, authenc 관련 조건을 확인하는 데 사용했습니다.

 

 

cloud-init 설정

VM은 cloud-init으로 최소 계정과 패키지만 준비했습니다.

#cloud-config
hostname: cve-lab-fedora43
manage_etc_hosts: true
users:
  - default
  - name: codex
    gecos: Codex Disposable Lab
    groups: wheel
    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
    shell: /bin/bash
    lock_passwd: true
    ssh_authorized_keys:
      - __CODEX_LAB_SSH_KEY__
ssh_pwauth: false
disable_root: true
package_update: false
packages:
  - git
  - gcc
  - make
  - dbus
  - dbus-daemon
  - polkit
  - rpm-build
  - dnf-plugins-core
write_files:
  - path: /etc/motd
    permissions: "0644"
    content: |
      Disposable CVE validation VM.
      Authorized local lab use only. Destroy overlay after testing.
runcmd:
  - [ sh, -lc, "systemctl enable --now sshd || true" ]
  - [ sh, -lc, "echo ready > /var/tmp/codex-cloud-init-ready" ]

 

과거의 저였다면 포너블과 리버싱을 위한 분석 환경도 자동으로 마련된 것으로 볼 수 있습니다.

중요한 점은 현재의 저는 그럴만한 시간이 허락하지 않으며, VM이 운영 서버가 아니라는 것입니다. 취약점 검증은 항상 disposable overlay에서 수행하고, 테스트가 끝나면 overlay를 폐기하는 방식으로 구성했습니다.

 

 

4. PoC 검증 결과

공개 PoC는 Theori 저장소를 기준으로 commit hash를 고정했습니다.

repository: https://github.com/theori-io/copy-fail-CVE-2026-31431
commit: 09e97bd8f1aa3868b720a7a12a60b1c365798e06
file_sha256: a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9

블로그에는 exploit payload 전체를 그대로 싣지 않았습니다. 대신 어떤 환경에서 어떤 commit의 어떤 파일을 실행했고, 실행 전후 상태가 어떻게 바뀌었는지를 재현 가능한 근거로 남겼습니다. 실제 대응 업무에서는 payload 자체보다 “우리 환경에서 취약 전제 조건이 성립하는가”, “검증 로그가 신뢰 가능한가”, “어떤 서버가 조치 대상인가”가 더 중요합니다.

 

 

검증 로그의 핵심은 다음과 같습니다.

== testbed ==
Fedora release 43 (Forty Three)
Linux cve-lab-fedora43 6.17.1-300.fc43.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Oct  6 15:37:21 UTC 2025 x86_64 GNU/Linux
== repo ==
09e97bd8f1aa3868b720a7a12a60b1c365798e06
a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9  copy_fail_exp.py
== preconditions ==
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_USER_API_AEAD=y
name:           algif_aead
filename:       (builtin)
description:    AEAD kernel crypto API user space interface
author:         Stephan Mueller <smueller@chronox.de>
license:        GPL
file:           crypto/algif_aead
== poc log ==
PRE_ID
uid=1002(attacker) gid=1002(attacker) groups=1002(attacker) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
RUN_POC
uid=0(root) gid=1002(attacker) groups=1002(attacker) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
root
POST_STATUS:0

 

 

검증 요약 JSON에는 다음과 같이 정리했습니다.

{
  "cve_id": "CVE-2026-31431",
  "verification_date_kst": "2026-04-30",
  "testbed": {
    "type": "KVM disposable VM",
    "image": "Fedora Cloud Base Generic 43",
    "network_exposure": "SSH forwarded only to 127.0.0.1:2322",
    "kernel": "6.17.1-300.fc43.x86_64",
    "crypto_config": [
      "CONFIG_CRYPTO_AUTHENC=y",
      "CONFIG_CRYPTO_USER_API_AEAD=y",
      "algif_aead builtin"
    ]
  },
  "poc_source": {
    "repository": "https://github.com/theori-io/copy-fail-CVE-2026-31431",
    "commit": "09e97bd8f1aa3868b720a7a12a60b1c365798e06",
    "file_sha256": "a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9"
  },
  "execution_result": {
    "pre_run_identity": "uid=1002(attacker) gid=1002(attacker) groups=1002(attacker)",
    "sudo_allowed": false,
    "post_run_identity": "uid=0(root) gid=1002(attacker) groups=1002(attacker)",
    "post_run_whoami": "root",
    "exit_status": 0,
    "result": "confirmed"
  }
}

 

 

이 결과에서 중요한 판단 근거는 세 가지입니다.

  1. 취약 조건이 있는 커널과 crypto 설정이 확인되었습니다.
  2. 실행 전 사용자는 uid=1002(attacker)였고, sudo 권한이 없었습니다.
  3. PoC 실행 후 uid=0(root), whoami=root, POST_STATUS:0이 기록되었습니다.

즉, 이 검증 환경에서는 Copy Fail PoC가 로컬 권한 상승으로 이어지는 것을 확인했습니다.

 

 

C 언어 기반 전제 조건 확인 코드

PoC 실행 전에는 exploit payload와 별도로, 커널의 AF_ALG AEAD 경로 접근 가능성을 확인하는 작은 C 프로그램을 작성했습니다. 이 코드는 취약점을 악용하지 않고, 검증 대상 경로가 노출되어 있는지만 확인합니다.

// Educational lab helper: checks whether AF_ALG AEAD socket path is available.
// It does not exploit CVE-2026-31431.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/if_alg.h>

int main(void) {
    int fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
    if (fd < 0) {
        printf("AF_ALG socket: unavailable (%s)
", strerror(errno));
        return 1;
    }

    struct sockaddr_alg sa = {0};
    sa.salg_family = AF_ALG;
    strncpy((char *)sa.salg_type, "aead", sizeof(sa.salg_type));
    strncpy((char *)sa.salg_name, "authenc(hmac(sha256),cbc(aes))", sizeof(sa.salg_name));

    if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        printf("AEAD authenc binding: unavailable (%s)
", strerror(errno));
        close(fd);
        return 2;
    }

    printf("AEAD authenc binding: available
");
    close(fd);
    return 0;
}

실행은 다음과 같이 했습니다.

gcc -Wall -Wextra -O2 /tmp/check-afalg-aead.c -o /tmp/check-afalg-aead
/tmp/check-afalg-aead
echo status:$?

실행 결과입니다.

AEAD authenc binding: available
status:0

이렇게 언어별로 역할을 분리했습니다.

  • Python: 공개 PoC 실행 및 권한 변화 확인
  • C: 커널 crypto API 경로 접근 가능성 확인
  • Bash: 운영 서버 영향 범위 점검 자동화

 

5. 영향받는 서버 범위 확인 스크립트 작성

PoC가 검증되면 다음 질문은 바로 이것입니다.

“그래서 우리 서버 중 어디가 조치 대상인가?”

이를 위해 검증 결과에서 운영 점검 항목을 뽑았습니다.

 

  • 실행 커널 버전: uname -r
  • Copy Fail 관련 커널 config: CONFIG_CRYPTO_AUTHENC, CONFIG_CRYPTO_USER_API_AEAD
  • algif_aead 내장 또는 모듈 상태
  • DirtyDecrypt 관련 config: CONFIG_RXRPC, CONFIG_AFS, CONFIG_AF_RXRPC
  • 배포판 백포트 여부 확인 필요성
  • 컨테이너는 이미지가 아니라 호스트 커널 기준으로 판단해야 한다는 점

 

작성한 Bash 스크립트는 다음과 같습니다.

#!/usr/bin/env bash
set -euo pipefail

kernel="${1:-$(uname -r)}"
base="${kernel%%-*}"

ver_ge() { printf '%s
%s
' "$2" "$1" | sort -V -C; }
ver_lt() { ! ver_ge "$1" "$2"; }
in_range() { ver_ge "$1" "$2" && ver_lt "$1" "$3"; }

config_file="/boot/config-$(uname -r)"
get_config() {
  local key="$1"
  if [[ -r /proc/config.gz ]]; then
    zgrep -E "^${key}=" /proc/config.gz || true
  elif [[ -r "$config_file" ]]; then
    grep -E "^${key}=" "$config_file" || true
  fi
}

echo "== host =="
echo "hostname=$(hostname)"
echo "kernel=$kernel"
echo "kernel_base=$base"
echo

echo "== CVE-2026-31431 Copy Fail rough scope =="
copyfail="needs vendor/backport check"
if in_range "$base" "6.18" "6.18.22" || in_range "$base" "6.19" "6.19.12"; then
  copyfail="likely affected unless vendor backport is present"
elif ver_ge "$base" "7.0"; then
  copyfail="check whether kernel includes 7.0 fix lineage"
elif ver_lt "$base" "4.14"; then
  copyfail="probably not affected by the referenced 4.14+ code path"
fi
echo "assessment=$copyfail"
get_config CONFIG_CRYPTO_AUTHENC
get_config CONFIG_CRYPTO_USER_API_AEAD
if command -v modinfo >/dev/null 2>&1; then
  modinfo algif_aead 2>/dev/null | sed -n '1,6p' || true
fi
echo

echo "== CVE-2026-31635 DirtyDecrypt rough scope =="
dirty="needs vendor/backport check"
if in_range "$base" "6.16.1" "6.18.23" || in_range "$base" "6.19" "6.19.13" || [[ "$base" =~ ^7\.0 ]]; then
  dirty="likely affected unless vendor backport is present"
fi
echo "assessment=$dirty"
get_config CONFIG_RXRPC
get_config CONFIG_AFS
get_config CONFIG_AF_RXRPC

echo
cat <<'NOTE'
NOTE:
- This script is a triage helper, not a final vulnerability verdict.
- Final decision must check distribution security advisories, package changelog, and backported fix commits.
- Containers share the host kernel, so run this on the host/node, not only inside container images.
NOTE

운영중인 테스트 서버에서 실제 실행한 결과는 다음과 같습니다.

bash /tmp/check-kernel-cve-scope.sh
== host ==
hostname=localhost.localdomain
kernel=5.14.0-611.55.1.el9_7.x86_64
kernel_base=5.14.0

== CVE-2026-31431 Copy Fail rough scope ==
assessment=needs vendor/backport check
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_USER_API_AEAD=y
name:           algif_aead
filename:       (builtin)
description:    AEAD kernel crypto API user space interface
author:         Stephan Mueller <smueller@chronox.de>
license:        GPL
file:           crypto/algif_aead

== CVE-2026-31635 DirtyDecrypt rough scope ==
assessment=needs vendor/backport check
CONFIG_AF_RXRPC=m

NOTE:
- This script is a triage helper, not a final vulnerability verdict.
- Final decision must check distribution security advisories, package changelog, and backported fix commits.
- Containers share the host kernel, so run this on the host/node, not only inside container images.

여기서 needs vendor/backport check라고 표시한 이유는 중요합니다. 엔터프라이즈 배포판 커널은 upstream 버전 숫자만으로 취약 여부를 단정하기 어렵습니다. RHEL, Rocky, Alma, Ubuntu, Debian, SUSE 등은 보안 패치를 낮은 버전 커널에 백포트하는 경우가 많습니다.

 

 

따라서 이 스크립트는 “최종 판정기”가 아니라 1차 분류기입니다. 운영에서는 다음 단계가 이어져야 합니다.

# RHEL/Rocky/Alma/Fedora 계열
uname -r
rpm -q kernel kernel-core
rpm -qa 'kernel*' | sort
dnf updateinfo list --cve CVE-2026-31431
dnf updateinfo list --cve CVE-2026-31635

# Debian/Ubuntu 계열
uname -r
dpkg -l 'linux-image*'
apt-cache policy linux-image-$(uname -r)
zgrep -i 'CVE-2026-31431\|CVE-2026-31635' /usr/share/doc/linux-image-$(uname -r)/changelog* 2>/dev/null

# SUSE 계열
uname -r
rpm -q kernel-default
zypper lp --cve=CVE-2026-31431
zypper lp --cve=CVE-2026-31635

결국 LLM이 만들어 준 것은 단순 요약문이 아니라, PoC 검증 결과를 운영 점검 항목으로 바꿔 주는 연결고리였습니다.

 

 

6. 더 빠른 대응이 가능해지는 지점

이 파이프라인을 구성하면서 가장 크게 줄어든 시간은 “PoC 실행 시간” 자체가 아니었습니다. 실제로 시간이 많이 드는 부분은 그 앞뒤였습니다.

  • 이 취약점이 어떤 조건에서 의미가 있는지 파악하는 시간 = 단축
  • 공개 PoC가 신뢰 가능한지 확인하는 시간 = 단축
  • 안전한 검증 환경을 만드는 시간 = 단축
  • 실행 로그를 나중에 설명 가능한 형태로 남기는 시간 = 단축
  • 검증 결과를 운영 서버 점검 스크립트로 바꾸는 시간 = 단축
  • 보안 담당자, 인프라 담당자, 서비스 담당자가 같이 볼 수 있는 언어로 정리하는 시간 = 초안 데이터를 보고 제가 할일

LLM을 여기에 붙이면 다음 효과가 있습니다.

 

1. 조사와 검증의 경계가 명확해집니다

LLM이 취약점 설명을 그럴듯하게 요약하는 것만으로는 부족합니다. 대신 다음 필드를 강제하면 결과 품질이 좋아집니다.

{
  "research_sources": [],
  "affected_versions": [],
  "fixed_versions_or_patch": "",
  "preconditions": [],
  "testbed": {},
  "execution_result": {},
  "limitations": [],
  "operator_actions": []
}

즉, “무엇을 봤는가”, “어디서 검증했는가”, “무엇은 아직 모르는가”를 분리합니다.

 

2. PoC 성공 여부보다 전제 조건을 남기게 됩니다

취약점 대응에서 흔한 실수는 “PoC 성공”이라는 한 줄만 남기는 것입니다. 하지만 운영 조치에는 다음 정보가 더 필요합니다.

  • 어떤 커널 버전이었는가
  • 어떤 config가 켜져 있었는가
  • 모듈은 내장인지 로드 가능한지
  • 일반 사용자 권한에서 실행했는가
  • sudo나 다른 권한 상승 경로가 섞이지 않았는가
  • 실행 결과가 root shell인지, crash인지, 단순 오류인지

이번 검증 로그는 실행 전 uid=1002(attacker), 실행 후 uid=0(root), 종료 코드 POST_STATUS:0을 남겼기 때문에, 나중에 보고서나 대응 티켓으로 옮기기 쉽습니다.

 

3. 운영 점검으로 바로 이어집니다

검증 결과가 있으면, LLM에게 “이 취약점을 설명해줘”가 아니라 다음처럼 요청할 수 있습니다.

위 PoC 검증 로그에서 운영 서버 점검에 필요한 조건만 추출하라.
다음 기준으로 Bash 스크립트를 작성하라.

- exploit 실행 금지
- 커널 버전 확인
- 관련 CONFIG 확인
- 관련 모듈 확인
- 배포판 backport 여부는 단정하지 말고 vendor 확인 필요로 표시
- 컨테이너 환경은 host kernel 기준이라고 경고
- 결과는 사람이 읽을 수 있는 텍스트로 출력

이렇게 하면 취약점 분석과 운영 대응 사이의 간격이 줄어듭니다.

 

마치며

LLM을 취약점 대응에 활용할 때 중요한 것은 “공격 코드를 더 빨리 만드는 것”이 아닙니다. 오히려 실무적으로 가치 있는 지점은 근거 수집, 격리 검증, 전제 조건 기록, 영향 범위 점검 자동화를 하나의 흐름으로 묶는 데 있습니다.

이번 Copy Fail 검증에서는 Fedora 43 기반 disposable VM에서 공개 PoC의 권한 상승 결과를 확인했고, 그 결과를 바탕으로 운영 서버 1차 점검 스크립트까지 작성했습니다. 이 방식은 모든 취약점에 그대로 적용되지는 않지만, 커널 취약점처럼 “재현 환경”과 “운영 영향 범위”가 모두 중요한 이슈에서는 꽤 효과적입니다.

다만 마지막 판단은 여전히 사람이 해야 합니다. 특히 배포판 커널의 백포트 여부, 실제 노출 조건, 재부팅 가능 일정, 서비스 영향도는 자동화만으로 확정하기 어렵습니다. LLM은 대응 속도를 높여 주는 도구이지, 책임을 대신 져 주는 주체는 아닙니다.

 

 

References