js逆向实战之AES加密

前言

仅学习之用,勿商,侵删。

目标网站:aHR0cHMlM0EvL3d3dy5tYW9tYW96dS5jb20vJTIzL2J1aWxk

环境

node(执行破解js,提供接口)

python3.6(执行爬虫)

开始!

分析

请求页面,白白净净三条Ajax。
js逆向实战之AES加密_第1张图片

随便进去看看请求头和返回的数据。

js逆向实战之AES加密_第2张图片
在这里插入图片描述
好球,都是加密的数据。

接下来找到加密位置。

八仙过海,可以尝试直接搜索常见的关键词:md5,base64,RSA,ASE,encrypt,decrypt,JSON.parse等等。或者用油猴插件一次性hook一下。

这里找到加密位置,关键位置断点:

js逆向实战之AES加密_第3张图片
js逆向实战之AES加密_第4张图片
刷新页面,停在断点位置,发现aes_encrypt接收一个l变量,里面只有一个时间戳。

js逆向实战之AES加密_第5张图片
F8和F10配合使用,执行一下加密,返回来的e.data就是前面post请求的请求头加密参数。e.url就是我们要请求的url。
js逆向实战之AES加密_第6张图片
后面还有两个请求,类似操作都可以找到。

第二次请求

这里发现l变量多接收了一个Type参数。
js逆向实战之AES加密_第7张图片
js逆向实战之AES加密_第8张图片
第三次请求

这里发现l变量除多接收了一个Type参数,还有page参数,大胆怀疑这应该就是翻页参数,这个也就是我们需要的数据请求,在/index/build.json这个post请求里。
js逆向实战之AES加密_第9张图片
js逆向实战之AES加密_第10张图片

再继续执行,请求已经通过axios发送了,返回加密的数据需要在前端解密了。

第一个返回数据,e.data是一串加密数据。
js逆向实战之AES加密_第11张图片
进入aes_decrypt解密函数里,多观察几次,可以发现,l是aes的iv(偏移量),数值固定。
js逆向实战之AES加密_第12张图片
最后返回解密的数据。
在这里插入图片描述

第二次和第三次请求也是一样,返回数据进行AES解密,就不放截图了。

抠js代码

终于到了这一步了,曾经我也觉得抠代码是很复杂很麻烦的一件事(现在也是…),然后看那些大神写的逆向流程,很多到这里就直接结束了(可能是有麻烦吧,或者觉得没有必要了)。

其实经过前面的分析流程,这里的抠代码环节已经很清晰了。万事开头难,你动手去试试可能就会发现,其实还好。

我们把两个关键函数构造出来,接下来就是缺啥补啥了

function my_encrypt(l) {
    data = aes_encrypt(JSON.stringify(l));
    // console.log(data)
    return data
}

function my_decrypt(e) {
    data = aes_decrypt(e.replace(/^\s+|\s+$/gm, ""));
    // console.log(e)
    return data
}

为了不占用篇幅,完整的代码后面就放到github或者码云上吧。

破解后的js代码量很少,就一个md5和AES,可以直接用python代码进行重新构造。

这里采用直接运行js。

node运行js解密接口:http://127.0.0.1:3000/

python测试代码:

# -*- coding: utf-8 -*-

import time
import requests

url = "https://www.xxxx.com/index/build.json"  # 保险一下
jm_url = "http://127.0.0.1:3000/"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
                  " Chrome/83.0.4103.97 Safari/537.36"
}


def get_payload(pages=1):
    """获取post的请求参数"""
    now_time = int(round(time.time() * 1000))

    data = {
        "data": {"Type": 0, "page": pages, "expire": now_time}
    }
    print(data)

    # 获取加密请求参数
    _payload = requests.post(url=jm_url + 'my_encrypt', json=data).text
    print(_payload)
    return _payload


def get_html(data):
    """请求页面,返回加密的数据"""
    response = requests.post(url=url, headers=headers, data=data)
    _encrypt_data = response.text
    print(_encrypt_data)
    return _encrypt_data


def get_decrypt_html(en_data):
    """获取解密数据"""
    data = {
        "data": en_data
    }
    response = requests.post(url=jm_url + 'my_decrypt', data=data)
    html = response.text
    print(html)


if __name__ == '__main__':
    page = 2  # 页码
    payload = get_payload(pages=page)
    encrypt_data = get_html(payload)
    get_decrypt_html(encrypt_data)

最后

github代码:https://github.com/downdawn/JSreverse

你可能感兴趣的:(爬虫与逆向)