a✳Aura's workspace好奇心永不休眠
我的文章GitHub
Aura Blog
记录 · 探索 · 分享
AuraPPC
返回知识库

PPC

队伍:Aura&Jumping

PPC

BaseCTF 崩啦 - 导言

如题,下载好附件后在 README.txt 中发现 flag。

BaseCTF 崩啦 II - 过期了?

要求找到 Damien Schroeder 队伍的所有逾期提交题目,并按照时间顺序用英文逗号连接,取 md5 值。

看了一下,所有题目的截止提交时间都为 2024-08-31T15:00:00+08:00,也就是找该队伍 2024.8.31 15:00:00 后的所有提交记录,找到以后通过题目名称去对应题目的 Id,排序以后是这样。

[2024/8/31 16:09:34 +08:00 INF] 8bcad0d3-6379-411f-5edb-650c20f30dd5



[2024/8/31 17:38:58 +08:00 INF] 563c8303-5eb1-affe-1369-e8889b9323eb



[2024/8/31 18:07:48 +08:00 INF]  ef0a3095-ece1-c427-ab20-99a79fe10bc8



[2024/8/31 18:30:22 +08:00 INF] 2ac9055a-1a79-857f-ed12-e33e5acdc9a3



[2024/8/31 20:28:55 +08:00 INF]  063c3506-d3e4-668b-88f7-2da39092dfe0



[2024/8/31 23:33:54 +08:00 INF] b18048d0-bd8e-0fd0-22b3-61780bae1608

按照要求拼接后长这样。

8bcad0d3-6379-411f-5edb-650c20f30dd5,563c8303-5eb1-affe-1369-e8889b9323eb,ef0a3095-ece1-c427-ab20-99a79fe10bc8,2ac9055a-1a79-857f-ed12-e33e5acdc9a3,063c3506-d3e4-668b-88f7-2da39092dfe0,b18048d0-bd8e-0fd0-22b3-61780bae1608

md5 后套上 BaseCTF 就是 flag。

BaseCTF 崩啦 III - 帮我查查队伍的解题

比起上一题,手动去做显得更吃力,所以需要借助一下脚本。

大致意思就是找到 Rick Hyatt 队伍所有未提交,提交错误,或者逾期提交的所有题目,按照 challenges.json 中的题目顺序拼接,取 md5 值。

正难则反,我们把该队伍所有提交正确的题目找出来,然后把这些题目作为黑名单,用脚本跑一下,自然就能得到想要的那些题目。

可以手动把该队伍的提交记录都取出来,先删掉逾期提交的题目,再去看剩余的题目是否有提交错误的。

怎么看提交是否正确,这里需要先去看 teams.json,找到该队伍的 Id,然后在 flags.json 把该队伍的 flag 提出来,依次对比即可。

最后只有 3 个题目提交正确,把他们写入一个 black.txt,作为黑名单。

[[Week2] Aura 酱的旅行日记 VI <图寻擂台>]
[[Week3] 你为什么不让我溢出]
[[Week2] try_to_factor]

接下来用脚本跑,把所有未在黑名单中的题目的 Id 拼出来即可。

import json
from hashlib import md5
with open('black.txt', 'r', encoding='utf-8') as file:
    blacklist = file.read()
with open('challenges.json', 'r') as file:
    data = json.load(file)
ids_to_output = []
cnt = 0
for item in data:
    if item['Name'] not in blacklist:
        ids_to_output.append(item['Id'])
        cnt += 1
output_ids = ','.join(ids_to_output)
print(output_ids)
print(cnt)
print(md5(output_ids.encode('utf-8')).hexdigest())

最终 md5 值:4f87919032dfc58a9a23044aab9acd99。

包上 BaseCTF 就是 flag。

BaseCTF 崩啦 IV - 排排坐吃果果

统计排名,细节很多。

  • 超时提交的不计分
  • 0 分的队伍也要计算到排名中,但有可能这类队伍就没提交记录,需要从 teams.json 里面初始化
  • 有的队伍会重复提交正确的 flag,分数不能重复累加
  • 有个重名的队伍,不过出题人很良心,把这个重名队伍的得分合并也视为正确答案

为了方便书写计算代码,这里把 submissions.log 通过脚本转成了 submit.json,同时忽略了超时提交的记录。

import re
from datetime import datetime
import json
comparison_time_str = "2024-08-31T15:00:00+08:00"
comparison_time = datetime.fromisoformat(comparison_time_str)
with open('submissions.log', 'r') as f:
    log_entries = f.read()
log_entries = log_entries.split('\n')
logs = []
def extract_info(log_line):
    patterns = {
        'time': r'\[(.*?)\]',
        'team': r'队伍 \[(.*?)\]',
        'challenge': r'提交题目 \[(.*?)\] 的答案',
        'flag': r'答案 \[(.*?)\]'
    }
    extracted_info = {key: re.search(pattern, log_line).group(1) if re.search(pattern, log_line) else None
                      for key, pattern in patterns.items()}
    return extracted_info
for log in log_entries:
    log_json = extract_info(log)
    if log_json['time']:
        log_json['time'] = time = datetime.strptime(log_json['time'][:-4], '%Y/%m/%d %H:%M:%S %z')
        if log_json['time'] <= comparison_time:
            log_json.pop('time', None)
            logs.append(log_json)
def save_to_json(data, filename):
    with open(filename, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=True, indent=3)
save_to_json(logs, 'submit.json')

生成了 submit.json 以后,接下来就是统计排名,需要把之前的细节都考虑到。

对于重复提交正确 flag 的队伍,这里使用 vis 字典进行打标记,未打标记的正常加分,打过标记的不再计分。

