前言

​ 在上次参加一个比赛的时候,第一次在比赛中看到反序列化题目中出现了mb_strpos和mb_substr这两个函数,当时看到那道题也是一头雾水,也不知道怎么做(还是知识太浅薄了),然后结束之后复现了两道题就因为一些事情不了了之了。不过把我气笑的是,那会该复现的下道题就是和这个知识点有关的题,看来还是得搞懂才行,这次又遇到不能放过了。

1.漏洞产生原因

​ mb_strpos和mb_substr以不同的方式处理无效的UTF-8序列,对某些不可见字符的解析差异导致漏洞。

参考链接:

https://www.sonarsource.com/blog/joomla-multiple-xss-vulnerabilities/

https://www.cnblogs.com/gxngxngxn/p/18187578

2.搭建试验环境

​ 在本地运行,然后访问http://127.0.0.1/flag.php

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
highlight_file(__FILE__);
error_reporting(0);
function substrstr($data)
{
$start = mb_strpos($data, "[");
echo $start.'<br>';
$end = mb_strpos($data, "]");
echo $end;
return mb_substr($data, $start, $end + 1 - $start);
}
$key = substrstr($_GET[0]."[welcomectfer]");
echo $key;

3.开始实验

(1)正常情况

尝试随便传参,可以看到,正常情况下,它会输出[]所在的位置下标,以及截取的[]中的内容

8

(2)mb_strpos 增加逃逸一个或多个字符

经过多次尝试终于发现,当传入的参数的值范围在%80~%bf时,mb_strpos返回的[]的下标位置并没有发生变化,可见mb_strpos会自动忽略这些不可见字符,而mb_substr不会忽略,它会将这个不可见字符解析为一个字符,并打印出来,就会导致截断的字符前移一个或多个位置。9

10

(3)在%c0~%c1,两个函数都正常

11

(4)mb_substr 减少逃逸

​ 在%c2~%dfmb_strpos正常解析,而mb_substr会把它与后面连着的一个字符([)都当作一个字符,即最终截断的字符会后移一个位置。!

12

​ 在%e0~%efmb_strpos正常解析,而mb_substr会把它与后面连着的两个字符([w)都当作一个字符,截断的字符会后移两个位置。!!

13

​ 在%f0~%f4mb_strpos正常解析,而mb_substr会把它(%f0)与后面连着的三个字符([we)都当作一个字符,截断的字符会后移三个位置。!!!

14

(5)任意构造

​ 知道了前面的知识之后,我们就可以利用增加逃逸和减少逃逸这两个特性实现任意字符的构造。

​ 暂时我们可以先使用增加逃逸(%9f),减少逃逸(%f0)来构造,当然使用别的也是可以的。

​ 比如我们用%9f来增加逃逸,那么想要逃逸出来几个字符我们在前面就要加上几个 %9f,比如,要逃逸”lalala”,共6个字符,那我们要在前面加上6个%9f,如下图,任意构造成功。!!

15