长亭百川云 - 文章详情

技巧|记一次渗透测试之AES加密参数与踩坑记录

沐尘

48

2024-07-18

朋友们现在只对常读和星标的公众号才展示大图推送,建议大家把“亿人安全****“设为星标”,否则可能就看不到了啦

**原文首发在先知社区
**

https://xz.aliyun.com/t/15031

介绍:又一次公司的测内网系统项目的出现了流量加密,于是进行前端调试js逆向后对其流量反解密进行渗透(一次简单记录分享,大佬勿喷)

登录系统后,查看了历史数据包,基本上都是/api/xxx/xxx?params=加密数据
这样的接口,所以就怀疑系统对流量做了加密,于是在前端调试开始找加密代码。

# 其中一个数据包展示  
GET /api/foidisplay/mzhyxyhhxjbxx/getBqCountBy?params=%2BkrOw%2Fizxq2qXvIYnwWiEoShthvEcp%2F%2Brera6frw9lbc9k8B4aEDqui9BIDQLuR5I3zAOCIaIykTiQmZxaGjXA%3D%3D HTTP/1.1  
Host: target.com  
Authorization: Bearer 7c28172e-e9a9-404d\-899a-e5b720f3a90e

首先F12
在下图处(当时的图找不到了)添加一个接口为断点,当系统访问到这个接口时就会触发断点,这时我们就可以开始进行断点调试开始找加密代码

还有2种方法是:
1、找加密关键字,如加密参数为params
这个参数,但是搜索出来很多,一个个排查太多了不现实。
2、直接搜索加密关键字encrypt
,也可以搜索出来js加密代码。
这次比较幸运直接搜关键字encrypt
就直接搜索了出来,知道了是使用了AES加密,但是这时还不知道使用的key
和iv
是哪个,于是在此加密代码下添加断点。断到这段代码后,e是明文参数,n是密钥,c是iv。
这里的key
和iv
就是取数据包中的Authorization
参数后16位字符串对明文进行加密。

# 使用AES加密,通过传入的参数 e(待加密数据),n(密钥),c(初始化向量)来实现加密过程,模式为 CBC,填充方式为 ZeroPadding,最后将加密后的结果以 Base64 编码返回。  
function w(e, n, c) {  
  var t \= g, a \= y;  
  n && (t \= v.enc.Utf8.parse(n),  
        a \= v.enc.Utf8.parse(c));  
  var u \= v.enc.Utf8.parse(e)  
    , r \= v.AES.encrypt(u, t, {  
      iv: a,  
      mode: v.mode.CBC,  
      padding: v.pad.ZeroPadding  
    });  
  return v.enc.Base64.stringify(r.ciphertext)

知道了用得何种加密后,我们就能开始使用python或者其他的语言来进行模拟加密,笔者喜欢用python,上代码

from Crypto.Cipher import AES  
import base64,json  
from urllib.parse import unquote,quote,urlencode  
  
\# 0填充  
def zero\_pad(data, block\_size):  
    \# 计算需要填充的字节数  
    padding\_length \= (block\_size \- len(data) % block\_size) % block\_size  
    \# 使用零字节填充  
    return data + b'\\0' \* padding\_length  
  
\# 加密  
def encrypt(data, key, iv):  
    cipher \= AES.new(key.encode(), AES.MODE\_CBC, iv.encode())  
    padded\_message \= zero\_pad(data.encode(), AES.block\_size)  
    ciphertext \= cipher.encrypt(padded\_message)  
    return base64.b64encode(ciphertext).decode('utf-8')  
  
\# 移除填充  
def zero\_unpad(data):  
    last\_nonzero\_byte \= len(data) \- 1  
    while last\_nonzero\_byte \>= 0 and data\[last\_nonzero\_byte\] \== 0:  
        last\_nonzero\_byte \-= 1  
    \# 截取去除填充的数据  
    return data\[:last\_nonzero\_byte + 1\]  
  
\# 解密  
def decrypt(data, key, iv):  
    cipher \= AES.new(key.encode(), AES.MODE\_CBC, iv.encode())  
    decrypted\_text \= cipher.decrypt(base64.decodebytes(data.encode()))  
    return zero\_unpad(decrypted\_text).decode('utf-8')  
  
if \_\_name\_\_ \== '\_\_main\_\_':  
    Authorization \= "Bearer 580ea5db-2205-4f13-b17f-17740feb4513"  
    key \= iv \= Authorization\[\-16:\]  
    while 1:  
        params \= unquote(input("输入加密的params值:"))  
        data \= decrypt(params,key,iv)  
        print("明文params:"+ decrypt(params,key,iv))  
        data \= json.loads(data)  
        print(urlencode(data))  
        json \= input("输入明文:")  
        print("密文params:" + quote(encrypt(json,key,iv)))  
\# %2BkrOw%2Fizxq2qXvIYnwWiEoShthvEcp%2F%2Brera6frw9lbc9k8B4aEDqui9BIDQLuR5I3zAOCIaIykTiQmZxaGjXA%3D%3D  
\# {"bqmc":"","bqtx":"","sfqy":"","currentPage":1,"pageSize":9}

通过对比抓包得到的加密字符串,发现是一致的,那么就可以确定了该加解密脚本是正常的,就可以开始利用此脚本进行辅助渗透了。
附上最后的成果,用sqlmap找到了一个高危sql注入。

踩坑记录

记录一

刚知道了是使用AES加密后,开心的去找gpt一顿输出来一个python加解密脚本,上面是系统生成的密文,下面是笔者用python脚本模拟生成的密文,可以发现在后面的一小段部分是不一样的。

于是又再一次去断点调试看看是不是系统进行了别的操作。分析过后并未发现改变的有哪一种操作。

然后去询问大佬,看看是哪一步出错了,把2个生成的密文发了给他,得出的结论是2个密文AES加密使用的填充方法不一样
系统密文使用的是Zero Padding 填充,python脚本使用的是PKCS#5 / PKCS#7 填充,因此可以断定是padding的问题,导致加密后的密文不一致。

  1. PKCS#5 / PKCS#7 填充:
    这是最常见的填充方式,它在最后一个块需要填充时,将填充的字节都设置为填充的字节数。例如,如果需要填充4个字节,则填充的字节都为4(即 \x04\x04\x04\x04
    )。

  2. Zero Padding 填充:
    这种方式是在最后一个块的末尾添加零字节,直到块的长度达到块大小(通常是16字节)。

  1. \# 经过百度后是padding的问题,填充方式python默认的不是zeropadding,加一部分就OK了  
    def zero\_pad(data, block\_size):  
     \# 计算需要填充的字节数  
     padding\_length \= (block\_size \- len(data) % block\_size) % block\_size  
    \# 使用零字节填充  
    return data + b'\\0' \* padding\_length
    

    ###记录二
    在上面添加的XHR断点调试后,经过了一段时间调试前端代码,但还是找不到加密代码出来,废了不少时间,后来直接搜索encrypt后直接就搜索出来了,但是有几段的加密代码,经过添加断点才确定了。

    前端调试总结:
    1、先全局搜索加密关键字,如本次的params参数
    2、全局搜索encrypt/decrypt,幸运的话可以一步找出来
    3、添加XHR断点,一步步进行前端调试寻找代码(比较慢,但也是最稳的办法)

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2