2.15 交互输入自动化

就编写自动化工具或测试工具而言,实现命令的交互输入自动化极其重要。在很多情况下,我们要同一些以交互方式读取输入的命令打交道。下面的例子就是一个要求提供交互式输入的命令执行过程。

$ command
Enter a number: 1
Enter name : hello
You have entered 1,hello

2.15.1 预备知识

能够自动接受输入的自动化工具,对于本地命令或远程应用来说都有益处。让我们看看如何实现自动化。

2.15.2 实战演练

思考一下交互式输入的过程。参照之前的代码,我们可以将涉及的步骤描述如下:

1[Return]hello[Return]

观察实际通过键盘输入的字符,可以将上面的1Returnhello以及Return转换为以下字符串:

"1\nhello\n"

按下回车键时会发送\n。通过添加\n,就可以得到发送给stdin的字符串。

因此,通过发送与用户输入等同的字符串,我们就可以实现在交互过程中自动发送输入。

2.15.3 工作原理

先写一个读取交互式输入的脚本,然后用这个脚本进行自动化的演示:

#!/bin/bash
#文件名: interactive.sh
read -p "Enter number:" no ;
read -p "Enter name:" name
echo You have entered $no, $name;

按照下面的方法向脚本自动发送输入:

$ echo -e "1\nhello\n" | ./interactive.sh
You have entered 1, hello

看来制作的输入生效了。

我们用echo -e来生成输入序列,-e表明echo会解释转义序列。如果输入内容比较多,那么可以用单独的输入文件结合重定向操作符来提供输入:

$ echo -e "1\nhello\n" > input.data
$ cat input.data
1
hello

制作输入文件时,你也可以不用echo命令:

$ ./interactive.sh 

这个方法是从文件中导入交互式输入数据。

如果你是逆向工程师,那可能同缓冲区溢出攻击打过交道。要实施攻击,我们需要将十六进制形式的shellcode(例如“\xeb\x1a\x5e\x31\xc0\x88\x46”)进行重定向。这些字符没法直接通过键盘输入,因为键盘上并没有其对应的按键。因此,我们应该使用:

echo -e \xeb\x1a\x5e\x31\xc0\x88\x46"

这条命令会将shellcode重定向到有缺陷的可执行文件中。

我们已经描述了一种方法,它通过stdin将所需的文本进行重定向,从而实现交互式输入程序自动化。但是我们并没有检查所发送的输入内容。我们期望程序以特定(固定)的次序处理我们所发送的输入。如果程序对于输入采取随机或其他处理次序,或者甚至不要求输入某些内容,那么之前的方法就要出问题了。它会发送不符合程序要求的错误输入。为了处理动态输入并通过检查程序运行时的输入需求来提供输入内容,我们要使用一个出色的工具expectexpect命令可以根据输入要求提供适合的输入。

2.15.4 补充内容

我们看看expect的用法。交互式输入自动化也可以用其他方法实现。expect脚本就是其中之一。

expect实现自动化

在默认情况下,多数常见的Linux发行版中并不包含expect。你得用软件包管理器手动进行安装。

expect等待特定的输入提示,通过检查输入提示来发送数据。

#!/usr/bin/expect
#文件名: automate_expect.sh
spawn ./interactive.sh
expect "Enter number:"
send "1\n"
expect "Enter name:"
send "hello\n"
expect eof

运行结果如下:

$ ./automate_expect.sh

在这个脚本中:

  • spawn参数指定需要自动化哪一个命令;

  • expect参数提供需要等待的消息;

  • send是要发送的消息;

  • expect eof指明命令交互结束。