目录
SQL注入产生原理
由于web应用程序没有对用户输入的数据进行判断,用户可以自由控制传入后端的数据,因此只要构造相应的语句就可以对数据库非法操作。
Mysql相关
想要进行sql注入必须要先了解一些Mysql的知识。Mysql默认有一个information_schema数据库用来存放其他所有数据库的信息,其中SCHEMATA、TABLES和COLUMNS分别存储了其他数据库的库名,库名和表名, 库名、表名、字段名,其表中记录库名、表名、字段名的字段名分别为table_schema、table_name、clumns_name。从这些字段名中可以找到其他数据库的信息。
联合注入
条件
1.页面上有相应位置回显
2.必须由两条或以上select语句构成
3.查询必须由相同的列
步骤
1.判断列数
可以通过order by+列数判断,如果列数超过则会显示Unknown column,不超过则正常显示,可以利用二分法快速判断列数
2.判断回显位
在确定完列数后利用union select判断相应的显示位置,列如有3列则构造union select 1,2,3通过回显即可判断
3.查询数据库等信息
整型注入
如sqlilabs中less-2中就是整形注入,此类型不需要闭合,直接执行语句查询即可
从图中可以看到当order by 4的时候不能正常回显,那么可以判断
列数小于4
当order by 3的时候可以正常回显那么可以判断出列数为3
当知道列数后就可以判断相应回显位置,在判断不能继续用id=1,否则将继续显示id=1的内容
通过回显可以判断出2,3的位置有回显,找到回显位后就可以进而查询各种信息,通过构造?id=0 union select 1,database(),3得到当前数据库
继续通过information_schema.tables找到所有表,这里可以用group_concat显示出所有内容
继续利用information_schema.column查询字段名
最后找到所有内容,这里如果数据库中表名是唯一的可以直接from表名
单引号闭合
sqlilabs中less-1为单引号闭合,当传入id=1时正常显示,id=1’时出现下面内容
从图中可以看出传入的id=1’使语句多出了一个单引号,而语句中单引号是不能单独出现的,因此我们将后面的单引号注释掉,可以使用#(当有过滤时可以用%23)
闭合成功后即可正常回显,接下来继续查询相应信息即可,方法与整形注入相同
双引号闭合
没啥好说的,与单引号闭合原理相同,方法也是注释掉后面的引号
报错注入
Xpath语法错误
extractvalue
extravalue主要作用为对xml文档查询用法为extravalue(xml文档,Xpath字符串)由于第二个参数必须要求为合法字符串形式,否则将会报错并且返回错误信息,这样就可以进行操作,可以用~ # $等进行报错
payload可以为
id='and(select extractvalue("1",concat('0x7e',(语句))))
例如salilab-less2中
updatexml
用法为updatexml(xml文档,路径,内容)与extravalue类似,只不过前者为更新文档后者为查询文档,在第二个参数路径可以使用非法字符进行报错
payload可以为
id='and(select updatexml("1",concat('0x7e',(语句),),'1'))
group_by
group by 的原理是循环读取每一行,把结果存在一个表中。读取每一行时,如果数据存在于临时表中,则不更新临时表的数据;反之不在时,则插入数据,因此可以利用floor(rand(0)*2)的重复性使group by报错
payload可为
'union select 1 (select count(*),concat((语句),floor(rand(0)*2))字段 from "表" group by 字段)
Boolean注入
Boolean注入判断较易,当访问页面时返回yes,在加单引号或者其他字符后返回no, 再通过更改id的传入值发现结果仍为yes或no即可判断为Boolean注入,该类型与上述几个有所区别,当查询时若执行语句并不能直接获得查询结果,需先判断库名的长度,可以利用length函数判断
例如
length(database())>=4
length(database())>=5
若第一句返回yes说明库名大于或等于4,若第二句返回no说明库名小于5,由此可以判断出库名的长度为4
在知道库名长度后可以利用substr函数进行逐字判断,函数用法为
substr(参数,起始位置,截取个数)
例如
substr(database(),1,1)='a'
意思为截取database()的值从第一个字符开始截取一个判断是否等于字符a,如果等于则返回yes否则返回no,由此可以逐字判断出数据库全名,得到数据库名后进而判断出表名、字段名等
可以利用burp快速爆破
时间注入
通常sql语句查询只有几毫秒因此可以利用sleep延长sql语句的执行时间结合if,进而通过burp中页面相应时间判断条件是否正确
例如
if(length(database())>1,sleep(5),1)
意思为如果database()库名大于1,则延迟5秒执行语句
如salilab-less9中
宽字节注入
类似于sqlilab-less32中传入id=1’时发现单引号被反斜杠转义,此种情况在数据库编码为GBK时存在宽字节注入,可以在地址后加%df,原理为反斜杠编码为%5c,而在GBK编码中%df%5c是繁体字連,这时候反斜杠不存在,单引号便不受反斜杠影响爆出错误
进而继续查询信息
cookie注入
cookie是保存于客户机上一个特殊的文件,主要用于记录客户机的个人信息,因此如果不对cookie中信息进行过滤就可以引起注入漏洞
cookie注入与传统的GET和POST并没有太大区别,只不过是形式不同而已
判断cookie注入的方法,可以先看URL是否存在.asp?id=的形式,通过更改cookie传入的参数来判断是否存在注入
另外还有一种方式就是通过burp抓包更改cookie的值来判断
例如sqlilab-less-20中
登陆成功后会在页面中显示出用户信息,在信息中能看到ID=8,猜测ID很可能就是从数据库中查询出来的,因此通过burp抓包本页面
看到cookie中存入了admin,尝试更改uname发现页面回显发生变化
据此判断存在cookie注入,剩下的方法与上边相同,通过更改uname的值来一步步实现信息查询
堆叠注入
堆叠注入顾名思义就是将多条语句一起执行,在mysql中 ; 表示语句结束,那么如果语句结束后继续构造下条语句会发生什么?堆叠注入由此而生
例如强网杯随便注入
但是这里过滤了select,可以通过预编译来绕过
预编译相关:
set 设置变量名和值
prepare 定义一个语句,并设置名称
execute 执行语句
二次注入
二次注入与上述几种情况有所区别,其本身页面并不存在漏洞,产生原理为攻击者在构造恶意数据存入数据库中后,当web应用调用sql查询时执行攻击者构造的语句从而形成的漏洞
其步骤基本分为插入数据和引用数据两步
例如sqlilab-less24
注册一个名为admin’#的用户密码为123456,当登入后修改密码为12345678
可以看出admin’#的密码并没有改变,而是直接改变了admin的密码,由此还可以实现很多功能
由于能力有限,若文章有错误还请包涵并指出