import json
import hashlib
from tqdm import tqdm
with open('challenges.json', 'r') as f:
    json_string = f.read()
challenges = json.loads(json_string)
with open('flags.json', 'r') as f:
    json_string = f.read()
flags = json.loads(json_string)
with open('teams.json', 'r') as f:
    json_string = f.read()
teams = json.loads(json_string)
with open('submit.json', 'r') as f:
    json_string = f.read()
submits = json.loads(json_string)
scores = {}
vis = {}
for team in teams:
    scores[team['Name']] = 0
    vis[team['Name']] = {}
    for problem in challenges:
        vis[team['Name']][problem['Id']] = False
for submit in tqdm(submits, desc="Processing submits"):
    sub_team = submit['team']
    sub_flag = submit['flag']
    sub_challenge = submit['challenge']
    challenge = next((item for item in challenges if item['Name'] == sub_challenge), None)
    points = challenge['Points']
    challenge_id = challenge['Id']
    team = next((item for item in teams if item['Name'] == sub_team), None)
    team_id = team['Id']
    if vis[sub_team][challenge_id]:
        continue
    flag = next((item for item in flags if (item['ChallengeId'] == challenge_id and item['TeamId'] == team_id)), None)
    if flag['Flag'] == sub_flag:
        vis[sub_team][challenge_id] = True
        scores[sub_team] += points
def sort_and_generate_flag(data):
    sorted_data = sorted(data.items(), key=lambda x: (-x[1], x[0]))
    concatenated_string = ';'.join(f"{team},{points}" for team, points in sorted_data)
    print(concatenated_string)
    md5_result = hashlib.md5(concatenated_string.encode('utf-8')).hexdigest()
    flag = f"BaseCTF{{{md5_result}}}"
    return flag
print(sort_and_generate_flag(scores))

BaseCTF 崩啦 V - 正义执行!

统计作弊队伍,只要提交其他队伍 Flag 都视为作弊。

需要将之前转 json 的脚本修改一下,把时间过滤删去即可。

import re
import json
with open('submissions.log', 'r', encoding='utf-8') as f:
    log_entries = f.read()
log_entries = log_entries.split('\n')
logs = []
def extract_info(log_line):
    patterns = {
        'time': r'\[(.*?)\]',
        'team': r'队伍 \[(.*?)\]',
        'challenge': r'提交题目 \[(.*?)\] 的答案',
        'flag': r'答案 \[(.*?)\]'
    }
    extracted_info = {key: re.search(pattern, log_line).group(1) if re.search(pattern, log_line) else None
                      for key, pattern in patterns.items()}
    return extracted_info
for log in log_entries:
    log_json = extract_info(log)
    logs.append(log_json)
def save_to_json(data, filename):
    with open(filename, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=True, indent=3)
save_to_json(logs, 'submit.json')

统计作弊队伍也有一些小细节。

  • 最后要的是未作弊的队伍
  • 有可能有的队伍交了多个其它队伍的 flag
  • 只要交了其它队伍的 flag,不管是哪个题,双方都视为作弊
import json
import hashlib
from pwnlib.dynelf import sizeof
from tqdm import tqdm
with open('challenges.json', 'r') as f:
    json_string = f.read()
challenges = json.loads(json_string)
with open('flags.json', 'r') as f:
    json_string = f.read()
flags = json.loads(json_string)
with open('teams.json', 'r') as f:
    json_string = f.read()
teams = json.loads(json_string)
with open('submit.json', 'r') as f:
    json_string = f.read()
submits = json.loads(json_string)
cheaters = []
all_teams = []
for team in teams:
    all_teams.append(team['Id'])
for submit in tqdm(submits, desc="Processing submits"):
    sub_team = submit['team']
    sub_flag = submit['flag']
    sub_challenge = submit['challenge']
    # challenge = next((item for item in challenges if item['Name'] == sub_challenge), None)
    # challenge_id = challenge['Id']
    team = next((item for item in teams if item['Name'] == sub_team), None)
    team_id = team['Id']
    flag = next((item for item in flags if (item['Flag'] == sub_flag)), None)
    if flag is None:
        continue
    if flag['TeamId']!=team_id:
        if team_id not in cheaters:
            cheaters.append(team_id)
        if flag['TeamId'] not in cheaters:
            cheaters.append(flag['TeamId'])

print(cheaters)
def sort_and_generate_flag():
    temp = []
    for team in all_teams:
        if team in cheaters:
            continue
        temp.append(team)
    ans = []
    for id in temp:
        team = next((item for item in teams if item['Id'] == id), None)
        ans.append(team['Name'])
    ans.sort()
    concatenated_string = ','.join(team for team in ans)
    print(concatenated_string)
    md5_result = hashlib.md5(concatenated_string.encode('utf-8')).hexdigest()
    flag = f"BaseCTF{{{md5_result}}}"
    return flag
print(sort_and_generate_flag())
Addie Will,Amber Powlowski,Annabelle Treutel,Camilla Halvorson,Candice Rempel,Einar Langosh,Gerson Reynolds,Guy Stiedemann,Jackson Beatty,Janiya Boehm,Jasen Weimann,Jewel Mohr,Kathlyn Wintheiser,Lexie O'Conner,Marquis Metz,Mikayla Lubowitz,Molly Rodriguez,Nellie Purdy,Queenie Franecki,Rick Auer,Rosendo Jenkins,Tess Koelpin,Wilhelmine Smith

👆所有未作弊的队伍(按队名字典序排序)

✳

感谢阅读,下一个线索见。

一方小小的桌面,一些慢慢积累的想法。
中

搜索文章

输入关键词,寻找一段记录。