cyi 源鲁杯2024第三轮wp
没有ak最后一轮misc,遗憾(musc真气人)
Round 3
Web
[Round 3] 404
ctrl+u查看源码,点进js文件(或者从控制台看到)
challenge.yuanloo.com:26187/script.js
访问f12g.php,会跳转,查看历史包,
5Y67Y2EucGhw5YGa5Liq5pWw5a2m6aKY5ZCn
base64解码:去ca.php做个数学题吧
经典数学题,脚本提取并计算
import math
import re
import requests
s = requests.Session()
url = 'http://challenge.yuanloo.com:26187/ca.php'
r = s.get(url)
r.encoding = 'utf-8' # 修改编码
print(r.text)
pattern = r'\d+\.\d+|\d+'
num = re.findall(pattern, r.text)
# n = 0
# for i in num:
# print(n, num[n])
# n += 1
pattern2 = r'[+\-*/]'
operators = re.findall(pattern2, r.text)
# n = 0
# for i in operators:
# print(n, operators[n])
# n += 1
temp1 = 0
temp3 = 0
if operators[1] == '+':
temp1 = (int(num[4]) + int(num[5])) * math.log(int(num[6]))
if operators[1] == '-':
temp1 = (int(num[4]) - int(num[5])) * math.log(int(num[6]))
if operators[1] == '*':
temp1 = (int(num[4]) * int(num[5])) * math.log(int(num[6]))
if operators[1] == '/':
temp1 = (int(num[4]) / int(num[5])) * math.log(int(num[6]))
temp2 = math.sqrt(abs(int(num[8]) - int(num[9]))) + pow(math.sin(int(num[10])), 2)
if operators[5] == '+':
temp3 = temp1 + (temp2 * math.tan(int(num[15]) / int(num[16])))
if operators[5] == '-':
temp3 = temp1 - (temp2 * math.tan(int(num[15])) / int(num[16]))
if operators[5] == '*':
temp3 = temp1 * (temp2 * math.tan(int(num[15])) / int(num[16]))
if operators[5] == '/':
temp3 = temp1 / (temp2 * math.tan(int(num[15])) / int(num[16]))
temp4 = math.cos(int(num[18])) * math.exp(math.log(int(num[19])))
ans = temp3 + temp4
# print(temp1,temp2,temp3,temp4,ans)
r = s.post(url, data={'user_answer': ans})
print(r.text)
YLCTF{a5f9d922-72f4-43d6-9d87-3e1e4c2fdeba}
[Round 3] PRead
导出笔记有任意文件读取
读源码
import os
import pickle
from flask import Flask, render_template, request, redirect, url_for, flash, jsonify, send_file
from datetime import datetime
from werkzeug.utils import secure_filename
app = Flask(__name__)
app.secret_key = 'MySe3re7K6y'
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB max-limit
# 确保上传文件夹存在
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
class Note:
def __init__(self, title, content):
self.id = datetime.now().strftime('%Y%m%d%H%M%S')
self.title = title
self.content = content
self.created_at = datetime.now()
class NoteManager:
def __init__(self):
self.notes = []
self.file_name = "notes.pkl"
self.file_path = "./notes/"
self.file = os.path.join(self.file_path, self.file_name)
self.load_notes()
def add_note(self, title, content):
note = Note(title, content)
self.notes.append(note)
self.save_notes()
return note
def get_note(self, note_id):
for note in self.notes:
if note.id == note_id:
return note
return None
def update_note(self, note_id, title, content):
note = self.get_note(note_id)
if note:
note.title = title
note.content = content
self.save_notes()
return True
return False
def delete_note(self, note_id):
self.notes = [note for note in self.notes if note.id != note_id]
self.save_notes()
def save_notes(self):
with open(self.file, 'wb') as f:
pickle.dump(self.notes, f)
def load_notes(self):
if os.path.exists(self.file):
with open(self.file, 'rb') as f:
self.notes = pickle.load(f)
def import_notes(self, file_path):
try:
with open(file_path, 'rb') as f:
imported_notes = pickle.load(f)
self.notes.extend(imported_notes)
self.save_notes()
return len(imported_notes)
except Exception as e:
print(f"Import error: {e}")
return 0
note_manager = NoteManager()
@app.route('/')
def index():
return render_template('index.html', notes=note_manager.notes)
@app.route('/add', methods=['GET', 'POST'])
def add_note():
if request.method == 'POST':
title = request.form['title']
content = request.form['content']
note_manager.add_note(title, content)
flash('笔记已添加成功', 'success')
return redirect(url_for('index'))
return render_template('add_note.html')
@app.route('/edit/<note_id>', methods=['GET', 'POST'])
def edit_note(note_id):
note = note_manager.get_note(note_id)
if request.method == 'POST':
title = request.form['title']
content = request.form['content']
if note_manager.update_note(note_id, title, content):
flash('笔记已更新成功', 'success')
return redirect(url_for('index'))
flash('更新笔记失败', 'error')
return render_template('edit_note.html', note=note)
@app.route('/delete/<note_id>')
def delete_note(note_id):
note_manager.delete_note(note_id)
flash('笔记已删除成功', 'success')
return redirect(url_for('index'))
@app.route('/export_notes', methods=['GET'])
def export_notes():
filename = request.args.get("filename")
file_path = os.path.join(note_manager.file_path, filename)
return send_file(file_path, as_attachment=True, download_name="notes_export.pkl")
@app.route('/import_notes', methods=['POST'])
def import_notes():
if 'file' not in request.files:
flash('没有文件', 'error')
return redirect(url_for('index'))
file = request.files['file']
if file.filename == '':
flash('没有选择文件', 'error')
return redirect(url_for('index'))
if file:
filename = secure_filename(file.filename)
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(file_path)
imported_count = note_manager.import_notes(file_path)
os.remove(file_path) # 删除临时文件
if imported_count > 0:
flash(f'成功导入 {imported_count} 条笔记', 'success')
else:
flash('导入失败,请检查文件格式', 'error')
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(host='0.0.0.0')
给了secret_key
https://www.cnblogs.com/niyani/p/17074125.html
读了打secret_key的这些文件发现flag(后来学习了一下,发现是用在session伪造,这也没伪造点啊,难道打pickle?等wp了)
tips:前两天的拟态非预期读start.sh,有文件读取的话整点小智慧(doge)
YLCTF{1905541f-d21c-4df6-9515-da7acf5ee7d1}
Pwn
[Round 3] Secret
nc题,太开心了
跟进check_password,发现输入SuperSecretPassword即可
YLCTF{27786369-e80e-4ca6-8188-55917d9d10b5}
Crypto
[Round 3] QWQ
aaencode
decode一下就行了,https://toolwa.com/aaencode/
LFGEGVCGPNUEA5RTL5DHK3S7O4YXI2C7ORUGSNK7M5QW2M27KFLVC7I=
base32转码:YLCTF{h@v3_Fun_w1th_thi5_gam3_QWQ}
Misc
[Round 3] Blackdoor
太原了,https://blog.csdn.net/YueXuan_521/article/details/134125759
html\include\include.php
YLCTF{e2bae51b981c707eb28302fe22d60340}
[Round 3] Tinted
不到hint真的看不出
hint1 : 利用取色器查看RGB数值
040067 FF0065 FF0072 040049 FF3C66 FF004A FF3C6A FF3C42 FF3C52 FF3C5A FF0066 00FF31 FF0052 040067 040062 040074 FF0052 FF004C FF0052 FF0039 FF0054 FF0064 FF004A FF0075 00FF52 040063 040075 040075 00FF53 00FF74 FF0057 00FF75 FF0051 040067 FF004A FF0074 FF0069 FF3C5A FF0057 00FF39 FF0054 FF0067 00FF4A FF3C7A 040054 FF0064 FF0052 FF3C76 040054 FF004C FF0069 FF0075 00FF52 040074 FF3C62 00FF71 00FF70 00FF62 FF0035 040035
https://www.cnblogs.com/LEOGG321/p/14095849.html
跟着文章将后两位提取
with open("C:\\Users\\86139\\Desktop\\040067.txt",'r') as f:
s = f.read().split('\n')
for i in s:
print(i[4:],end='')
得到:(后来发现可以直接cyberchef梭了)67657249664A6A42525A663152676274524C523954644A75526375755374577551674A74695A573954674A7A54645276544C69755274627170623535
十六进制解码:gerIfJjBRZf1RgbtRLR9TdJuRcuuStWuQgJtiZW9TgJzTdRvTLiuRtbqpb55
选择magic模式(cyberchef对可能的形式进行猜测),本次解码原理是base64换表解密
YLCTF{25e1d30c-9141-4784-a3b8-9a99358f4340}
[Round 3] CheckImg
和figure一样,出题人只会对png转来转去(bushi)
(如果zsteg报错,加这个export RUBY_THREAD_VM_STACK_SIZE=500000000)
zsteg -e b1,r,lsb,xy flag.png > 1.txt
把后面冗余数据删除
搜60 82 ae 42发现
直接winhex开梭,全选--编辑--修改选块--反转字节再十六进制转码,保存为1.png
zsteg 1.png
一眼dna编码
得到
KVEEQRSCI5DVKVSXKZEUQS2FJBKE2WKKGI2EKNCWJFCUQNSKIVAVINBTKVKE2TZUKVHUWRZWGRIVSVSNJZJFIQKNIZLDINKHJQ2FSQKWJVBUSTSIKFLVMSKFKNFEGVZVKVGEMSJWJMZDMVSTJNDUQQSGI5KEYN2LKY2DETKWK5EEQTSCGJDFMU2IJA3ECTKVKVNEWU2CIFGUYVKBIRJEMRSRINKE2TKGKAZU6M2UJVAVAUSLKFDFMRKGJFMDITR5
(也可以cyberchef一把梭)base32:Base32编码解码,Base32在线转换工具 - 千千秀字
最后ciphey一把梭
ciphey -t UHHFBGGUVWVIHKEHTMYJ24E4VIEH6JEAT43UTMO4UOKG64QYVMNRTAMFV45GL4YAVMCINHQWVIESJCW5ULFI6K26VSKGHBFGTL7KV42MVWHHNB2FVSHH6AMUUZKSBAMLUADRFFQCTMMFP3O3TMAPRKQFVEFIX4N=
YLCTF{bea5f037-0f60-46fa-9350-c261de6f51e6}
Re
[Round 3] ezmaze
一维迷宫,要满足+和F,上面那几个数字ascll转字符是wasd
from collections import deque
maze_map = ("*****++*********+******+*++******+++*****F"
"*+*******+*+++*****+***++****+***+*****+***+*+***+++++++************")
directions = {
'w': (-10, 0), # 向上
'a': (-1, 0), # 向左
's': (10, 0), # 向下
'd': (1, 0) # 向右
}
maze = []
row_length = 1
for i in range(0, len(maze_map), row_length):
maze.append(list(maze_map[i:i + row_length]))
start = (5 // row_length, 5 % row_length) # 起始位置 (5)
goal = (maze_map.index('F') // row_length, maze_map.index('F') % row_length) # 目标位置 F
def bfs(maze, start, goal):
row = len(maze)
col = len(maze[0])
queue = deque([(start, "")])
visited = {start}
while queue:
(x, y), path_now = queue.popleft()
# print(f"{x}, {y}, {path_now}")
if (x, y) == goal:
return path_now
for direction, (dx, dy) in directions.items():
x_n, y_n = x + dx, y + dy
origin_x, origin_y = x_n, y_n
while 0 <= x_n < row and 0 <= y_n < col and maze[x_n][y_n] in ['+', 'F']:
if (x_n, y_n) not in visited:
visited.add((x_n, y_n))
if maze[x_n][y_n] == 'F':
return path_now + direction
queue.append(((x_n, y_n), path_now + direction))
x_n += dx
y_n += dy
x_n, y_n = origin_x, origin_y
path = bfs(maze, start, goal)
print(path)
#dsasasdsaw
YLCTF{efac19a75e413ad6680adec92504b654}
[Round 3] CASE
考点:伪随机数
通过获取当前时间戳来作为随机数种子
获得系统时间戳和对应的加密数据
nc challenge.yuanloo.com 25679 & echo "$(date +%s)"
from ctypes import *
c = cdll.LoadLibrary("libc.so.6")
c.srand(1729673028)
r=[]
for i in range(43):
r.append(c.rand())
print(r)
#[1832493461, 585578708, 2089548833, 578005299, 615532445, 513627915, 1728887083, 1848055492, 1813385881, 1655305840, 283734118, 1748836532, 347059411, 207225596, 30222674, 1464715199, 2131846712, 1111959327, 1619622171, 1869061540, 551853291, 1266831835, 1462910643, 1329122180, 1101406669, 1661912176, 1386875239, 625627464, 774754962, 285087152, 1258985799, 459764775, 870665860, 1201050985, 1037770074, 1486198305, 1714678900, 619173509, 1186770150, 1380581134, 126995701, 1470504268, 981934018]
逆一下
v5 = [1832493461, 585578708, 2089548833, 578005299, 615532445, 513627915, 1728887083, 1848055492, 1813385881, 1655305840, 283734118, 1748836532, 347059411, 207225596, 30222674, 1464715199, 2131846712, 1111959327, 1619622171, 1869061540, 551853291, 1266831835, 1462910643, 1329122180, 1101406669, 1661912176, 1386875239, 625627464, 774754962, 285087152, 1258985799, 459764775, 870665860, 1201050985, 1037770074, 1486198305, 1714678900, 619173509, 1186770150, 1380581134, 126995701, 1470504268, 981934018]
v11 = [0x91,0x4e,0x76,0x35,0xea,0x65,0x6d,0x1e,0x5f,0x2,0xe5,0x9,0x22,0x52,0x67,0x5e,0x40,0xf6,0x48,0x34,0xb9,0xc3,0x4d,0xef,0xfb,0xc8,0x1f,0x3f,0xf6,0xf9,0x46,0x2b,0xd2,0xed,0xa0,0x90,0xc2,0x5b,0xa0,0x9c,0x68,0x51,0xde]
def decrypt(v5, v11):
decrypted = []
for i in range(len(v11)):
random余数 = v5[i] % 255
original_byte = v11[i] ^ random余数
decrypted.append(original_byte)
return decrypted
v12 = decrypt(v5, v11)
decrypted_string = ''.join(chr(i) for i in v12)
print(decrypted_string)
#LYPGS{5nqq5sn7-ro96-4968-nr66-p59105836536}
凯撒直接爆了