标题: 我的Java反序列化学习之路 创建: 2020-05-26 14:53 更新: 链接: https://scz.617.cn/web/202005261453.txt 这是一篇Java反序列化初学者的吹牛贴,没有任何有效内容。其中大部分内容分散在 这三处: https://scz.617.cn/misc https://scz.617.cn/network https://scz.617.cn/web 人一般只会吹嘘自己并不擅长的东西,因为TA并不真正了解而懂得深浅进而缺乏敬畏。 你见我吹嘘过SMB吗?但我经常在微博上晒英语学习打卡记录。 初始接触Java反序列化,是2019年11月,猝不及防遭遇CVE-2019-6980(Zimbra),狠 狠打击了我。 决定好好学学这个方向。我是带着一种我花开罢百花杀的神经病思维开始的,当然, 我们都知道,黄巢他死了。只当是个笑话。 展示一下6个月来Java反序列化学习之路,其中不少章节已在个人主页不同篇章中分 享过。 如果有新手想入门Java反序列化,不妨也这样神经病一遭,或许真就入门了呢? ========================================================================== 标题: WEB系列(55)--学习Java反序列化漏洞 创建: 2019-11-25 15:10 更新: 2020-05-26 14:45 -------------------------------------------------------------------------- 目录: ☆ Serializable接口详解 1) SerializeCustomer.java 2) DeserializeCustomer.java 3) 序列化文件格式 3.1) 手工解码序列化文件 3.2) SerializationDumper 4) Customer1Demo.java 5) SerializeCustomer2.java 6) DeserializeCustomer2.java 7) 强行序列化static和transient变量 7.1) SerializeCustomer3.java 7.2) DeserializeCustomer3.java 7.3) SerializeCustomer4.java 7.4) DeserializeCustomer4.java 7.5) customer4.bin对SerializationDumper的影响 7.6) 相关调用栈回溯 7.6.1) ObjectStreamClass. 7.6.2) Customer3.readObject() 7.6.3) ObjectInputStream.resolveClass() 7.6.4) 简化版调用关系 7.7) 相关源码分析 7.7.1) ObjectStreamClass.java 7.7.2) ObjectInputStream.java 7.8) 序列化/反序列化过程中的回调函数 7.8.1) SerializeCustomer5.java 7.8.2) DeserializeCustomer5.java 7.8.3) 回调函数出场顺序 7.9) 神秘的readObjectNoData() 7.9.1) SerializeCustomer6.java 7.9.2) DeserializeCustomer6.java 7.10) readObject vs readUnshared 7.10.1) SerializeCustomer11.java 7.10.2) DeserializeCustomer11.java 7.10.3) 分岔发生在readOrdinaryObject(unshared) 8) Commons Collections反序列化漏洞 8.1) ReflectExec.java 8.2) TransformedMap利用链 8.2.1) TransformedMapExec.java 8.2.2) sun.reflect.annotation.AnnotationInvocationHandler 8.2.3) VulnerableServer.java 8.2.4) EvilClientWithTransformedMap.java 8.2.5) 测试 8.2.6) 简化版调用关系 8.2.7) 为什么Map的key必须是"value"这个字符串 8.2.8) AnnotationInvocationHandler()第一形参还能使用其他接口吗 8.2.9) EvilClientWithTransformedMap2.java 8.3) LazyMap利用链 8.3.1) LazyMapExec.java 8.3.2) EvilClientWithLazyMap.java 8.3.3) 测试 8.3.4) 简化版调用关系 8.3.5) AnnotationInvocationHandler()第一形参还能使用其他接口吗 8.3.6) EvilClientWithLazyMap2.java 8.3.7) EvilClientWithLazyMap3.java 8.3.8) ysoserial/CommonsCollections1 8.3.9) 8u232为什么失败 8.3.10) commons-collections4-4.0的变化 8.3.11) EvilClientWithLazyMap4.java 8.3.12) 字符串的哈希 8.3.13) LazyMapExecWithHashtable.java 8.3.14) 简化版调用关系 8.3.15) ysoserial/CommonsCollections7 8.4) TiedMapEntry利用链 8.4.1) TiedMapEntryExec.java 8.4.2) ConcurrentHashMapExec.java 8.4.3) 简化版调用关系 8.4.4) EvilClientWithConcurrentHashMap.java 8.4.5) TiedMapEntryExecWithHashSet.java 8.4.6) 简化版调用关系 8.4.7) ysoserial/CommonsCollections6 8.5) Apache Commons Collections 3.2.2的修补方案 8.6) 利用java.net.URLClassLoader干复杂的事 8.6.1) ConnectShellEx.java 8.6.2) EvilURLClassLoader.java 8.6.3) 测试EvilURLClassLoader 8.6.4) EvilURLClassLoaderWithTransformer.java 8.6.5) 测试EvilURLClassLoaderWithTransformer 8.6.6) EvilURLClassLoaderWithConcurrentHashMap.java 8.6.7) 测试EvilURLClassLoaderWithConcurrentHashMap 8.7) BadAttributeValueExpException利用链 8.7.1) EvilClientWithBadAttributeValueExpException.java 8.7.2) 简化版调用关系 8.7.3) ysoserial/CommonsCollections5 8.8) TemplatesImpl利用链 8.8.1) JacksonExploit.java 8.8.2) TemplatesImplExec.java 8.8.3) 简化版调用关系 8.8.4) ysoserial/CommonsCollections2 8.8.5) TemplatesImplExecWithTrAXFilter.java 8.8.6) 简化版调用关系 8.8.7) ysoserial/CommonsCollections3 8.8.8) TemplatesImplExecWithTrAXFilter4.java 8.8.9) 简化版调用关系 8.8.10) ysoserial/CommonsCollections4 8.8.11) commons-collections4-4.1的变化 8.8.12) TemplatesImplExecWithBeanComparator.java 8.8.13) 简化版调用关系 8.8.14) ysoserial/CommonsBeanutils1 8.8.15) 能否用TreeSet替换PriorityQueue 8.9) DefaultedMap利用链 8.9.1) DefaultedMapExecWithBadAttributeValueExpException.java 8.9.2) 简化版调用关系 9) URLDNS 9.1) HashMapURLDNS.java 9.2) 简化版调用关系 9.3) ysoserial.payloads.URLDNS 10) MozillaRhino反序列化漏洞 10.1) org.mozilla.javascript.NativeError 10.1.0) JacksonExploit.java 10.1.1) NativeErrorExec.java 10.1.2) 简化版调用关系 10.1.3) NativeErrorExec2.java 10.1.4) 调试器对被调试进程的挠动 10.1.5) ysoserial.payloads.MozillaRhino1 10.2) org.mozilla.javascript.NativeJavaObject 10.2.1) NativeJavaObjectExec.java 10.2.2) 简化版调用关系 10.2.3) ysoserial.payloads.MozillaRhino2 10.2.4) NativeJavaObjectExec6.java 10.2.5) CVE-2019-6980(Zimbra) ☆ Externalizable接口详解 1) SerializeCustomer7.java 2) DeserializeCustomer7.java 3) 解码customer7.bin 4) Customer7.readExternal()调用栈回溯 ☆ XMLEncoder/XMLDecoder 1) Customer8.java 2) SerializeCustomer8.java 3) DeserializeCustomer8.java 4) Customer8.setName()调用栈回溯 4.1) 相关源码分析 4.2) 简化版调用关系 5) SerializeProcessBuilder.java(失败) 6) ProcessBuilder.xml 7) DeserializeProcessBuilder.java 8) ProcessBuilder.start()调用栈回溯 9) Customer9.java 10) customer9.xml 10.1) XML中可用关键字 11) DeserializeCustomer9.java 12) Runtime.xml 13) DeserializeRuntime.java 14) SerializeHashMap.java 15) DeserializeHashMap.java 15.1) HashMap.put()调用栈回溯 ☆ XStream 1) Customer10Parent.java 2) Customer10.java 3) SerializeCustomer10.java 4) DeserializeCustomer10.java 5) DeserializeCustomer10Secure.java 6) SerializeSortedSet.java(失败) 7) 基于sorted-set的PoC(sorted-set.xml) 7.1) TreeSetConverter 7.2) SingleValueConverterWrapper 7.3) DynamicProxyConverter 7.4) ReflectionConverter 7.5) CollectionConverter 8) DeserializeUsingXStream.java 9) ProcessBuilder.start()调用栈回溯 10) DeserializeUsingXStream1.java 10.1) xstream-1.4.11.1.jar的修补方案(InternalBlackList) 11) XStream Converters 11.1) Person.java 11.2) Birthday.java 11.3) BirthdayConverter.java 11.4) SerializeBirthday.java 11.5) DeserializeBirthday.java 12) 基于tree-map的PoC(tree-map.xml) 12.1) TreeMapConverter 12.2) ProcessBuilder.start()调用栈回溯 13) CVE-2013-7285 13.1) TicketService.xml 13.2) DeserializeTicketService.java 13.3) ProcessBuilder.start()调用栈回溯 13.4) 失败的测试用例 13.4.1) TicketStation.xml 13.4.2) TicketStationConverter.java 13.4.3) DeserializeTicketStation.java 14) CVE-2016-0792(XStream+Groovy) 14.1) map_old.xml 14.2) map.xml 14.2.1) ProcessBuilder.start()调用栈回溯 14.2.2) MapConverter 14.2.3) ReflectionConverter 14.2.4) SingleValueConverterWrapper 14.2.5) ReflectionConverter 14.2.6) ReflectionConverter 14.2.7) CollectionConverter 14.2.8) SingleValueConverterWrapper 14.2.9) 简化版调用关系 14.3) CVE-2016-0792漏洞利用原理 14.3.1) 与InternalBlackList无关 14.4) groovy-all-2.4.9.jar无法利用成功 15) 基于linked-hash-set的PoC(linked-hash-set.xml) 15.1) CollectionConverter for java.util.LinkedHashSet 15.2) ReflectionConverter for jdk.nashorn.internal.objects.NativeString 15.3) ReflectionConverter for com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data 15.4) ReflectionConverter for javax.activation.DataHandler 15.5) ReflectionConverter for com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource 15.6) ReflectionConverter for javax.crypto.CipherInputStream 15.7) ReflectionConverter for javax.crypto.NullCipher 15.8) ReflectionConverter for javax.imageio.spi.FilterIterator 15.9) ReflectionConverter for java.util.Collections$EmptyIterator 15.10) ReflectionConverter for java.lang.ProcessBuilder 15.11) CollectionConverter for java.util.ArrayList 15.12) SingleValueConverterWrapper for java.lang.String 15.13) SingleValueConverterWrapper for java.lang.Boolean 15.14) ReflectionConverter for javax.imageio.ImageIO$ContainsFilter 15.15) JavaMethodConverter for java.lang.reflect.Method 15.16) ReflectionConverter for java.lang.Object 15.17) ReflectionConverter for java.lang.ProcessBuilder$NullInputStream 15.18) EncodedByteArrayConverter for byte[] 15.19) ProcessBuilder.start()调用栈回溯 ☆ SnakeYaml 1) 自己编译SnakeYaml 2) SerializeCustomer12.java 3) DeserializeCustomer12.java 4) DeserializeUsingSnakeYaml.java 4.1) yaml_http.xml 4.1.1) java.net.URL.(java.lang.String)调用栈回溯 4.1.2) javax.script.ScriptEngineManager:123 4.1.3) jdk.nashorn.api.scripting.NashornScriptEngineFactory. 4.2) yaml_http_2.xml 5) 执行命令 5.1) AwesomeScriptEngineFactory.java 5.2) yaml_exec.jar 5.2.1) ServiceLoader 5.3) yaml_exec.xml 5.4) AwesomeScriptEngineFactory.调用栈回溯 5.5) 无jar包执行命令 5.5.1) yaml_http_root.xml 5.6) 不用构造函数转用静态代码块 5.6.1) AwesomeScriptEngineFactory1.java 5.6.2) yaml_exec_1.xml 5.6.3) java.lang.Runtime.exec()调用栈回溯 6) 缓解措施 6.1) DeserializeUsingSnakeYamlSecure.java 6.2) DeserializeUsingSnakeYamlInsecure.java 7) Customer13.java 8) SerializeCustomer13.java 8.1) 序列化时对get*()的回调 9) DeserializeCustomer13.java 9.1) 反序列化时对set*()的回调 ☆ Jackson 1) SerializeCustomer14.java 2) DeserializeCustomer14.java 3) DefaultTyping 3.1) JAVA_LANG_OBJECT 3.1.1) SerializeCustomer15.java 3.1.2) DeserializeCustomer15.java 3.2) OBJECT_AND_NON_CONCRETE 3.2.1) SerializeCustomer16.java 3.2.2) DeserializeCustomer16.java 3.3) NON_CONCRETE_AND_ARRAYS 3.3.1) SerializeCustomer17.java 3.3.2) DeserializeCustomer17.java 3.4) NON_FINAL 3.4.1) SerializeCustomer18.java 3.4.2) DeserializeCustomer18.java 3.4.3) 调用栈回溯 3.4.3.1) Customer18ExtB. 3.4.3.2) Customer18ExtB.setGender 4) JsonTypeInfo 4.1) JsonTypeInfo.Id.NONE 4.2) JsonTypeInfo.Id.CLASS 4.2.1) SerializeCustomer19.java 4.2.2) DeserializeCustomer19.java 4.2.3) 调用栈回溯 4.2.3.1) Customer19ExtB. 4.2.3.2) Customer19ExtB.setGender 4.3) JsonTypeInfo.Id.MANIMAL_CLASS 4.4) JsonTypeInfo.Id.NAME 4.5) JsonTypeInfo.Id.CUSTOM 5) CVE-2017-7525 5.1) JacksonExploit.java 5.2) TemplatesImpl.xml 5.2.1) transletBytecodes属性 5.2.2) outputProperties属性 5.2.3) transletName属性 5.3) 调用栈回溯 5.3.1) TemplatesImpl.defineTransletClasses 5.3.2) java.lang.Runtime.exec 5.4) 简化版调用关系(Jackson 2.7.9+Java 1.8.0_40) 5.5) 为什么Java 1.8.0_232无法成功 5.5.1) TemplatesImpl_bad_1.xml 5.6) Jackson 2.7.9.1的修补方案 6) CVE-2017-17485 6.1) spring_evil.xml 6.2) FileSystemXmlApplicationContext.xml 6.2.1) java.lang.ProcessBuilder.start()调用栈回溯 6.2.2) 简化版调用关系 6.3) ClassPathXmlApplicationContext.xml 6.3.1) java.lang.ProcessBuilder.start()调用栈回溯 6.3.2) 简化版调用关系 6.4) Jackson 2.7.9.2的修补方案 7) CVE-2017-15095 7.1) Jackson_JdbcRowSetImpl.json 7.2) 测试 7.3) 简化版调用关系 8) CVE-2019-12086 8.1) 恶意MySQL Server读取MySQL Client端文件 8.1.1) 抓包"LOAD DATA LOCAL INFILE" 8.1.2) rogue_mysql_server.py 8.1.3) rogue_mysql_server_multi.py 8.2) MiniAdmin.xml 8.2.1) jdbc.NonRegisteringDriver.connect()调用栈回溯 8.2.2) 攻击中的MySQL登录认证报文 8.3) MySQL Connector/J 8.0.15的修补方案 8.4) Jackson 2.9.9的修补方案 9) CVE-2019-12814(XXE) 9.1) XSLTransformer.xml 9.2) FtpURLConnection.checkURL()调用栈回溯 9.3) Jackson 2.9.9.1的修补方案 10) 基于XPathParser的利用链(XXE) 10.1) XPathParser.xml 10.2) FtpURLConnection.checkURL()调用栈回溯 10.3) Jackson 2.7.9.4的修补方案 11) CVE-2020-8840(JNDI注入) 11.0) JacksonDeserialize.java 11.1) Jackson_JndiConverter.json 11.2) 测试 11.3) 简化版调用关系 11.4) Jackson 2.9.10.3的修补方案 12) CVE-2018-5968(JNDI注入) 12.1) Jackson_JndiDataSourceFactory.json 12.2) Jackson_StatisticsService.json 12.3) Jackson 2.9.4的修补方案 13) org.apache.tomcat.dbcp.dbcp.BasicDataSource 13.0) JacksonDeserialize2.java 13.1) Jackson_BasicDataSource.json 13.1.1) 简化版调用关系 13.2) org.apache.tomcat.dbcp.dbcp2.BasicDataSource 13.2.1) Jackson_BasicDataSource2.json 13.3) Jackson 2.9.4的修补方案 14) CVE-2019-14540(JNDI注入) 14.1) Jackson_HikariConfig.json ☆ Fastjson 1) SerializeCustomer20.java 2) DeserializeCustomer20.java 3) SerializeCustomer21.java 4) DeserializeCustomer21.java 4.1) 无set*()的私有成员在反序列化过程中如何被赋值 4.2) JavaBeanInfo.build() 5) 基于TemplatesImpl的利用链 5.0) FastjsonDeserialize.java 5.1) Fastjson_TemplatesImpl.json 5.1.1) _bytecodes属性 5.1.2) _outputProperties属性 5.1.3) _name属性 5.1.4) _tfactory属性 5.2) 调用栈回溯 5.3) 若干细节 5.3.1) _bytecodes为什么需要BASE64编码 5.3.2) _outputProperties与getOutputProperties()如何产生关联 5.4) 简化版调用关系(Fastjson 1.2.24+Java 1.8.0_232) 5.5) Fastjson 1.2.25的修补方案 6) com.sun.rowset.JdbcRowSetImpl 6.1) Fastjson_JdbcRowSetImpl.json 6.2) 测试 6.3) 简化版调用关系 7) 各种补丁绕过 7.1) 1.2.25-1.2.41补丁绕过 7.1.1) Fastjson_JdbcRowSetImpl_1.json 7.1.2) 测试 7.1.3) 绕过原理 7.2) 1.2.25-1.2.42补丁绕过 7.2.1) Fastjson_JdbcRowSetImpl_2.json 7.2.2) 1.2.42的变化(用了哈希匹配) 7.2.3) FastjsonTypenameHash.java 7.2.4) FastjsonTypenameHash2.java 7.3) 1.2.25-1.2.43补丁绕过 7.3.1) Fastjson_JdbcRowSetImpl_3.json 7.3.2) 1.2.43的变化 7.3.3) 简化版调用关系 7.4) 1.2.25-1.2.45补丁绕过 7.4.1) Fastjson_JndiDataSourceFactory.json 7.4.2) 1.2.45的变化 7.4.3) 简化版调用关系 7.5) 1.2.25-1.2.47补丁绕过 7.5.1) Fastjson_JdbcRowSetImpl_5.json 7.5.2) 简化版调用关系 7.5.3) Fastjson_JdbcRowSetImpl_6.json 7.6) 1.2.48的变化 8) org.apache.tomcat.dbcp.dbcp.BasicDataSource 8.0) FastjsonDeserialize2.java 8.1) EvilCode.java 8.2) BCELEncode.java 8.3) BCELDecode.java 8.4) Fastjson_BasicDataSource.json 8.5) 简化版调用关系 8.6) 为什么FastjsonDeserialize未能得手 8.7) 1.2.25的修补方案 8.7.1) Fastjson_BasicDataSource_bad_0.json 8.7.2) Fastjson_BasicDataSource_bad_1.json 8.7.3) Fastjson_BasicDataSource_bad_2.json 8.7.4) Fastjson_BasicDataSource_bad_3.json 8.8) org.apache.tomcat.dbcp.dbcp2.BasicDataSource 8.8.1) Fastjson_BasicDataSource2.json 8.9) 通用性更好的PoC 8.9.1) Fastjson_BasicDataSource3.json 8.9.2) 测试 8.9.3) 简化版调用关系 8.10) 转储反序列化过程中动态生成的类 8.11) 通过$ref指定被触发的getter 8.11.1) Fastjson_BasicDataSource4.json 8.11.2) 测试 8.11.3) 复杂版调用关系 8.11.4) 简化版调用关系 8.11.5) Fastjson_BasicDataSource5.json 8.12) Fastjson_BasicDataSource6_bad.json 9) JSONLexerBase.scanString OOM DoS 9.1) Fastjson_JSONLexerBase_DoS.json 9.2) 简化版调用关系 9.3) 相关源码 9.4) Fastjson_JSONLexerBase_DoS_bad.json 10) Fastjson反序列化过程中触发域名解析请求 10.1) Fastjson_InetAddress_DNS.json 10.2) 简化版调用关系 10.3) 1.2.48的修补方案 10.3.1) TypeUtils.getClassFromMapping() and IdentityHashMap.findClass() 10.4) Fastjson_Inet4Address_DNS.json 10.5) Fastjson_Inet6Address_DNS.json 10.6) Fastjson_InetSocketAddress_DNS.json 10.7) 简化版调用关系 10.8) Fastjson_URL_DNS.json 10.9) 简化版调用关系 10.10) DNSLog Server 11) org.apache.xbean.propertyeditor.JndiConverter 11.1) Fastjson_JndiConverter.json 11.1) 1.2.66的修补方案 11.2) 如何知道被哪个黑名单命中 12) org.hibernate.jmx.StatisticsService 13) com.mchange.v2.c3p0.JndiRefForwardingDataSource 13.1) Fastjson_JndiRefForwardingDataSource.json 13.2) 简化版调用关系 14) org.springframework.jndi.support.SimpleJndiBeanFactory 14.1) Fastjson_SimpleJndiBeanFactory.json 14.2) 简化版调用关系 14.3) Fastjson_SimpleJndiBeanFactory2.json 14.4) 简化版调用关系 15) org.apache.shiro.jndi.JndiObjectFactory 15.0) 排错 15.1) Fastjson_JndiObjectFactory.json 16) br.com.anteros.dbcp.AnterosDBCPConfig 16.0) 如何寻找依赖库 16.1) Fastjson_AnterosDBCPConfig.json 16.2) Fastjson_AnterosDBCPConfig2.json 17) org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup 17.1) Fastjson_CacheJndiTmLookup.json 18) com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig 18.1) Fastjson_JtaTransactionConfig.json 19) org.apache.commons.configuration.JNDIConfiguration 19.1) Fastjson_JNDIConfiguration.json 19.2) org.apache.commons.configuration2.JNDIConfiguration 19.2.1) Fastjson_JNDIConfiguration2.json 20) 1.2.36-1.2.62正则表达式DoS 20.1) Fastjson_RegMatchSegement_DoS.json 20.2) Fastjson_RlikeSegement_DoS.json 20.3) 调用栈回溯 21) com.zaxxer.hikari.HikariConfig 21.1) Fastjson_HikariConfig.json 22) com.mchange.v2.c3p0.WrapperConnectionPoolDataSource 22.0) GenerateCommonsCollections7.java 22.1) Fastjson_WrapperConnectionPoolDataSource.json 22.2) 简化版调用关系 ☆ marshalsec 1) 自己编译marshalsec 2) marshalsec.SnakeYAML 3) marshalsec.Jackson ☆ ysoserial 1) 自己编译ysoserial ☆ Java执行外部命令 1) Exec.java 2) 为什么(java Exec 'sh -c "uname -a"')会失败 2.1) 捕捉异常查看命令行切割方式 2.2) java.util.StringTokenizer 3) 神奇的$@ 4) Bash Brace Expansion ☆ Java设计模式之代理模式 1) 静态代理模式 1.1) TicketService.java 1.2) TicketStation.java 1.3) TicketStationProxy.java 1.4) TicketServiceClient.java 2) 动态代理模式 2.1) GeneralInvocationHandler.java 2.2) TicketServiceClient1.java 2.3) GeneralInvocationHandler2.java 2.4) TicketServiceClient2.java 2.5) TicketStation.SellTicket()调用栈回溯 2.6) 获取动态生成的"com.sun.proxy.$Proxy0" 2.7) 反编译动态生成的"com.sun.proxy.$Proxy0" 2.8) 其他方案获取"com.sun.proxy.$Proxy0" 3) 简单对比静态代理模式、动态代理模式 4) cglib动态代理 4.1) GeneralCglibProxy.java 4.2) TicketServiceClient3.java 4.3) TicketStation.SellTicket()调用栈回溯 4.4) 获取动态生成的"TicketStation$$EnhancerByCGLIB$$abea2160" 4.5) 反编译动态生成的类 4.6) 其他方案获取动态生成的类 4.6.1) GeneralCglibProxy4.java 4.6.2) TicketServiceClient4.java 5) 简单对比Java原生动态代理、cglib动态代理 ☆ Java RMI 1) HelloRMIInterface.java 2) HelloRMIInterfaceImpl.java 3) HelloRMIServer.java 4) HelloRMIClient.java 5) HelloRMIServer/HelloRMIClient不在同一台主机上时的幺蛾子 5.0) 转储"com.sun.proxy.$Proxy0" 5.1) Java RMI与DCE/MS RPC、ONC/Sun RPC 5.1.1) HelloRMI_1.cap部分报文解码 5.2) HelloRMIServer2.java 5.3) 深入LocateRegistry.createRegistry() 5.4) 深入new HelloRMIInterfaceImpl() 5.5) 深入r.rebind() 6) 侦听指定IP、指定PORT 6.1) HelloRMIServerSocketFactoryImpl.java 6.2) HelloRMIInterfaceImpl3.java 6.3) HelloRMIServer3.java 6.4) 另一种方案 6.4.1) HelloRMIInterfaceImpl8.java 6.4.2) HelloRMIDynamicServer8.java 7) java.rmi.Naming 7.1) HelloRMIServer4.java 7.2) HelloRMIClient4.java 7.3) Naming.rebind 7.4) Naming.lookup 8) 分离周知端口与动态端口 8.1) HelloRMIWellknownServer.java 8.2) HelloRMIDynamicServer.java 8.3) 周知端口与动态端口不在同一台主机上时的幺蛾子 8.4) 周知端口与动态端口不在同一台主机上时的网络通信报文 8.5) HelloRMIDynamicServer2.java 9) JDK自带RMI相关工具 9.1) rmiregistry 9.1.1) inside rmiregistry 9.1.2) 扫描识别rmiregistry 9.2) rmic 9.3) rmid 10) 从周知端口获取所有动态端口信息 10.1) rmiinfo.java 10.2) rmi-dumpregistry.nse 10.2.1) HelloRMI_6.cap部分报文解码 10.3) rmiregistry_detect.nasl 10.3.1) HelloRMI_7.cap部分报文解码 10.4) jndiinfo.java 11) JNDI 11.1) HelloRMIDynamicServer5.java (JNDI+RMI) 11.2) HelloRMIClient5.java 11.3) HelloRMIDynamicServer6.java 11.4) HelloRMIClient6.java 12) RMI-IIOP 12.1) HelloRMIInterfaceImpl7.java 12.1.1) rmic 12.2) HelloRMIDynamicServer7.java (JNDI+CORBA) 12.3) HelloRMIClient7.java 12.4) orbd 12.4.1) inside orbd 12.5) 测试RMI-IIOP 12.5.1) HelloRMIDynamicServer7/HelloRMIClient7不在同一台主机上时的幺蛾子 12.6) RMI-IIOP vs RMI 13) "java.rmi.server.codebase"的误会 13.1) HelloRMIInterface.java 13.2) HelloRMIInterfaceImpl.java 13.3) HelloRMIDynamicServer9.java 13.4) HelloRMIClient9.java 13.5) jndi.policy 13.6) 编译 13.7) 测试 13.7.1) Client/Server位于同一主机同一目录(成功) 13.7.2) Client/Server位于同一主机不同目录(失败) 13.7.3) 调试分析"13.7.2" 14) Dynamic code downloading using Java RMI 14.1) ParamInterface.java 14.2) MethodInterface.java 14.3) MethodInterfaceImpl.java 14.4) MethodInterfaceServer.java 14.5) ParamInterfaceStringImpl.java 14.6) MethodInterfaceClient.java 14.7) jndi.policy 14.8) 编译 14.9) 测试 14.9.1) Client/Server位于同一主机同一目录 14.9.2) Client/Server/rmiregistry位于同一主机不同目录 14.10) 相关stackoverflow问答点评 14.11) server.policy 14.12) client.policy 14.13) MethodInterfaceClient1.java (more about SecurityManager) 14.14) 什么情况下需要使用远程codebase 15) Binding a Remote Object by Using a Reference 15.1) RemoteReferenceServer.java 15.2) 测试 15.3) 切割RemoteReferenceServer 15.3.1) RemoteReferenceServerA.java 15.3.2) RemoteReferenceServerB.java ☆ Java RMI中的绑定与查询 1) 展示几个现象 1.1) 现象1 1.2) 现象2 1.3) 现象3 2) RMI架构简述 3) Remote实例 4) 动态端口是如何开始侦听的 5) 本地绑定 6) 远程绑定 7) 动态IP问题 8) RemoteObject.ref 9) 远程绑定大概率不会遭遇"动态IP问题" 10) 调试思路回顾 ☆ JNDI+LDAP 1) 简版LDAP Server 2) jndi.ldif 3) HelloRMIInterface.java 4) HelloRMIInterfaceImpl.java 5) JNDILDAPServer.java 6) JNDILDAPClient.java 7) 编译 8) 测试 8.1) 为何有个GET请求404时客户端仍然正常结束 8.2) 用jdb+Arthas调试分析客户端 9) HelloRMIInterfaceImpl8.java 10) JNDILDAPServer2.java 11) "UnicastRemoteObject.exportObject" vs "extends UnicastRemoteObject" ☆ JNDI注入 1) ExploitObject.java 2) EvilServer.java 3) VulnerableClient.java 4) 测试(RMI) 4.1) 为什么Java 8u232失败 4.2) ExploitObject()调用栈回溯 4.2.1) 简化版调用关系 4.2.2) 相关源码 5) ConnectShell.java 6) 测试(LDAP) 6.0) 用marshalsec测试成功 6.1) 用ldap-server.jar测试失败 6.1.1) 用marshalsec测试时的调用栈回溯 6.1.2) 调试用ldap-server.jar的情形 6.1.3) EvilServer2.java 6.1.4) EvilServer3.java (最普适) 7) 测试(CORBA)失败 8) org.springframework.transaction.jta.JtaTransactionManager 8.1) VulnerableServer.java 8.2) EvilServer3.java 8.3) ExploitObject.java 8.4) EvilClient.java 8.5) 测试 8.5.1) ExploitObject()调用栈回溯 8.6) 用ysoserial.exploit.JRMPListener攻击JNDI客户端 ☆ 8u191之后的JNDI注入(RMI) 1) org.apache.naming.factory.BeanFactory + javax.el.ELProcessor 1.1) EvilServer4.java 1.2) 测试 1.3) 简化版调用关系 1.4) 相关源码 2) org.apache.naming.factory.BeanFactory + groovy.lang.GroovyClassLoader 2.1) EvilServer7.java 2.2) 测试 ☆ 8u191之后的JNDI注入(LDAP) 1) EvilLDAPServer.java 2) EvilServer5.java 2.0) 测试 2.1) 调试ctx.rebind() 2.1.1) 简化版调用关系 2.1.2) 相关源码 2.2) 调试ctx.lookup() 2.2.1) 简化版调用关系 2.2.2) 相关源码 3) EvilServer6.java ☆ JNDI+DNS 1) JNDIDNSClient.java ☆ CVE-2017-3241详解 1) Message.java 2) SomeInterface.java 3) SomeInterfaceImpl.java 4) SomeDynamicServer.java 5) SomeNormalClient.java 6) 测试正常用法 7) sun.rmi.server.UnicastRef.unmarshalValue() 8) normal版PublicKnown.java 9) fake版PublicKnown.java 10) SomeEvilClient.java 11) 测试异常用法 11.1) PublicKnown.readObject()调用栈回溯 11.2) 简化版调用关系 12) 关于package的幺蛾子 12.1) Message2.java 12.2) SomeInterface2.java 12.3) SomeInterface2Impl.java 12.4) SomeDynamicServer2.java 12.5) SomeNormalClient2.java 12.6) normal版PublicKnown2.java 12.7) fake版PublicKnown2.java 12.8) SomeEvilClient2.java 12.9) 编译 12.10) 测试 13) 关于AbstractPlatformTransactionManager的幺蛾子 13.1) Message3.java 13.2) SomeInterface3.java 13.3) SomeInterface3Impl.java 13.4) SomeDynamicServer3.java 13.5) SomeNormalClient3.java 13.6) normal版PublicKnown3.java 13.7) fake版PublicKnown3.java 13.8) SomeEvilClient3.java 13.9) 编译 13.10) 测试 14) JtaTransactionManager利用链 14.1) fake版JtaTransactionManager.java 14.2) EvilClientWithJtaTransactionManager.java 14.3) 编译 14.4) 测试 14.4.1) ExploitObject()调用栈回溯 14.4.2) 用rmi-dumpregistry.nse观察周知端口 14.4.3) 用marshalsec测试 15) 为什么Message3需要继承AbstractPlatformTransactionManager ☆ CVE-2017-3241进阶 1) SomeInterface4.java 2) SomeInterface4Impl.java 3) SomeDynamicServer4.java 4) SomeNormalClient4.java 5) 测试正常用法 6) SomeEvilClient4_0.ydb 7) sun.rmi.server.UnicastRef.marshalValue() 7.1) 简化版调用关系 8) normal版PublicKnown4.java 9) SomeEvilClient4_1.ydb 10) LazyMapExecWithHashtable2.java 11) SomeEvilClient4_2.ydb 12) SomeEvilClient4_3.ydb 13) ysoserial/CommonsCollections7 ☆ YouDebug 1) 自己编译YouDebug 2) HelloYouDebug.java 3) HelloYouDebug.ydb 4) 测试 ☆ 攻击RMI Registry 1) RMIRegistryServer.java 2) EvilRMIRegistryClientWithBadAttributeValueExpException.java 2.1) EvilRMIRegistryClientWithBadAttributeValueExpException1.java 3) 测试 4) 简化版调用关系 5) GeneralInvocationHandler3.java 6) EvilRMIRegistryClientWithBadAttributeValueExpException3.java 7) 测试 7.1) 远程测试 8) 简化版调用关系(重点看这个) 9) ysoserial/RMIRegistryExploit 9.1) 不安全的实现 9.2) RMIRegistryExploit.policy 10) sun.rmi.registry.RegistryImpl.checkAccess 11) sun.rmi.registry.RegistryImpl_Skel.dispatch 12) 8u232为什么失败 12.1) sun.rmi.registry.RegistryImpl.registryFilter 12.2) sun.rmi.registry.registryFilter属性 12.3) java.security文件 13) 为什么CommonsCollections5攻击JDK自带rmiregistry失败 14) 基于报错回显的PoC 14.1) DoSomething.java 14.2) RMIRegistryExploitWithHashtable.java 14.3) RMIRegistryExploitWithHashtable2.java 14.4) 测试 14.4.1) 测试1 14.4.2) 测试2(connect shell) 14.4.3) 测试3(rmiregistry) 14.4.4) 远程测试 14.5) RMIRegistryExploitWithHashtable3.java 14.5.1) ProtectClient.policy 15) 用ysoserial.exploit.JRMPClient打常规RMI周知端口 ☆ ysoserial.payloads.JRMPListener+ysoserial.exploit.JRMPClient 1) VulnerableServer2.java 2) ysoserial.payloads.JRMPListener 2.1) 简化版调用关系 3) ysoserial.exploit.JRMPClient 3.1) 简化版调用关系(重点看这个) 3.2) 相关源码 3.3) 网络通信报文 4) EvilClientWithUnicastRemoteObject.java 4.1) UnicastRemoteObjectTest.java 5) DGCClientWithHashtable.java 6) 测试 7) 8u232为什么失败(有白名单检查) 8) 用DGCClientWithHashtable打常规RMI动态端口 9) 用DGCClientWithHashtable打常规RMI周知端口 ☆ ysoserial.exploit.JRMPListener+ysoserial.payloads.JRMPClient 1) VulnerableClient.java 2) ysoserial.exploit.JRMPListener 2.1) 简化版调用关系(重点) 2.2) 相关源码 2.3) EvilRMIRegistryWithHashtable.java 2.4) EvilRMIRegistryWithHashtable2.java 2.5) 客户端安全 2.6) 蜜罐 3) VulnerableServer2.java 4) ysoserial.payloads.JRMPClient 4.1) 简化版调用关系 4.2) 相关源码 4.3) EvilClientWithRemoteObjectInvocationHandler.java 4.3.1) 简化版调用关系 4.3.2) EvilRMIRegistryClientWithRemoteObjectInvocationHandler.java 4.3.3) 简化版调用关系 4.4) EvilClientWithUnicastRef.java 4.4.1) 简化版调用关系 4.4.2) EvilRMIRegistryClientWithUnicastRef.java 4.4.3) 简化版调用关系 4.4.4) 相关源码 4.5) EvilRMIRegistryClientWithRMIConnectionImpl_Stub.java 5) 组合打常规RMI周知端口 5.1) sun.rmi.transport.DGCImpl_Stub.leaseFilter 5.1.1) 简化版调用关系(重点) 5.1.2) 相关源码 5.2) 为什么EvilRMIRegistryClientWithUnicastRef打8u232失败 6) 8u232远程打1099/TCP彻底作废 6.1) 深入RegistryImpl.checkAccess() ☆ Using Custom Socket Factories with Java RMI 1) XorInputStream.java 2) XorOutputStream.java 3) XorSocket.java 4) XorServerSocket.java 5) XorServerSocketFactory.java 6) XorClientSocketFactory.java 7) SomeInterface5.java 8) SomeInterface5Impl.java 9) SomeDynamicServer5.java 10) SomeDynamicServerEx5.java 11) XorCommunication.policy 12) 测试 13) XorServerSocketFactory.createServerSocket()调用栈回溯 ☆ Registry Whitelist Bypass from An Trinh 1) VulnerableServer2.java 2) EvilClientWithUnicastRemoteObject2.java 2.1) 简化版调用关系 3) RMIRegistryServer.java 4) EvilRMIRegistryClientWithUnicastRemoteObject.java 4.1) 简化版调用关系 5) EvilRMIRegistryClientWithUnicastRemoteObjectFail.java 5.1) 简化版调用关系 5.2) 相关源码 5.3) ModifyRebind.ydb 6) EvilRMIRegistryClientWithUnicastRemoteObject2.java ☆ 参考资源