2.14 交互输入自动化
就编写自动化工具或测试工具而言,实现命令的交互输入自动化极其重要。在很多情况下,我们要同一些交互式读取输入的命令打交道。“交互式输入”是指只有当命令要求获取输入时,才由用户手动键入。下面的例子就是一个要求提供交互式输入的命令执行过程。
- $ command
- Enter a number: 1
- Enter name : hello
- You have entered 1,hello
2.14.1 预备知识
能够自动接受上例中那种交互式输入的自动化工具,对于本地命令或远程应用来说非常有用。让我们看看如何实现自动化。
2.14.2 实战演练
试着思考交互式输入的过程。参照之前的代码,我们可以将这些步骤描述如下:
1[Return]hello[Return]
观察实际通过键盘输入的字符,可以将上面的1
、Return
、hello
以及Return
转换为以下字符串:
"1\nhello\n"
我们按下回车键时会发送 \n
。添加上 \n
后,就得到了发送给stdin
的实际字符串。
因此,通过发送与用户输入等同的字符串,我们就可以实现在交互式进程中自动传递输入。
2.14.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
来生成输入序列。如果输入内容比较多,那么可以用单独的输入文件结合重定向操作符来提供输入。
- $ echo -e "1\nhello\n" > input.data
- $ cat input.data
- 1
- hello
制作输入文件时,你也可以不用echo
命令:
- $ ./interactive.sh < input.data
这个方法是从文件中导入交互式输入数据。
如果你是一位逆向工程师,那你可能同缓冲区溢出攻击打过交道。要实施攻击,我们需要将十六进制形式的shellcode
(例如“\xeb\x1a\x5e\x31\xc0\x88\x46
”)进行重定向。这些字符没法直接通过键盘输入,因为键盘上并没有其对应的键值。因此,我们应该使用:
echo -e "\xeb\x1a\x5e\x31\xc0\x88\x46"
这条命令会将shellcode
重定向到有缺陷的可执行文件中。
我们已经描述了一种方法,它通过stdin
将所需的文本进行重定向,从而实现交互式输入程序自动化。但是我们并没有检查所发送的输入内容。我们期望程序以特定(固定)的次序处理我们所发送的输入。如果程序对于输入采取随机或其他处理次序,或者甚至不要求输入某些内容,那么之前的方法就要出问题了。它会发送不符合程序要求的错误输入。为了处理动态输入并通过检查程序运行时的输入需求来提供输入内容,我们要使用一个出色的工具expect
。expect
命令可以根据适合的输入要求提供适合的输入。让我们看看如何使用expect
。
2.14.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
指明命令交互结束。