【问题标题】:Python requests https: code 403 without but code 200 when using BurpSuite使用 BurpSuite 时 Python 请求 https:没有但代码 200 的代码 403
【发布时间】:2021-03-06 03:01:48
【问题描述】:

我目前正在尝试抓取retailmenot.com,这是我的代码到目前为止的样子:

import requests
from collections import OrderedDict

s = requests.session()

s.headers = OrderedDict()
s.headers["Connection"] = "close"
s.headers["Upgrade-Insecure-Requests"] = "1"
s.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36"
s.headers["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
s.headers["Sec-Fetch-Site"] = "none"
s.headers["Sec-Fetch-Mode"] = "navigate"
s.headers["Sec-Fetch-Dest"] = "document"
s.headers["Accept-Encoding"] = "gzip, deflate"
s.headers["Accept-Language"] = "en-GB,en-US;q=0.9,en;q=0.8"

s.get("https://www.retailmenot.com/sitemap/A")

当我使用此代码时,我会立即被重定向到 CloudFlare 页面。也就是说,每当我通过 burpsuite 将我的流量替换为以下代码的最后一行时:

s.get("https://www.retailmenot.com/sitemap/A", proxies = {"https":"https://127.0.0.1:8080"}, verify ="/Users/Downloads/cacert (1).pem")

我直接进入网站。我觉得这有点奇怪,想知道是否有人可以向我解释为什么会发生这种情况以及是否有办法通过使用一些不同的证书来获得类似的结果(为了使用 BurpSuite 证书,我需要保持应用程序打开)。非常感谢!

【问题讨论】:

  • Burp 可能会更改标头的顺序,添加一些标头或类似内容,从而绕过机器人保护。更好地比较传入和传出请求。它可能与证书无关。
  • @SteffenUllrich 感谢您的回复。我知道 BurpSuite 发送的标头的顺序,这就是我使用OrderedDict() 的原因。疯狂的是我尝试了很多东西,似乎唯一有效的方法就是使用 BurpSuite 证书。你知道发生了什么吗?
  • 很难说。也许是 TLS 指纹。通过使用 BurpSuite,TLS 连接在 BurpSuite 和服务器之间,因此如果那里有 TLS 配置,它会使用属性。
  • @SteffenUllrich 非常感谢您的回复。我认为这可能是因为 TLS 指纹?你知道我可以使用其他证书吗?
  • TLS指纹与使用的证书完全无关。

标签: python ssl python-requests certificate burp


【解决方案1】:

看起来问题在于底层客户端 TLS 行为。

我有一个使用 OpenSSL 1.1.1b 的旧版本 Python 和一个使用 OpenSSL 1.1.1f 的新版本。它在第一个版本中失败,但在第二个版本中有效。这也可以解释为什么它可以与 Burp 一起使用:它使用稍微不同的 TLS 行为。

我试图找出问题所在:让非工作版本使用工作版本的密码将无济于事。主要的其他区别是支持的签名算法。实际上,使用上面提到的 openssl 1.1.1b(还有 Anaconda Python 附带的较新版本),差异可以减少到 sigalgs:

 $ openssl s_client -connect www.retailmenot.com:443 -crlf
 ...[various output]...
 <paste the expected HTTP request>
 ...
 HTTP/1.1 403 Forbidden

 $ openssl s_client -connect www.retailmenot.com:443 -crlf -sigalgs 'ECDSA+SHA256'
 ...[various output]...
 <paste the expected HTTP request>
 ...
 HTTP/1.1 200 OK

不幸的是,我无法在 Python 请求中直接在 TLS 堆栈中设置签名算法。 API 没有公开,它只是使用默认值 - 因此失败或成功取决于 OpenSSL 的构建方式。

但看起来可以通过指定不同的安全级别来间接设置值:

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context

CIPHERS = ('DEFAULT:@SECLEVEL=2')
class CipherAdapter(HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        context = create_urllib3_context(ciphers=CIPHERS)
        kwargs['ssl_context'] = context
        return super(CipherAdapter, self).init_poolmanager(*args, **kwargs)

    def proxy_manager_for(self, *args, **kwargs):
        context = create_urllib3_context(ciphers=CIPHERS)
        kwargs['ssl_context'] = context
        return super(CipherAdapter, self).proxy_manager_for(*args, **kwargs)

s = requests.session()
s.mount('https://www.retailmenot.com/', CipherAdapter())
...
print(s.get("https://www.retailmenot.com/sitemap/A"))

这与特定的标头设置一起导致我在&lt;Response [200]&gt; 中的测试,而使用相同的 Python 版本并且没有更改安全级别会导致&lt;Response [403]&gt;

【讨论】:

  • 嘿斯蒂夫。非常感谢您的回答!有没有办法在 python 请求中使用某种其他 CA 以使其工作?如果没有,是否有某种解决方法,或者是 python 请求无法完成的事情?
  • @NazimKerimbekov:这与使用的 CA 完全无关。 CA 仅由客户端在本地用于验证服务器证书。它不会影响 TLS 握手的样子,也不会影响服务器的回答。同样,它适用于我的一个 Python 版本(Ubuntu 20.04),因此可以使用 Python,具体取决于 Python 中使用的 OpenSSL 的构建方式
  • 非常感谢您的回复 Steffen。我在 iMac 上运行 Python 3.9。我应该更新我的python版本吗?换电脑?
  • @NazimKerimbekov:与 Python 的版本无关。由于 Python 不提供设置签名算法的 API,因此它完全取决于 OpenSSL(Python 使用的)是如何编译的。因此,仅更新您的 Python 将无济于事。同样,它可以在 Ubuntu 20.04 上与 Python 一起使用,因此将计算机更改为此(或在 Mac 上安装为 VM)会有所帮助。
  • @SteffenUllrich 描述的“非对称密钥算法(RSA 和 ECDSA)”下的解决方案here 是否可行?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-11
相关资源
最近更新 更多