• 如何绕过api的防重放做安全测试


    一、问题引入:api接口测试,会检测请求头中的nonce参数的值,每次请求的值必须不同,否则发包失败

            笔者在进行api接口的测试时(因为菜没有工具,只能另辟蹊跷),使用postman+xray进行安全测试,但是因为nonce参数检测的缘故,导致xray的发出的扫描包全部失效,导致无法使用xray进行安全扫描,由此引入问题。

    二、解决思路

     2.1 给xray配置http请求的Header头的nonce参数(pass)

     这种方式,流量走向还是 postman --> xray --> 服务器

     查看xray的配置文件,我的版本为1.9,配置文件config.yaml

    但是在这个配置文件中,headers的配置的值是静态的,nonce的值并不能动态变化,也就是说每次发包的nonce值还是一致的,并没有解决问题。此条思路pass,或者是我理解的不够,没有配置好,希望知道的大佬告知一声。

    2.2 在xray之后再配置一条代理,流量postman-->xray-->代理--> 服务器

            后来决定另辟一条线,就是给xray加代理,在xray的上层代理处将xray发出扫描的扫描请求包的header头中nonce替换掉,已实现绕过api防止重放的验证。

    在xray的配置文件中配置代理即可,当前xray支持 https http socket5的代理

    三、实践(postman --> xray --> burpsuite --> 服务器)

    我这里为了实现上述的解决方案,用了postman+xray+burpsuite的结局方案。

    整理思路及配置如下:

    • 1、postman配置代理为xray

    • 2、主机安装xray和burp的证书

    双击对应的证书文件即可

    • 3、xray配置代理为burpsuite监听端口

    • 4、burp创建扩展脚本(当前bp版本为2023.1),将所有请求包的nonce参数的值替换

    1. # -*- coding: utf-8 -*-
    2. from burp import IBurpExtender
    3. from burp import IHttpListener
    4. import random
    5. import string
    6. class BurpExtender(IBurpExtender, IHttpListener):
    7. def registerExtenderCallbacks(self, callbacks):
    8. # 获取 Burp 的回调对象
    9. self._callbacks = callbacks
    10. # 获取扩展工具
    11. self._helpers = callbacks.getHelpers()
    12. # 设置扩展名
    13. callbacks.setExtensionName("Nonce Modifier")
    14. # 注册 HTTP 监听器
    15. callbacks.registerHttpListener(self)
    16. def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
    17. # 仅处理请求
    18. if messageIsRequest:
    19. print("Processing HTTP request message")
    20. # 获取请求信息
    21. request_info = self._helpers.analyzeRequest(messageInfo.getRequest())
    22. headers = request_info.getHeaders()
    23. # 修改请求头中的 nonce 参数
    24. modified_headers = self.modifyNonceHeader(headers)
    25. # 打印修改后的请求头
    26. print("Modified Headers:", modified_headers)
    27. # 构造修改后的请求
    28. modified_request = self._helpers.buildHttpMessage(modified_headers, messageInfo.getRequest()[request_info.getBodyOffset():])
    29. # 更新请求消息
    30. messageInfo.setRequest(modified_request)
    31. def modifyNonceHeader(self, headers):
    32. # 寻找并修改 nonce 参数
    33. for i in range(len(headers)):
    34. if headers[i].lower().startswith("nonce:"):
    35. headers[i] = "Nonce: {}".format(self.generateRandomNonce())
    36. return headers
    37. def generateRandomNonce(self):
    38. # 生成随机 8 位字符串
    39. # 生成随机 8 位字符串,并去除两侧空白字符
    40. nonce = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(8)).strip()
    41. print("Generated Nonce:", nonce)
    42. return nonce

    至此,所有配置完毕。

    ps:也可以使用其他代理工具,只要能实现对应功能即可,比如mitmproxy代理工具

    四、实践2(postman->xray->mitmproxy--》服务器)

    1、配置mitmproxy

    首先安装mitmproxy 的证书,才能抓包

    1. #启动监听端口
    2. mitmdump -p 9999

    浏览器配置代理为127.0.0.1:9999 (可使用浏览器switchyOmega 扩展插件)

    访问http://mitm.it获取对应证书,并双击安装

    2、配置mitmproxy脚本,并启动监听

    因为防重放的问题,需要所有讲经过mitmproxy的流量都配置不同的nonce头,故启动前执行脚本proxy.py

    1. import random
    2. def request(flow):
    3. # 生成随机 nonce 并设置为请求头
    4. flow.request.headers['nonce'] = str(random.randint(100, 999999))
    mitmweb.exe -p 9999 -s proxy.py --set block_global=false --ssl-insecure

     此时,mitmproxy的配置完成,可通过访问http://localhost:8081访问web管理界面

    3、配置xray

    两处都需要配置,设置为mitmproxy的代理端口即可

    4、配置postman

    将postman的代理端口设置为xray的即可

    五、可能存在的问题

    1、如果服务器必须使用https请求,这里涉及证书的问题,因为比较经过多层代理转发,xray可能会有tls连接失败的问题(后续测试,是没有在xray中的配置文件的mitm 的upstream_proxy 做配置的原因)

    [ERRO] 2023-10-17 16:09:16 [sqldet:detector.go:307] Post "https://xxx.xxx.xxx.xxx/open/api/groups": remote error: tls: user canceled

    目前推测还是证书的问题,还希望有大佬看到能详解。
     

    ps:目前xray结合mitmproxy没有出现过相关问题,建议用这种方式

  • 相关阅读:
    面试面经|Java开发面试JVM面试题
    按照Gartner的概念,国内所谓低代码产品都是“伪低代码”——到底什么才是“低代码”?
    linux系统下,在vscode的命令行中调试python文件
    Netty架构详解
    如何从算法方面提升论文档次
    Open3D FPS最远点下采样
    Maven的安装与配置以及注意事项
    spring源码理解
    关于大数据测试,你一定要试试python的fake库
    AI都那么发达了,我还有必要学习编程吗
  • 原文地址:https://blog.csdn.net/youuzi/article/details/133887463