V3D4's Blog

安全技术记录/分享/交流

0%

SQL注入一

1.sql注入步骤开始清晰(整型注入)

​ union select 的作用是将两次查询结果和为一次再输出,先用union select *,*,*…等来判断字段列数,无报错及说明字段名猜测成功,之后再让前面查询的id查不出来(id输入很大或者可以and 0),即可只显示union select的内容。前台返回结果并不是表真实列数,再查看哪个字段有回显,即前台显示的是哪几个字段内容。

​ Mysql所有内容都存储于information_schema库中,里面有三个重要字段schemamata(存放所有数据库信息schema_name),tables(存放所有数据库中的表名 table_name,table_schema表所属数据库名),columns(存放前包含前两者的东西加上字段名column_name,内容最为详细).
​ Group_concat语句用于将所有查询出来的内容拼为一行,不然只会显示一个数据,如Group_concat(schema_name)
​ Database()用于查询当前数据库名称,如select 1,database(),3 from information_schema.schemata(可以不加from)
​ 知道数据库之后可以开始查询当前数据库所有表名,语句为 select group_concat(table_name) from information_schema.tables where table_schema=database()
​ 知道表名后可以开始查询当前表中所有字段名,语句为select group_concat(column_name) from information_schema.columns where table_schema=database() and tablename=xxx(自己想查的表)
​ 知道字段名称可以开始查数据了,语句为select 1,group_contact(字段名),3 from 查出来数据库名.表名
​ Contact_ws函数用于将两个字段一起显示,例 concat_ws(‘:’,user,pwd)就是将两个字段以冒号分隔一起显示,想显示所有再在外面加group_concat(concat_ws(':',user,pwd))
​ 快速判断几列可以用order by,原理:order by x(数字)将会按照第x列来进行排序,超过了便会报错,所以能够快速确定列数

2.基于报错的GET单引号双引号注入

​ 在id=x后面加单(双引号)观察是否会报错,根据报错语句来实行注入,让我们自己的语句能够闭合(加单双引号,括号等),同时将后面的语句注释掉,一般可以用的方式有加/**/(基本用不上),–+(加号等于空格),%23(#的url编码,直接输入不会被转义所以要这样),从而实现注入

3.基于报错的POST单引号双引号注入

(以前写的,仅针对当时看的例子,很多地方表述不清,见谅)

​ 一般为登陆界面,也是单双引号,不能在url中输入,需要在账户名密码中进行注入,在username中进行注入是,由于不知道账户是否存在,应该在username里闭合后加上 or 1,让其永远为真 ,这里的注释符号跟上面相同,但要多试几次,因为可能会被url转义,#可以直接用,不再需要变成23%,注释掉后sql语句中便不再判断密码,即可登陆成功(在用hackbar的时候passwd一般不能少)

4.基于报错的POST双注入

​ 由于有时候加只加单引号或者双引号不能根据报错得到我们想知道的东西,所以有时候需要单双引号一起用,再根据报错来判断sql语句,实现注入。
​ 知道用户名的情况下可以不用加or 1,就会登陆到当前用户名账户。使用之前的方式,发现order by判断列数成功后,union select却不回显数据,就需要 用到双注入。
​ 先自己尝试,在mysql中自己查询数据发现

s1

​ group by之后直接查询所有数据只会返回分类后的第一条。
​ Group by 后面如果加数字,那么就是根据select中的东西作为主键,如下图

s2

Group by 1就是以table_schema作为主键,2就是count(*)
使用group by * 会新生成一个临时表,临时表中*为主键,不能重复,所以利用这一特性,可以用rand函数实现注入,让其出错,从而从报错信息中获取数据,具体payload如下
Union select table_schema,count(*) from information_schema.tables group by concat(floor(rand()*2),version());

​ 其中的version()就是我们想要查询的内容,可以换成其他我们想查的,如database()等,floor是将rand值转化为整型,即只取0,1(必不可少),我们所需要知道的信息就全都在报错语句里。(如下图)

s3

5.5.20即为数据库版本号,在错误信息里输出了
在version这个地方就是我们要双注入的地方了,之所以叫双注入就是因为在这里要在查询一次,payload如下(例子)
Union select table_schema,count(*) from information_schema.tables group by concat(floor(rand()*2),(select group_concat(table_name) from information_schema.tables where table_schema=database()))
这时候使用group_concat肯能导致查询数据太长查不出啦,可以在后面加
limit 0,1来限制返回行数,第一个数字代表第几行开始,第二个数字代表查几行如下
Union select table_schema,count(*) from information_schema.tables group by concat(floor(rand()*2),(select table_name from information_schema.tables where table_schema=database() limit 0,1))
不报错就可能是查完了,当group by两个都错的时候他就会以一种奇特的方式运行,反到可以查出数据来,所以这时就确定了有几个表
注意双注入要多试几次因为rand可能随机到一样的,直到报错为止