声明
本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责!
前言
最近一段时间都在搞各种APP,有些APP虽然我搞出来了,但不能商用,思来想去,总不能白搞了,故写此文档用于技术交流。
本文档所用到的工具:
链接: pan.baidu.com/s/1FoEjXZ28… 提取码: m5vh
一、案例资源
目标APP
Zea1t+mAmui0og==
示例页面
二、案例分析
使用Fiddler拦截到文章访问链接
aHR0cHM6Ly9zdG9ja2luZm8uaHRzZWMuY29tOjE5MDkxL2h0c2VjTmV3c0RldGFpbC92aWV3L2h0c2VjTmV3cy9pbmRleC5odG1sP25ld3N0eXBlPXN0b2NrbmV3cyZzb3VyY2V0eXBlPWNyb3NzcHpiJnNoYXJlZnJvbT1hcHAmaWQ9Y2xzX3B6Yi0xNTM2MjY4JnR5cGU9cHpiJnRoZW1lPWRheSZjaGFubmVsPWFuZHJvaWQmdmVyc2lvbj04LjcwJmFwcHZlcj04LjcwJnRoZW1lPWRheSZ2ZXJzaW9uPTguNzAmY2hhbm5lbD1hbmRyb2lk
使用Fiddler拦截到文章请求接口
aHR0cHM6Ly9zdG9ja2luZm8uaHRzZWMuY29tOjE5MDg5L2FwaS9OZXdzRGV0YWlsP3NvdXJjZXR5cGU9Y3Jvc3NwemImaWQ9Y2xzX3B6Yi0xNTM2MjY4JnZlcnNpb249OC43MCZjaGFubmVsPWFuZHJvaWQ=
文章请求接口返回页面数据
从响应体可以看出summarylink就是加密后的内容,relate_stock就是加密后的股票代码。
三、JS逆向代码分析
定位关键代码块
从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调试栈追踪
追栈到for循环中可以发现$decrypt_ECB前relate_stock仍是加密的。
追栈到for循环外可以发现$decrypt_ECB后relate_stock已解密,展现出股票代码列表。
同样方式可以解密出内容。
Fiddler插件调试
将关键代码复制出来,写一个返回解密内容的方法,即可拿到加密后的内容。