服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

安卓协议逆向 cxdx 分析与实现

日期: 来源:看雪学苑收集编辑:行简


本文为看雪论坛优秀文章

看雪论坛作者ID:行简





Kit


app 版本:5.0.0
设备:K40 刷 piexl 11 rom
抓包工具:Charles
反汇编工具:JEB、JADX、IDA
inject:frida




抓包


POST /v1/api/app/login/doLogin HTTP/1.1X-OsVersion: 30User-Agent: Mozilla/5.0 (Linux; Android 11; M2012K11AC Build/RQ3A.211001.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 CSDNApp/5.0.0(Android)wToken/0.0.1X-RandomNum: 54736X-Access-Token: 00871d5df0d4f51efb5883b3b2fd2359platform: androidX-Ca-Signature-Headers: X-Ca-Timestamp,X-Ca-Key,X-Ca-NonceAuthorization:X-OS: Androidc_appVersion: 5.0.0X-App-ID: CSDN-APPX-App-Theme: daycontent-type: application/json; charset=UTF-8X-Ca-Signature: BqhPpXbobBOndykiyCtOVK06GHLkfLbs1y4B3Ek0gnY=X-ConnectionType: WIFIUserToken:X-TimeStamp: 1671939318488Cookie: UserName=;UserToken=X-Ca-Key: 203789067Accept: application/jsonX-Device-ID: aid0f0fef992b53479187546b3c621157f0wToken: e447_5rU5WWYQegPo5EMOZSnKzF4YPtJSetwo+lGrEUrtZaKEe73GkiTOoE83PLp0yivsi4pZV7HySc+lbsebppMqHlXmQwVLx0vrlQpYC0b99vOYBRZWnVbeMhLZ4WUuAAKH/V07WkNSNXORUsgHumLj1BZZ7x1riK8beahdp9ctmSwP3AdA/sZA4OkzEVF4rJ+G6nwyyGcI/JLoRH0/1hPUT91sdBKKA64yj1QKRAZuJjsX9WRcqo9xYgfcJDnpqVnhObGQD96CfSok8z8d9otv+Fl6ULZrddvcnvzs6cJhjuW3ryBn151Xat/2CU/9EXUEKG3e0g4/K9rEaDRb2JhDGEDwIj+Qd5RU1uaBKxS/7jlSVq8wQ7x3qVVN1tHqS4AXhVow6eMABT6PArcEfkFm42bwXOFWsAUd5C7uGvHGIlTGytU6Vx/CJPwPvCuSffef5mQL7daszEzN+zQJ9VjxgOrjKXkDVkt6O6UpyA+1u3lowOqUaSPK6u2vND/Xqus7&ff4b_85475962D8E15A4E7AE60ED42FF3568E8EDB86EE620E495591X-DeviceModel: Redmi M2012K11ACversion: 5.0.0X-Ca-Nonce: be0eca5c-e959-4b0f-b4e7-22e00118157eX-Ca-Timestamp: 1671939318489X-Sign: 70B21B02FD0EFD2353F0D7F4F2E7CDB6FC1C3C42Host: passport.csdn.netConnection: Keep-AliveAccept-Encoding: gzipContent-Length: 95{"pwdOrVerifyCode":"123456","loginType":"1","userIdentification":"17750659921","checkAli":true}

意料之中一大堆参数,反复几次总结需分析的参数应该为以下几个:
X-Sign、wToken、X-Ca-Signature、X-Access-Token、X-Ca-Timestamp





分析


先搜索 X-Sign,就一处。

跟进得:
public static Map<String, String> z(String url, Map<String, String> requestMap) {    String str;    String a2 = wo3.a(CSDNApp.csdnApp);    HashMap hashMap = new HashMap();    hashMap.put("platform", "android");    hashMap.put("version", xn3.u());    hashMap.put("c_appVersion", xn3.u());    if (!TextUtils.isEmpty(it3.g())) {        hashMap.put("JWT-TOKEN", it3.g());        no3.a("==JWT-TOKEN==", it3.g());    }    hashMap.put("Authorization", StringUtils.isEmpty(it3.g()) ? "" : "Bearer " + it3.g());    hashMap.put("X-Device-ID", a2);    hashMap.put("X-OS", "Android");    hashMap.put("X-App-ID", "CSDN-APP");    hashMap.put("X-Access-Token", MD5.md5(a2 + "AndroidCSDN-APPb85fF96d-7Aa4-4Ec1-bf1D-2133c1A45656"));    hashMap.put("X-OsVersion", Build.VERSION.SDK_INT + "");    String str2 = Build.BRAND + Operators.SPACE_STR + Build.MODEL;    int length = str2.length();    for (int i = 0; i < length; i++) {        char charAt = str2.charAt(i);        if ((charAt <= 31 && charAt != '\t') || charAt >= 127) {            str2.replace(charAt, ' ');        }    }    hashMap.put("X-DeviceModel", str2);    hashMap.put("X-ConnectionType", yp3.b(CSDNApp.csdnApp));    hashMap.put("UserToken", StringUtils.isEmpty(it3.q()) ? "" : it3.q());    hashMap.put("X-App-Theme", CSDNApp.isDayMode ? "day" : "night");    int c2 = xn3.c(10000, 99999);    String str3 = new Date().getTime() + "";    try {        str = mq3.a(a2 + c2 + str3 + zf1.o);    } catch (DigestException e2) {        e2.printStackTrace();        str = "";    }    hashMap.put("X-Sign", str);    hashMap.put("X-RandomNum", c2 + "");    hashMap.put("X-TimeStamp", str3);    StringBuilder sb = new StringBuilder();    sb.append("UserName=");       sb.append(it3.p());    sb.append(";UserToken=");    sb.append(StringUtils.isEmpty(it3.q()) ? "" : it3.q());    hashMap.put(IWebview.COOKIE, sb.toString());    if (!StringUtils.isEmpty(url) && requestMap != null && requestMap.containsKey("category")) {        hashMap.put("X-PageKey", "blog." + requestMap.get("category"));        hashMap.put("X-Path", "app.csdn.net/blog/" + requestMap.get("category"));    }    if (!StringUtils.isEmpty(url) && url.equals(s22.G0)) {        hashMap.put("X-PageKey", vr3.Q6);        hashMap.put("X-Path", "app.csdn.net/blog/detail");        if (requestMap != null && requestMap.containsKey("from")) {            hashMap.put("X-Referer", "blog." + requestMap.get("from"));        }    }    hashMap.put("User-Agent", CSDNApp.csdnApp.userAgent + " CSDNApp/" + xn3.u() + "(Android)wToken/0.0.1");    try {        hashMap.put("wToken", TigerTallyAPI.vmpSign(1, str3.getBytes("UTF-8")));    } catch (UnsupportedEncodingException e3) {        e3.printStackTrace();    }    return hashMap;}

pretty nice,很多参数都在这里,那就从上往下分析:
hashMap.put("platform", "android"); // 固定值hashMap.put("version", xn3.u()); // 固定值hashMap.put("c_appVersion", xn3.u()); // 固定值hashMap.put("Authorization", StringUtils.isEmpty(it3.g()) ? "" : "Bearer " + it3.g()); // 无用,请求头中为空hashMap.put("X-Device-ID", a2); // a2 在 String a2 = wo3.a(CSDNApp.csdnApp);

hook wo3.a看看:
function main() {    Java.perform(function () {        var wo3 = Java.use("wo3");        wo3["a"].implementation = function (context) {            console.log('a is called' + ', ' + 'context: ' + context);            var ret = this.a(context);            console.log('a ret value is ' + ret);            return ret;        };    });}setImmediate(main)

结果:
a is called, context: net.csdn.csdnplus.CSDNApp@dc96acba ret value is aid0f0fef992b53479187546b3c621157f0

多次 hook 该值并没有改变,查看不同数据包的内容也是一样的,但在 Java 层仅分析到 aid 复制点,后面数据同一设备都是一样的,怀疑是消息散列值,有可能是 DeviceID 或者 UUID,有在 Java 层看到,但 hook 不到,往下分析:
hashMap.put("X-OS", "Android"); // 固定值hashMap.put("X-App-ID", "CSDN-APP"); // 固定值hashMap.put("X-Access-Token", MD5.md5(a2 + "AndroidCSDN-APPb85fF96d-7Aa4-4Ec1-bf1D-2133c1A45656")); // a2 就是上面的 X-Device-ID 再进行加盐处理后进行 MD5 加密复现一下:

from hashlib import md5 def encrypt_md5(mes):    new_md5 = md5()    # 这里必须用encode()函数对字符串进行编码,不然会报 TypeError: Unicode-objects must be encoded before hashing    new_md5.update(mes.encode(encoding='utf-8'))    # 加密    return new_md5.hexdigest() if __name__ == '__main__':    print(encrypt_md5('aid0f0fef992b53479187546b3c621157f0AndroidCSDN-APPb85fF96d-7Aa4-4Ec1-bf1D-2133c1A45656'))

结果 00871d5df0d4f51efb5883b3b2fd2359,校验无误,继续往下:
hashMap.put("X-OsVersion", Build.VERSION.SDK_INT + ""); // sdk 版本吧,可随机的样子hashMap.put("X-DeviceModel", str2); // 通过上面获取来的,分析一下就是手机 + 手机名称hashMap.put("X-ConnectionType", yp3.b(CSDNApp.csdnApp)); // 网络连接类型hashMap.put("UserToken", StringUtils.isEmpty(it3.q()) ? "" : it3.q()); // 抓包为空值,放弃hashMap.put("X-App-Theme", CSDNApp.isDayMode ? "day" : "night"); // 主题模式hashMap.put("X-Sign", str);

str 是上面计算来的,拿来分析下:
int c2 = xn3.c(10000, 99999);String str3 = new Date().getTime() + "";try {    str = mq3.a(a2 + c2 + str3 + zf1.o);} catch (DigestException e2) {    e2.printStackTrace();    str = "";}hashMap.put("X-Sign", str);

c2:10000 - 99999 之间的随机值;str3:时间戳转字符串;a2:上面分析过为 X-Device-ID 值;zf1.o:跟进查看为定值:public static final String o = "F403F982CA92F73AC142D50FFA69853D";

参数搞定,看 mq3.a 方法:
public static String a(String decrypt) throws DigestException {    try {        MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");        messageDigest.update(decrypt.getBytes());        byte[] digest = messageDigest.digest();        StringBuffer stringBuffer = new StringBuffer();        for (byte b : digest) {            String hexString = Integer.toHexString(b & 255);            if (hexString.length() < 2) {                stringBuffer.append(0);            }            stringBuffer.append(hexString);        }        return stringBuffer.toString().toUpperCase();    } catch (NoSuchAlgorithmException e) {        e.printStackTrace();        throw new DigestException("签名错误!");    }}

SHA1算法,先 hook 再还原:
function main() {    Java.perform(function () {        var mq3 = Java.use("mq3");        mq3["a"].implementation = function (decrypt) {            console.log('a is called' + ', ' + 'decrypt: \n' + decrypt);            var ret = this.a(decrypt);            console.log('a ret value is ' + ret);            return ret;        };    });}setImmediate(main)// frida -FU -l CSDN/csdn.js

结果:
a is called, decrypt:aid0f0fef992b53479187546b3c621157f0709751671957807054F403F982CA92F73AC142D50FFA69853Da ret value is E11539C9183644EEB69C7FEBAC1D58A2D874895C

还原:
import hashlib # 使用sha1加密算法,返回str加密后的字符串def sha1_secret_str(s: str):    sha = hashlib.sha1(s.encode('utf-8'))    encrypts = sha.hexdigest()    return encrypts.upper() if __name__ == '__main__':    # 待加密的字符串    s = 'aid0f0fef992b53479187546b3c621157f0709751671957807054F403F982CA92F73AC142D50FFA69853D'    res = sha1_secret_str(s)    print(res)

结果:E11539C9183644EEB69C7FEBAC1D58A2D874895C 校验无误,继续往下分析:
hashMap.put("X-RandomNum", c2 + ""); // 10000 - 99999 之间的随机值;hashMap.put("X-TimeStamp", str3); // str3:时间戳转字符串;hashMap.put(IWebview.COOKIE, sb.toString()); // 看抓包结果应该是 Cookie 值,对照结果 UserName=;UserToken= 啥操作没做,应该是要登录后才有值也是固定值hashMap.put("User-Agent", CSDNApp.csdnApp.userAgent + " CSDNApp/" + xn3.u() + "(Android)wToken/0.0.1");

对照其抓包内容:CSDNApp.csdnApp.userAgent 获取设备 header,xn3.u() 获取 app 版本号。
// Mozilla/5.0 (Linux; Android 11; M2012K11AC Build/RQ3A.211001.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 CSDNApp/5.0.0(Android)wToken/0.0.1hashMap.put("wToken", TigerTallyAPI.vmpSign(1, str3.getBytes("UTF-8")));

看到 wToken 就有点不好的预感,应该是阿里安全的,前段时间很火的某box就是用的这个,跟进看看,最终定位到:
private static native String _genericNt3(int i, byte[] bArr);

so 层了,放着先看看别的参数吧,这块代码,能解决的参数都解决了,但 X-Ca-Signature 没在这出现,jadx 再搜跟到以下代码:
private static Map<String, String> c(StringBuilder strBuilder, Map<String, String> headerParams) {    if (ft3.b() != 1) {        headerParams.put("X-Ca-Stage", ft3.b() == 2 ? "TEST" : "PRE");    }    try {        Mac mac = Mac.getInstance("HmacSHA256");        byte[] bytes = y12.c.getBytes("UTF-8");        mac.init(new SecretKeySpec(bytes, 0, bytes.length, "HmacSHA256"));        String str = new String(Base64.encodeBase64(mac.doFinal(strBuilder.toString().getBytes("UTF-8"))));        headerParams.put("X-Ca-Signature", str);        no3.a("==HmacSHA256==", str);    } catch (UnsupportedEncodingException e2) {        e2.printStackTrace();    } catch (InvalidKeyException e3) {        e3.printStackTrace();    } catch (NoSuchAlgorithmException e4) {        e4.printStackTrace();    }    return headerParams;}

不难看出该值是通过 HmacSHA256 加密后再进行 Base64 编码后得到的结果,其 key 值为:
public static final String c = "0u94vkvsewic9kkgsp1r3nuq3ir0lv3n";hook 看看要加密 strBuilder 有啥:function main() {    Java.perform(function () {        var r12 = Java.use("r12");        r12["c"].implementation = function (strBuilder, headerParams) {            console.log('strBuilder: \n' + strBuilder);            var ret = this.c(strBuilder, headerParams);            var keyset = ret.keySet();            var result = "";            var it = keyset.iterator();            while (it.hasNext()) {                var keystr = it.next().toString();                var valuestr = ret.get(keystr).toString();                console.log(keystr)                console.log(valuestr)                result += valuestr;            }            return ret;        };    });}setImmediate(main)// frida -FU -l CSDN/csdn.js

结果:
strBuilder:POSTapplication/jsonapplication/json; charset=UTF-8X-Ca-Key:203789067X-Ca-Nonce:3339aae3-e295-410c-8345-52c9ebc56b5aX-Ca-Timestamp:1671963564343/v1/api/app/login/doLogin

其中 X-Ca-Key 是个定值:
headerParams.put("X-Ca-Key", y12.b);public static final String b = "203789067";X-Ca-Nonce 为 UUID 值:headerParams.put("X-Ca-Nonce", UUID.randomUUID().toString());X-Ca-Timestamp 为时间戳。

python还原算法,与抓包结果一致:
from hashlib import sha256import hmac, base64 def get_sign(data, key):    key = key.encode('utf-8')    message = data.encode('utf-8')    sign = base64.b64encode(hmac.new(key, message, digestmod=sha256).digest()).decode()    print(sign)    return signif __name__ == '__main__':    # 待加密的字符串    s = "POST" + "\n" + \        "application/json" + "\n" + \        "\n" + \        "application/json; charset=UTF-8" + "\n" + \        "\n" + \        "X-Ca-Key:203789067" + "\n" + \        "X-Ca-Nonce:3339aae3-e295-410c-8345-52c9ebc56b5a" + "\n" + \        "X-Ca-Timestamp:1671963564343" + "\n" + \        "/v1/api/app/login/doLogin"    k = '0u94vkvsewic9kkgsp1r3nuq3ir0lv3n'    res = get_sign(s, k)    print(res)

抓包结果:QJYeguZxkE+ZojwTP0rIJ+IzjaSHI82uR2y0xOIG35U=

到这几乎参数都解决了,剩个 so 层的 wtoken,在 Java 层能够定位到:com/aliyun/TigerTally/TigerTallyAPI,其中,要找的就是 libtiger_tally.so 了:
static {    System.loadLibrary("tiger_tally");}

换思路做吧,不想折腾,想了想我直接 rpc 调用不就好了。




rpc 远程调用


frida rpc 脚本:
var response = null;Java.enumerateClassLoaders({    onMatch: function (loader) {        try {            if (loader.findClass("com.aliyun.TigerTally.TigerTallyAPI")) {                Java.classFactory.loader = loader;                response = Java.use("com.aliyun.TigerTally.TigerTallyAPI")            } else {            }        } catch (error) {        }    }, onComplete: function () {    }}); function stringToByte (str) {     var ch, st, re = [];     for (var i = 0; i < str.length; i++ ) {           ch = str.charCodeAt(i);          st = [];               do {                 st.push( ch & 0xFF );             ch = ch >> 8;          } while ( ch );        re = re.concat(st.reverse());      }     return re;} function getwwoken(data){    var result = response._genericNt3(1, stringToByte(data));    return result;} rpc.exports = {    getwtoken:getwwoken}

补环境:
import timeimport hmacimport uuidimport randomimport base64from hashlib import sha256, md5, sha1 def get_x_osversion():    return "30" def get_x_os():    return "android" def get_x_appid():    return "CSDN_APP" def get_x_app_theme():    return "day" def get_x_connection_type():    return "WIFI" def get_x_timestramp():    return str(int(time.time() * 1000)) def get_x_device_model():    return "Redmi M2012K11AC" def get_x_ca_Signature_Headers():    return "X-Ca-Timestamp,X-Ca-Key,X-Ca-Nonce" def get_User_Agent():    return "Mozilla/5.0 (Linux; Android 11; M2012K11AC Build/RQ3A.211001.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 CSDNApp/5.0.0(Android)wToken/0.0.1" def get_x_ca_nonce():    return str(uuid.uuid4()) def get_x_device_id():    return "aid0f0fef992b53479187546b3c621157f0" def get_access_token():    X_Access_Token = "aid0f0fef992b53479187546b3c621157f0AndroidCSDN-APPb85fF96d-7Aa4-4Ec1-bf1D-2133c1A45656"    md5_mes = md5(X_Access_Token.encode())    return md5_mes.hexdigest() x_timestramp = get_x_timestramp()x_ca_nonce = get_x_ca_nonce()def get_x_randomnum():    return str(random.randint(10000, 99999)) def get_x_ca_signature():    data = "POST" + "\n" + \        "application/json" + "\n" + \        "\n" + \        "application/json; charset=UTF-8" + "\n" + \        "\n" + \        "X-Ca-Key:203789067" + "\n" + \        "X-Ca-Nonce:3339aae3-e295-410c-8345-52c9ebc56b5a" + "\n" + \        "X-Ca-Timestamp:1671963564343" + "\n" + \        "/v1/api/app/login/doLogin"    key = "0u94vkvsewic9kkgsp1r3nuq3ir0lv3n".encode("utf-8")    message = data.encode("utf-8")    sign = base64.b64encode(hmac.new(key, message, digestmod=sha256).digest())    return str(sign, 'utf-8'), x_timestramp, x_ca_nonce def get_xsign():    xsign_mes = get_x_device_id() + get_x_randomnum() + x_timestramp + "F403F982CA92F73AC142D50FFA69853D"    return sha1(xsign_mes.encode("utf-8")).hexdigest().upper()

远程调用:
import fridafrom login_env import *import requests def on_message(message, data):    print("[%s] => %s" % (message, data)) def inject_hook():    session = frida.get_usb_device().attach('net.csdn.csdnplus')    with open('CSDN/rpc.js', 'r') as f:        js_code = f.read()    script = session.create_script(js_code)    script.on('message', on_message)    script.load()    return script def message(message, data):    if message["type"] == 'send':        print("[*] {0}".format(message['payload']))    else:        print(message) def req():    url = "https://passport.csdn.net/v1/api/app/login/doLogin"    headers = {        "X-OsVersion": "30",        "User-Agent": "Mozilla/5.0 (Linux; Android 11; M2012K11AC Build/RQ3A.211001.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 CSDNApp/5.0.0(Android)wToken/0.0.1",        "X-RandomNum": get_x_randomnum(),        "X-Access-Token": get_access_token(),        "platform": "android",        "X-Ca-Signature-Headers": "X-Ca-Timestamp,X-Ca-Key,X-Ca-Nonce",        "Authorization": "",        "X-OS": "Android",        "c_appVersion": "5.0.0",        "X-App-ID": "CSDN-APP",        "X-App-Theme": "day",        "content-type": "application/json; charset=UTF-8",        "X-Ca-Signature": get_x_ca_signature()[0],        "X-ConnectionType": "WIFI",        "UserToken": "",        "X-TimeStamp": get_x_ca_signature()[1],        "X-Ca-Key": "203789067",        "Accept": "application/json",        "X-Device-ID": get_x_device_id(),        "wToken": res,        "X-DeviceModel": "Redmi M2012K11AC",        "version": "5.0.0",        "X-Ca-Nonce": get_x_ca_signature()[2],        "X-Ca-Timestamp": get_x_ca_signature()[1],        "X-Sign": get_xsign(),        "Host": "passport.csdn.net",        "Connection": "Keep-Alive",        "Accept-Encoding": "gzip",    }    data = {"pwdOrVerifyCode":"123456","loginType":"1","userIdentification":"17750659921","checkAli":"true"}    response = requests.post(url, headers=headers,json=data)    print(response.text)  if __name__ == '__main__':    rpc_script = inject_hook()    res = rpc_script.exports.getwtoken(get_x_ca_signature()[1])    req()'''

结果,校验一致:
{"message":"用户名或密码错误","status":false,"code":"1039"}





看雪ID:行简

https://bbs.kanxue.com/homepage-945390.htm

*本文由看雪论坛 行简 原创,转载请注明来自看雪社区


# 往期推荐

1、Kernel PWN从入门到提升

2、Kernel PWN-开启smap保护的babydrive

3、【详解】CTFHUB-FastBin Attack

4、Relocate、PLT、GOT And Lazy Binding

5、拦截Windows关机消息

6、无路远征——GLIBC2.37后时代的IO攻击之道 house_of_一骑当千



球分享

球点赞

球在看


点击“阅读原文”,了解更多!

相关阅读

  • WSDM 2023 | 学习蒸馏图神经网络

  • ©作者 | 郭雨心单位 | 北京邮电大学来源 | 北邮GAMMA Lab图神经网络 (GNNs) 能够有效地获取图的拓扑和属性信息,在许多领域得到了广泛的研究。近年来,为提高 GNN 的效率和有
  • 浅谈在数据包被加密和签名保护时的渗透方式

  • 场景在金融银行类安全测试中,经常见到数据包加密、签名保护,这种业务不能直接进行有效的安全测试,修改数据包参数会重放失败,爬虫见到密文也是懵逼测试套路对于这种业务,不管是手
  • 13 个你可能未使用过的 Python 技巧!

  • 来源丨关于数据分析与可视化大多数程序员不知道的令人难以置信的功能列表。Python 是顶级编程语言之一,它具有许多程序员从未使用过的许多隐藏功能。在这篇博客中,我将分享你
  • 讲一个本周发生的小故事~

  • 喵~大家周四好呀。 最近又到了换季时,我的身体各种过敏反应都比较厉害,整个人的状态也不是很好。这两周取消了一些学习和出差计划,多一些时间留给自己静养。大家也要多保重身体
  • 江西7所高校新增一批专业!

  • 点击图片进入活动专题近日,教育部网站公布了《2023年高等职业教育专科专业设置备案和审批结果的通知》教育部网站截图详情如下↓教育部关于公布2023年高等职业教育专科专业设
  • 教育部公布

  • ↑↑↑点击蓝字,轻松关注! 日前,教育部组织完成了2023年高等职业教育专科专业设置备案和审批相关工作,并将结果予以公布。一起了解——经省

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • 拒付赎金,法拉利遭受勒索软件攻击后数据泄露

  • 近日,法拉利证实其发生了一起网络事件,黑客能够访问其IT环境中的部分系统。这家意大利豪华跑车制造商在一份声明中表示,攻击者获得了对其网络的访问权限,并向其索要赎金,否则就将
  • 安卓协议逆向 cxdx 分析与实现

  • 本文为看雪论坛优秀文章看雪论坛作者ID:行简一Kitapp 版本:5.0.0设备:K40 刷 piexl 11 rom抓包工具:Charles反汇编工具:JEB、JADX、IDAinject:frida二抓包POST /v1/api/app/login/
  • 议题征集 | 看雪·第七届安全开发者峰会启动!

  • 看雪·第七届安全开发者峰会随着云计算、大数据、人工智能等新技术的融合越发深入,网络已经覆盖了人们生活的方方面面。随之而来的网络钓鱼、恶意软件、身份盗用、数据泄露等
  • Realworld CTF 2023 ChatUWU 详解

  • 本文为看雪论坛优秀文章看雪论坛作者ID:pank1s一个基于 socket.io 的聊天室,当时进去很混乱,也很纳闷一个公共的聊天室打XSS别人不会上车吗?但实际不是这样的,重点是这个 socket.
  • 周末直播预告 | 充电不停

  • 快来预约*声明:针对未购课用户,观看视频号完整直播均需付费01系统0day安全-《网络协议fuzz之cgi》时间:3月25日(周六)20点02看雪安卓高研2w班-《更强的加密之如何使用DFA攻击密码