Procedural logic IssuesThe topic tip is to bypass the test center: SQL Statement Injection
<?php
if ($_post[user] && $_post[pass]) {
$conn = mysql_connect ("********," * * * * *, "********");
mysql_select_db ("Phpformysql") or Die ("Could not select Database");
if ($conn->connect_error) {die
("Connection failed:". Mysql_error ($conn));
}
$user = $_post[user];
$pass = MD5 ($_post[pass]);
$sql = "Select pw from php where user= ' $user '";
$query = mysql_query ($sql);
if (! $query) {
printf ("Error:%s\n", Mysql_error ($conn));
Exit ();
}
$row = Mysql_fetch_array ($query, MYSQL_ASSOC);
echo $row ["PW"];
if ($row [PW] && (!strcasecmp ($pass, $row [PW])) {
echo "<p>logged in! key:************** </p> ";
}
else {
echo ("<p>log in Failure!</p>");
}
}
? >
Early knowledge (may be slightly):
The optional second parameter in Mysql_fetch_array (), result_type, is a constant that can accept the following values: Mysql_assoc,mysql_num and Mysql_both. This feature is for PHP 3.0.7 New Plus.
The default value for this parameter is Mysql_both. If you use Mysql_both, you will get an array that contains both associative and numeric indexes. Use MYSQL_ASSOC only to get the associated index (as in Mysql_fetch_assoc ()),
Use Mysql_num only to get a numeric index (as in Mysql_fetch_row ()). It simply returns an associative array.
Mysql_connect-Open a connection to the MySQL server
STRCASECMP ($pass, $row [PW]) binary Security comparison string (case insensitive). The request is PASS==ROW[PW]
Analysis of the subject:
One, the vulnerability point $sql = "Select pw from php where user= ' $user '"; Because the front is post, so it's a key-injection.
Unlike the ' Programmer's Problem ', where the user and password are divided, so comment out PW is not possible, as long as the value of ROW[PW] and pass after MD5 value is equal can and $pass after MD5 value is we can control through the normal input
At the same time, the value of ROW[PW] is extracted from the $sql target in one sentence: As long as we can modify the value of $sql, this problem solved. Re-examine the injection point: $sql = "Select pw from php where user= ' $user '";
Here we can use the SQL statement to return a value directly to $sql.
That is, do not need to visit the database in the problem, as long as we modify the value of the $sql, this problem solved.
Second, the rest is to guess the user name, try the admin, wrong, and then try the default username into, to prevent the short-circuit, to ensure that the latter union execution.
Explain:
1. The first single quotation mark: the Where user= to close the original
2. And 0=1: To make the previous expression return a null value.
3. We then use the Union SELECT MD5 (2) to directly retuen the MD5 value to $sql as the return value, so that the $query will have a value at the time of the query.
4. The last # to comment out the useless things behind
Username:username ' UNION select MD5 (1) #
Password:1