使用 openssl 子进程将 Python STDOUT 写入文件

发布于 2024-11-24 08:26:36 字数 537 浏览 1 评论 0原文

我正在尝试编写一个 python 脚本来自动执行通过 openSSL 检查 SSL 重新协商的过程并将结果输出到文件中。我遇到了两个问题。

我的第一个问题是初始握手的输出被写入文件,但实际的重新协商部分却没有。相反,它显示在控制台上。

subprocess.call("echo \"R\" | openssl s_client -connect example.com:443", 
        shell=True, stdout=FILE)

我的另一个问题(尽管这可能是错误的地方)是我无法让 openSSL 命令用于发送 GET 命令。

subprocess.call("echo -e \"GET / HTTP/1.1\r\n\r\n\" | openssl s_client -connect
        example.com:443", shell=True)   

同样,初始连接已建立,但 openSSL 存在,它不处理 GET 请求。

任何帮助将不胜感激。谢谢。

I am trying to write a python script to automate the process of checking for SSL renegotiation through openSSL and output the results to a file. I have run into 2 problems.

My first problem is that the output from the initial handshake gets written to the file, however the actual renegotiation part does not. It is instead displayed on the console.

subprocess.call("echo \"R\" | openssl s_client -connect example.com:443", 
        shell=True, stdout=FILE)

My other problem (although this may be the wrong spot for it) is that I cannot get the openSSL command to work for sending the GET command.

subprocess.call("echo -e \"GET / HTTP/1.1\r\n\r\n\" | openssl s_client -connect
        example.com:443", shell=True)   

Again, the initial connection is set up but then openSSL exists, it does not process the GET request.

Any help would be greatly appreciated. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

时光暖心i 2024-12-01 08:26:36

没有理由使用 shell=True 作为输入。相反,请使用 stdin=subprocess.PIPE。另请注意,您的请求无效,因为 HTTP 1.1 需要 Host 标头。此外,我想不出使用命令行 openssl 而不是 ssl 模块的原因

话虽这么说,这是一个有效的示例:

import subprocess

f = open('http_answer', 'w')
_,log = subprocess.Popen(
    ['openssl', 's_client', '-quiet', '-connect', 'twitter.com:443'],
    stdout=f, stderr=subprocess.PIPE, stdin=subprocess.PIPE
).communicate('GET / HTTP/1.0\r\n\r\n')
print('Output of SSL:\n' + log)

There's no reason to use shell=True for inputs. Instead, use stdin=subprocess.PIPE. Also, note that your request is not valid since HTTP 1.1 requires the Host header. Additionally, I can't think of a reason to use the command line openssl instead of the ssl module.

That being said, here's a working example:

import subprocess

f = open('http_answer', 'w')
_,log = subprocess.Popen(
    ['openssl', 's_client', '-quiet', '-connect', 'twitter.com:443'],
    stdout=f, stderr=subprocess.PIPE, stdin=subprocess.PIPE
).communicate('GET / HTTP/1.0\r\n\r\n')
print('Output of SSL:\n' + log)
月野兔 2024-12-01 08:26:36

请记住,openssl s_client 还使用 stderr 来输出某些输出。您需要检查重新协商是否进入 stderr,我相信它确实如此,尽管我的记忆可能正在消失。

我用不同的方式完成了这个任务,尽管不是用Python。我创建了一个进程,并将 stdin、stdout、stderr 文件描述符挂接到我可以读/写的文件描述符上,并且实际上驱动输入并读取输出。这需要更多的工作,但您可以完全控制正在发生的事情以及与流程的交互。我已经在 php 中完成了此操作,并且可以在 http://netsekure 在线进行测试。 org/2009/11/tls-renegotiation-test/

或者,您可以尝试使用 python 对 openssl 本身进行编程,而不是使用 s_client,但这需要更多工作,而且我已经使用了之前的方法。

您可以检查两件事,但您没有明确对哪一项感兴趣:

  • 检查远程服务器是否支持客户端发起的重新协商
  • 检查远程服务器是否支持安全重新协商扩展

这两者都可以通过执行简单地推断出来s_client 和 grep 是适用于这两种情况的关键字。这完全取决于您需要多少控制/复杂程度。

Keep in mind that openssl s_client uses also stderr for some of the output. You need to check whether the renegotiation goes to stderr, which I believe it does, though my memory might be fading.

I've accomplished this in a different way, though not in python. I've created a process and hooked the stdin, stdout, stderr file descriptors to ones I can read/write and I actually drive the input and read the output. It is a bit more work, but you have full control over what is going on and interacting with the process. I've done this in php and the test is available online at http://netsekure.org/2009/11/tls-renegotiation-test/.

Alternatively, you can just try using python to program openssl itself, instead of using the s_client, but this is more work and I've used the previous approach.

There are two things you can be checking and you didn't make it clear which one you are interested in:

  • checking whether remote server supports client initiated renegotiation
  • checking whether remote server supports the secure renegotiation extension

Both of these can be simply deduced by just doing s_client and grep for the keywords applicable to both cases. It all depends on how much control/sophistication you need.

○闲身 2024-12-01 08:26:36

@phihag 我对你的票据做了一些细微的修改,对我来说效果很好。

import subprocess

f = open('http_answer', 'w')
_,log = subprocess.Popen(
    ['openssl', 's_client', '-quiet', '-connect', 'twitter.com:443','-sess_out', 'session.txt'],
    stdout=f, stderr=subprocess.PIPE, stdin=subprocess.PIPE ).communicate('GET / HTTP/1.0\r\nHOST: twitter.com\r\n\r\n') print('Output of SSL:\n' + log)

列出更改
1. 添加了“sess_out”“session.txt”参数,该参数保留了所有 SSL 会话参数,可以使用以下 openssl 命令查看这些参数

$openssl sess_id -in test.txt -text -cert -noout
  1. 向 GET 命令添加了主机信息,因为较新的部分仅使用 HOST 选项才能很好地响应。

    'GET / HTTP/1.0\r\nHOST: twitter.com\r\n\r\n'

@Drew,为时已晚,但我希望这有点帮助。谢谢。

@phihag I have made slight changes to your scrip and is working well for me.

import subprocess

f = open('http_answer', 'w')
_,log = subprocess.Popen(
    ['openssl', 's_client', '-quiet', '-connect', 'twitter.com:443','-sess_out', 'session.txt'],
    stdout=f, stderr=subprocess.PIPE, stdin=subprocess.PIPE ).communicate('GET / HTTP/1.0\r\nHOST: twitter.com\r\n\r\n') print('Output of SSL:\n' + log)

Listing the changes
1. added 'sess_out' 'session.txt' parameters which preserves all the SSL Session paramerters which can be views using the following openssl command

$openssl sess_id -in test.txt -text -cert -noout
  1. Added host information to the GET command, as the newer section respond well only with the HOST option.

    'GET / HTTP/1.0\r\nHOST: twitter.com\r\n\r\n'

@Drew, Its too late but I hope this is bit helpful. Thank you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文