在项目组工作的过程中,遇到了一个任务:需要重复执行某程序,生成大量的流量。抓取流量,用于AI的学习。因此需要写脚本不断执行程序。我选择了python语言。
一、
(1)dewdrop
dewdrop是一款linux后门软件。在靶机上运行dewdrop服务器后,就可以在攻击机上运行dewdrop客户端连接上靶机,实现远程控制。
我选择subprocess模块。subprocess模块允许启动一个新进程,并将它连接到标准输入/标准输出/标准错误管道。
1 | import sys |
使用方法:
在tipoff同目录下新建一个command.txt文件。文件中每一行为所执行的命令。
运行程序,即可不断随机执行命令。
```
python rundewdrop.py [victim ip] [victim port] [Listener ip] [Listener port] [Number of command]1
2
3
4
5
6
7
8
9
10
11
### (2)nopen
nopen也是一款linux后门软件,使用方法与dewdrop类似。在靶机上运行nopen server后,可以使nopen client远程控制。
然而,脚本却艰难重重。
#### 1.subprocess模块
我的第一选择当然是选择与dewdrop相同的方法,使用了subprocess模块。然而,却遇到了问题。nopen client出现了报错。error: failed to open global_output_file
1
2
3
4
5
瞬间懵逼......
有趣的是,这个nopen client程序还会骂人,还是骂20遍:What? are you nuts?
1
2
3
4
5
6
7
8
9
10
11
#### 2.其他重定向方法
我还采取了其他重定向输入方法。如<,管道符|,都遇到了一模一样的问题。仿佛只要重定向就会报错。
#### 3.寻找原因
既然找不到原因,就直接逆向分析......动调调试了很久,找到了报错的关键之处。
运行nopen client后,每输入一条命令,都会尝试去运行fdopen函数。FILE* fdopen(int fildes,const char* mode);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
fdopen的第一个参数为文件描述符。但是诡异的是:动调发现,运行到这里,打开的文件文件描述符为0。0正是标准输入流。打开文件成功即可继续运行。打开文件失败则报错退出。
明明是在已经输入命令之后,难以理解为什么又会打开标准输入流。手动测试了fdopen这个函数。它确实能打开标准输入流,甚至向标准输入流中输出。然而一但进行重定向,这个函数就返回null。
在钟sir的指导下,了解到了也存在0不是标准输入流的可能。程序是可以将0重定向到其他流的。
继续逆向分析,却收效甚微......就算找到了错误的地方,也仍然不一定能找到解决方法。
#### 4.termios模块伪造终端输入
这是一个突发奇想,既然无法重定向输入,能否选择其他方式输入?一番搜索之下,找到了python的termios模块,可以伪造终端输入。
在 Linux 中可以通过一组函数调用(通用终端接口,简称GTI)来控制终端。termios是在 POSIX 规范中定义的标准接口。python中的termios模块正是通过这个接口,从底层实现伪造终端输入。
因此思路很简单:只需打开一个终端,运行nopen。再打开另一个终端,通过伪造输入向nopen所在终端输入命令,实现nopen重复的运行。
脚本如下:#!/usr/bin/python
import sys,os,fcntl,termios
from random import choice
if len(sys.argv) != 3:
sys.stderr.write(“usage: ttyexec.py tty command_number\n”)
sys.exit(1)
fd = os.open(“/dev/“ + sys.argv[1], os.O_RDWR)
command_number = int(sys.argv[2])
with open(‘commands.txt’, ‘r’) as f:
command_list = [line.strip() for line in f.readlines()]
for i in range(command_number):
cmd = choice(command_list)
for j in range(len(cmd)):
fcntl.ioctl(fd, termios.TIOCSTI, cmd[j])
fcntl.ioctl(fd, termios.TIOCSTI, '\n')
os.close(fd)
1 |
|
IOError:[Errno 1]Operation not permitted
1 |
|
#!/usr/bin/python
import sys,os,fcntl,termios
from random import choice
if len(sys.argv) != 3:
sys.stderr.write(“usage: ttyexec.py tty command_number\n”)
sys.exit(1)
fd = os.open(“/dev/“ + sys.argv[1], os.O_RDWR)
command_number = int(sys.argv[2])
sleep(10)
with open(‘commands.txt’, ‘r’) as f:
command_list = [line.strip() for line in f.readlines()]
for i in range(command_number):
cmd = choice(command_list)
for j in range(len(cmd)):
fcntl.ioctl(fd, termios.TIOCSTI, cmd[j])
fcntl.ioctl(fd, termios.TIOCSTI, '\n')
os.close(fd)
1 |
|
- 在同一终端运行nopen client
(3)telnet
实现telnet的重定向方法很多,这里采用与dewdrop相同的方法,使用subprocess模块。不同之处仅仅在于需要输入用户名和密码。
1 | import sys |
使用方法:
运行环境python2
需要在同一目录新建一个commands.txt,commands.txt中每一行为所需执行的命令。
运行命令
1
$ python runtelnet.py {ip地址} {用户名} {密码} {发包个数}
已解决发包次数过多后断开的问题。(脚本中每执行一条命令后sleep 0.2秒)
(4)ssh
ssh会自动检测输入是否被重定向。
1 | Pseudo-terminal will not be allocated because stdin is not a terminal |
可以使用-tt强制分配为伪终端,即使标准输入不是终端。尽管如此,ssh的密码依然无法通过重定向输入,需要手动输入。
1 | import sys |
使用方法:
运行环境 python2
需要在本目录新建一个commands.txt,commands.txt中每行为所需要执行的命令。
运行命令
1
$ python runssh.py {目标ip} {执行命令个数}
执行后需要手动输入靶机密码。输入密码后程序自动继续运行。
已解决发包次数过多后断开的问题。(脚本中每执行一条命令后sleep 0.2秒)