前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VNCTF2022公开赛-easyJ4va

VNCTF2022公开赛-easyJ4va

原创
作者头像
c2k2o6
发布2022-02-15 14:25:42
5640
发布2022-02-15 14:25:42
举报
文章被收录于专栏:c2k2o6

环境已经关了,这里主要说下思路

拿到题目,很容易发现一个任意文件读取

读取根目录flag,权限不够,发现根目录有/readflag

那么思路就是要rce或者其他有执行/readflag得操作了

由题目知道是 tomcat java的

读源码

搭建过tomcat的师傅们知道tomcat一般的默认路径

挨个读取文件

/usr/local/tomcat/webapps/ROOT/WEB-INF/classes/util/Secr3t.class

/usr/local/tomcat/webapps/ROOT/WEB-INF/classes/servlet

/usr/local/tomcat/webapps/ROOT/WEB-INF/classes/controller

/usr/local/tomcat/webapps/ROOT/WEB-INF/classes/entity

/usr/local/tomcat/webapps/ROOT/WEB-INF/classes/util

主要是这三个文件

SerAndDe.class

User.class

HelloWorldServlet.class

然后去反编译

代码语言:javascript
复制

@WebServlet(name = "HelloServlet", urlPatterns = {"/evi1"})
/* loaded from: file(5) */
public class HelloWorldServlet extends HttpServlet {
    private volatile String name = "m4n_q1u_666";
    private volatile String age = "666";
    private volatile String height = "180";
    User user;

    public void init() throws ServletException {
        this.user = new User(this.name, this.age, this.height);
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String reqName = req.getParameter("name");
        if (reqName != null) {
            this.name = reqName;
        }
        if (Secr3t.check(this.name)) {
            Response(resp, "no vnctf2022!");
        } else if (Secr3t.check(this.name)) {
            Response(resp, "The Key is " + Secr3t.getKey());
        }
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String key = req.getParameter("key");
        String text = req.getParameter("base64");
        if (!Secr3t.getKey().equals(key) || text == null) {
            Response(resp, "KeyError");
            return;
        }
        if (this.user.equals((User) SerAndDe.deserialize(Base64.getDecoder().decode(text)))) {
            Response(resp, "Deserialize…… Flag is " + Secr3t.getFlag().toString());
        }
    }

    private void Response(HttpServletResponse resp, String outStr) throws IOException {
        ServletOutputStream out = resp.getOutputStream();
        out.write(outStr.getBytes());
        out.flush();
        out.close();
    }
}
代码语言:javascript
复制
public class SerAndDe {
    private SerAndDe() {
    }

    public static byte[] serialize(Object object) {
        ObjectOutputStream oos = null;
        ByteArrayOutputStream bos = null;
        try {
            try {
                bos = new ByteArrayOutputStream();
                oos = new ObjectOutputStream(bos);
                oos.writeObject(object);
                byte[] b = bos.toByteArray();
                if (oos != null) {
                    try {
                        oos.close();
                    } catch (IOException ex) {
                        System.out.println("io could not close:" + ex.toString());
                    }
                }
                if (bos != null) {
                    bos.close();
                }
                return b;
            } catch (IOException e) {
                System.out.println("serialize Exception:" + e.toString());
                if (oos != null) {
                    try {
                        oos.close();
                    } catch (IOException ex2) {
                        System.out.println("io could not close:" + ex2.toString());
                        return null;
                    }
                }
                if (bos != null) {
                    bos.close();
                }
                return null;
            }
        } catch (Throwable th) {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException ex3) {
                    System.out.println("io could not close:" + ex3.toString());
                    throw th;
                }
            }
            if (bos != null) {
                bos.close();
            }
            throw th;
        }
    }

    public static Object deserialize(byte[] bytes) {
        ByteArrayInputStream bais;
        try {
            bais = null;
            try {
                bais = new ByteArrayInputStream(bytes);
                Object readObject = new ObjectInputStream(bais).readObject();
                if (bais != null) {
                    try {
                        bais.close();
                    } catch (IOException ex) {
                        System.out.println("LogManage Could not serialize:" + ex.toString());
                    }
                }
                return readObject;
            } catch (IOException | ClassNotFoundException e) {
                System.out.println("deserialize Exception:" + e.toString());
                if (bais != null) {
                    try {
                        bais.close();
                    } catch (IOException ex2) {
                        System.out.println("LogManage Could not serialize:" + ex2.toString());
                        return null;
                    }
                }
                return null;
            }
        } catch (Throwable th) {
            if (bais != null) {
                try {
                    bais.close();
                } catch (IOException ex3) {
                    System.out.println("LogManage Could not serialize:" + ex3.toString());
                    throw th;
                }
            }
            throw th;
        }
    }
}
代码语言:javascript
复制

public class User implements Serializable {
    private String name;
    private String age;
    private transient String height;

    public User(String name, String age, String height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return this.age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getHeight() {
        return this.height;
    }

    public void setHeight(String height) {
        this.height = height;
    }

    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
        s.defaultReadObject();
        this.height = (String) s.readObject();
    }

    @Override // java.lang.Object
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof User)) {
            return false;
        }
        User user = (User) obj;
        if (!user.getAge().equals(this.age) || !user.getHeight().equals(this.height) || !user.getName().equals(this.name)) {
            return false;
        }
        return true;
    }

    @Override // java.lang.Object
    public String toString() {
        return "User{name='" + this.name + "', age='" + this.age + "', height='" + this.height + "'}";
    }
}

java代码审计

可以知道得先得到一个key doGet 方法那里得到key

直接读key是行不通得

图片
图片
图片
图片

然后这里要设法绕过

图片
图片

乍一看是决定无法成功得

经过师傅提示 ,跟java线程安全有关系,burpsuite开两个intruder

图片
图片
图片
图片

然后去爆破,等个几分钟 响应包中发现得到key

之后 去  doPost 方法 设法得到flag

图片
图片

这里反序列化必须满足条件

新建一个t3目录

图片
图片

根据原先得目录结构 新建这几个文件

图片
图片
图片
图片

对t3文件夹 直接 右键 idea打开

图片
图片

文件--项目结构设置

图片
图片
图片
图片

模块标记为源

直接把 User和 SerAndDe得代码 拷贝进去

写一个main

图片
图片

然后是漫长得改bug

SerAndDe中bug很多 

图片
图片

通过idea提示 等等 终于改完bug

运行之后 发现 还不行

图片
图片

注意到 User中得 

代码语言:javascript
复制
private transient String height;

https://blog.csdn.net/qq_42843172/article/details/107193866

transient关键字:游离的,被该关键字修饰的变量不参与序列化

所有这里还得重写 User中得     

readObject 和  writeObject 方法

图片
图片

然后再次运行main就成功了

图片
图片

post传入key和 base64即可

图片
图片

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
代码审计
代码审计(Code Audit,CA)提供通过自动化分析工具和人工审查的组合审计方式,对程序源代码逐条进行检查、分析,发现其中的错误信息、安全隐患和规范性缺陷问题,以及由这些问题引发的安全漏洞,提供代码修订措施和建议。支持脚本类语言源码以及有内存控制类源码。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档