在发送STDIN输入之前等待子过程的提示

发布于 2025-01-23 02:39:45 字数 745 浏览 3 评论 0原文

我有一个Linux X86二进制文件,该二进制要求密码,并将打印出密码是正确还是不正确的。我想使用python来模糊输入。

下面是我运行二进制文件的屏幕截图,然后给它给字符串“ asdf”,然后接收字符串“错误”

屏幕截图:

”

到目前为止,我试图使用python3 subprocess模块​​来

  1. 运行二进制当子过程
  2. 接收到密码的提示
  3. 时,请发送字符串。
  4. 在此处接收响应

是我的脚本

p = subprocess.Popen("/home/pj/Desktop/L1/lab1",stdin=subprocess.PIPE, stdout=subprocess.PIPE)
print (p.communicate()[0])

运行此脚本的结果是,

b'Please supply the code: \nIncorrect\n'

我希望只收到提示,但是在我有机会发送输入之前,二进制文件也返回不正确的响应。

如何改进脚本以成功与此二进制互动?

I have a linux x86 binary that asks for a password and will print out whether the password is correct or incorrect. I would like to use python to fuzz the input.

Below is a screenshot of me running the binary, then giving it the string "asdf", and receiving the string "incorrect"

Screenshot:

Screenshot

So far, I have tried to use the Python3 subprocess module in order to

  1. run the binary as a subprocess
  2. receive the prompt for a password
  3. send a string.
  4. receive the response

Here is my script

p = subprocess.Popen("/home/pj/Desktop/L1/lab1",stdin=subprocess.PIPE, stdout=subprocess.PIPE)
print (p.communicate()[0])

the result of running this script is

b'Please supply the code: \nIncorrect\n'

I am expecting to receive only the prompt however the binary is returning a response of incorrect as well before I have gotten the chance to send my input.

How can I improve my script in order to interact with this binary successfully?

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

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

发布评论

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

评论(1

半﹌身腐败 2025-01-30 02:39:45

阅读文档

popen.communicate(input = none)

与过程互动:将数据发送到STDIN。从Stdout读取数据,
stderr,直到到达文件终止。等待过程终止。
可选的输入参数应该是要发送给孩子的字符串
流程
,或不,如果不应将数据发送给孩子。

communicate()返回元组(stdoutdata,stderrdata)

请注意,如果要将数据发送到该过程的stdin,则需要
stdin = Pipe创建Popen对象。同样,要获得任何东西
除了结果元组中,您还需要给出stdout = pipe
和/或stderr = pipe

因此,您什么也没发送到该过程,然后读取stdout的全部。


在您的情况下,您实际上不需要等待提示即可将数据发送到该过程,因为流不同步地工作:仅在尝试读取其stdin>:如果您的输入时,该过程才能获得您的输入:

In [10]: p=subprocess.Popen(("bash", "-c","echo -n 'prompt: '; read -r data; echo $data"),stdin=subprocess.PIPE,stdout=subprocess.PIPE)

In [11]: p.communicate('foobar')
Out[11]: ('prompt: foobar\n', None)

如果您坚持出于何种原因等待提示(例如,您的流程也会在提示之前检查输入,期待其他内容),您需要手动阅读stdout,请非常小心您阅读了多少:因为Python的file.read is阻止,一个简单的read()会死去,因为它等待EOF,并且子过程不会关闭stdout - 因此不会产生EOF-来自你。如果输入或输出长度可能会超过STDIO的缓冲长度(在您的特定情况下不太可能),则您还需要在单独的线程中进行stdout读取和stdin写作

这是一个示例,使用 pexpect 这为您服务(我是我使用pexpect.fdexpect代替pexpect.spawn 在文档中提出的建议'因为它在所有平台上都可以使用):

In [1]: import pexpect.fdpexpect

In [8]: p=subprocess.Popen(("bash", "-c","echo -n 'prom'; sleep 5; echo 'pt: '; read -r data; echo $data"),stdin=subprocess.PIPE,stdout=subprocess.PIPE)

In [10]: o=pexpect.fdpexpect.fdspawn(p.stdout.fileno())

In [12]: o.expect("prompt: ")
Out[12]: 0

In [16]: p.stdin.write("foobar")    #you can communicate() here, it does the same as
                                    # these 3 steps plus protects from deadlock
In [17]: p.stdin.close()
In [18]: p.stdout.read()
Out[18]: 'foobar\n'

Read the documentation carefully (emphasis mine):

Popen.communicate(input=None)

Interact with process: Send data to stdin. Read data from stdout and
stderr, until end-of-file is reached. Wait for process to terminate.
The optional input argument should be a string to be sent to the child
process
, or None, if no data should be sent to the child.

communicate() returns a tuple (stdoutdata, stderrdata).

Note that if you want to send data to the process’s stdin, you need to
create the Popen object with stdin=PIPE. Similarly, to get anything
other than None in the result tuple, you need to give stdout=PIPE
and/or stderr=PIPE too.

So, you're sending nothing to the process, and reading all of stdout at once.


In your case, you don't really need to wait for the prompt to send data to the process because streams work asynchronously: the process will get your input only when it tries to read its STDIN:

In [10]: p=subprocess.Popen(("bash", "-c","echo -n 'prompt: '; read -r data; echo $data"),stdin=subprocess.PIPE,stdout=subprocess.PIPE)

In [11]: p.communicate('foobar')
Out[11]: ('prompt: foobar\n', None)

If you insist on waiting for the prompt for whatever reason (e.g. your process checks the input before the prompt, too, expecting something else), you need to read STDOUT manually and be VERY careful how much you read: since Python's file.read is blocking, a simple read() will deadlock because it waits for EOF and the subprocess doesn't close STDOUT -- thus doesn't produce EOF -- until it get input from you. If the input or output length is likely to go over stdio's buffer length (unlikely in your specific case), you also need to do stdout reading and stdin writing in separate threads.

Here's an example using pexpect that takes care of that for you (I'm using pexpect.fdexpect instead of pexpect.spawn suggested in the doc 'cuz it works on all platforms):

In [1]: import pexpect.fdpexpect

In [8]: p=subprocess.Popen(("bash", "-c","echo -n 'prom'; sleep 5; echo 'pt: '; read -r data; echo $data"),stdin=subprocess.PIPE,stdout=subprocess.PIPE)

In [10]: o=pexpect.fdpexpect.fdspawn(p.stdout.fileno())

In [12]: o.expect("prompt: ")
Out[12]: 0

In [16]: p.stdin.write("foobar")    #you can communicate() here, it does the same as
                                    # these 3 steps plus protects from deadlock
In [17]: p.stdin.close()
In [18]: p.stdout.read()
Out[18]: 'foobar\n'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文