如何在 Python 中在终端密码提示中输入密码

Posted

技术标签:

【中文标题】如何在 Python 中在终端密码提示中输入密码【英文标题】:How to enter a password into the terminal password prompt in Python 【发布时间】:2019-08-15 11:40:00 【问题描述】:

我正在尝试制作一个简单的 Python 脚本,在使用“su”命令(或任何其他需要管理员权限或只需要密码才能执行的命令)后在命令行中输入给定密码。

我尝试为此使用 Subprocess 模块以及 pynput,但无法弄清楚。

import subprocess
import os

# os.system('su') # Tried using this too

process = subprocess.Popen('su', stdin=subprocess.PIPE, stdout=subprocess.PIPE)
process.stdin.write(b"password_to_enter")
print(process.communicate()[0])
process.stdin.close()

我希望在输入“su”命令后在给定的密码提示中输入“password_to_enter”,但事实并非如此。我也试过给它正确的密码,但还是不行。

我做错了什么?

PS:我在 Mac 上

【问题讨论】:

【参考方案1】:

su 命令需要从终端读取。在我的 Linux 机器上运行上面的示例会返回以下错误:

su: must be run from a terminal

这是因为su 试图确保它是从终端运行的。您可以通过分配pty 并自己管理输入和输出来绕过此问题,但要做到这一点可能非常棘手,因为在 after su 提示输入密码之前,您无法输入密码。例如:

import subprocess
import os
import pty
import time

# Allocate the pty to talk to su with.
master, slave = pty.openpty()

# Open the process, pass in the slave pty as stdin.
process = subprocess.Popen('su', stdin=slave, stdout=subprocess.PIPE, shell=True)

# Make sure we wait for the "Password:" prompt.
# The correct way to do this is to read from stdout and wait until the message is printed.
time.sleep(2)

# Open a write handle to the master end of the pty to write to.
pin = os.fdopen(master, "w")
pin.write("password_to_enter\n")
pin.flush()

# Clean up
print(process.communicate()[0])
pin.close()
os.close(slave)

有一个名为pexpect 的库使与交互式应用程序的交互变得非常简单:

import pexpect
import sys

child = pexpect.spawn("su")
child.logfile_read = sys.stdout
child.expect("Password:")
child.sendline("your-password-here")
child.expect("#")
child.sendline("whoami")
child.expect("#")

【讨论】:

谢谢。问题:这对中间攻击中的人有多安全?例如。另一个非 root 进程可以通过在su 之前读取它来劫持这个 PTY 通信吗? 另一个问题:您上面的代码没有捕获su 的“密码:”提示。我仍然可以在终端中看到它。知道为什么会这样吗? 一般来说,TTY 管道对于中间人的攻击是相当安全的。在 Linux 上,作为 root 可以克隆和拦截来自不同进程的管道,但您应该对普通用户安全。由于stdout=PIPE 位,密码提示未被捕获,如果将其切换为 DEVNULL,它应该隐藏输出(请参阅subprocess 文档)。 谢谢谢谢。使用命名管道怎么样?我可以通过 TTY 提供敏感数据的应用程序也允许我通过文件提供它。所以我也可以使用命名管道。与 TTY 相比,对命名管道的安全性有何看法? 请询问其他问题:os.close(slave) 的安全性如何?为什么不pty.os.close(slave)?为什么不关闭master?

以上是关于如何在 Python 中在终端密码提示中输入密码的主要内容,如果未能解决你的问题,请参考以下文章

Ubuntu 终端切换root 操作

mysql在终端里中自动输入密码

电脑输入多次密码错误显示输入的一行英文字但是输入之后还是不行怎么处理?

linux在终端输入密码时显示星号的实现方法

ubuntu 16.04 root 初始密码设置

如何从 bash 脚本中 ssh?