ICMP后门(上)补充篇
前言
在上一篇文章中,我简要讲解了ICMP协议,以及实现了一个简单的ping功能,在文章发表之后,后台很多朋友留言,说对校验和的计算不是很了解,实现的ping功能仅实现了发送,接收没有实现,一个完整ping如何实现等等。本来对于ICMP后门写三篇文章的,但是对大家的疑惑临时开辟了一个补充篇,对ICMP协议校验方式,以及实现一个完整功能的ping给大家进行详细的讲解。
第一节 ICMP协议校验和
对于校验和的计算,我对写校验和的代码进行了如下注释,注意看注释就会明白校验的整个流程。
def checksum(packet): """ 校验 """ #packet为icmp头部和data的字节流,其中icmp校验和字段初始化为0 sum =0 #countTo:记录packet是有多少个16位,因为对每两个字节进行校验 countTo = (len(packet)//2)*2 count =0 while count <countTo: #将每两个字节中的第二个字节作为高位,第一个字节作为低位组成16位的值 sum += ((packet[count+1] << 8) | packet[count]) count += 2 #packet并不一定都是偶数字节,可能是奇数,把最后一个字节加到sum中 if countTo<len(packet): sum += packet[len(packet) - 1] sum = sum & 0xffffffff #sum中超过16位的高位加到低位 sum = (sum >> 16) + (sum & 0xffff) sum = sum + (sum >> 16) #对sum取反 answer = ~sum #到这应该就结束了,但是字节序有问题,下面是将主机字节序转为网络字节序 #即高位转低位,低位转高位 answer = answer & 0xffff answer = answer >> 8 | (answer << 8 & 0xff00) return answer