-
Notifications
You must be signed in to change notification settings - Fork 5
/
ping.py
89 lines (71 loc) · 2.49 KB
/
ping.py
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
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/python
# Copyright (c) 2003 CORE Security Technologies
#
# This software is provided under under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
# for more information.
#
# $Id: ping.py,v 1.3 2003/10/27 17:36:56 jkohen Exp $
#
# Simple ICMP ping.
#
# This implementation of ping uses the ICMP echo and echo-reply packets
# to check the status of a host. If the remote host is up, it should reply
# to the echo probe with an echo-reply packet.
# Note that this isn't a definite test, as in the case the remote host is up
# but refuses to reply the probes.
# Also note that the user must have special access to be able to open a raw
# socket, which this program requires.
#
# Authors:
# Gerardo Richarte <gera@coresecurity.com>
# Javier Kohen <jkohen@coresecurity.com>
#
# Reference for:
# ImpactPacket: IP, ICMP, DATA.
# ImpactDecoder.
import select
import socket
import time
import sys
from impacket import ImpactDecoder, ImpactPacket
if len(sys.argv) < 3:
print "Use: %s <src ip> <dst ip>" % sys.argv[0]
sys.exit(1)
src = sys.argv[1]
dst = sys.argv[2]
# Create a new IP packet and set its source and destination addresses.
ip = ImpactPacket.IP()
ip.set_ip_src(src)
ip.set_ip_dst(dst)
# Create a new ICMP packet of type ECHO.
icmp = ImpactPacket.ICMP()
icmp.set_icmp_type(icmp.ICMP_ECHO)
# Include a 156-character long payload inside the ICMP packet.
icmp.contains(ImpactPacket.Data("A"*156))
# Have the IP packet contain the ICMP packet (along with its payload).
ip.contains(icmp)
# Open a raw socket. Special permissions are usually required.
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
seq_id = 0
while 1:
# Give the ICMP packet the next ID in the sequence.
seq_id += 1
icmp.set_icmp_id(seq_id)
# Calculate its checksum.
icmp.set_icmp_cksum(0)
icmp.auto_checksum = 1
# Send it to the target host.
s.sendto(ip.get_packet(), (dst, 0))
# Wait for incoming replies.
if s in select.select([s],[],[],1)[0]:
reply = s.recvfrom(2000)[0]
# Use ImpactDecoder to reconstruct the packet hierarchy.
rip = ImpactDecoder.IPDecoder().decode(reply)
# Extract the ICMP packet from its container (the IP packet).
ricmp = rip.child()
# If the packet matches, report it to the user.
if rip.get_ip_dst() == src and rip.get_ip_src() == dst and icmp.ICMP_ECHOREPLY == ricmp.get_icmp_type():
print "Ping reply for sequence #%d" % ricmp.get_icmp_id()
time.sleep(1)