
CVE-2025-40778의 개념 증명: 비요청 추가 섹션 레코드를 통한 BIND 9 DNS 캐시 중독.
이 취약점은 공격자가 BIND 리졸버의 DNS 캐시를 손상시켜 합법적인 사용자가 모르는 사이에 악성 IP 주소로 리디렉션되도록 합니다.
공격은 신뢰를 악용하는 데 의존합니다. 피해자는 리졸버를 신뢰하고, 리졸버(BIND)는 권한 있는 서버로부터 받은 응답을 신뢰합니다. 이 결함은 BIND가 DNS 응답의 ADDITIONAL 섹션에 제공된 요청되지 않은 데이터를 처리하고 캐싱하기 때문에 발생하며, 해당 데이터가 완전히 다른, 요청되지 않은 도메인에 속하더라도 그렇습니다.
설정: 공격자는 특정 도메인(예: poc.lab)에 대한 악성 권한 DNS 서버를 제어합니다. 공격자는 대상 리졸버(BIND)가 이 도메인을 질의할 때까지 기다립니다.
주입: 리졸버가 공격자의 서버에 poc.lab을 질의하면, 공격자는 poc.lab에 대한 합법적인 응답을 보내지만 ADDITIONAL 섹션에 다른 도메인(예시에서는 www.hacker.com, 그러나 facebook.com과 같은 합법적인 도메인이 될 수 있음)에 대한 요청되지 않은 응답을 포함하여 악성 IP 주소를 가리키도록 합니다.
포이즈닝: 취약점으로 인해 리졸버는 요청되지 않은 "Additional" 레코드를 수락하고 캐시에 저장합니다. 공격자가 요청되지 않은 도메인에 대한 권한이 있는지 확인하지 않습니다.
피해자의 질의: 피해자가 나중에 리졸버에 요청되지 않은 도메인(www.hacker.com)을 질의하면, 리졸버는 캐시에서 포이즈닝된 레코드를 반환하여 피해자를 공격자가 제어하는 악성 IP 주소로 리디렉션합니다.
[!IMPORTANT]
이 PoC의 주요 포인트
간접 공격: 피해자는 공격자와 직접 통신하지 않습니다.
신뢰 앵커 손상: 피해자의 머신은 정상적으로 작동합니다. 인프라(DNS)가 거짓말을 하고 있는 것입니다.
메커니즘: 이 익스플로잇은 ADDITIONAL 섹션 처리를 이용하여 요청되지 않은 레코드를 주입합니다.
[!CAUTION]
이 PoC는 교육 목적으로만 제공됩니다. 이 정보를 무단으로 사용하여 시스템을 손상시키는 것은 불법적이고 비윤리적입니다. 네트워크 또는 시스템에서 취약점을 테스트하거나 악용하기 전에 항상 허가를 받으십시오.
이 데모에서는 다음 가상 머신(VM)이 사용됩니다:
다음 명령어는 CVE-2025-40778 취약점을 시연하기 위해 Debian 기반 시스템에서 BIND 9.21.12를 설정하는 방법입니다.
[!NOTE] 이 데모는 이 취약점의 영향을 받는 버전 중 하나인 BIND 9.21.12를 사용합니다.
기타 알려진 영향을 받는 버전 범위:
- 9.11.0 – 9.16.50
- 9.18.0 – 9.18.39
- 9.20.0 – 9.20.13
- 9.21.0 – 9.21.12
다음 명령어는 필요한 종속성을 설치하고, BIND 9.21.12 소스 코드를 다운로드하여 컴파일하고, 시스템에 설치합니다.
sudo apt install -y build-essential pkg-config perl meson ninja-build libssl-dev libuv1-dev liburcu-dev libcap-dev liblmdb-dev libnghttp2-dev
cd /usr/local/src
sudo wget -O bind-9.21.12.tar.xz https://isc.mirrorservice.org/bind/9.21.12/bind-9.21.12.tar.xz
sudo tar -xf bind-9.21.12.tar.xz
cd bind-9.21.12
sudo meson setup build --prefix=/usr/local --sysconfdir=/etc --localstatedir=/var
sudo ninja -C build
sudo ninja -C build install
echo /usr/local/lib/x86_64-linux-gnu | sudo tee /etc/ld.so.conf.d/bind9-local.conf
sudo ldconfig
ldconfig -p | grep 'libdns-9.21.12' || true
/usr/local/sbin/named -v
다음은 최종 명령어의 예상 출력입니다:
> student@student:/usr/local/src/bind-9.21.12$ /usr/local/sbin/named -v
BIND 9.21.12 (Development Release) <id:9bafc35>
BIND 서버를 시작하기 전에 named 서비스를 실행할 전용 사용자와 그룹을 생성해야 합니다:
sudo groupadd --system named 2>/dev/null || true
sudo useradd --system --no-create-home --home /nonexistent --shell /usr/sbin/nologin --gid named named 2>/dev/null || true
이 BIND 설치는 기본 구성 파일을 제공하지 않으므로 필요한 디렉토리를 수동으로 생성해야 합니다:
sudo mkdir -p /etc/bind
sudo mkdir -p /var/cache/bind
sudo mkdir -p /var/log/named
sudo mkdir -p /var/run/named
sudo chown -R named:named /var/cache/bind /var/log/named /var/run/named
sudo chmod 750 /var/cache/bind /var/log/named /var/run/named
다음 단계는 아래 내용으로 기본 구성 파일 /etc/bind/named.conf를 생성하는 것입니다:
include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.logging";
include "/etc/rndc.key";
옵션 구성을 위해 다음 내용으로 /etc/bind/named.conf.options 파일을 생성합니다:
options {
directory "/var/cache/bind";
recursion yes;
allow-recursion { 192.168.174.0/24; };
allow-query { 192.168.174.0/24; };
listen-on { 192.168.174.131; 127.0.0.1; };
listen-on-v6 { none; };
dnssec-validation no;
forwarders {
1.1.1.1;
8.8.8.8;
};
minimal-responses no;
// for manual start
pid-file "/var/run/named/named.pid";
};
도메인 poc.lab에 대한 포워드 영역을 설정하여 표준 포트 53에서 192.168.174.130에 있는 공격자의 DNS 서버로 질의를 전달하려면 /etc/bind/named.conf.local 파일을 다음과 같이 편집해야 합니다:
zone "poc.lab" {
type forward;
forward only;
forwarders { 192.168.174.130; };
};
로깅 구성을 위해 다음 내용을 포함하는 /etc/bind/named.conf.logging 파일을 생성합니다:
logging {
channel queries_file {
file "/var/log/named/queries.log" versions 3 size 20m;
severity info;
print-time yes;
print-category yes;
};
channel default_stderr {
stderr;
severity info;
print-time yes;
print-category yes;
};
category queries { queries_file; };
category default { default_stderr; };
};
마지막으로 RNDC를 구성해야 합니다:
sudo /usr/local/sbin/rndc-confgen -a -c /etc/bind/rndc.key
sudo chown root:named /etc/bind/rndc.key
sudo chmod 640 /etc/bind/rndc.key
먼저 포트 53이 다른 서비스에서 사용되고 있지 않은지 확인해야 합니다 (우리의 경우 systemd-resolved를 비활성화해야 했습니다):
sudo systemctl disable --now systemd-resolved || true
sudo ss -lunp | grep ':53' || true # To verify that port 53 is free
마지막으로 다음 명령어를 사용하여 BIND 서버를 시작할 수 있습니다:
sudo /usr/local/sbin/named -g -u named -c /etc/bind/named.conf
[!TIP]
BIND가 올바르게 실행 중인지 확인하기 위해 다음 명령어를 사용할 수 있습니다:
ss -lunpt | grep :53
피해자 머신에서 BIND 서버를 DNS 리졸버로 사용하도록 설정해야 합니다. 또한 충돌을 방지하기 위해 systemd-resolved를 비활성화해야 합니다:
sudo systemctl disable --now systemd-resolved
그런 다음 다음 명령어를 사용하여 정적 DNS 서버를 설정할 수 있습니다:
sudo rm -f /etc/resolv.conf
sudo nano /etc/resolv.conf
> nameserver 192.168.174.129
> options timeout:1 attempts:1
sudo chattr +i /etc/resolv.conf #block overwrites
공격자 머신에서 저장소에 제공된 스크립트(attacker.py)를 실행해야 합니다.
우리의 시나리오에서 공격자는 poc.lab 도메인을 제어합니다. 해당 도메인이나 하위 도메인에 대한 질의를 받으면 공격자의 IP 주소를 가리키는 요청되지 않은 응답 레코드(www.hacker.com)를 추가합니다.
피해자가 poc.lab 도메인을 질의하면 BIND 서버는 요청을 공격자의 DNS 서버로 전달합니다. 공격자는 BIND 서버의 캐시를 오염시키는 요청되지 않은 응답 레코드로 응답합니다. 피해자가 www.hacker.com에 접속하면 합법적인 IP 주소 대신 공격자의 IP 주소로 리디렉션됩니다.
다음은 피해자가 두 도메인을 질의한 시연입니다:
student@student:~/Desktop$ dig www.poc.lab +noall +answer
www.poc.lab. 60 IN A 192.168.174.99
student@student:~/Desktop$ dig www.hacker.com +noall +answer
www.hacker.com. 60 IN A 192.168.174.130
위와 같이 www.hacker.com에 대한 피해자의 DNS 질의는 공격자의 IP 주소(192.168.174.130)를 반환합니다.
[!NOTE]
이 동영상은 설명된 취약점을 시연한 것입니다: https://drive.google.com/file/d/1PATD0tUqw8-BipfSf6TkQQfnJBvV110Z/view?usp=sharing