这个是学长给的必学的一个网站

[https://www.cnblogs.com/Eddi eMurphy-blogs/p/18310518]( https://www.cnblogs.com/Eddi eMurphy-blogs/p/18310518)

整个都是参考这篇文章和ai协助的


让大王来看看

what

先来理解一下什么是 mb_strpos()mb_substr()

首先mb_strpos()mb_substr() 在面对 非法编码的字符或多字节截断字符 时,行为不一致,可能引发绕过漏洞

他俩是多字节字符串处理函数。为什么叫“多字节”?因为像中文“中”这个字在 UTF-8 中不是一个字节,而是 3 个字节

mb_strpos($str, $needle) 它是用来在字符串中查找某个子字符串的位置的。

1
2
$str = "hello admin";
echo mb_strpos($str, "admin"); // 输出:6

‘mb_substr($str, $start, $length)’它是用来“截取”字符串一部分的,比如从第几个字开始截几个字符。

1
2
$str = "hello admin";
echo mb_substr($str, 6, 5); // 输出:admin

漏洞的来源

这两个函数处理非法字符串时的行为不同

好这时候又有了 什么是非法字符串呢

比如我们本来传的是 UTF-8 编码的字符串,但里面混入了破坏性内容,比如截断的多字节字符:

1
2

$payload = "ad" . "\xe4\xb8" . "min";

\xe4\xb8 是“中文‘中’”这个字符的前两个字节,应该还有第三个字节,结果你故意不给它。这时候这个字符串在 UTF-8 编码下是“非法”的。

具体的差异如下:

mb_strpos() 遇到非法字符会:

报错或返回 false,表示没找到(它识别不了这个破损字符)。

mb_substr() 遇到非法字符会:

照样截取下去,只要你给的位置不是非法字符本身,它就能继续往后取。

比如这个

1
2
3
4
5
$input = $_GET['name'];

if (mb_strpos($input, 'admin') !== false) {
die("不准输入 admin!");
}

看似不让我输入admin 实则不然

我只要再在中间 name=ad%E4%B8min

这个strpos遇到非法字符了所以就结束了 实现一个绕过

好的然后我们开始看佬的博客

这是提到的黄河流域的源码

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.'<br>';
return mb_substr($data, $start, $end + 1 - $start);
}
$key = substrstr($_GET[0]."[welcome".$_GET[1]."sdpcsec]");
echo $key;

好像是之前学的字符串逃逸 总而言之思路就是说

%9f可以造成字符串往后移动一位,因为它不解析,%f0可以把字符串吞掉三位

吼的我们来看一下

看不了 不知道为什么我的这个不回显哈

image-20250709203320228

我的只有这两个地方会变。。。。总之知道是会变的 ok我们继续往下

我们知道了这两个东西的作用

由此我们可以用这两个玩意进行任意字符串构造:

image-20250709212809871

比较重要的是介个 就是说我想实现后面这个命令 只要让前面的%9f给他顶掉就可以了