-
Notifications
You must be signed in to change notification settings - Fork 3
/
start.py
executable file
·83 lines (59 loc) · 2.25 KB
/
start.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
#!/usr/bin/python3
import argparse
import sys
import struct
from socket import *
from typing import List
ICMP_ECHO = 8
ICMP_CODE = 0
ICMP_IDENT = 12345
HEADER_LENGTH = 8
TARGET_LENGTH = 1200
def calculate_checksum(msg: bytes) -> int:
"""
Simplified checksum calculation for even-length packets
"""
s = 0
for n, i in enumerate(msg):
s += i << ((n % 2) * 8)
s = (s & 0xffff) + (s >> 16)
return htons(~s & 0xffff)
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | Type | Code | Checksum |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | Identifier | Sequence Number |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#
def make_packet(csum: int, seq: int, data: bytes) -> bytes:
return struct.pack(">BBHHH", ICMP_ECHO, ICMP_CODE, csum, ICMP_IDENT, seq) + data
def send_initial_ping(data: bytes, destination: str) -> None:
"""
Create and send the initial seed ping
"""
ping_socket = socket(AF_INET, SOCK_RAW, getprotobyname("icmp"))
# Checksum field of 0 goes into calculating checksum
packet = make_packet(csum=0, seq=0, data=data)
checksum = calculate_checksum(packet)
# ... again, but this time with proper checksum
packet = make_packet(csum=checksum, seq=0, data=data)
ping_socket.sendto(packet, (destination, 0))
ping_socket.close()
def load_program(filename: str) -> bytes:
result = bytes()
memory_values = open(filename).read().splitlines()
for number in memory_values:
number = int(number[::-1], 2)
result += number.to_bytes(4, byteorder='little')
return result
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--target", type=str, required=True,
help="Target IP to send ICMP packet to")
parser.add_argument("-p", "--program", type=str, required=True,
help="Program file to execute")
args = parser.parse_args()
data = load_program(args.program)
# Padding to the correct packet size
data += bytes(TARGET_LENGTH - len(data) - HEADER_LENGTH)
send_initial_ping(data, args.target)
print("Started!")