sql注入基础

前言

sql注入相信大家或多或少都了解过,它的原理呢就是通过拼接你的输入到后端的sql语句中然后执行返回你获取的信息,它的危害就不言而喻了。已下主要针对mysql数据库,其它数据库同理,只是有些函数和语法不同而已。

小案例

首先我们先看一个简单的例子吧
我下面会专门把拼接后的语句显示出来方便大家理解
SqlLabs-Less1
先看它正常有哪些返回
当输入的id存在就会返回对应的用户名和密码,不存在就不返回。
sqllabs-Less1
sqllabs-Less1
然后当我输入http://127.0.0.1/sqli-labs/Less-1/?id=1’就会出现
sqllabs-Less1
这里的%27是单引号(’)的url编码,这里有个小地方可以注意一下,就是有些同学可能在后面加上单引号(’)后发现没有报错,这时候先检查一下你的单引号是否是中文的单引号。
这里我们就知道了我们如果要查询其他信息可能可以通过用户名或密码处返回,还有报错的地方
这里通过用户名处返回,首先确定当前查询数据表的列数,然后插入我们构造的查询语句,最后通过payload:http://127.0.0.1/sqli-labs/Less-1/?id=123%27%20union%20select%201,user(),database()%23返回了当前用户名和当前数据库名
(其中空格的url编码是%20,#的编码是%23)
sqllabs-Less1
最后再看一下它的源码
sqllabs-Less1

sql注入漏洞

注入条件

  • 后端通过拼接字符串构造sql语句
  • 拼接的字符串参数我们可控(即没有完全过滤关键字)

注入分类

数字类型和字符类型

我们的sql数据类型就分数字和字符

select * from users where useranme = 'tom'    #字符型
select * from users where age = 18            #数字型

那我们该怎么区分后端的sql语句是哪一种呢?
数字是可以做算数运算的,所以当我们输入 ?id=2 和 ?id=4-2 返回的页面是一样的那就说明是数字类型,反之则是字符类型。

Union联合注入

联合注入就是通过Union关键字连接两个查询,这时候就能查询多个结果,但页面可能只会显示第一个,所以这时候常常使第一个查询为空。

报错注入

当我们的后端构造的sql语句有错误时机会返回到前端页面,方便程序员调试,这同时也可以返回数据库信息,所以我们可以通过故意构造错误的sql语句来返回我们的查询结果。
主要有一下几个方法

updatexml (XML_document, XPath_string, new_value);
我们可以通过控制第二个参数来查询数据
extractvalue(XML_document,xpath_string)
这函数和上一个一样,也是通过控制第二个参数来查询数据
foor()和rand()结合
foor()向下取整,rand()返回0-1的随机数

以上只是几种常用的报错,详细可看看这篇文章https://www.cnblogs.com/feizianquan/p/10794681.html

时间盲注和布尔盲注

它们都叫盲注,故名思意,盲注就是不会回显数据库的信息,只有正确和错误。那我们就可以通过猜解查询的结果,然后根据不同的现象判断猜测是否正确。所以时间盲注就是根据响应时间不同判断,布尔盲注就是根据页面不同来判断。一般盲注都要一个字母一个字母去猜。常用函数

substr(string str,int start,int length)   返回字符串从某个开始位置后多少位(标号从1开始)
left(string str,int len)   返回字符串左边len个字符
right(string str,int len)   返回字符串右边len个字符
if(2>3,<true>,<false>)  第一个参数是判断,第二个是条件为真执行的语句,第三个是条件为假执行的语句。
sleep(5)  响应时间(s)

所以经常用到python脚本去跑,可以看一下我之前的一篇文章https://blog.csdn.net/qq_35599248/article/details/113621280?spm=1001.2014.3001.5501

主要就先说这几类吧,其他的二次注入,header注入,堆叠注入,宽字节注入后面再说。
现在总结一下就是总的可以分为它是有回显的还是没有回显,有回显可以利用Union联合注入、报错注入,没有回显就是时间盲注和布尔盲注。字符类型还是数字类型是为了在字符串拼接后闭合引号保持sql语句的完整性和正确性。

注入思路

  1. 首先判断是字符型还是数字型。
    比如通过 ?id = 1 和 ?id = 2-1页面一样,那么可以推断它可能是数字型注入,反之则可能是字符型注入。字符型注入则需要确定它是单引号还是双引号,或者还有没有括号,同时要把后面的语句注释掉。
    常见测试手法
    ?id = 1’#
    ?id = 1"#
    ?id = 1’)#
  2. 然后猜字段数
    根据第一步我们以及能大概猜出字符串拼接处的格式,然后我们用order by猜字段数,还有select 1,2,3这种也可以。
  3. 最后根据具体情况插入构造sql语句
    如果有回显,那么判断回显位,然后在对应回显位插入构造的sql语句
    如果有报错就尝试用报错函数updatexml(),extractvalue()等构造
    如果没有回显再尝试盲注。

信息获取

我们发现了注入漏洞我们获取数据库信息的流程是什么呢
首先我们查看当前的数据库,用户名,可通过database()、user()获取。
然后呢就通过mysql里面初始数据库information_schema来获取了解整个数据库的所有表名和库名
information_schema
通过这个就可以获取当前数据库的列名及其他表名

绕过

如果后端对传入的参数做了检测,那我们就需要用到一些绕过技巧,绕过的本质就是让传入的参数在它检测的范围之外或者在它处理后仍然形成我们需要的语句。所以我们要掌握同一种结果不同的表达方式。比如like代替=,and可以用&&代替等。

空格过滤

常用注释(/**/或者/*!*/),括号,还有引号

select/**/*from/**/users
select/**/*from/**//*!users*/
select(*)from(users)
select*from`users`where`username`='admin'
and,or过滤

可通过||,&&,^(异或)绕过

关键字匹配

关键字匹配:大小写绕过 SeleCt
关键字替换:双写 selselectect

url编码

因为浏览器在提交URL时会自动对某些字符进行编码,如果在后端只进行了一次解码,这可通过两次url编码绕过。

未编码前:?id=-1' UNION SELECT 1,2,3,4#
一次编码后:?id=-1%27%20UNION%20SELECT%201,2,3,4%23
二次编码后:?id=-1%2527%2520UNION%2520SELECT%25201,2,3,4%2523

还有一些其他的绕过技巧可看看下面这两篇文章
https://binghe.blog.csdn.net/article/details/85869703
https://www.freebuf.com/articles/network/262295.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值