sqli学习笔记-01
声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任。
主要复习一下sqli,根据sqli-lab来进行实操复习的(重发一下昨天的,昨天的有个表哥有问题)
git clone [email protected]:juananpe/sqli-lab.gitcd sqli-lab
#需要花些时间,耐心等待
docker-compose up -d
本地浏览器输入:
http://127.0.0.1:8888/
从服务器接收到的响应
如何处理输入的 SQL 查询
基于程度和顺序(哪里发生了影响)
一阶注射:输入的注射语句直接对web产生了影响 二阶注射:类似于存储型XSS,无法直接对web产生影响,但是会间接产生危害
介绍几个常用函数:
主要是concat(),group_concat(),concat_ws() 这三个函数
不使用字符串连接函数时,
SELECT id,name FROM info LIMIT 1;的返回结果为 +----+--------+ | id | name | +----+--------+ | 1 | BioCyc | +----+--------+
id | name |
---|---|
1 | BioCyc |
但是这里存在的一个问题是当使用union联合注入时,我们都知道,联合注入要求前后两个选择的列数要相同,这里id,name是两个列,当我们要一个列的时候,(当然不排除你先爆出id,再爆出name,分两次的做法)该怎么办?----> concat()
concat()语法及使用特点:
CONCAT(str1,str2,…)
返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。可以有一个或多个参数。使用示例: SELECT CONCAT(id, ',', name) AS con FROM info LIMIT 1;
返回结果为
con |
---|
1,BioCyc |
一般的我们都要用一个字符将各个项隔开,便于数据的查看。
SELECT CONCAT('My', NULL, 'QL');
返回结果为
CONCAT('My', NULL, 'QL') |
---|
NULL |
CONCAT_WS()
代表CONCAT With Separator
,是CONCAT()的特殊形式。第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。如果分隔符为 NULL,则结果为 NULL。函数会忽略任何分隔符参数后的 NULL 值。但是CONCAT_WS()不会忽略任何空字符串。(然而会忽略所有的 NULL)。
concat()语法及使用特点:
CONCAT_WS(separator,str1,str2,…)
Separator为字符之间的分隔符
使用示例: SELECT CONCAT_WS('_',id,name) AS con_ws FROM info LIMIT 1;
返回结果为
con_ws |
---|
1_BioCyc |
SELECT CONCAT_WS(',','First name',NULL,'Last Name');返回结果为
CONCAT_WS(',','First name',NULL,'Last Name') |
---|
First name,Last Name |
GROUP_CONCAT函数返回一个字符串结果,该结果由分组中的值连接组合而成。使用表info作为示例,其中语句SELECT locus,id,journal FROM info WHERE locus IN('AB086827','AF040764');
的返回结果为
locus | id | journal |
---|---|---|
AB086827 | 1 | Unpublished |
AB086827 | 2 | Submitted (20-JUN-2002) |
AF040764 | 23 | Unpublished |
AF040764 | 24 | Submitted (31-DEC-1997) |
1、使用语法及特点: GROUP_CONCAT([DISTINCT] expr [,expr ...] [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] [,col ...]] [SEPARATOR str_val])
在 MySQL 中,你可以得到表达式结合体的连结值。通过使用 DISTINCT 可以排除重复值。如果希望对结果中的值进行排序,可以使用 ORDER BY 子句。SEPARATOR 是一个字符串值,它被用于插入到结果值中。缺省为一个逗号 (","),可以通过指定 SEPARATOR "" 完全地移除这个分隔符。可以通过变量 group_concat_max_len 设置一个最大的长度。在运行时执行的句法如下: SET [SESSION | GLOBAL] group_concat_max_len = unsigned_integer;
如果最大长度被设置,结果值被剪切到这个最大长度。如果分组的字符过长,可以对系统参数进行设置:SET @@global.group_concat_max_len=40000;
2、使用示例:语句 SELECT locus,GROUP_CONCAT(id) FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus;
的返回结果为
locus | GROUP_CONCAT(id) |
---|---|
AB086827 | 1,2 |
AF040764 | 23,24 |
语句 SELECT locus,GROUP_CONCAT(distinct id ORDER BY id DESC SEPARATOR '_') FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus;
的返回结果为
locus | GROUP__CONCAT(distinct id ORDER BY id DESC SEPARATOR '_') |
---|---|
AB086827 | 2_1 |
AF040764 | 24_23 |
语句SELECT locus,GROUP_CONCAT(concat_ws(', ',id,journal) ORDER BY id DESC SEPARATOR '. ') FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus;
的返回结果为
locus | GROUP__CONCAT(concat_ws(', ',id,journal) ORDER BY id DESC SEPARATOR '. ') |
---|---|
AB086827 | 2, Submitted (20-JUN-2002). 1, Unpublished |
AF040764 | 24, Submitted (31-DEC-1997) . 23, Unpublished |
3、sql注入中一般使用方法
列出所有的数据库
select group_concat(schema_name) from information_schema.schemata
列出某个库当中所有的表
select group_concat(table_name) from information_schema.tables where table_schema='xxxxx'
注意: --+
可以用#替换,url 提交过程中 Url 编码后的#为%23
or 1=1--+
'or 1=1--+
"or 1=1--+
)or 1=1--+
')or 1=1--+
") or 1=1--+
"))or 1=1--+
一般的代码为:
$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
此处考虑两个点,一个是闭合前面你的 ‘ ,另一个是处理后面的 ‘,一般采用两种思 路,闭合后面的引号或者注释掉,注释掉采用--+
或者 #(%23)
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的 列的顺序必须相同。
SQL UNION 语法
SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2
注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SQL UNION ALL 语法
SELECT column_name(s) FROM table_name1
UNION ALL
SELECT column_name(s) FROM table_name2
另外,UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
Select * from users where id=1 and 1=1;
这条语句为什么能够选择出 id=1 的内容,and 1=1 到底起作用了没有?这里就要清楚 sql 语句执行顺序了。同时这个问题我们在使用万能密码的时候会用到。
Select * from admin where username=’admin’ and password=’admin’
我们可以用 ’or 1=1#
作为密码输入。原因是为什么?
这里涉及到一个逻辑运算,当使用上述所谓的万能密码后,构成的 sql 语句为: Select * from admin where username=’admin’ and password=’’or 1=1#’
Explain:上面的这个语句执行后,我们在不知道密码的情况下就登录到了 admin 用户了。原因是在 where 子句后,我们可以看到三个条件语句 username=’admin’ and password=’’or 1=1
。三个条件用 and 和 or 进行连接。在 sql 中,我们 and 的运算优先 级大于 or 的元算优先级。因此可以看到 第一个条件(用 a 表示)是真的,第二个条件(用 b表示)是假的,aand b=false,第一个条件和第二个条件执行and后是假,再与第三 个条件 or 运算,因为第三个条件 1=1 是恒成立的,所以结果自然就为真了。因此上述的语 句就是恒真了。
3的意思是 id=1 条件与 1 进行&
位操作,id=1 被当作 true,与 1 进行 & 运算 结果还是 1, 再进行=操作,1=1,还是 1(ps:&的优先级大于=)
我们的数据库存储的数据按照上图的形式,一个数据库当中有很多的数据表,数据表当中有 很多的列,每一列当中存储着数据。我们注入的过程就是先拿到数据库名,在获取到当前数 据库名下的数据表,再获取当前数据表下的列,最后获取数据。
Mysql 有一个系统数据库 information_schema,存储着所有的数据库的相关信息,一般的, 我们利用该表可以进行一次完整的注入。以下为一般的流程。
猜数据库 select schema_name from information_schema.schemata
猜某库的数据表 select table_name from information_schema.tables where table_schema=’xxxxx’
猜某表的所有列 Select column_name from information_schema.columns where table_name=’xxxxx’
获取某列的内容Select *** from ****
好了,一些基本的基础知识就暂时讲到这里
★
欢 迎 加 入 星 球 !
代码审计+免杀+渗透学习资源+各种资料文档+各种工具+付费会员
进成员内部群
星球的最近主题和星球内部工具一些展示
关 注 有 礼
还在等什么?赶紧点击下方名片关注学习吧!
推荐阅读