[练习]sqli-lab31~50

Less31~40

网页卡了几天终于可以上传笔记了。。。


Less-31

与 less-30 相同的解法,是指闭合方式改为id=("1")


Less-32

先数字 + 单引号试试看

less32-1.png

没有报错,但是看下面的提示发现单引号被转义了。

看标题提示是要绕过 addslashes() 函数。

addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。

预定义字符是:

  • 单引号(')
  • 双引号(")
  • 反斜杠(\)
  • NULL

可以利用宽字节绕过,也就是宽字节注入

\'在传输时会被编码成%5c%27,如果网站使用的是gbk编码的话可以在斜杠前添加其他的编码,从而使得这个编码和%5c结合,被编码成汉字,从而绕过该函数对于单引号的转义。而%E6和%df都能和%5C结合编码成汉字。

在单引号前面加上 %E6 就可以和斜杠“\”的 url 编码组合成一个汉字,从而绕过过滤

payload

?id=0%e6' union select 1,2,database() --+

less-33

和 32 完全相同,payload 也适用,不再赘述


less-34

与 less-33 相同,只不过换成了用 POST 传参


Less-35

"why care for addlashes"

这关依旧使用了 addlashes 进行过滤,但是因为是字符型注入,不用使用单引号闭合。所以直接上联合注入就可以了,十分简单。

payload

?id=0 union select 1,2,database() --+

less-36

这关使用的是 mysql_real_escape_string 转义,依旧能使用宽字节注入绕过,可以用 %e6,%df 等进行拼接

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。

下列字符受影响:

  • \x00
  • \n
  • \r
  • \
  • '
  • "
  • \x1a

less36-1.png

payload

?id=0%e6' union select 1,2,database() --+

less-37

同 less-36, 不过使用了 POST 传参


less-38

叠堆注入,堆叠注入是指注入的多条 SQL 语句可以一起执行。MySQL 命令行中, 每一条语句结尾加; 表示语句结束。

局限

1、堆叠注入需要后端 API 是否支持多语句执行,数据库引擎是否支持的限制,如果有一个不支持则无法使用

2、如果后端只返回一条数据则在前端是无法查看到第二条注入语句执行结果。

3、使用堆叠注入前也需要知道数据表的信息

堆叠注入比 UNION 注入更加强大,不仅可以拼接查询语句也可以拼接更新 / 删除语句。

由于显示限制等原因,一般无法直接在前台页面直接显示我们想要查询的内容,不过可以利用这个漏洞来进行修改用户密码等操作。(不过本题依然能使用联合注入来查询内容)

对于叠堆注入,最重要的是 mysqli_multi_query() 函数。

先查一下

less38-1.png

尝试修改密码

?id=1';update users set  pawword ='123456' where username='Dumb' --+

less38-2.png

修改成功


less-39

同 less-38,只不过是字符型注入。


less-40

同 less-38,不过闭合方式改为了id=('value'),同时也屏蔽了报错抛出信息,也可以采用盲注。


总结

这次的做下来涉及的知识点不算很多,

对于宽字节的话可以使用 %df 和 %e6 进行绕过。

关于 addslashes 和 mysql_real_escape_string 的区别

  • mysql_real_escape_string() 并不转义 % 和 _
  • addslashes 是先返回转以后的字符串然后再传输
  • mysql_real_escape_string 转义链接了服务器的内容
  • mysql_real_escape_string 考虑到连接的当前字符集

当时在查资料时看到这么一句话在使用mysql_real_escape_string()时,如何能够安全的防护这种问题,需要将mysql设置为gbk即可。

我的理解是,如果在 mysql 里设置了 gbk 编码,那么 mysql_real_escape_string() 会转义 gbk 编码后的内容,也就是说单引号依旧会被转义。

update set 语句

UPDATE table_name SET column1=value1,column2=value2,... WHERE some_column=some_value;
或
update 表名 set 字段=新值,… where 条件

最近感觉有点浮躁啊,写笔记的过程好煎熬 (`_ っ´)

Less-41~50


依旧是一题叠堆注入,使用单引号闭合。

这次换成插入一条用户数据吧

payload

?id=1'insert into users(id,username,password) values ('123','sammy','123456'); --+

less41-1.png

接着查看一下表是否修改成功

?id=123

less41-2.png

成功插入 sammy 数据。


Less-42

less42-1.png

这次换成了 POST 型,这回就修改上次插入的用户

这次的注入点在 password,在 username 那里试了好久。。。。

payload

';update users set password = 'sammy' where username='sammy'; --+

less42-2.png

登陆成功

less42-3.png

关键源码

$con1 = mysqli_connect($host,$dbuser,$dbpass, $dbname);
   
   $username = mysqli_real_escape_string($con1, $_POST["login_user"]);//在username这里添加了过滤
   $password = $_POST["login_password"];

less-43

闭合方式改为id=('value')外其余均与上题相同


less-44

依旧与 less-42 相同,不过屏蔽了错误信息的抛出,可以进行盲注。感觉对于叠堆注入的话好像也没什么太大的阻碍。。

在 password 的地方可以使用万能密码

1' or '1'='1

less-45

与 less-44 相同,不过闭合方式改为id=('value')


less-46

终于来点新东西了,这题是 order by 注入,注入点在 order by 后面的参数上。

这里简单介绍一下

order by 注入类型判断:

在注入点后面跟上 rand(),如果是数字型的注入点,那么每次查询结果的顺序都会变化,如果是字符型的注入点,那么每次查询结果的顺序都不变化。

order by 与报错注入

利用方式

and (updatexml(1,concat(0x7e,(select database())),0));

order by 与联合查询

order by 使用联合注入的前提是该 sql 查询语句需要使用括号进行了闭合

  • $query = "select * from users order by id $input ";没有使用括号包裹的时候,是无法直接使用 union 查询的。
  • $query = "(select * from users order by id $input) ";使用括号进行包裹的时候,此时是可以进行 union 查询的。

利用方式

(select * from users order by id ) union(select 1,(payload),3);

order by 与盲注

当页面没有展示 MYSQL 的错误信息时,可以根据页面的返回进行盲注

利用方式

select * from users order by id ^(select(select version()) regexp '^5');

简单解释一下就是在 regexp 正则匹配的时候,如果匹配到数据返回 1(00000001) 的时候,此时的 1 会和 id 中的数据的二进制进行异或,按照异或的结果进行升序排列,所以显示的排列会发生变化;反之当进行正则匹配的时候,未匹配到数据返回 0(00000000),此时数字和 0 异或的结果还是本身,所以显示的排列不会发生改变。

总结:当页面排序紊乱时则说明正则匹配到正确数据,页面排序未发生紊乱时则说明正则没有匹配到数据

46 这题直接用报错注入

?sort=1 and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema= database()))) --+

less46-1.png


less-47

在 46 的基础上加入了单引号闭合,其他均相同


less-48

这题屏蔽了报错抛出信息,不能用报错注入了,改用盲注

?sort=id ^(select(select database()) regexp '^security')

排序紊乱,证明查到了正确数据

less48-1.png

后续与其他盲注相同


less-49

屏蔽了错误信息,只能进行时间盲注

?sort=1' and if(length(database())=8,sleep(1),1) --+

less-50

同 less-49,不过是数字型注入


总结

添加数据

insert into 表名 (字段1,字段2,字段3...) value (值1,值2,值3...);

更新数据

update 表名 set 字段1=新值1,字段2=新值... where 条件;

order by 注入

order by 注入类型判断:

在注入点后面跟上 rand(),如果是数字型的注入点,那么每次查询结果的顺序都会变化,如果是字符型的注入点,那么每次查询结果的顺序都不变化。

order by 与报错注入

利用方式

and (updatexml(1,concat(0x7e,(select database())),0));

order by 与联合查询

order by 使用联合注入的前提是该 sql 查询语句需要使用括号进行了闭合

  • $query = "select * from users order by id $input ";没有使用括号包裹的时候,是无法直接使用 union 查询的。
  • $query = "(select * from users order by id $input) ";使用括号进行包裹的时候,此时是可以进行 union 查询的。

利用方式

(select * from users order by id ) union(select 1,(payload),3);

order by 与盲注

当页面没有展示 MYSQL 的错误信息时,可以根据页面的返回进行盲注

利用方式

布尔盲注

select * from users order by id ^(select(select version()) regexp '^5');

时间盲注

?sort=1' and if(length(database())=8,sleep(1),1) --+

简单解释一下就是在 regexp 正则匹配的时候,如果匹配到数据返回 1(00000001) 的时候,此时的 1 会和 id 中的数据的二进制进行异或,按照异或的结果进行升序排列,所以显示的排列会发生变化;反之当进行正则匹配的时候,未匹配到数据返回 0(00000000),此时数字和 0 异或的结果还是本身,所以显示的排列不会发生改变。

总结:当页面排序紊乱时则说明正则匹配到正确数据,页面排序未发生紊乱时则说明正则没有匹配到数据

不知道为什么这几天写笔记都好着磨啊 (;´Д`) 一下午才憋出一篇。。。