python渗透测试编程之远程控制工具
目录
1.subprocess.call(args,*stdin=None,stderr=None,shell=False)
远程控制工具简介
远程控制程序是一个很常见的计算机术语,指的是可以在一台设备上控制另外一台设备的软件。
通常情况下,远程控制程序分为控制端和被控制端。如果一台计算机执行了被控端,就会被另外一台有控制端的计算机所控制。这类型软件很多,比如Teamviewer,还有一些黑客恶意入侵所打造的后门木马。
我们从技术角度分类。远程控制软件的分类标准有很多,这里仅仅介绍常见的标准
第一个标准就是远程控制软件被控端和控制端的连接方式。按照不同的连接方式,可以将远程控制软件分为正向和反向两种。
简单举例。我现在是攻击者hacker,目标机器的计算机为A,如果我们的远程控制软件是正向的,那么A在执行我们的控制软件后,仅仅会打开一个端口,然后等待hacker连接。这个时候A并不会通知hacker我开启了端口,因此hacker必须知道计算机A的IP地址,这就在实际应用中有很多的麻烦。
那么反向代理则不同了。当A在远程执行了被控端后,会主动去连接hacker,因此黑客也无须知道计算机A的IP地址,只需要把这个远程控制及被控端发送给目标即可。这是目前常用的方式。
另外一个标准就是按照目标操作系统的不同分类。比如在WINDOWS下运行的就是exe文件,在Android操作系统上大都是apk文件。显然我们在windows下的文件不能在Android下执行。
Python中的subprocess模块
接下来编写一个远程控制工具。这个远程控制工具要分成服务端和被控端两个部分,服务端主要用来发送控制命令和接收执行结果,被控端主要用来接收并执行控制命令。程序编写先从控制命令的执行开始,首先来介绍一下执行控制命令的subprocess模块。
这个模块主要作用是执行外部的命令和程序,subprocess也是替换了一些以前旧的模块和函数,例如os.system*、os.spawn*、popen2.*、commands.*等。
当运行Python时候,其实也是在运行一个进程。在Python中,可以通过标准库中的subprocess来fork一个紫禁城,subprocess中包含多个创建子进程的函数。
1.subprocess.call(args,*stdin=None,stderr=None,shell=False)
这个里面最重要的参数就是args,它可以是一个字符安川,也可以是一个包含程序参数的列表,用来指明需要执行的命令,使用这个参数就可以Python中执行相对应的命令,如果是序列类型,第一个元素通常是可执行文件的路径。也可以显式地使用executetable参数来指定可执行文件的路径。
stdin、stdout、stderr分别表示程序的标准输入、输出、错误句柄。它们可以是PIPE,文件描述符或文件对象、默认值为None,表示从父进程继承。
shell=True参数会让subprocess.call接受字符串类型的变量作为命令,并调用shell去执行这个字符串,当shell=False时,表示subprocess.call只接受数组变量作为命令,并将数组的第一个元素作为命令剩下的全部作为该命令的参数。
如果子进程不需要进行交互操作,就可以使用该函数来创建。
举例
import subprocess
child = subprocess.call("notepad.exe")
print child
这个就执行了开启notepad文件。输出child会返回一个值,如果返回值为0,就表示成功,非0则表示失败。
2.subprocess.check_call()
这个函数的作用与前面的subprocess.call()几乎相同。
举例
child=subprocess.check_call ("ping www.test.com",shell=True)
print child
0
不同的是,这个subprocess.check_call()函数会对返回值进行检查,如果返回值非0,则抛出CalledProcessError异常,这个异常会有个returncode属性,记录子进程的返回值,可用try...except...来检查。
3.subprocess.check_output()
这个函数与前两个函数的区别在于它会返回子进程向标准输出的输出结果。这个函数在进行交互的时候相当有用。
检查退出信息,如果returncode不为0,则抛出错误subprocess.CalledProcessError,该对象包含returncode属性和output属性,output属性作为标准输出的输出结果,可以用try...except...来检查。
4.subprocess.Popen
如果我们希望自定义来使用一些功能的话。Popen时最好的选择,这个类的格式如下所示。
classPopen(args,bufsize=0,executable=None,stidn=None,stdout=None,stderr=None,preexec_fn=None,close_fds=False,shell=False,cwd=None,env=None,universal_newlines=False,startupinfo=None,creationflags=0):
这个里面最重要的参数就是args,同样这个args参数可以是一个字符串,也可以是一个包含程序参数的列表。要执行的程序一般就是这个列表的第一项,或者是字符本身。
subprocess.Popen(["notepad","test.txt"])
另外,需要注意的是,Popen对象创建后,主程序不会自动等待子进程完成,创建一个Python程序,输入如下代码,然后执行。
可以看到并没有等待子进程输出,而是直接输出了“parent process”
如果需要等待子进程的话,就需要使用wait(),接下来看看添加了这个函数的程序
执行这个程序之后,先查询了信息,然后再输出了parent process。
接下来用这个模块来编写一个函数,用来执行需要执行的命令,返回值为执行结果。
import subprocess
def run_command(command):
command=command.rstrip()
try:
child = subprocess.check_output(command,shell=True)
except:
child = 'Can not execute the commmand.\r\n'
return childexecute="ifconfig"
output = run_command(execute)
print output
执行后结果如下所示。
利用客户端向服务端发送控制命令
创建思路
接下来回顾一下之前的socket通信问题。
首先考虑客户端。
1)创建套接字,连接远端地址;
2)连接后发送数据和接收数据;
3)传输完毕后,关闭套接字。
面向服务端。
1)创建套接字;
2)绑定端口;
3)对套接字进行监听;
4)拿到请求的对象和地址;
5)连接后发送数据和接收数据;
6)传输完毕后,关闭套接字。
具体可以查看这篇博文:
菜鸟渗透日记25---python渗透测试编程之安全渗透常见模块1-socket
现在根据这篇博文里面的代码进行修改,使得服务端可以接受来自客户端的输入。调整结果如下:
实现代码
客户端代码
import socket
str_msg=raw_input("please input the information:")
s2 = socket.socket()
s2.connect(("127.0.0.1",1234))
s2.send(str_msg)
print str(s2.recv(1024))
s2.close()
服务端代码
import socket
import subprocess
def run_command(command):
command=command.rstrip()
print command
try:
child = subprocess.check_output(command,shell=True)
print child
except:
child = 'Can not execute the commmand.\r\n'
return child
s1 = socket.socket()
s1.bind(("127.0.0.1",1234))
s1.listen(5)
while 1:
conn,address = s1.accept()
print "a new connect from ",address
data= conn.recv(1024)
print "The command is " + data
output = run_command(data)
conn.sendall(output)
conn.close()
最后的运行结果如下:
剩下的部分留到下次更新吧。比如采用命令行的控制还有将python转为exe更便捷使用。
本文地址:https://blog.csdn.net/leesir98/article/details/107457812
推荐阅读