From 28f9a15ec2538dca5e2f8938351285445daa55fe Mon Sep 17 00:00:00 2001 From: Conrad Sollitt Date: Sun, 9 Jan 2022 11:26:05 -0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=92=20Updates=20for=20Advanced=20Explo?= =?UTF-8?q?its=20and=20[exec.c]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/PHP Custom Build Instructions.txt | 16 ++++ docs/playground-server-setup.sh | 2 + scripts/app-error-testing-2.php | 123 ++++++++++++++++++++----- 3 files changed, 117 insertions(+), 24 deletions(-) diff --git a/docs/PHP Custom Build Instructions.txt b/docs/PHP Custom Build Instructions.txt index 653a5a6..4192606 100644 --- a/docs/PHP Custom Build Instructions.txt +++ b/docs/PHP Custom Build Instructions.txt @@ -104,3 +104,19 @@ https://php.tutorials24x7.com/blog/how-to-install-php-8-from-source-on-ubuntu-20 php_error_docref(NULL, E_WARNING, "You cannot copy files using this build of PHP."); RETURN_FALSE; } + +-------------------------------------------------------------------------------------- +| ext\standard\exec.c +-------------------------------------------------------------------------------------- +# 4 functions end up being disabled in code. Originally when FastSitePHP +# was published [php.ini] setting [disable_functions] was used however +# based on https://github.com/mm0r1/exploits it can be bypassed by user code +# so the custom build of PHP is needed. + + PHP_FUNCTION(shell_exec) + PHP_FUNCTION(exec) + PHP_FUNCTION(system) + PHP_FUNCTION(passthru) + { + php_error_docref(NULL, E_ERROR, "This function is disabled by using a custom PHP build for the FastSitePHP Playground."); + RETURN_FALSE; diff --git a/docs/playground-server-setup.sh b/docs/playground-server-setup.sh index 63ce23d..c5d9301 100644 --- a/docs/playground-server-setup.sh +++ b/docs/playground-server-setup.sh @@ -71,8 +71,10 @@ wget https://www.php.net/distributions/php-7.4.27.tar.bz2 tar xjf php-7.4.27.tar.bz2 wget https://fastsitephp.s3-us-west-1.amazonaws.com/playground/php-7.4.27/file.h wget https://fastsitephp.s3-us-west-1.amazonaws.com/playground/php-7.4.27/file.c +wget https://fastsitephp.s3-us-west-1.amazonaws.com/playground/php-7.4.27/exec.c mv file.h ~/php-7.4.27/ext/standard/file.h mv file.c ~/php-7.4.27/ext/standard/file.c +mv exec.c ~/php-7.4.27/ext/standard/exec.c cd php-7.4.27 ./configure --with-apxs2=/usr/bin/apxs --disable-all --enable-json --enable-filter --enable-ctype --enable-opcache # run `make` - this is expected to take several minutes once `wait` is called on most servers diff --git a/scripts/app-error-testing-2.php b/scripts/app-error-testing-2.php index 5ac2e74..2063565 100644 --- a/scripts/app-error-testing-2.php +++ b/scripts/app-error-testing-2.php @@ -2,7 +2,7 @@ // -------------------------------------------------------------------------------------- // -// Use this file to manually test some advanced PHP bugs. +// Advanced Exploit Testing // // When this file was first created PHP references were blocked from saving // however that turned out to be unreliable so now end users can save PHP code @@ -16,26 +16,34 @@ // security with memory corruption. If methods are found in the future the custom // build of PHP may include more changes rather than relying on [php.ini]. In the // meantime no security-sensitive info exists on the server so the playground site -// will stay up. If attacks are found in the future it could be taken down or switched -// to a different setup. +// will stay up. If attacks are found in the future it could be taken down or +// switched to a different setup. // // -------------------------------------------------------------------------------------- $app->get('/', function() use ($app) { - $html = <<<'HTML' -

Critical Error Testing

- -HTML; + $routes = $app->routes(); + + $html = '

Critical Error Testing

'; + return $html; }); // https://bugs.php.net/bug.php?id=81705 // This returns an E_NOTICE error "Array to string conversion" the first time the -// script is loaded and occasionally when running multiple times. This does not appear -// to cause the "SEGV on address 0x123" error that was described in the original error. +// page is loaded and often when refreshing the page (even without viewing this route). +// Because of this issue the code is commented out by default. +// +// Running this does not cause the "SEGV on address 0x123" error that +// was described in the original error. +/* $app->get('/php-bug-81705', function() { $my_var = str_repeat("a", 1); set_error_handler( @@ -47,19 +55,86 @@ function() use(&$my_var) { $my_var .= [0]; return $my_var; }); +*/ + +// If security is in place this will generate an error +// otherwise if security is bypassed the file will show. +$app->get('/get-error-file', function() use ($app) { + $path = __DIR__ . '/../../../../app/app.php'; + $app->header('Content-Type', 'text/plain'); + return file_get_contents($path); +}); +// https://github.com/mm0r1/exploits +// +// Prior to a new custom PHP build using changes in [exec.c] the first route +// below for [php-concat-bypass] successfully worked to bypass security. +// // Automatic testing is currently not handled for any testing route and routes // are manually handled when the server is setup. As PHP exploits are found they -// should be tested. Example: -// https://github.com/mm0r1/exploits -// Check each PHP file one by one. Example on how to test: -// https://github.com/mm0r1/exploits/blob/master/php-concat-bypass/exploit.php -// Copy the following to this route: -// new Pwn('uname -a'); -// Then copy [class Helper] and [class Pwn] outside of the functions and run -// Currently the exploits cause 502 Bad Gateway errors but do not take the server -// down or return the expected exploit info with the production server. On -// a test server it seemed to work. -$app->get('/mm0r1-exploits', function() { - return 'Copy Content from: https://github.com/mm0r1/exploits'; +// should be tested. +// +// Check each PHP file one by one. For each of these routes the actual class +// and function code must be copied from the [exploit.php] file. It can go at +// the below the routes. + +// https://github.com/mm0r1/exploits/blob/master/php-concat-bypass/exploit.php +// Result: +// 502 Bad Gateway from nginx using default code (some tested servers) +// It causes a "Segmentation fault" for Apache but doesn't stop +// the site from working so these errors are acceptable for now. +// To view related apache log on server: +// tail /var/log/apache2/error.log +// BEFORE UPDATE in [exec.c]: +// It runs and bypasses security when using modified code from (not always required): +// https://github.com/mm0r1/exploits/commit/e287753cadd23836c35c8b5cb39a135e174b13db +// Uncomment `$addr += 0x10;` and comment out `$addr -= 0x10;` +// AFTER UPDATE: +// Pwn::{closure}(): This function is disabled by using a custom PHP build for the FastSitePHP Playground. +$app->get('/mm0r1-exploits-php-concat-bypass', function() { + // Default code to show current system info + new Pwn("uname -a"); + + // Successful attack on the system. After this try route [/get-error-file] + // to confirm security was bypassed. + // + // new Pwn("echo 'FallbackResource index.php' > " . __DIR__ . '/../.htaccess'); + // return 'Updated [.htaccess], refresh page and try again'; +}); + +// https://github.com/mm0r1/exploits/blob/master/php-filter-bypass/exploit.php +// Result: fopen() has been disabled for security reasons +$app->get('/mm0r1-exploits-php-filter-bypass', function() { + pwn('uname -a'); +}); + +// https://github.com/mm0r1/exploits/blob/master/php-json-bypass/exploit.php +// Result: UAF failed. +$app->get('/mm0r1-exploits-php-json-bypass', function() { + global $cmd, $n_alloc, $y; + $cmd = "id"; + $n_alloc = 10; # increase this value if you get segfaults + $y = [new Z()]; + json_encode([&$y]); }); + +// https://github.com/mm0r1/exploits/blob/master/php7-backtrace-bypass/exploit.php +// Result: Couldn't determine binary base address +$app->get('/mm0r1-exploits-php-backtrace-bypass', function() { + error_reporting(E_ERROR); + pwn("uname -a"); +}); + +// https://github.com/mm0r1/exploits/blob/master/php7-gc-bypass/exploit.php +// Result: UAF failed +$app->get('/mm0r1-exploits-php-gc-bypass', function() { + error_reporting(E_ERROR); + pwn("uname -a"); +}); + +// IMPORTANT - for [mm0r1/exploits] the classes and functions +// need to be manually copied here when testing, example: +/* +class Helper { public $a, $b, $c; } +class Pwn { +*/