-
Notifications
You must be signed in to change notification settings - Fork 0
/
simp.src
620 lines (544 loc) · 17.9 KB
/
simp.src
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
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
// command: simp
// Usage: simp [ip_address]:[port]
// Scans and executes exploits against a target
// --- Globals ---------------------------------------
TAB = char(9)
NEWLINE = char(10)
// Format tags
BOLD = "<b>"
RED = "<color=#FF0000>"
GREEN = "<color=#00FF00>"
YELLOW = "<color=#FFFF00>"
CYAN = "<color=#00CCFF>"
ip = null
port = null
verbose = false
metaxploit = null
crypto = null
attack_tree = null
// --- FORMATTING ------------------------------------
format = function(text, tags)
text = tags + text
if text.indexOf("<b>") != null then text = text + "</b>"
if text.indexOf("<color=#") != null then text = text + "</color>"
return text
end function
bold = function(text)
return format(text, BOLD)
end function
print_error = function(text)
print(format(text, BOLD + RED))
end function
// --- Attack Class ----------------------------------
Attack = {}
Attack.memory_address = null
Attack.buffer_overflow = null
Attack.details = null
Attack.handler = null
Attack.user = null
Attack.target_ip = null
Attack.New = function(memory_address, attack_raw)
attack_lines = attack_raw.split("\n")
buffer_overflow_raw = attack_lines[0]
requirements = attack_lines[1:]
buffer_overflow = buffer_overflow_raw.matches("(?<=\<b\>)(.*)(?=\</b\>)").values[0]
handler = metalib.overflow(memory_address, buffer_overflow)
user = infer_user(handler)
// TODO: Change ??? behavior to retry overflow with arguments!
self = new Attack
self.memory_address = memory_address
self.buffer_overflow = buffer_overflow
self.requirements = requirements
self.handler = handler
self.user = user
return self
end function
Attack.display_attack_options = function()
if self.handler == null then
self.probe
return
end if
print_header("OPTIONS:")
handler_type = typeof(self.handler)
if handler_type == "shell" then self.display_shell_options
if handler_type == "computer" then self.display_computer_options
if handler_type == "file" then self.display_file_options
end function
Attack.display_computer_options = function()
print(bold(" [0] ") + "Try to obtain /etc/passwd")
print(bold(" [1] ") + "Try to obtain user mail credentials")
print(bold(" [2] ") + "List users")
print(bold(" [3] ") + "List running processes")
print
choice = user_input(bold("Select option: "))
// Crack passwords
if choice == "0" then
passwd_file = obtain_passwd_file(self.handler)
if passwd_file != null then
crack_file(passwd_file)
user_input("\n", false, true)
else
print_error("Unable to obtain passwd.")
user_input("\n", false, true)
end if
// Mail credentials
else if choice == "1" then
mail_file = obtain_mail_file(self.user, self.handler)
if mail_file != null then
crack_file(mail_file)
user_input("\n", false, true)
else
print_error("Unable to obtain Mail.txt.")
user_input("\n", false, true)
end if
// List users
else if choice == "2" then
home_dir = self.handler.File("/home")
for user in home_dir.get_folders
print(user.name)
end for
user_input("\n", false, true)
else if choice == "3" then
processes = self.handler.show_procs
print(format_columns(processes))
user_input("\n", false, true)
end if
end function
Attack.display_file_options = function()
print(bold("Permissions: ") + self.handler.permissions)
print(bold(" [0] ") + "Try to obtain /etc/passwd")
print(bold(" [1] ") + "List users")
if self.handler.is_folder then print(bold(" [2] ") + "List folder contents")
print
choice = user_input(bold("Select option: "))
// Crack passwords
if choice == "0" then
passwd_file = obtain_passwd_file(self.handler)
if passwd_file != null then
crack_file(passwd_file)
user_input("\n", false, true)
else
print_error("Unable to obtain passwd.")
user_input("\n", false, true)
end if
// List users
else if choice == "1" then
home_dir = null
if self.handler.path != "/home" then
home_dir = self.handler
else
home_dir = crawl_to_dir("/home", self.handler)
end if
if home_dir == null or not home_dir.has_permission("r") then
print_error("Unable to list contents of /home")
else
for user in home_dir.get_folders
print(" - " + user.name)
end for
end if
user_input("\n", false, true)
// File listings
else if choice == "2" then
result = [ bold("PERMISSIONS OWNER GROUP SIZE NAME") ]
for file in self.handler.get_files
result.push(file.permissions + " " + file.owner + " " + file.group + " " + file.size + " " + file.name)
end for
print(format_columns(result.join("\n")))
user_input("\n", false, true)
end if
end function
Attack.display_shell_options = function()
print(bold(" [0] ") + "Try to obtain /etc/passwd")
print(bold(" [1] ") + "Try to obtain user mail credentials")
print(bold(" [2] ") + "Enter shell")
print
choice = user_input(bold("Select option: "))
if choice == "0" then
passwd_file = obtain_passwd_file(self.handler)
if passwd_file != null then
crack_file(passwd_file)
user_input("\n", false, true)
else
print_error("Unable to obtain passwd.")
user_input("\n", false, true)
end if
else if choice == "1" then
mail_file = obtain_mail_file(self.user, self.handler)
if mail_file != null then
crack_file(mail_file)
user_input("\n", false, true)
else
print_error("Unable to obtain Mail.txt.")
user_input("\n", false, true)
end if
else if choice == "2" then
self.execute_shell_terminal
end if
end function
// For unknown vulnerability types, try overflow again with optional argument
Attack.probe = function(optional_arg = null, auto_advance = false)
if optional_arg == null then
print(bold("REQUIREMENTS:"))
for requirement in self.requirements
print(requirement)
end for
print
optional_arg = user_input("<b>Input Probe Argument:</b> ")
end if
metaxploit = get_metaxploit
result = metalib.overflow(self.memory_address, self.buffer_overflow, optional_arg)
if result != null then
self.handler = result
self.user = infer_user(result)
if optional_arg.indexOf(".") != null then self.target_ip = optional_arg
end if
if not auto_advance then user_input("\n", false, true)
end function
// Connect to attack target and start a terminal session.
// Clears logs in advance if root obtained.
Attack.execute_shell_terminal = function(remote_shell = null)
if remote_shell == null then remote_shell = self.handler
print_header()
if self.user == "root" then
self.corrupt_logs(remote_shell)
print("Corrupted target logs")
end if
print("Connecting...")
remote_shell.start_terminal
end function
// "Corrupt" logs on attack target.
Attack.corrupt_logs = function(handler = null)
if handler == null then handler = self.handler
if typeof(handler) == "shell" then remote_computer = handler.host_computer
if typeof(handler) == "computer" then remote_computer = handler
syslog = remote_computer.File("/var/system.log")
syslog.delete
remote_computer.touch("home/guest", "system.log")
syslog = remote_computer.File("/home/guest/system.log")
syslog.set_content("Your {}'s have been thoroughly salted!")
syslog.chmod("u-rwx")
syslog.chmod("g-rwx")
syslog.chmod("o-rwx")
syslog.set_owner("root")
syslog.set_group("root")
syslog.move("/var", "system.log")
end function
// --- AttackTree Class ------------------------------
AttackTree = {}
AttackTree.attacks = null
AttackTree.New = function(scan)
index = 0
attacks = []
i = 0
for memory_address in scan
attacks_raw = metaxploit.scan_address(metalib, memory_address)
attacks_raw = attacks_raw.replace("decompiling source...\nsearching unsecure values...\n","")
attacks_raw = attacks_raw.split("\n\n")
for attack_raw in attacks_raw
if attack_raw != "" then
print("<b>[" + i + "]</b>")
attack = Attack.New(memory_address, attack_raw)
attacks.push(attack)
print("<b> - - - </b>")
end if
i = i + 1
end for
end for
self = new AttackTree
self.attacks = attacks
return self
end function
AttackTree.recursive_probe = function()
probe_arg = user_input(bold("Probe Argument: "))
for attack in self.attacks
if attack.handler == null then attack.probe(probe_arg, true)
end for
end function
AttackTree.display_attacks = function()
if globals.verbose == false then clear_screen
reqs_label = ""
if globals.verbose == true then reqs_label = "REQUIREMENTS"
print("-" * 55)
print(" <b>ID USER HANDLER " + reqs_label + "</b>")
print("-" * 55)
i = 0
for attack in self.attacks
if attack.handler == null and globals.port != 0 and globals.port != 8080 and globals.verbose == false then
i = i + 1
continue
end if
if attack.user == "root" then
color = GREEN
else if attack.user == "guest" then
color = "<color=#FFFFFF>"
else if attack.user == "???" then
color = "<color=#303030>"
else
color = YELLOW
end if
requirements = ""
if attack.handler == null then
handler = "???"
requirements = "NEED (x" + attack.requirements.len + ")"
else if typeof(attack.handler) == "file" then
handler = typeof(attack.handler) + ": " + attack.handler.path
else if typeof(attack.handler) == "number" then
handler = "#" + attack.handler
else
handler = typeof(attack.handler)
end if
// Router bounced target
if attack.target_ip != null then
handler = handler + " -> " + attack.target_ip
end if
line = " " * 70
line = line.insert(0, color)
line = line.insert(16, bold("[" + i + "]"))
line = line.insert(28, attack.user)
line = line.insert(39, handler)
line = line.insert(60, requirements)
line = line.insert(70, "</color>")
print(line)
i = i + 1
end for
print(bold(" [*] ") + "Recursive Probe")
print
selection = user_input("<b>Select attack:</b> ")
if selection == "" then exit
if selection.to_int < self.attacks.len then
self.attacks[selection.to_int].display_attack_options
else if selection == "*" then
self.recursive_probe
else
end if
end function
// --- Global Functions ------------------------------
local_computer = get_shell.host_computer
print_header = function(label = null, divider_length = 55)
divider = "-" * divider_length
print("\n<b>" + divider + "</b>")
if label != null then print("<b>" + label + "</b>")
end function
// Prompt user for input.
// prompt: Prompt to display.
// char: First character of response that will return true (default 'y')
confirmation_prompt = function(prompt, char = "y")
choice = user_input(prompt)
if choice.lower.indexOf(char) == 0 then return true
end function
exit_prompt = function(prompt = "<b>Exit simp?</b> ")
choice = confirmation_prompt(prompt)
if choice == true then exit()
end function
get_metaxploit = function()
if globals.metaxploit == null then
metaxploit = include_lib("/lib/metaxploit.so")
if not metaxploit then metaxploit = include_lib(current_path + "/metaxploit.so")
if not metaxploit then
exit("<color=#FF0000>Error: Can't find metaxploit library in the /lib path or the current folder</color>")
end if
globals.metaxploit = metaxploit
end if
return globals.metaxploit
end function
get_crypto = function()
if globals.crypto == null then
crypto = include_lib("/lib/crypto.so")
if not crypto then crypto = include_lib(current_path + "/crypto.so")
if not crypto then
exit("<color=#FF0000>Error: Can't find crypto library in the /lib path or the current folder</color>")
end if
globals.crypto = crypto
end if
return globals.crypto
end function
get_cached_scan = function(cached_scan_filename)
path = "/" + active_user + "/Scans"
if active_user != "root" then path = "/home" + path
local_computer = get_shell.host_computer
cached_scan_file = local_computer.File(path + "/" + cached_scan_filename)
if cached_scan_file == null then
local_computer.touch(path, cached_scan_filename)
cached_scan_file = local_computer.File(path + "/" + cached_scan_filename)
cached_scan_file.chmod("o-rwx")
cached_scan_file.chmod("g-rwx")
if active_user == "root" then cached_scan_file.chmod("u-rwx")
end if
return cached_scan_file
end function
crawl_to_dir = function(dir, file_handler)
file = file_handler
while file.path != "/"
if file.parent == null then
print_error("Unable to crawl to '/'")
return null
end if
file = file.parent
end while
for folder in file.get_folders
if folder.path == dir then return folder
end for
return null
end function
infer_user = function(handler)
if typeof(handler) == "shell" or typeof(handler) == "ftpshell" then
handler = handler.host_computer.File("/")
end if
if typeof(handler) == "computer" then
handler = handler.File("/")
end if
if typeof(handler) == "file" then
root_dir = crawl_to_dir("/root", handler)
if root_dir != null and root_dir.has_permission("w") then return "root"
home_dir = crawl_to_dir("/home", handler)
result = null
if home_dir != null then
for user in home_dir.get_folders
if user.name == "guest" then
result = user
continue
end if
if user.has_permission("w") then return user.name
end for
end if
return "guest"
end if
return "???"
end function
get_user_home = function()
if active_user == "root" then return "/root"
return "/home/" + active_user
end function
get_hashes_file = function()
config_dir = get_user_home + "/Config"
computer = get_shell.host_computer
hashes_file = computer.File(config_dir + "/Hashes.txt")
if hashes_file == null then
computer.touch(config_dir, "Hashes.txt")
hashes_file = computer.File(config_dir + "/Hashes.txt")
hashes_file.chmod("o-rwx")
hashes_file.chmod("g-rwx")
if active_user == "root" then hashes_file.chmod("u-rwx")
end if
return hashes_file
end function
get_cached_hash_value = function(hash)
hashes_file = get_hashes_file
lines = hashes_file.get_content.split("\n")
for line in lines
line_parts = line.split("=")
if line_parts[0] == hash then return line_parts[1]
end for
return null
end function
save_hash_to_cache = function(hash, hash_value)
hashes_file = get_hashes_file
hash_line = hash + "=" + hash_value
hashes_file_content = hashes_file.get_content
if hashes_file_content != "" then hashes_file_content = hashes_file_content + NEWLINE
hashes_file.set_content(hashes_file_content + hash_line)
end function
get_crypto = function()
if globals.crypto == null then
crypto = include_lib("/lib/crypto.so")
if not crypto then crypto = include_lib(current_path + "/crypto.so")
if not crypto then
exit("<color=#FF0000>Error: Can't find crypto library in the /lib path or the current folder</color>")
end if
globals.crypto = crypto
end if
return globals.crypto
end function
crack = function(hash)
if hash.indexOf(":") != null then hash = hash.split(":")[1]
result = get_cached_hash_value(hash)
if result == null then
result = get_crypto.decipher(hash)
save_hash_to_cache(hash, result)
end if
return result
end function
crack_file = function(file)
contents = file.get_content
print
print("<b>" + file.name + "contents:</b>")
lines = contents.split("\n")
i = 0
for line in lines
if line.trim == "" then continue
print(" <b>[" + i + "]</b> " + line)
i = i + 1
end for
print
choice = 0
if lines.len > 1 then choice = user_input("<b>Decipher which line?</b> ").to_int
if choice != null then
line_tokens = lines[choice].split(":")
user = line_tokens[0]
password = crack(line_tokens[1])
print("<b>User:</b> " + user)
print("<b>Password:</b> " + password)
end if
end function
obtain_passwd_file = function(handler)
if typeof(handler) == "computer" then
remote_computer = handler
return remote_computer.File("/etc/passwd")
else if typeof(handler) == "file" then
etc_dir = crawl_to_dir("/etc", handler)
for file in etc_dir.get_files
if file.name == "passwd" then return file
end for
else if typeof(handler) == "shell" then
return obtain_passwd_file(handler.host_computer)
end if
return null
end function
obtain_mail_file = function(user, handler)
if typeof(handler) == "computer" then
remote_computer = handler
return remote_computer.File("/home/" + user + "/Config/Mail.txt")
else if typeof(handler) == "file" then
etc_dir = crawl_to_dir("/home/" + user + "/Config", handler)
for file in etc_dir.get_files
if file.name == "Mail.txt" then return file
end for
else if typeof(handler) == "shell" then
return obtain_email_file(handler.host_computer)
end if
return null
end function
// --- MAIN ------------------------------------------
if params.len == 0 or params.len > 2 or params[0] == "-h" or params[0] == "--help" then
exit("<b>Usage: simp (-v) [ip_address]:[port]</b>")
end if
if params.indexOf("-v") != null or params.indexOf("--verbose") then verbose = true
address_tokens = params[params.len - 1].split(":")
ip = address_tokens[0]
port = address_tokens[1].to_int
// Load library
metaxploit = get_metaxploit
net_session = metaxploit.net_use(ip, port)
if not net_session then
print_error("Error: Unable to connect to net session.")
exit
end if
// Check for online admins
if net_session.is_root_active_user then
exit_prompt("<b><color=#FFAA00>An admin is online. Abort?</color></b> ")
end if
metalib = net_session.dump_lib
cached_scan_filename = metalib.lib_name.replace("\.so", "") + "-" + metalib.version + ".scan"
cached_scan = get_cached_scan(cached_scan_filename)
if cached_scan.get_content == "" then
print_header(format("SCANNING: ", GREEN) + metalib.lib_name + " v" + metalib.version)
scan = metaxploit.scan(metalib)
cached_scan.set_content(scan.join(","))
else
print_header(format("USING CACHED SCAN: ", GREEN) + cached_scan_filename)
scan = cached_scan.get_content.split(",")
end if
attack_tree = AttackTree.New(scan)
while true
attack_tree.display_attacks
end while