sqli-labs靶场通关笔记:第29-31关 HTTP参数污染
第29关 HTTP参数污染
本关设置了web应用防火墙(WAF),利用白名单保护机制来检测和拦截恶意请求。看本关源代码。
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
//disable error reporting
error_reporting(0);// take the variables
if(isset($_GET['id'])) // 检查URL参数中是否存在id
{$qs = $_SERVER['QUERY_STRING']; // 获取完整的查询字符串$hint=$qs; // 保存查询字符串用于提示$id1=java_implimentation($qs); // 模拟Java处理HPP的函数,提取第一个id参数值$id=$_GET['id']; // 获取PHP解析的id参数值//echo $id1;whitelist($id1); // 调用白名单过滤函数,验证id1是否为纯数字//logging the connection parameters to a file for analysis.$fp=fopen('result.txt','a'); // 以追加模式打开日志文件fwrite($fp,'ID:'.$id."\n"); // 记录请求的id参数fclose($fp); // 关闭文件资源// connectivity $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; // SQL查询语句,存在SQL注入风险$result=mysql_query($sql); // 执行SQL查询$row = mysql_fetch_array($result); // 获取查询结果if($row) // 如果查询到结果{echo "<font size='5' color= '#99FF00'>"; echo 'Your Login name:'. $row['username']; // 输出用户名echo "<br>";echo 'Your Password:' .$row['password']; // 输出密码echo "</font>";}else {echo '<font color= "#FFFF00">';print_r(mysql_error()); // 输出MySQL错误信息echo "</font>"; }
}else { echo "Please input the ID as parameter with numeric value";} // 提示用户输入数值型ID//WAF implimentation with a whitelist approach..... only allows input to be Numeric.
function whitelist($input) // 白名单过滤函数,只允许纯数字输入
{$match = preg_match("/^\d+$/", $input); // 使用正则表达式检查是否为纯数字if($match){//echo "you are good";//return $match;}else{ header('Location: hacked.php'); // 非数字输入重定向到hacked.php//echo "you are bad";}
}// The function below immitates the behavior of parameters when subject to HPP (HTTP Parameter Pollution).
function java_implimentation($query_string) // 模拟Java处理HPP的函数
{$q_s = $query_string;$qs_array= explode("&",$q_s); // 将查询字符串按&分割为数组foreach($qs_array as $key => $value) // 遍历参数数组{$val=substr($value,0,2); // 获取参数名前两个字符if($val=="id") // 找到第一个id参数{$id_value=substr($value,3,30); // 提取id参数值(从第3个字符开始的30个字符)return $id_value;echo "<br>";break;}}
}
?>
这里的WAF白名单只允许输入的参数id为纯数字,阻止了sql注入攻击。
本关的关键点在于,调用java_implimentation函数处理查询字符串,这个函数的作用是模拟 Java 对 HTTP 参数的解析方式,只返回第一个id参数的值。而直接使用$_GET['id']获取的id是PHP默认行为(如果有多个id参数,则取最后一个)。
WAF检测的是传入的第一个id值,如果在传入第二个id值中构造sql语句,则会产生注入攻击。
这种传递多个参数,干扰正常逻辑,影响服务器判断的行为,就是HTTP参数污染(HPP)。
构造测试语句:
这里id=1返回的是用户Dumb,id=1&id=2返回的是用户Angelina,也就是说实际上第一个id被用于白名单检查,第二个id被用于sql查询。
通过参数污染构造攻击语句:
?id=1&id=-1' union select 1,2,database() --+