背景:在一次组长分配的系统渗透中遇到了流量加密,遂进行了前端js逆向调试进行解密操作(比较基础,适合小白)

在对系统进行渗透时,使用bp抓包发现流量是经过加密的,以下是某个流量包

POST /api/targetList/getpagelist HTTP/1.1
Host: target.com
Content-Length: 317
Accept: application/json, text/plain, */*
Authorization: jwt token
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0
Content-Type: application/json
Origin: 
Referer: 
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Connection: close

{"requestData":{"data":"加密的数据","sign":""}}

在数据包中发现了加密的参数requestData同时还有其他参数(sign、checkSum、CurrentTimeStamp、traceId),但这些不影响发包,于是全局搜索(ctrl+shift+f)关键字requestData即可
很幸运点开第一个js文件就发现了加密函数,但是具体的加密是d()函数,于是下一个断点进行调试

经过前端的一步一步js调试,最后找到了d()函数,附上js代码

//加密函数
//按chatgpt的解释:首先将密钥和初始向量转换为 UTF-8 编码格式。然后将要加密的数据 e 也转换为 UTF-8 编码格式。接着使用 AES 加密算法对数据进行加密,使用 CBC 模式和 PKCS7 填充。最后,将加密后的结果以 Base64 编码形式返回
function d(e, t, a) {
    var o, n;
    if (!t  !a)
      return !1;
    o = m.a.enc.Utf8.parse(t),
      n = m.a.enc.Utf8.parse(a);
    var i = m.a.enc.Utf8.parse(e)
      , r = m.a.AES.encrypt(i, o, {
        iv n,
        mode m.a.mode.CBC,
        padding m.a.pad.Pkcs7
      });
    return m.a.enc.Base64.stringify(r.ciphertext)
  }

此时知道了数据是使用了 AES 加密算法,这时候我们就能使用python脚本模拟js代码进行加解密了,附上python代码

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
import base64
import jwt,json

# 导入jwt token
token = 'your jwt token'

#加密
def encrypt_message(message, key, iv):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    padded_message = pad(message.encode(), AES.block_size)
    ciphertext = cipher.encrypt(padded_message)
    return base64.b64encode(ciphertext)

#解密
def decrypt_message(ciphertext, key, iv):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted_message = cipher.decrypt(base64.b64decode(ciphertext))
    return unpad(decrypted_message, AES.block_size).decode()

#取key
def get_key(token, key):
    try:
        # 解析 JWT
        payload = json.loads(base64.b64decode(token.split('.')[1]).decode('utf-8'))
        # 获取key值
        value = payload.get(key)
        return value.encode()
    except jwt.ExpiredSignatureError:
        print("JWT 已过期")
    except jwt.InvalidTokenError:
        print("无效的 JWT")

if __name__ == "__main__":
    SecretKey = get_key(token, 'SecretKey')
    SecretIV = get_key(token, 'SecretIV')
    # 加密
    message_decode = input("输入要加密的信息:")
    encrypt_result = encrypt_message(message_decode, SecretKey, SecretIV)
    print("加密信息: ", encrypt_result.decode('utf-8'))
    # 解密
    message = input("输入要解密的信息:").encode()
    decryp_result = decrypt_message(message, SecretKey, SecretIV)
    print("解密信息: ",decryp_result)

最后将数据包一步步解密->修改参数测试->加密发包也是成功的发现了报错sql注入漏洞,附上成果图

最后将这个系统渗透完了,自己在想对于流量有加密数据的怎么可以优化一下方便自己渗透呢?
优化:能不能将脚本集成到bp进行自动化加解密操作?
抓包->数据包参数data解密->bp->测试->bp->数据包参数data加密->请求
想到了burpy这个bp插件进行加密解密,下面为burpy所关联的脚本
https://github.com/mr-m0nst3r/Burpy

import json
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad,pad
import base64

class Burpy:
    '''
    header is dict
    body is string
    '''
    def __init__(self):
        '''
        here goes some code that will be kept since "start server" clicked, for example, webdriver, which usually takes long time to init
        '''
        pass

    def main(self, header, body):
        return header, body


    def encrypt(self, header, body):
        '''
        Auto Enc/Dec feature require this function
        '''
        token = header.get('Authorization')
        SecretKey = self.get_key(token, 'SecretKey')
        SecretIV = self.get_key(token, 'SecretIV')
        body = json.loads(body)#这里转换为str后出现了多余的空格
        message = json.dumps(body["requestData"]["data"]).replace(" ", "")

        cipher = AES.new(SecretKey, AES.MODE_CBC, SecretIV)
        padded_message = pad(message.encode(), AES.block_size)
        ciphertext = cipher.encrypt(padded_message)
        body = '{"requestData":{"data":"' + base64.b64encode(ciphertext).decode('utf-8')+'","sign":""}}'
        print(body)
        return header, body

    def get_key(self,token, key):
        import jwt, json
        import base64
        try:
            # 解析 JWT
            payload = json.loads(base64.b64decode(token.split('.')[1]).decode('utf-8'))
            # 获取值
            value = payload.get(key)
            return value.encode()
        except jwt.ExpiredSignatureError:
            print("JWT 已过期")
        except jwt.InvalidTokenError:
            print("无效的 JWT")

    def decrypt(self, header, body):
        '''
        Auto Enc/Dec feature require this function
        '''
        # header = magic(header)
        # body = magic(body)
        token = header.get('Authorization')
        SecretKey = self.get_key(token, 'SecretKey')
        SecretIV = self.get_key(token, 'SecretIV')
        body = json.loads(body)

        cipher = AES.new(SecretKey, AES.MODE_CBC, SecretIV)
        decrypted_text = cipher.decrypt(base64.decodebytes(bytes(body["requestData"]["data"], encoding='utf8')))
        body = '{"requestData":{"data":'+unpad(decrypted_text, AES.block_size).decode()+',"sign":""}}'
        #print(body)
        return header, body


    def processor(self, payload):
        '''
        Enable Processor feature require this function
        payload processor function
        '''
        return payload

编写好脚本后,直接在burpy中启动服务start server,利用bp进行抓包后,右键点击Burpy decrypt就可以将数据包解密,修完完参数后,右键点击Burpy encrypt就可以将数据包加密,然后就可以发送数据包了。
最后附上使用bp使用burpy解密成功效果图