总共4题,贴了3题,还有一道go逆向的直接看这位师傅的吧
几个关键点:mfc逆向,win32 加密api的识别,ZwSetInformationThread反调试
看程序图标是个mfc的程序,先打开看看,随便输入一点东西,看到弹窗弹出
直接拖进ida搜索Wrong!!!
字符串,借此通过查看引用跳转到主函数
先简单的修复一下变量名
大概可以看到key
的前4位经过一次sub_403510
,后4位也经过一次sub_403510
,整个key8位
又经过一次sub_403510
随后进入sub_403510
函数看一看,看到有一堆为win32 加密api的函数
那就对照着MSDN一个个函数查阅一下
CryptAcquireContext 函数用于获取特定加密服务提供程序 (CSP) 中特定密钥容器的句柄。此返回的句柄用于调用使用所选 CSP 的 CryptoAPI 函数。
CryptCreateHash 函数启动数据流的哈希。它创建加密服务提供程序 (CSP) 哈希对象的句柄并将其返回给调用应用程序。此句柄用于对 CryptHashData 和 CryptHashSessionKey 的后续调用,以哈希会话密钥和其他数据流。
注意这里Algid是标识要使用的哈希算法的参数,通过不同的值的传入选择不同的hash算法,可查下面的链接
ALG_ID (Wincrypt.h) - Win32 apps | Microsoft Docs
CryptHashData 函数将数据添加到指定的哈希对象。此函数和CryptHashSessionKey可以多次调用,以计算长数据流或不连续数据流的哈希值。
CryptGetHashParam 函数检索控制哈希对象操作的数据。可以使用此函数检索实际的哈希值。
CryptEncrypt 函数对数据进行加密。用于加密数据的算法由 CSP 模块持有的密钥指定,并由 hKey 参数引用。
程序大概的逻辑就是这样
然后我们就通过动调去拿数据,这里有两种方式,一种是通过ida patch反调试函数的方式,一种是通过od 的sharp od插件直接绕过
对比各种反调试和去IAT表找导入函数没有找到,后面在strings界面可以发现ZwSetInformationThread
反调试的特征ZwSetInformationThread - CTF Wiki (ctf-wiki.org)
ZwSetInformationThread通过为线程设置 ThreadHideFromDebugger,可以禁止线程产生调试事件
绕过: ZwSetInformationThread 函数的第 2 个参数为 ThreadHideFromDebugger,其值为 0x11。调试执行到该函数时,若发现第 2 个参数值为 0x11,跳过或者将 0x11 修改为其他值即可
看来是自己实现调用dll导入的
类似于这种写法
我们可以先在调用处下一个断点,跑起来之后再修改patch 0x11 改掉,我这里patch成了0x9
然后继续下断点拿密文
然后再扔到md5解密网站解密
类似的拿到sha1解密后的key后四位 https://crackstation.net/
key:NocTuRne
md5(key)
:C0804C74E05B4C7440AC4D7480954C74
之后就是模拟调用win32 的aes解密api来解密的过程了
拿到flag!
另外经mas0n师傅补充,附上frida来hook求解的方法
拖进ida里发现经过upx加壳
直接upx -d脱壳
接着再使用pyinstxtractor解包得到一堆文件(比较坑的地方是本地python环境必须与源程序的python环境相同才能解包PYZ-00.pyz),下面是彻底解包后的几个关键的文件
奇怪的交易.pyc
文件内容如下
python反编译 - 在线工具 (tool.lu)
这样其实逻辑很明显还是有问题的,题目特意用的Python3.10版本,导致反编译结果会不正确
通过pycdump可以dump出opcode,对比进行变量名和代码逻辑的修复
可以参考下面的文章
Python字节码文档 Python字节码详解(介绍了Python的特有类型以及遍历等操作)
修复后的 奇怪的交易.py
发现从cup包导入了一个encrypt函数
以下是对经key加密后的cup.pyc.encrypted的解密脚本[原创]Python逆向——Pyinstaller逆向-软件逆向-看雪论坛-安全社区|安全招聘|bbs.pediy.com
解密得到发现是一个python实现的xxtea加密,最基础的版本,甚至连key都没变
python实现xxtea加解密参考链接
先解密xxtea得到结果rsa加密的密文c
接下来是一个低解密指数 rsa 就可以得到flag了
先用BlackDex脱个壳,然后把解密后的dex文件pull到自己的电脑上后拖进jadx
看到主要是一个登录逻辑
题目逻辑非常简单,可以直接Aes解密,但由于主类里有了解密的方法,肯定是要选择更加有意思的方法来玩玩,我这里的做法是直接采用frida来hook
先hook绕过认证
返回页面如下
看到有两个解密相关的方法,果断继续hook
直接拿到flag
奇怪的交易这题附件过大,这里就直接贴我的链接了
奇怪的交易
BOOL
CryptAcquireContextA(
[out] HCRYPTPROV
*
phProv,
[
in
] LPCSTR szContainer,
[
in
] LPCSTR szProvider,
[
in
] DWORD dwProvType,
[
in
] DWORD dwFlags
);
BOOL
CryptAcquireContextA(
[out] HCRYPTPROV
*
phProv,
[
in
] LPCSTR szContainer,
[
in
] LPCSTR szProvider,
[
in
] DWORD dwProvType,
[
in
] DWORD dwFlags
);
BOOL
CryptCreateHash(
[
in
] HCRYPTPROV hProv,
[
in
] ALG_ID Algid,
[
in
] HCRYPTKEY hKey,
[
in
] DWORD dwFlags,
[out] HCRYPTHASH
*
phHash
);
BOOL
CryptCreateHash(
[
in
] HCRYPTPROV hProv,
[
in
] ALG_ID Algid,
[
in
] HCRYPTKEY hKey,
[
in
] DWORD dwFlags,
[out] HCRYPTHASH
*
phHash
);
BOOL
CryptHashData(
[
in
] HCRYPTHASH hHash,
[
in
] const BYTE
*
pbData,
[
in
] DWORD dwDataLen,
[
in
] DWORD dwFlags
);
BOOL
CryptHashData(
[
in
] HCRYPTHASH hHash,
[
in
] const BYTE
*
pbData,
[
in
] DWORD dwDataLen,
[
in
] DWORD dwFlags
);
BOOL
CryptGetHashParam(
[
in
] HCRYPTHASH hHash,
[
in
] DWORD dwParam,
[out] BYTE
*
pbData,
[
in
, out] DWORD
*
pdwDataLen,
[
in
] DWORD dwFlags
);
BOOL
CryptGetHashParam(
[
in
] HCRYPTHASH hHash,
[
in
] DWORD dwParam,
[out] BYTE
*
pbData,
[
in
, out] DWORD
*
pdwDataLen,
[
in
] DWORD dwFlags
);
BOOL
CryptEncrypt(
[
in
] HCRYPTKEY hKey,
[
in
] HCRYPTHASH hHash,
[
in
]
BOOL
Final,
[
in
] DWORD dwFlags,
[
in
, out] BYTE
*
pbData,
[
in
, out] DWORD
*
pdwDataLen,
[
in
] DWORD dwBufLen
);
BOOL
CryptEncrypt(
[
in
] HCRYPTKEY hKey,
[
in
] HCRYPTHASH hHash,
[
in
]
BOOL
Final,
[
in
] DWORD dwFlags,
[
in
, out] BYTE
*
pbData,
[
in
, out] DWORD
*
pdwDataLen,
[
in
] DWORD dwBufLen
);
int
main(){
BYTE pbData[]
=
{
0x5c
,
0x53
,
0xa4
,
0xa4
,
0x1d
,
0x52
,
0x43
,
0x7a
,
0x9f
,
0xa1
,
0xe9
,
0xc2
,
0x6c
,
0xa5
,
0x90
,
0x90
,
0x0
};
/
/
key_buf
BYTE flag_encrypt[]
=
{
0x5B
,
0x9C
,
0xEE
,
0xB2
,
0x3B
,
0xB7
,
0xD7
,
0x34
,
0xF3
,
0x1B
,
0x75
,
0x14
,
0xC6
,
0xB2
,
0x1F
,
0xE8
,
0xDE
,
0x33
,
0x44
,
0x74
,
0x75
,
0x1B
,
0x47
,
0x6A
,
0xD4
,
0x37
,
0x51
,
0x88
,
0xFC
,
0x67
,
0xE6
,
0x60
,
0xDA
,
0x0D
,
0x58
,
0x07
,
0x81
,
0x43
,
0x53
,
0xEA
,
0x7B
,
0x52
,
0x85
,
0x6C
,
0x86
,
0x65
,
0xAF
,
0xB4
,
0x0
};
DWORD dwDataLen
=
0x10
;
DWORD ddwDataLen;
DWORD
*
pdwDataLen
=
&ddwDataLen;
*
pdwDataLen
=
0x20
;
BOOL
v6;
/
/
[esp
+
4h
] [ebp
-
18h
]
HCRYPTKEY phKey;
/
/
[esp
+
Ch] [ebp
-
10h
] BYREF
HCRYPTPROV phProv;
/
/
[esp
+
10h
] [ebp
-
Ch] BYREF
HCRYPTHASH phHash;
/
/
[esp
+
14h
] [ebp
-
8h
] BYREF
phProv
=
0
;
phHash
=
0
;
phKey
=
0
;
v6
=
CryptAcquireContextA(&phProv,
0
,
0
,
0x18u
,
0xF0000000
);
if
(v6)
{
v6
=
CryptCreateHash(phProv,
0x8003u
,
0
,
0
, &phHash);
if
(v6)
{
v6
=
CryptHashData(phHash, pbData, dwDataLen,
0
);
if
(v6)
{
v6
=
CryptDeriveKey(phProv,
0x660Eu
, phHash,
1u
, &phKey);
/
/
key的md5值再生成aes密钥
if
(v6)
v6
=
CryptDecrypt(phKey,
0
,
1
,
0
, flag_encrypt, pdwDataLen);
printf(
"%s"
, flag_encrypt);
}
}
}
if
(phKey)
CryptDestroyKey(phKey);
if
(phHash)
CryptDestroyHash(phHash);
if
(phProv)
CryptReleaseContext(phProv,
0
);
return
v6;
}
int
main(){
BYTE pbData[]
=
{
0x5c
,
0x53
,
0xa4
,
0xa4
,
0x1d
,
0x52
,
0x43
,
0x7a
,
0x9f
,
0xa1
,
0xe9
,
0xc2
,
0x6c
,
0xa5
,
0x90
,
0x90
,
0x0
};
/
/
key_buf
BYTE flag_encrypt[]
=
{
0x5B
,
0x9C
,
0xEE
,
0xB2
,
0x3B
,
0xB7
,
0xD7
,
0x34
,
0xF3
,
0x1B
,
0x75
,
0x14
,
0xC6
,
0xB2
,
0x1F
,
0xE8
,
0xDE
,
0x33
,
0x44
,
0x74
,
0x75
,
0x1B
,
0x47
,
0x6A
,
0xD4
,
0x37
,
0x51
,
0x88
,
0xFC
,
0x67
,
0xE6
,
0x60
,
0xDA
,
0x0D
,
0x58
,
0x07
,
0x81
,
0x43
,
0x53
,
0xEA
,
0x7B
,
0x52
,
0x85
,
0x6C
,
0x86
,
0x65
,
0xAF
,
0xB4
,
0x0
};
DWORD dwDataLen
=
0x10
;
DWORD ddwDataLen;
DWORD
*
pdwDataLen
=
&ddwDataLen;
*
pdwDataLen
=
0x20
;
BOOL
v6;
/
/
[esp
+
4h
] [ebp
-
18h
]
HCRYPTKEY phKey;
/
/
[esp
+
Ch] [ebp
-
10h
] BYREF
HCRYPTPROV phProv;
/
/
[esp
+
10h
] [ebp
-
Ch] BYREF
HCRYPTHASH phHash;
/
/
[esp
+
14h
] [ebp
-
8h
] BYREF
phProv
=
0
;
phHash
=
0
;
phKey
=
0
;
v6
=
CryptAcquireContextA(&phProv,
0
,
0
,
0x18u
,
0xF0000000
);
if
(v6)
{
v6
=
CryptCreateHash(phProv,
0x8003u
,
0
,
0
, &phHash);
if
(v6)
{
v6
=
CryptHashData(phHash, pbData, dwDataLen,
0
);
if
(v6)
{
v6
=
CryptDeriveKey(phProv,
0x660Eu
, phHash,
1u
, &phKey);
/
/
key的md5值再生成aes密钥
if
(v6)
v6
=
CryptDecrypt(phKey,
0
,
1
,
0
, flag_encrypt, pdwDataLen);
printf(
"%s"
, flag_encrypt);
}
}
}
if
(phKey)
CryptDestroyKey(phKey);
if
(phHash)
CryptDestroyHash(phHash);
if
(phProv)
CryptReleaseContext(phProv,
0
);
return
v6;
}
var baseAddr
=
Process.findModuleByName(
'Crackme_1.exe'
);
/
/
input
32
length flag, e.g.
11111111111111111111111111111111
/
/
key: NocTuRne
/
/
frida attach
-
p
48964
-
l agent\hook_win.js
/
/
memcmp
var hookAddr
=
ptr(
0x0109D4BC
);
Interceptor.attach(hookAddr, {
onEnter: function(args) {
let Buf1
=
args[
0
];
let Buf2
=
args[
1
];
let Size
=
args[
2
];
console.log(
"-----\n[Size]\n"
, Size);
let size
=
Size.toInt32();
console.log(
"-----\n[Buf1]\n"
, Buf1.readByteArray(size));
console.log(
"-----\n[Buf2]\n"
, Buf2.readByteArray(size));
console.log(
"---------------------------"
);
},
onLeave: function(arg) {
return
arg;
}
})
var libAddr
=
Process.findModuleByName(
'ADVAPI32.dll'
);
var fn_CryptEncrypt
=
libAddr.getExportByName(
"CryptEncrypt"
);
var fn_CryptDecrypt
=
libAddr.getExportByName(
"CryptDecrypt"
);
var flag
=
null;
Interceptor.replace(fn_CryptEncrypt, fn_CryptDecrypt);
Interceptor.attach(fn_CryptDecrypt, {
onEnter: function(args) {
args[
4
].writeByteArray([
0x5b
,
0x9c
,
0xee
,
0xb2
,
0x3b
,
0xb7
,
0xd7
,
0x34
,
0xf3
,
0x1b
,
0x75
,
0x14
,
0xc6
,
0xb2
,
0x1f
,
0xe8
,
0xde
,
0x33
,
0x44
,
0x74
,
0x75
,
0x1b
,
0x47
,
0x6a
,
0xd4
,
0x37
,
0x51
,
0x88
,
0xfc
,
0x67
,
0xe6
,
0x60
,
0xda
,
0x0d
,
0x58
,
0x07
,
0x81
,
0x43
,
0x53
,
0xea
,
0x7b
,
0x52
,
0x85
,
0x6c
,
0x86
,
0x65
,
0xaf
,
0xb4
]);
args[
5
].writeInt(
0x40
);
flag
=
args[
4
];
console.log(
"hook fn_CryptDecrypt"
);
return
args;
},
onLeave: function(arg) {
console.log(flag.readCString());
return
arg;
}
})
var baseAddr
=
Process.findModuleByName(
'Crackme_1.exe'
);
/
/
input
32
length flag, e.g.
11111111111111111111111111111111
/
/
key: NocTuRne
/
/
frida attach
-
p
48964
-
l agent\hook_win.js
/
/
memcmp
var hookAddr
=
ptr(
0x0109D4BC
);
Interceptor.attach(hookAddr, {
onEnter: function(args) {
let Buf1
=
args[
0
];
let Buf2
=
args[
1
];
let Size
=
args[
2
];
console.log(
"-----\n[Size]\n"
, Size);
let size
=
Size.toInt32();
console.log(
"-----\n[Buf1]\n"
, Buf1.readByteArray(size));
console.log(
"-----\n[Buf2]\n"
, Buf2.readByteArray(size));
console.log(
"---------------------------"
);
},
onLeave: function(arg) {
return
arg;
}
})
var libAddr
=
Process.findModuleByName(
'ADVAPI32.dll'
);
var fn_CryptEncrypt
=
libAddr.getExportByName(
"CryptEncrypt"
);
var fn_CryptDecrypt
=
libAddr.getExportByName(
"CryptDecrypt"
);
var flag
=
null;
Interceptor.replace(fn_CryptEncrypt, fn_CryptDecrypt);
Interceptor.attach(fn_CryptDecrypt, {
onEnter: function(args) {
args[
4
].writeByteArray([
0x5b
,
0x9c
,
0xee
,
0xb2
,
0x3b
,
0xb7
,
0xd7
,
0x34
,
0xf3
,
0x1b
,
0x75
,
0x14
,
0xc6
,
0xb2
,
0x1f
,
0xe8
,
0xde
,
0x33
,
0x44
,
0x74
,
0x75
,
0x1b
,
0x47
,
0x6a
,
0xd4
,
0x37
,
0x51
,
0x88
,
0xfc
,
0x67
,
0xe6
,
0x60
,
0xda
,
0x0d
,
0x58
,
0x07
,
0x81
,
0x43
,
0x53
,
0xea
,
0x7b
,
0x52
,
0x85
,
0x6c
,
0x86
,
0x65
,
0xaf
,
0xb4
]);
args[
5
].writeInt(
0x40
);
flag
=
args[
4
];
console.log(
"hook fn_CryptDecrypt"
);
return
args;
},
onLeave: function(arg) {
console.log(flag.readCString());
return
arg;
}
})
from
cup
import
*
from
libnum
import
*
if
__name__
=
=
'__main__'
:
flag
=
input
(
'请输入flag'
)
pub_key
=
[
0x649EE967E7916A825CC9FD3320BEABF263BEAC68C080F52824A0F521EDB6B78577EC52BF1C9E78F4BB71192F9A23F1A17AA76E5979E4D953329D3CA65FB4A71DA57412B59DFD6AEDF0191C5555D3E5F582B81B5E6B23163E9889204A81AFFDF119FE25C92F4ED59BD3285BCD7AAE14824240D2E33C5A97848F4EB7AAC203DE6330D2B4D8FF61691544FBECD120F99A157B3D2F58FA51B2887A9D06CA383C44D071314A12B17928B96F03A06E959A5AFEFA0183664F52CD32B9FC72A04B45913FCB2D5D2D3A415A14F611CF1EAC2D6C785142A8E9CC41B67A6CD85001B06EDB8CA767D367E56E0AE651491BF8A8C17A38A1835DB9E4A9292B1D86D5776C98CC25
,
0x647327833ACFEF1F9C83E74E171FC300FA347D4A6769476C33DA82C95120ACB38B62B33D429206FE6E9BB0BB7AB748A1036971BEA36EC47130B749C1C9FF6FE03D0F7D9FC5346EB0E575BDFA6C530AA57CD676894FC080D2DD049AB59625F4B9C78BCFD95CDCD2793E440E26E189D251121CB6EB177FEDB596409034E8B0C5BBD9BD9342235DBB226C9170EFE347FF0FD2CFF9A1F7B647CC83E4D8F005FD7125A89251C768AFE70BDD54B88116814D5030F499BCAC4673CCCC342FB4B6AC58EA5A64546DC25912B6C430529F6A7F449FD96536DE269D1A1B015A4AC6B6E46EE19DCE8143726A6503E290E4BAE6BD78319B5878981F6CFFDB3B818209341FD68B
]
m
=
libnum.s2n(flag)
c
=
str
(
pow
(m, pub_key[
1
], pub_key[
0
]))
store
=
[]
cipher
=
[
3532577106
,
1472742623
,
3642468664
,
4193500461
,
2398676029
,
617653972
,
1474514999
,
1471783658
,
1012864704
,
3615627536
,
993855884
,
438456717
,
3358938551
,
3906991208
,
198959101
,
3317190635
,
3656923078
,
613157871
,
2398768861
,
97286225
,
2336972940
,
1471645170
,
3233163154
,
583597118
,
2863776301
,
3183067750
,
1384330715
,
2929694742
,
3522431804
,
2181488067
,
3303062236
,
3825712422
,
145643141
,
2148976293
,
2940910035
,
506798154
,
994590281
,
2231904779
,
3389770074
,
2814269052
,
1105937096
,
1789727804
,
3757028753
,
2469686072
,
1162286478
,
680814033
,
2934024098
,
2162521262
,
4048876895
,
2121620700
,
4240287315
,
2391811140
,
3396611602
,
3091349617
,
3031523010
,
2486958601
,
3164065171
,
1285603712
,
798920280
,
2337813135
,
4186055520
,
3523024366
,
1077514121
,
1436444106
,
2731983230
,
1507202797
,
500756149
,
198754565
,
2382448647
,
880454148
,
1970517398
,
3217485349
,
1161840191
,
560498076
,
1782600856
,
2643721918
,
1285196205
,
788797746
,
1195724574
,
4061612551
,
103427523
,
2502688387
,
4147162188
,
617564657
,
978211984
,
1781482121
,
2205798970
,
3939973102
,
3826603515
,
659557668
,
2582884932
,
1561884856
,
2217488804
,
1189296962
,
169145316
,
2781742156
,
1323893433
,
824667876
,
408202876
,
3759637634
,
4094868412
,
1508996065
,
162419237
,
3732146944
,
3083560189
,
3955940127
,
2393776934
,
2470191468
,
3620861513
,
481927014
,
2756226070
,
3154651143
,
1261069441
,
2063238535
,
2222237213
,
101459755
,
3159774417
,
1721190841
,
1078395785
,
176506553
,
3552913423
,
1566142515
,
1938949000
,
1499289517
,
3315102456
,
829714860
,
3843359394
,
952932374
,
1283577465
,
2045007203
,
3957761944
,
3767891405
,
2917089623
,
3296133521
,
482297421
,
1734231412
,
3670478932
,
2575334979
,
2827842737
,
3413631016
,
1533519803
,
4008428470
,
3890643173
,
272960248
,
317508587
,
3299937500
,
2440520601
,
27470488
,
1666674386
,
1737927609
,
750987808
,
2385923471
,
2694339191
,
562925334
,
2206035395
]
i
=
0
while
i <
len
(c):
index
=
0
for
ii
in
c[i:i
+
4
]:
index
=
(index <<
8
)
+
ord
(ii)
store.append(index)
i
+
=
4
if
not
i <
len
(c):
key
=
[
54
,
54
,
54
,
54
]
store_len
=
len
(store)
res
=
encrypt(store_len, store, key)
if
store
=
=
cipher:
print
(
'You are right!'
)
input
('')
quit()
else
:
print
(
'Why not drink a cup of tea and have a rest?'
)
continue
from
cup
import
*
from
libnum
import
*
if
__name__
=
=
'__main__'
:
flag
=
input
(
'请输入flag'
)
pub_key
=
[
0x649EE967E7916A825CC9FD3320BEABF263BEAC68C080F52824A0F521EDB6B78577EC52BF1C9E78F4BB71192F9A23F1A17AA76E5979E4D953329D3CA65FB4A71DA57412B59DFD6AEDF0191C5555D3E5F582B81B5E6B23163E9889204A81AFFDF119FE25C92F4ED59BD3285BCD7AAE14824240D2E33C5A97848F4EB7AAC203DE6330D2B4D8FF61691544FBECD120F99A157B3D2F58FA51B2887A9D06CA383C44D071314A12B17928B96F03A06E959A5AFEFA0183664F52CD32B9FC72A04B45913FCB2D5D2D3A415A14F611CF1EAC2D6C785142A8E9CC41B67A6CD85001B06EDB8CA767D367E56E0AE651491BF8A8C17A38A1835DB9E4A9292B1D86D5776C98CC25
,
0x647327833ACFEF1F9C83E74E171FC300FA347D4A6769476C33DA82C95120ACB38B62B33D429206FE6E9BB0BB7AB748A1036971BEA36EC47130B749C1C9FF6FE03D0F7D9FC5346EB0E575BDFA6C530AA57CD676894FC080D2DD049AB59625F4B9C78BCFD95CDCD2793E440E26E189D251121CB6EB177FEDB596409034E8B0C5BBD9BD9342235DBB226C9170EFE347FF0FD2CFF9A1F7B647CC83E4D8F005FD7125A89251C768AFE70BDD54B88116814D5030F499BCAC4673CCCC342FB4B6AC58EA5A64546DC25912B6C430529F6A7F449FD96536DE269D1A1B015A4AC6B6E46EE19DCE8143726A6503E290E4BAE6BD78319B5878981F6CFFDB3B818209341FD68B
]
m
=
libnum.s2n(flag)
c
=
str
(
pow
(m, pub_key[
1
], pub_key[
0
]))
store
=
[]
cipher
=
[
3532577106
,
1472742623
,
3642468664
,
4193500461
,
2398676029
,
617653972
,
1474514999
,
1471783658
,
1012864704
,
3615627536
,
993855884
,
438456717
,
3358938551
,
3906991208
,
198959101
,
3317190635
,
3656923078
,
613157871
,
2398768861
,
97286225
,
2336972940
,
1471645170
,
3233163154
,
583597118
,
2863776301
,
3183067750
,
1384330715
,
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2022-6-6 19:22
被t0hka1编辑
,原因: