Python简单远联
Python 提供了两个级别访问的网络服务:
- 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法。
- 高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。
什么是 Socket?
Socket又称”套接字”,应用程序通常通过”套接字”向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。
socket()函数
Python 中,我们用 socket() 函数来创建套接字,语法格式如下:
1 |
|
参数
- family: 套接字家族可以是 AF_UNIX 或者 AF_INET
- type: 套接字类型可以根据是面向连接的还是非连接分为
SOCK_STREAM
或SOCK_DGRAM
- proto: 一般不填默认为0.
Socket 对象(内置)方法
服务器端套接字 | |
---|---|
s.bind() | 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。 |
s.listen() | 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。 |
s.accept() | 被动接受TCP客户端连接,(阻塞式)等待连接的到来 |
客户端套接字 | |
---|---|
s.connect() | 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。 |
s.connect_ex() | connect()函数的扩展版本,出错时返回出错码,而不是抛出异常 |
公共用途的套接字函数 | |
---|---|
s.recv() | 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。 |
s.send() | 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。 |
s.sendall() | 完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。 |
s.recvfrom() | 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。 |
s.sendto() | 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。 |
s.close() | 关闭套接字 |
s.getpeername() | 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。 |
s.getsockname() | 返回套接字自己的地址。通常是一个元组(ipaddr,port) |
s.setsockopt(level,optname,value) | 设置给定套接字选项的值。 |
s.getsockopt(level,optname[.buflen]) | 返回套接字选项的值。 |
s.settimeout(timeout) | 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect()) |
s.gettimeout() | 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。 |
s.fileno() | 返回套接字的文件描述符。 |
s.setblocking(flag) | 如果 flag 为 False,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用 recv() 没有发现任何数据,或 send() 调用无法立即发送数据,那么将引起 socket.error 异常。 |
s.makefile() | 创建一个与该套接字相关连的文件 |
python中subprocess模块:
subprocess可以帮我们执行命令,获取执行结果及返回内容。
subprocess中有如下几种方法,我们用的是其中的run方法,这里详细说一下subprocess.run方法
subprocess.run,subprocess.getoutput,subprocess.Popen、subprocess.call
subprocess.run()
此方法为python3.5版本后的推荐方法,可以获取执行结果、返回内容等一些常用的信息, 满足大部分开发需要。
1 |
|
args: 要执行的命令。类型为str(如 “ls -l”)或包含str的list,tuple等(如 [“ls”, “-l”]), 推荐使用list形式,如果传入的args为str且包含参数,则 必须shell=True,默认为False。
stdin、stdout、stderr: 子进程的标准输入、输出、错误,常用的为stdout,我们可以获取命令执行后的输出内容。
shell:如果该参数为 True,将通过操作系统的 shell 执行指定的命令,默认为False。
timeout:设置命令超时时间。如果命令执行时间超时,子进程将被杀死,并弹出 TimeoutExpired 异常。
check:如果该参数设置为 True,并且进程退出状态码不是 0,则弹 出 CalledProcessError 异常。
encoding: 如果指定了该参数,则 stdin、stdout 和 stderr 可以接收字符串数据,并以该编码方式编码。否则只接收 bytes 类型的数据。
capture_output: 设置为True,将捕获stdout和stderr,从而获执行命令后取返回的内容。
————————————————————————————————————————————-
好的,了解过这些基础方法的用法之后,我们可以试着自己写一个简单的远联:
客户端代码思路:
1.我们需要去连接服务端开启监听的IP对应的端口。
2.接收服务端下达给我们的指令
3..我们利用subprocess去定义一个方法用来将执行命令的结果进行接收并返回给服务端
下面我们写客户端代码:
1 |
|
服务端代码思路:
1.首先我们需要利用socket在本地端口开启监听,让客户端主动连过来。
(为什么要将服务端设置在本地? 原因:如果我们主动去对靶机进行连接,这时候防护设备估计就会给你直接杀了。但是我们让靶机主动连过来的话,防护设备就会以为是靶机用户的主动行为操作,出站规则不会像进站那样严格。)
2.如果我们不止连接一台靶机的话可以在本地开启初始化连接数量。
3.如果客户端长时间未连接怎么办?——可以在服务端设置阻塞模式,一直等待客户端链接
4.我们需要发送给客户端靶机要执行的命令
5.我们需要接收客户端执行命令的结果
1 |
|