BLA
BLA (Blind LLM Agents) is the open-source Blue Defense MCP and CLI built to protect software artifacts against automated AI reverse-engineering workflows.
翻譯準備中
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Non-destructive checker for PHP2Shell (CVE-2026-109618 / CVE-2026-109619) — read-only, stdlib-only Python. PHP 취약점 비파괴 점검 도구
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗PHP2Shell(CVE-2026-109618 / CVE-2026-109619) 노출을 비파괴로 점검하는 두 도구입니다. 판정 기준은 PHP_취약점_동향_2026-10.md §2입니다.
| 도구 | 실행 위치 | 답하는 질문 |
|---|---|---|
php2shell_remote.py | 아무 곳 (대상 URL) | 공개된 PHP 버전이 취약 버전인가 — 1차 선별 |
php2shell_host.py | PHP 서버 안 | 이 서버의 SAPI·실효 설정에서 공격 경로가 성립하는가, 무엇을 어디서 고쳐야 하는가 — 관리자 보고서 |
웹에서 바로 시작하기: https://edgebit.co.kr/php2shell/ — 사이트 주소를 넣으면 실행할 점검 명령을 만들어 줍니다(주소는 브라우저 밖으로 전송되지 않음).
버전만으로는 실제 도달 여부를 알 수 없습니다. 원격 점검에서 걸린 서버는 내부 점검기로 확정하십시오.
⚠️ 허가된 시스템에만 사용하십시오. 본인 소유이거나 서면으로 점검 허가를 받은 시스템만 대상입니다. 소프트웨어는 보증 없이 제공되며, 생성된 보고서에는 대상의 취약점 정보가 들어 있으므로 공개하지 마십시오. 자세한 내용은 LEGAL.md를 보십시오.
python3는 3.6이라 php2shell_host.py가 문법 오류로 실행되지 않습니다(이때 종료 코드 1은 Python이 낸 것이며 판정이 아닙니다). sudo apt-get install python3.8 후 python3.8로 실행하십시오.php2shell_host.py)설정 파일·패키지 정보(/var/lib/dpkg/status, changelog)·/proc·로그를 읽기만 합니다. 명령 실행 0건, 네트워크 요청 0건이며 보고서 디렉터리 외에는 아무것도 쓰지 않습니다. 이 사실은 보고서의 투명성 부록에 읽은 파일 목록과 함께 기록됩니다.
# 서버에서 실행 (설정·로그를 읽으려면 root 권한 필요)
sudo python3 php2shell_host.py
# 원격 점검 결과를 함께 반영 (헤더 버전·TLS 체인 문제를 보고서에 합침)
python3 php2shell_remote.py https://example.com/ --json > remote.json
sudo python3 php2shell_host.py --remote-json remote.json
# 영어·일본어 보고서 (원격 점검도 같은 언어로 실행)
python3 php2shell_remote.py https://example.com/ --json --lang en > remote.json
sudo python3 php2shell_host.py --remote-json remote.json --lang en
# 웹서버 설정에 없는 웹루트 추가, 보고서 위치 지정
sudo python3 php2shell_host.py --webroot /srv/app --out /tmp/php2shell_report
# 서버 파일시스템 사본을 오프라인 분석
python3 php2shell_host.py --root /mnt/server-copy
| 옵션 | 기본값 | 설명 |
|---|---|---|
--root | / | 점검할 파일시스템 루트(사본 분석용) |
--out | ./php2shell_report_<호스트> | 보고서 디렉터리 |
--webroot | 없음 | 추가로 검사할 웹루트(반복 지정 가능) |
--remote-json | 없음 | php2shell_remote.py --json 결과(반복 지정 가능) |
--since | 2026-10-17 | 이 날짜 이후 변경된 .php를 침해 확인 항목으로 표시(첫 공격 관측일) |
--lang | ko | 보고서·화면 출력 언어(ko·en·ja). 보고서는 원격 결과의 사유 문장을 그대로 옮기므로 php2shell_remote.py도 같은 --lang으로 실행하십시오. |
report.json(기계 판독), report_<lang>.md(메일·이슈 첨부용), report_<lang>.html(A4 인쇄용). <lang>은 --lang 값입니다. report.json의 코드값(verdict, priority, version_status 등)은 언어와 무관하고, 설명 문장(rationale, notes 등)은 --lang 언어로 기록됩니다. 기존 연동 호환을 위해 판정 라벨 필드명은 verdict_ko를 유지하며 값은 --lang 언어입니다. 근거 문서 인용(DOC:NN)은 언어별 번역본을 가리키고, 번역본은 원문과 줄번호가 같습니다. 보고서 구성: 요약 → 점검 대상(서빙 경로) → CVE별 판정과 근거 경로 → 조치 사항(파일·줄 단위, 확인 명령, 영향) → 침해 징후(확인 필요) → 투명성 부록.
| 판정 | 의미 |
|---|---|
| 도달가능 | 이 서버의 SAPI·실효 설정에서 문서가 확인한 공격 경로의 전제조건이 성립 |
| 완화됨(임시) | 문서의 임시 완화가 요청 파싱 전 단계(php.ini, pool php_admin_value, 웹서버 설정)에 적용됨. 안전이 아님 — 설정만으로는 완전히 완화되지 않음(문서 96행) |
| 판정보류 | 근거 부족·설정 읽기 실패·서비스 미사용. 도달불가가 아님 |
| 패치됨 | 수정 버전 이상 또는 패키지 changelog에 두 CVE 백포트 기록 |
점검하는 조건: SAPI(mod_php/FPM), memory_limit(잠금 여부 포함), post_max_size·upload_max_filesize, nginx client_max_body_size, session.upload_progress.enabled, fatal_error_backtraces(8.5), expose_php, .user.ini·ini_set()처럼 설정했지만 효과 없는 완화, 설정 변경 후 미재시작(파일 mtime 기준 추정), TLS 인증서 체인, 워커 비정상 종료·메모리 고갈 로그, 첫 공격 관측일 이후 변경된 .php.
종료 코드: 0 도달가능·판정보류 없음, 1 도달가능 1건 이상, 2 오류 또는 PHP 서빙 경로를 하나도 찾지 못함(지원하지 않는 배치일 수 있음), 3 도달가능은 없지만 판정보류가 있음.
보고서 말미에는 운영 중인 구버전 서버를 업그레이드 전까지 어떻게 다룰지(오늘 할 일 → 패키지 확보 → 무중단 업그레이드 경로 → 불가능할 때 → 다른 조직 서버에서 발견했을 때) 안내가 붙습니다.
php_value/php_admin_value는 VirtualHost·Directory 구분 없이 전역으로 취급합니다. .htaccess는 AllowOverride를 해석하지 않으므로 위험을 높이는 값만 반영합니다.php:*-apache 이미지는 php_version.h로 버전을 읽어 인식하지만, 공식 php:*-fpm 이미지(/usr/local/etc/php)와 RHEL의 mod_php는 아직 서빙 경로로 인식하지 못합니다. 이때는 경로 0개로 끝나며 종료 코드 2를 돌려줍니다.PHP_VALUE를 합쳐서 판정합니다.--root 분석에서 디렉터리 자체가 절대경로 심링크이면 glob이 사본 밖을 볼 수 있습니다.AC:H/AT:P)은 판정하지 않습니다.php2shell_remote.py)대상 URL에 공격 페이로드, multipart 업로드, SOAP 요청, 세션 조작, 코드 실행 시도는 하지 않고 HTTP GET 한 번만 보냅니다(리다이렉트는 따라갑니다).
python3 php2shell_remote.py <URL> [--timeout 초] [--max-bytes 바이트] [--cafile 파일] [--insecure] [--json]
| 옵션 | 기본값 | 설명 |
|---|---|---|
URL | (필수) | 점검 대상. http:// 또는 https://로 시작해야 합니다. |
--timeout | 8 | 연결부터 본문 읽기까지 전체 제한 시간(초). 최소 0.1. 소켓 수신 1회도 같은 시간만큼 대기할 수 있어 최악의 경우 이 값의 약 2배가 걸립니다. |
--max-bytes | 262144 | 읽을 응답 본문 최대 크기(256KiB). 최소 1024. |
--cafile | 없음 | 시스템 신뢰 저장소에 추가로 신뢰할 CA/중간 CA 인증서 파일. PEM·DER 모두 가능. 검증은 유지됩니다. |
--insecure | 꺼짐 | HTTPS 인증서·호스트명 검증을 생략합니다. 사설 인증서를 쓰는 내부 테스트 서버에만 사용하십시오. --cafile보다 우선합니다. |
--json | 꺼짐 | 결과를 JSON으로 출력합니다. |
--lang | ko | reason·notes·화면 출력 언어(ko·en·ja). status는 언어와 무관한 코드값입니다. |
# 기본 점검
python3 php2shell_remote.py https://example.com/
# JSON 출력 (다른 도구에서 파싱할 때)
python3 php2shell_remote.py https://example.com/ --json
# 사설 인증서를 쓰는 내부 서버, 느린 응답 허용
python3 php2shell_remote.py https://intranet.local/ --insecure --timeout 20
# 여러 대상 일괄 점검 (targets.txt: 한 줄에 URL 하나)
while read -r url; do
python3 php2shell_remote.py "$url" --json
done < targets.txt
unable to get local issuer certificate)브라우저에서는 열리는데 이 도구에서 위 오류가 나면, 대개 서버가 중간 CA 인증서를 보내지 않는 설정 오류입니다. 브라우저는 인증서의 AIA 주소에서 중간 CA를 스스로 받아 오지만 Python(OpenSSL)은 그렇게 하지 않습니다. 이 경우 도구가 notes에 안내를 출력합니다.
# 1) 서버가 보내는 체인 확인: "0 s:" 한 장만 나오면 중간 CA 누락
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
# 2) leaf 인증서의 AIA "CA Issuers" URL 확인
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| openssl x509 -noout -ext authorityInfoAccess
# 3) 그 URL에서 중간 CA를 받아 --cafile로 지정 (DER 그대로 사용 가능)
curl -o intermediate.crt http://<CA Issuers URL>
python3 php2shell_remote.py https://example.com/ --cafile intermediate.crt
--insecure와 달리 --cafile은 인증서 검증을 유지합니다. 근본 해결은 서버에 fullchain(leaf + 중간 CA)을 설정하는 것이며, 이 누락은 API 클라이언트·모니터링 도구도 똑같이 실패시키므로 별도로 보고할 만합니다.
Windows에서 한글이 깨지면 PYTHONIOENCODING=utf-8을 설정하거나 PowerShell에서 $env:PYTHONIOENCODING='utf-8'을 실행한 뒤 돌리십시오.
판정: likely_vulnerable
사유: PHP 8.2.10은 문서의 수정 버전 8.2.35 미만입니다.
HTTP: 403
X-Powered-By: PHP/8.2.10
PHP: 8.2.10 (출처: X-Powered-By)
- 비파괴적 GET 요청만 수행했습니다.
- 버전 판정만으로 실제 도달 가능성이나 배포판 백포트를 확정할 수 없습니다.
- HTTP 오류 응답(403 Forbidden)의 헤더로 판정했습니다.
JSON 출력 필드: target, status, reason, http_status, detected_version, version_source, server, powered_by, final_url, redirects, notes.
| 판정 | 의미 |
|---|---|
likely_vulnerable | 공개된 PHP 버전이 문서의 수정 버전보다 낮거나, 공식 수정 릴리스가 없는 EOL 브랜치(8.2 미만)임 |
not_vulnerable_by_version | 공개된 버전이 수정 기준 이상임 |
unknown | PHP 흔적은 있으나 버전 비공개, 패치 번호 없이 8.3처럼 일부만 공개, 또는 기준표보다 새로운 브랜치 |
not_detected | 응답에서 PHP 흔적을 찾지 못함. PHP가 없다는 뜻은 아님 |
error | 연결 실패, TLS 오류, 잘못된 응답 등 |
invalid | URL 형식 오류 |
수정 기준 버전: 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35.
판정에 영향을 주는 동작:
final_url, redirects에 기록됩니다. 다른 호스트로 넘어가거나 https에서 http로 다운그레이드되면 notes에 경고가 남습니다..php 링크)에만 있으면 근거가 약하다는 note가 붙습니다.| 코드 | 의미 |
|---|---|
0 | not_vulnerable_by_version |
1 | likely_vulnerable |
2 | error, invalid |
3 | unknown, not_detected — 판정 불가 |
CI나 스크립트에서 1을 실패 조건으로 쓸 수 있습니다. 3은 "문제없음"이 아니라 "판정할 근거가 없음"입니다.
운영 환경에서는 프록시/로드밸런서가 버전을 숨길 수 있고, 배포판 백포트·SAPI·session.upload_progress·fatal_error_backtraces는 원격 GET만으로 확인할 수 없습니다. 배포판 패키지(예: 8.2.7-1+deb12u5)는 버전 번호가 낮아도 백포트로 수정됐을 수 있으므로 likely_vulnerable은 changelog로 확인하십시오. 따라서 not_vulnerable_by_version은 패치 적용 확인의 보조 신호이며, 최종 판단은 서버 인벤토리와 패키지 변경 이력으로 하십시오. 자사 또는 명시적으로 허가받은 시스템에만 실행하십시오.
lab/)PHP 버전·SAPI·패키지 배치·완화 상태가 다른 8개 사이트를 Docker로 띄워 두 점검기를 함께 돌립니다. 사이트는 index.php 하나뿐이며 127.0.0.1에만 바인딩하고, 공격 요청은 보내지 않습니다. 접속 포트는 PHP 버전입니다(7.2.34 → 7234).
cd lab
./run.sh # Windows Git Bash: PYTHON=python ./run.sh
REPORT_LANG=en ./run.sh # 영어(en)·일본어(ja) 출력으로 실행
cat out/summary.txt # 사이트별 원격 판정과 내부 점검 요약
docker compose down
| 포트 | 구성 | 확인하는 것 |
|---|---|---|
| 7224 | Ubuntu 18.04 · PHP 7.2.24 · nginx+FPM | 패치가 없는 EOL 브랜치, Python 3.6 환경 |
| 7234 | 공식 php:7.2.34-fpm · nginx | 7.2 마지막 릴리스, 공식 이미지 배치 |
| 7403 | Ubuntu 20.04 · PHP 7.4.3 · .user.ini 완화 | 소스 백포트만 있는 브랜치, 효과 없는 완화 검출 |
| 8102 | Ubuntu 22.04 · PHP 8.1.2 · mod_php | 배포판 백포트 판별(원격은 취약, 내부는 패치됨) |
| 8306 | Ubuntu 24.04 · PHP 8.3.6 · pool 완화 | 배포판 백포트, php_admin_value 완화 |
| 8336 | 공식 php:8.3.36-fpm · nginx | 수정 버전, 공식 이미지 배치 |
| 8426 / 8427 | 공식 php:8.4.26/27-apache | 수정 직전·직후 mod_php |
docs/sample-report/는 이 랩의 한 사이트(7403)에서 생성한 실제 보고서입니다(report_ko·report_en·report_ja의 .md/.html, report.json은 ko).
메시지 카탈로그를 고친 뒤에는 python lab/check_i18n.py로 세 언어의 키·placeholder 일치를 확인합니다.
Kevin Hwang. 파이썬을 쓰고·실행하고·자동으로 돌리는 학습용 Windows 데스크톱 앱 PyAutoFlow도 만들고 있습니다.
기사·블로그·발표 자료에서 이 저장소나 보고서 예시를 소개할 때는 아래 형식으로 출처를 밝혀 주시기 바랍니다. 보도·인용에 대해서는 법적 의무가 아닌 요청입니다. 문서를 복제·각색하는 경우에는 CC BY 4.0에 따라 저작자 표시가 필요합니다.
출처: php2shell-check — Kevin Hwang (https://github.com/neoqmin/php2shell) 개발자는 파이썬 학습·자동화 데스크톱 앱 PyAutoFlow(https://pyautoflow.com/)를 만들고 있습니다.
사용 조건과 책임 제한은 LEGAL.md를 함께 보십시오.