爬虫进阶之AES ECB加密算法JS逆向

353 阅读3分钟

声明

本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!

本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责!

前言

最近一段时间都在搞各种APP,有些APP虽然我搞出来了,但不能商用,思来想去,总不能白搞了,故写此文档用于技术交流。

本文档所用到的工具:

链接: pan.baidu.com/s/1FoEjXZ28… 提取码: m5vh

一、案例资源

目标APP

Zea1t+mAmui0og==

示例页面

image.png

二、案例分析

使用Fiddler拦截到文章访问链接

aHR0cHM6Ly9zdG9ja2luZm8uaHRzZWMuY29tOjE5MDkxL2h0c2VjTmV3c0RldGFpbC92aWV3L2h0c2VjTmV3cy9pbmRleC5odG1sP25ld3N0eXBlPXN0b2NrbmV3cyZzb3VyY2V0eXBlPWNyb3NzcHpiJnNoYXJlZnJvbT1hcHAmaWQ9Y2xzX3B6Yi0xNTM2MjY4JnR5cGU9cHpiJnRoZW1lPWRheSZjaGFubmVsPWFuZHJvaWQmdmVyc2lvbj04LjcwJmFwcHZlcj04LjcwJnRoZW1lPWRheSZ2ZXJzaW9uPTguNzAmY2hhbm5lbD1hbmRyb2lk

使用Fiddler拦截到文章请求接口

aHR0cHM6Ly9zdG9ja2luZm8uaHRzZWMuY29tOjE5MDg5L2FwaS9OZXdzRGV0YWlsP3NvdXJjZXR5cGU9Y3Jvc3NwemImaWQ9Y2xzX3B6Yi0xNTM2MjY4JnZlcnNpb249OC43MCZjaGFubmVsPWFuZHJvaWQ=

文章请求接口返回页面数据

image.png

从响应体可以看出summarylink就是加密后的内容,relate_stock就是加密后的股票代码。

三、JS逆向代码分析

定位关键代码块

image.png

从JS代码中不难看出使用的是AES ECB加密算法

AES ECB(Electronic Codebook)加解密算法是一种基于块加密的对称密钥加密算法,其中明文被分成固定长度的块,每个块都使用相同的密钥进行加密。ECB模式简单易用,但是容易受到重放攻击和数据泄露攻击。

在Java中,可以使用javax.crypto包中的类来实现AES ECB加解密算法。具体实现方式可以参考以下代码:

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class AESEcbUtil {

    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";

    public static String encrypt(String plainText, String key) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), ALGORITHM);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    public static String decrypt(String encryptedText, String key) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), ALGORITHM);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        return new String(decryptedBytes);
    }
}

在Python中,可以使用pycryptodome库来实现AES ECB加解密算法。具体实现方式可以参考以下代码:

from Crypto.Cipher import AES
import base64

def encrypt(plain_text, key):
    cipher = AES.new(key.encode(), AES.MODE_ECB)
    encrypted_bytes = cipher.encrypt(plain_text.encode())
    return base64.b64encode(encrypted_bytes).decode()

def decrypt(encrypted_text, key):
    cipher = AES.new(key.encode(), AES.MODE_ECB)
    decrypted_bytes = cipher.decrypt(base64.b64decode(encrypted_text))
    return decrypted_bytes.decode().rstrip('\0')

在JavaScript中,可以使用crypto库来实现AES ECB加解密算法。具体实现方式可以参考以下代码:

const crypto = require('crypto');

function encrypt(plainText, key) {
    const cipher = crypto.createCipheriv('aes-256-ecb', key, null);
    let encrypted = cipher.update(plainText, 'utf8', 'base64');
    encrypted += cipher.final('base64');
    return encrypted;
}

function decrypt(encryptedText, key) {
    const decipher = crypto.createDecipheriv('aes-256-ecb', key, null);
    let decrypted = decipher.update(encryptedText, 'base64', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
}

JS调试栈追踪

image.png

追栈到for循环中可以发现$decrypt_ECB前relate_stock仍是加密的。

image.png

追栈到for循环外可以发现$decrypt_ECB后relate_stock已解密,展现出股票代码列表。

同样方式可以解密出内容。

Fiddler插件调试

将关键代码复制出来,写一个返回解密内容的方法,即可拿到加密后的内容。

379b3a55015a639b3a224bb38567b52.jpg