· 4 years ago · Jun 01, 2021, 11:50 PM
1import tkinter as tk
2import tkinter.ttk as ttk
3import subprocess
4from tkinter.messagebox import showwarning
5import nmap3
6import argparse
7import os
8import threading
9from ftplib import FTP
10from bs4 import BeautifulSoup, Comment
11import requests
12from tkinter import *
13from tkinter import messagebox
14from tkinter.ttk import *
15from functools import partial
16
17def option_selected(menu_item):
18 print(f"{menu_item} was clicked")
19
20'''
21CHECK BOX CUSTOM CLASS
22'''
23
24check_nu = b'iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TRZEWB4uIOGSoTi2IijpKFYtgobQVWnUwufQLmjQkKS6OgmvBwY/FqoOLs64OroIg+AHi4uqk6CIl/i8ptIjx4Lgf7+497t4BQqPCVLNrHFA1y0jFY2I2tyr2vCKAIAYRwYzETD2RXszAc3zdw8fXuyjP8j735wgqeZMBPpF4jumGRbxBPL1p6Zz3iUOsJCnE58QRgy5I/Mh12eU3zkWHBZ4ZMjKpeeIQsVjsYLmDWclQiaeIw4qqUb6QdVnhvMVZrdRY6578hYG8tpLmOs0RxLGEBJIQIaOGMiqwEKVVI8VEivZjHv5hx58kl0yuMhg5FlCFCsnxg//B727NwuSEmxSIAd0vtv0xCvTsAs26bX8f23bzBPA/A1da219tALOfpNfbWvgI6N8GLq7bmrwHXO4AQ0+6ZEiO5KcpFArA+xl9Uw4YuAX61tzeWvs4fQAy1NXyDXBwCIwVKXvd4929nb39e6bV3w/0UXLbKEvbjQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB+MMDRctIGmzOYIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAALElEQVQoz2M0Njb+z0AiYGFgYGA4c+YMI7EaTExM/jMxkAFGNQ1jTYzkpD0ATtMHS/nRiQwAAAAASUVORK5CYII='
25check_nc = b'iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TRZEWB4uIOGSoTi2IijpKFYtgobQVWnUwufQLmjQkKS6OgmvBwY/FqoOLs64OroIg+AHi4uqk6CIl/i8ptIjx4Lgf7+497t4BQqPCVLNrHFA1y0jFY2I2tyr2vCKAIAYRwYzETD2RXszAc3zdw8fXuyjP8j735wgqeZMBPpF4jumGRbxBPL1p6Zz3iUOsJCnE58QRgy5I/Mh12eU3zkWHBZ4ZMjKpeeIQsVjsYLmDWclQiaeIw4qqUb6QdVnhvMVZrdRY6578hYG8tpLmOs0RxLGEBJIQIaOGMiqwEKVVI8VEivZjHv5hx58kl0yuMhg5FlCFCsnxg//B727NwuSEmxSIAd0vtv0xCvTsAs26bX8f23bzBPA/A1da219tALOfpNfbWvgI6N8GLq7bmrwHXO4AQ0+6ZEiO5KcpFArA+xl9Uw4YuAX61tzeWvs4fQAy1NXyDXBwCIwVKXvd4929nb39e6bV3w/0UXLbKEvbjQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB+MMDRctDrVlNE0AAAAjdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVAgd2l0aCBsb3ZlyGW0XgAAAJdJREFUKM+d0rENAyEMBdDvKA1zeART07MIGzAFE7EDK1B5CMqf7pIUlyP3JZdP+rItZkb8mScAjDFkF8QY+cCNbCF3R86ZvXduIXdHKYWqipSSXKJP0FqTEMK7Xu+dOWe6+yU4UEpJVBWlFLr7TwAAYmYcY8haC7VWzjkBAGfga+UhBLTWRFVPwREzI0nsjpndO67c+b0XBDxvkWRMW24AAAAASUVORK5CYII='
26
27
28class custom_checkbox_text(tk.Frame):
29 def __init__(self, parent, colour, text, *args, **kwargs):
30 tk.Frame.__init__(self, parent)
31 self.checkbox = custom_checkbox(self, colour, *args, **kwargs)
32 self.checkbox.grid(row=0, column=0)
33 self.label = tk.Label(self, text=text)
34 self.label.grid(row=0, column=1)
35
36 self.label.bind("<Enter>", self.checkbox.focus_in)
37 self.label.bind("<Leave>", self.checkbox.focus_out)
38 self.label.bind("<Button-1>", self.on_label_click)
39
40 self.columnconfigure(0, weight=1)
41 self.columnconfigure(0, weight=1)
42 self.rowconfigure(0, weight=1)
43
44 def on_label_click(self, event=None):
45 if self.checkbox.variable.get() == self.checkbox['onvalue']:
46 self.checkbox.variable.set(self.checkbox['offvalue'])
47 else:
48 self.checkbox.variable.set(self.checkbox['onvalue'])
49 self.checkbox.focus_update()
50 def select(self):
51 self.checkbox.select()
52 def get(self):
53 return self.checkbox.variable.get()
54
55
56class custom_checkbox(tk.Checkbutton):
57 def __init__(self, parent, colour, *args, **kwargs):
58 default_kwargs = {'image': None, 'selectimage': None, 'indicatoron': False,
59 'onvalue': 1, 'offvalue': 0, 'variable': None, 'offrelief': 'sunken'}
60 for key, value in default_kwargs.items():
61 if key not in kwargs:
62 kwargs[key] = value
63
64 self.colour = colour
65 self.curr_colour = "black"
66 self.hover = False
67 if kwargs['variable'] is None:
68 self.variable = kwargs['variable'] = tk.IntVar(value=1)
69 else:
70 self.variable = kwargs['variable']
71 print(kwargs, kwargs['variable'].get())
72 if kwargs['variable'].get() == 0:
73 if kwargs['image'] is None:
74 self.off_image = kwargs['image'] = tk.PhotoImage(data=check_nu)
75 else:
76 self.off_image = kwargs['image']
77 if kwargs['selectimage'] is None:
78 self.on_image = tk.PhotoImage(data=check_nc)
79 else:
80 self.on_image = kwargs['selectimage']
81 else:
82 if kwargs['image'] is None:
83 self.on_image = kwargs['image'] = tk.PhotoImage(data=check_nc)
84 else:
85 self.on_image = kwargs['image']
86 if kwargs['selectimage'] is None:
87 self.off_image = tk.PhotoImage(data=check_nu)
88 else:
89 self.off_image = kwargs['selectimage']
90
91 tk.Checkbutton.__init__(self, parent, *args, **kwargs)
92 self.bind("<Enter>", self.focus_in)
93 self.bind("<Leave>", self.focus_out)
94 self.variable.trace("w", self.focus_update)
95
96 def select(self):
97 """Put the button in on-state."""
98 self.tk.call(self._w, 'select')
99
100 def edit_check(self, colour, image):
101 image.put((colour,), to=(0, 0, 1, 13)) # LEFT
102 image.put((colour,), to=(0, 0, 13, 1)) # TOP
103 image.put((colour,), to=(12, 0, 13, 13)) # RIGHT
104 image.put((colour,), to=(0, 12, 13, 13)) # BOTTOM
105
106 def focus_in(self, event=None):
107 image = self.on_image if self.variable.get() == self['onvalue'] else self.off_image
108 self.edit_check(self.colour, image)
109 self.curr_colour = self.colour
110 self.configure(image=image)
111 self.image = image
112 self.hover = True
113
114 def focus_out(self, event=None):
115 image = self.on_image if self.variable.get() == self['onvalue'] else self.off_image
116 self.edit_check("black", image)
117 self.curr_colour = "black"
118 self.configure(image=image)
119 self.image = image
120 self.hover = False
121
122 def focus_update(self, *args):
123
124 if self.variable.get() == self['onvalue']:
125 image = self.on_image
126 else:
127 image = self.off_image
128 self.configure(image=image)
129 self.image = image
130 if self.hover:
131 self.focus_in()
132
133
134'''
135TOOLTIP CLASS
136'''
137
138class CreateToolTip(object):
139 """
140 create a tooltip for a given widget
141 """
142 def __init__(self, widget, text='widget info'):
143 self.waittime = 500 #miliseconds
144 self.wraplength = 180 #pixels
145 self.widget = widget
146 self.text = text
147 self.widget.bind("<Enter>", self.enter)
148 self.widget.bind("<Leave>", self.leave)
149 self.widget.bind("<ButtonPress>", self.leave)
150 self.id = None
151 self.tw = None
152
153 def enter(self, event=None):
154 self.schedule()
155
156 def leave(self, event=None):
157 self.unschedule()
158 self.hidetip()
159
160 def schedule(self):
161 self.unschedule()
162 self.id = self.widget.after(self.waittime, self.showtip)
163
164 def unschedule(self):
165 id = self.id
166 self.id = None
167 if id:
168 self.widget.after_cancel(id)
169
170 def showtip(self, event=None):
171 x = y = 0
172 x, y, cx, cy = self.widget.bbox("insert")
173 x += self.widget.winfo_rootx() + 25
174 y += self.widget.winfo_rooty() + 20
175 # creates a toplevel window
176 self.tw = tk.Toplevel(self.widget)
177 # Leaves only the label and removes the app window
178 self.tw.wm_overrideredirect(True)
179 self.tw.wm_geometry("+%d+%d" % (x, y))
180 label = tk.Label(self.tw, text=self.text, justify='left',
181 background="#ffffff", relief='solid', borderwidth=1,
182 wraplength = self.wraplength)
183 label.pack(ipadx=1)
184
185 def hidetip(self):
186 tw = self.tw
187 self.tw= None
188 if tw:
189 tw.destroy()
190
191
192global ibuster,inikto
193ibuster = 0
194inikto = 0
195
196global busterList,niktoList
197niktoList = []
198busterList = []
199
200global smbCheckCmd
201global bruteSMBcmd
202global bruteFTPcmd
203global bruteSSHcmd
204global rootDir
205
206
207def btnAlotNikto(frame):
208 global inikto
209 if inikto > 3:
210 inikto = 0
211 else:
212 pass
213 #print(inikto)
214 #print(frame["nikto"][inikto])
215 raise_frame(frame["nikto"][inikto])
216 inikto += 1
217
218
219def btnAlotBuster(frame):
220 global ibuster
221 if ibuster > 3:
222 ibuster = 0
223 else:
224 pass
225 #print(ibuster)
226 #print(frame["buster"][ibuster])
227 raise_frame(frame["buster"][ibuster])
228 ibuster += 1
229
230def raise_frame(frame):
231 frame.tkraise()
232
233class NewprojectApp:
234 def __init__(self,listing, master=None):
235 global rootDir
236 global spList
237 # build ui
238 self.m = tk.Menu(master, tearoff=0)
239 self.m.add_command(label="Force Stop", command=partial(option_selected, 'Cut'))
240 self.m.bind("<FocusOut>", self.popupFocusOut) # Needed for menu to hide
241 self.mainFrame = ttk.Frame(master)
242 self.BtnFrame = ttk.Frame(self.mainFrame)
243 style = ttk.Style()
244 style.configure("Mine.TButton", background="red")
245 self.bactions = ttk.Button(self.BtnFrame, style="Mine.TButton")
246 self.bactions.configure(text='Actions')
247 self.bactions.pack(pady='50', side='bottom')
248 self.bactions.configure(command=self.actionWindow)
249 self.bsprayShow = ttk.Button(self.BtnFrame)
250 self.bsprayShow.configure(text='Spraying')
251 self.bsprayShow.pack(side='top')
252 self.bsprayShow.configure(command=lambda: raise_frame(self.fsprayShow))
253 self.bcredsWrite = ttk.Button(self.BtnFrame)
254 #self.bcredsWrite.configure(text='Write Creds')
255 #self.bcredsWrite.pack(side='top')
256 #self.bcredsWrite.configure(command=lambda:raise_frame(self.fcredsWrite))
257 self.bnikto = ttk.Button(self.BtnFrame)
258 self.bnikto.configure(text='Nikto')
259 self.bnikto.pack(side='top')
260 self.bnikto.configure(command=lambda:btnAlotNikto(self.frameDict))
261 self.bsshBrute = ttk.Button(self.BtnFrame)
262 self.bsshBrute.configure(text='SSH Brute')
263 self.bsshBrute.configure(command=lambda:raise_frame(self.fsshBrute))
264 self.bsshBrute.pack(side='top')
265 self.bftpBrute = ttk.Button(self.BtnFrame)
266 self.bftpBrute.configure(text='FTP Brute')
267 self.bftpBrute.configure(command=lambda:raise_frame(self.fFtpBrute))
268 self.bftpBrute.pack(side='top')
269 self.bsmbBrute = ttk.Button(self.BtnFrame)
270 self.bsmbBrute.configure(text='SMB Brute')
271 self.bsmbBrute.configure(command=lambda:raise_frame(self.fsmbBrute))
272 self.bsmbBrute.pack(side='top')
273 self.bdirbuster = ttk.Button(self.BtnFrame)
274 self.bdirbuster.configure(text='Dirbuster')
275 self.bdirbuster.configure(command=lambda:btnAlotBuster(self.frameDict))
276 self.bdirbuster.pack(side='top')
277 self.bsmbCheck = ttk.Button(self.BtnFrame)
278 self.bsmbCheck.configure(text='SMBCheck')
279 self.bsmbCheck.configure(command=lambda:raise_frame(self.fSmbChecker))
280 self.bsmbCheck.pack(side='top')
281 self.bNmapView = ttk.Button(self.BtnFrame)
282 self.bNmapView.configure(text='View NMAP')
283 self.bNmapView.configure(command=lambda:raise_frame(self.fNmap))
284 self.bNmapView.pack(side='top')
285 self.BtnFrame.configure(height='200', width='200')
286 self.BtnFrame.grid(column='0', row='1')
287 self.fcredsWrite = ttk.Frame(self.mainFrame)
288 self.fcredsWrite.configure(height='600', width='600')
289 self.fcredsWrite.grid(column='1', row='1')
290 self.fSmbChecker = ttk.Frame(self.mainFrame)
291 self.fSmbChecker.configure(height='600', width='600')
292 self.fSmbChecker.grid(column='1', row='1')
293 self.fsprayShow = ttk.Frame(self.mainFrame)
294 self.fsprayShow.configure(height='600', width='600')
295 self.fsprayShow.grid(column='1', row='1')
296 self.fNikto1 = ttk.Frame(self.mainFrame)
297 self.fNikto1.configure(height='600', width='600')
298 self.fNikto1.grid(column='1', row='1')
299 self.fNikto2 = ttk.Frame(self.mainFrame)
300 self.fNikto2.configure(height='600', width='600')
301 self.fNikto2.grid(column='1', row='1')
302 self.fNikto3 = ttk.Frame(self.mainFrame)
303 self.fNikto3.configure(height='600', width='600')
304 self.fNikto3.grid(column='1', row='1')
305 self.fNikto4 = ttk.Frame(self.mainFrame)
306 self.fNikto4.configure(height='600', width='600')
307 self.fNikto4.grid(column='1', row='1')
308 self.fbuster1= ttk.Frame(self.mainFrame)
309 self.fbuster1.configure(height='600', width='600')
310 self.fbuster1.grid(column='1', row='1')
311 self.fbuster2 = ttk.Frame(self.mainFrame)
312 self.fbuster2.configure(height='600', width='600')
313 self.fbuster2.grid(column='1', row='1')
314 self.fbuster3 = ttk.Frame(self.mainFrame)
315 self.fbuster3.configure(height='600', width='600')
316 self.fbuster3.grid(column='1', row='1')
317 self.fbuster4 = ttk.Frame(self.mainFrame)
318 self.fbuster4.configure(height='600', width='600')
319 self.fbuster4.grid(column='1', row='1')
320 self.fsshBrute = ttk.Frame(self.mainFrame)
321 self.fsshBrute.configure(height='600', width='600')
322 self.fsshBrute.grid(column='1', row='1')
323 self.fFtpBrute = ttk.Frame(self.mainFrame)
324 self.fFtpBrute.configure(height='600', width='600')
325 self.fFtpBrute.grid(column='1', row='1')
326 self.fsmbBrute = ttk.Frame(self.mainFrame)
327 self.fsmbBrute.configure(height='600', width='600')
328 self.fsmbBrute.grid(column='1', row='1')
329 self.mainFrame.configure(height='200', width='200')
330 self.mainFrame.pack(side='top')
331 self.fNmap = ttk.Frame(self.mainFrame)
332 self.fNmap.configure(height='600', width='600')
333 self.fNmap.grid(column='1', row='1')
334 self.niktoFrames = [self.fNikto1,self.fNikto2,self.fNikto3,self.fNikto4]
335 self.busterFrames = [self.fbuster1,self.fbuster2,self.fbuster3,self.fbuster4]
336 self.frameDict = {"nikto":self.niktoFrames,"buster":self.busterFrames}
337 self.idListBuster = [self.fbuster1.winfo_id(),self.fbuster2.winfo_id(),self.fbuster3.winfo_id(),self.fbuster4.winfo_id()]
338 self.idListNikto = [self.fNikto1.winfo_id(),self.fNikto2.winfo_id(),self.fNikto3.winfo_id(),self.fNikto4.winfo_id()]
339 self.idCredsWrite = self.fcredsWrite.winfo_id()
340 self.idSprayShow = self.fsprayShow.winfo_id()
341 self.idSmbCheck = self.fSmbChecker.winfo_id()
342 self.idSmbBrute = self.fsmbBrute.winfo_id()
343 self.idFtpBrute = self.fFtpBrute.winfo_id()
344 self.idSshBrute = self.fsshBrute.winfo_id()
345 self.idNamp = self.fNmap.winfo_id()
346 self.bnikto.bind("<Button-3>", self.right_click) # For menu
347 self.bsprayShow.bind("<Button-3>", self.right_click)
348 self.bdirbuster.bind("<Button-3>", self.right_click)
349 self.bsshBrute.bind("<Button-3>", self.right_click)
350 self.bsmbCheck.bind("<Button-3>", self.right_click)
351 self.bsmbBrute.bind("<Button-3>", self.right_click)
352 self.bftpBrute.bind("<Button-3>", self.right_click)
353 # Main widget
354 self.mainwindow = self.mainFrame
355 self.bsprayShow.pack_forget()
356 spList = [] # subprocess list so we can end each of them on exit.
357 print("BUSTER : {}\n".format(self.idListBuster))
358 print("NIKTO : {}\n".format(self.idListNikto))
359 print("CredsWrite : {}\n".format(self.idCredsWrite))
360 print("SprayShow : {}\n".format(self.idSprayShow))
361 print("SmbCheck : {}\n".format(self.idSmbCheck))
362 print("SmbBrute : {}\n".format(self.idSmbBrute))
363 print("FtpBrute : {}\n".format(self.idFtpBrute))
364 print("SshBrute : {}\n".format(self.idSshBrute))
365
366
367 '''
368 Creds Write
369 '''
370
371 try:
372 print("Starting CredsWrite\n")
373 spList.append( subprocess.Popen(
374 ["xterm", "-into", str(self.idCredsWrite), "-geometry", "100x100", "-hold", "-e",
375 "nano {}/credsWrite.txt".format(rootDir)],
376 stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE))
377 except:
378 self.bsmbCheck.pack_forget()
379
380
381
382 '''
383 DIRBUSTER
384 '''
385
386 try:
387 print("Starting Dirbuster\n")
388 i = 0
389 for cmd in busterList:
390 spList.append(subprocess.Popen(
391 ["xterm", "-into", str(self.idListBuster[i]), "-geometry", "100x100","-hold","-e","{} & wait".format(cmd)],
392 stdin=subprocess.PIPE, stdout=subprocess.PIPE))
393 #print(cmd)
394 i += 1
395 if i < 4:
396 newI = 4 - i
397 for notAv in range(0,newI):
398 if i == 5:
399 break
400 else:
401 pass
402 spList.append(subprocess.Popen(
403 ["xterm", "-into", str(self.idListBuster[i]), "-geometry", "100x100", "-hold", "-e",
404 "echo '[!] Nothing here!'"],
405 stdin=subprocess.PIPE, stdout=subprocess.PIPE))
406 i +=1
407 '''
408 DIRBUSTER ^^^^^
409 '''
410
411 '''
412 NIKTO
413 '''
414
415 try:
416 print("Starting Nikto\n")
417 i = 0
418 for cmd in niktoList:
419 spList.append(subprocess.Popen(
420 ["xterm", "-into", str(self.idListNikto[i]), "-geometry", "100x100", "-hold", "-e",
421 "{} & wait".format(cmd)],
422 stdin=subprocess.PIPE, stdout=subprocess.PIPE))
423 i += 1
424 if i < 4:
425 newI = 4 - i
426 for notAv in range(0, newI):
427 if i == 5:
428 break
429 else:
430 pass
431 spList.append(subprocess.Popen(
432 ["xterm", "-into", str(self.idListNikto[i]), "-geometry", "100x100", "-hold", "-e",
433 "echo '[!] Nothing here!'"],
434 stdin=subprocess.PIPE, stdout=subprocess.PIPE))
435 i += 1
436 except:
437 pass
438
439
440 '''
441 NIKTO ^^^^
442 '''
443
444 '''
445 SMBCHECK
446 '''
447 global smbCheckCmd
448 try:
449 print("Starting SmbCheck\n")
450 spList.append(subprocess.Popen(
451 ["xterm", "-into", str(self.idSmbCheck), "-geometry", "100x100", "-hold", "-e", "{} & wait".format(smbCheckCmd)],
452 stdin=subprocess.PIPE, stdout=subprocess.PIPE))
453 except:
454 self.bsmbCheck.pack_forget()
455
456 '''
457 SMB BRUTE
458 '''
459
460 global bruteSMBcmd
461 try:
462 print("Starting SmbBrute\n")
463 spList.append(subprocess.Popen(
464 ["xterm", "-into", str(self.idSmbBrute), "-geometry", "100x100", "-hold", "-e", "{} & wait".format(bruteSMBcmd)],
465 stdin=subprocess.PIPE, stdout=subprocess.PIPE))
466 except Exception as e:
467 #print(e)
468 self.bsmbBrute.pack_forget()
469
470 '''
471 FTP BRUTE
472 '''
473
474 global bruteFTPcmd
475 try:
476 print("Starting FtpBrute\n")
477 spList.append(subprocess.Popen(
478 ["xterm", "-into", str(self.idFtpBrute), "-geometry", "100x100", "-hold", "-e",
479 "{} & wait".format(bruteFTPcmd)],
480 stdin=subprocess.PIPE, stdout=subprocess.PIPE))
481 except Exception as e:
482 #print(e)
483 self.bftpBrute.pack_forget()
484
485 '''
486 SSH BRUTE
487 '''
488
489 global bruteSSHcmd
490 try:
491 print("Starting SshBrute\n")
492 spList.append(subprocess.Popen(
493 ["xterm", "-into", str(self.idSshBrute), "-geometry", "100x100", "-hold", "-e",
494 "{} & wait".format(bruteSSHcmd)],
495 stdin=subprocess.PIPE, stdout=subprocess.PIPE))
496 except:
497 self.bsshBrute.pack_forget()
498
499 '''
500 NMAP READ
501 '''
502 try:
503 spList.append(subprocess.Popen(
504 ["xterm", "-into", str(self.idNamp), "-geometry", "100x100", "-hold", "-e", "cat {}/nmap/nmap_scan.txt".format(rootDir)],
505 stdin=subprocess.PIPE, stdout=subprocess.PIPE))
506 except:
507 pass
508 self.spList = spList # subprocess list so we can end each of them on exit.
509 '''
510 p2 = subprocess.Popen(
511 ["xterm", "-into", str(self.idList[1]), "-geometry", "100x100","-hold", "-e", "ping -c 4 localhost"],
512 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
513 p3 = subprocess.Popen(
514 ["xterm", "-into", str(self.idList[2]), "-geometry", "100x100"],
515 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
516 p4 = subprocess.Popen(
517 ["xterm", "-into", str(self.idList[3]), "-geometry", "100x100", "-e", "ping localhost"],
518 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
519 '''
520 except FileNotFoundError:
521 showwarning("Error", "xterm is not installed")
522 raise SystemExit
523
524 def popupFocusOut(self, event=None): # For menu to hide
525 self.m.unpost()
526
527 def right_click(self, event): # For menu
528 self.m.tk_popup(event.x_root, event.y_root)
529 self.m.focus_set()
530
531
532 def sprayingShow(self):
533 self.bsprayShow.pack()
534 self.mainwindow.lift()
535 #print("Running sprayingShow")
536 global sprayingCmd
537 try:
538 self.sprayingCmd = sprayingCmd
539 except:
540 messagebox.showerror("Error",message="You need to set the credentials first.")
541 self.actionWindow.lift()
542 #print(self.sprayingCmd)
543 try:
544 spList.append(subprocess.Popen(
545 ["xterm", "-into", str(self.idSprayShow), "-geometry", "100x100", "-hold", "-e",
546 "{} & wait".format(self.sprayingCmd)],
547 stdin=subprocess.PIPE, stdout=subprocess.PIPE))
548 except:
549 self.bsshBrute.pack_forget()
550
551 def onExit(self):
552 for service in self.spList:
553 service.terminate()
554
555 def actionWindow(self):
556 global actionWindow
557 # Toplevel object which will
558 # be treated as a new window
559 try:
560 if actionWindow.state() == "normal": actionWindow.lift()
561 except:
562 actionWindow = Toplevel(self.mainwindow)
563 actionWindow.frame2 = ttk.Frame(actionWindow)
564 actionWindow.atctions = ttk.Label(actionWindow.frame2)
565 actionWindow.atctions.configure(text='Action Launcher')
566 actionWindow.atctions.pack(side='top')
567 actionWindow.separatorLine = ttk.Separator(actionWindow.frame2)
568 actionWindow.separatorLine.configure(orient='horizontal')
569 actionWindow.separatorLine.pack(fill='x', side='top')
570 actionWindow.frame2.configure(height='22', width='500')
571 actionWindow.frame2.pack(side='top')
572 actionWindow.frame2.pack_propagate(0)
573 actionWindow.frame4 = ttk.Frame(actionWindow)
574 actionWindow.bspray = ttk.Button(actionWindow.frame4)
575 actionWindow.bspray.configure(text='Sprayer')
576 actionWindow.bspray.configure(command=self.sprayingShow)
577 actionWindow.bspray.pack(pady='20', side='top')
578 actionWindow.bCredsWrite = ttk.Button(actionWindow.frame4)
579 actionWindow.bCredsWrite.configure(text='Write Credentials')
580 actionWindow.bCredsWrite.configure(command=self.writeCredsWindows)
581 actionWindow.bCredsWrite.pack(pady='20',side='top')
582 actionWindow.button4 = ttk.Button(actionWindow.frame4)
583 actionWindow.button4.configure(state='disabled', text='Launch owasp zap')
584 actionWindow.button4.pack(side='top')
585 actionWindow.frame4.configure(height='200', width='500')
586 actionWindow.frame4.pack(side='bottom')
587 actionWindow.frame4.pack_propagate(0)
588 self.actionWindow = actionWindow
589
590 def writeCredsWindows(self):
591 global writeCredsWindow
592 global rootDir
593 global sprayMode
594 self.mode = tk.IntVar()
595 if os.path.exists("{}/credsWrite.txt".format(rootDir)):
596 with open("{}/credsWrite.txt".format(rootDir), "r") as d:
597 data = d.read()
598 else:
599 data = '''admin\nroot\nuser\npassword'''
600 try:
601 if self.writeCredsWindow.state() == "normal": self.writeCredsWindow.lift()
602 except:
603 self.writeCredsWindow = Toplevel(self.actionWindow)
604 self.writeCredsWindow.frame4 = ttk.Frame(self.writeCredsWindow)
605 self.writeCredsWindow.frame5 = ttk.Frame(self.writeCredsWindow.frame4)
606 self.writeCredsWindow.sprayList = tk.Text(self.writeCredsWindow.frame5)
607 self.writeCredsWindow.sprayList.configure(height='10', width='50')
608 _text_ = data
609 self.writeCredsWindow.sprayList.insert('0.0', _text_)
610 self.writeCredsWindow.sprayList.grid(column='0', row='0')
611 self.writeCredsWindow.frame8 = ttk.Frame(self.writeCredsWindow.frame5)
612 self.writeCredsWindow.checkPassOnly = custom_checkbox_text(self.writeCredsWindow.frame8,"black","Password Only",onvalue=1,variable=self.mode)
613 #self.writeCredsWindow.checkPassOnly.configure(text='Password Only')
614 self.writeCredsWindow.checkPassOnly.pack(side='bottom')
615 self.writeCredsWindow.checkuserOnly = custom_checkbox_text(self.writeCredsWindow.frame8,"black","Username Only",onvalue=2,variable=self.mode)
616 #self.writeCredsWindow.checkuserOnly.configure(text='Username Only')
617 self.writeCredsWindow.checkuserOnly.pack(side='bottom')
618 self.writeCredsWindow.checkCombo = custom_checkbox_text(self.writeCredsWindow.frame8,"black","Combo Mode (user:pass)",onvalue=3,variable=self.mode)
619 #self.writeCredsWindow.checkCombo.configure(text='Combo Mode (user:pass)')
620 self.writeCredsWindow.checkCombo.pack(side='bottom')
621 self.writeCredsWindow.checkLP = custom_checkbox_text(self.writeCredsWindow.frame8,"black","User as passowrd",onvalue=4,variable=self.mode)
622 #self.writeCredsWindow.checkLP.configure(text='User as passowrd')
623 self.writeCredsWindow.checkLP.pack(side='bottom')
624 ttpUserOnly = CreateToolTip(self.writeCredsWindow.checkuserOnly,
625 "This will use the usernames you provide and our wordlist as passwords")
626 ttpPassOnly = CreateToolTip(self.writeCredsWindow.checkPassOnly,
627 "This will use the passwords you provide and our wordlist as usernames")
628 self.writeCredsWindow.label2 = ttk.Label(self.writeCredsWindow.frame8)
629 self.writeCredsWindow.label2.configure(text='Spraying Options')
630 self.writeCredsWindow.label2.pack(side='top')
631 self.writeCredsWindow.separator1 = ttk.Separator(self.writeCredsWindow.frame8)
632 self.writeCredsWindow.separator1.configure(orient='horizontal')
633 self.writeCredsWindow.separator1.pack(fill='x', pady='10', side='top')
634 self.writeCredsWindow.frame8.configure(height='200', width='200')
635 self.writeCredsWindow.frame8.grid(column='1', row='0')
636 self.writeCredsWindow.frame5.configure(height='200', width='200')
637 self.writeCredsWindow.frame5.pack(side='top')
638 self.writeCredsWindow.frame7 = ttk.Frame(self.writeCredsWindow.frame4)
639 self.writeCredsWindow.Bsave = ttk.Button(self.writeCredsWindow.frame7)
640 self.writeCredsWindow.Bsave.configure(text='Save')
641 self.writeCredsWindow.Bsave.configure(command=self.save)
642 self.writeCredsWindow.Bsave.grid(column='0', padx='20', pady='5', row='0')
643 self.writeCredsWindow.frame7.configure(height='200', width='200')
644 self.writeCredsWindow.frame7.pack(side='top')
645 self.writeCredsWindow.frame4.configure(height='200', width='200')
646 self.writeCredsWindow.frame4.pack(side='right')
647 try:
648 if sprayMode == "passOnly":
649 self.writeCredsWindow.checkPassOnly.select()
650 elif sprayMode == "userOnly":
651 self.writeCredsWindow.checkuserOnly.select()
652 elif sprayMode == "comboMode":
653 self.writeCredsWindow.checkCombo.select()
654 elif sprayMode == "User as Password":
655 self.writeCredsWindow.checkLP.select()
656 else:
657 pass
658 except:
659 pass
660
661
662 def save(self):
663 global rootDir
664 global sprayMode
665 global result
666 if self.mode.get() == 0:
667 messagebox.showerror("Missing Parameters",message="Please select 1 spraying mode.")
668 self.writeCredsWindow.lift()
669 else:
670 if self.mode.get() == 1:
671 sprayMode = "passOnly"
672 elif self.mode.get() == 2:
673 sprayMode = "userOnly"
674 elif self.mode.get() == 3:
675 sprayMode = "comboMode"
676 elif self.mode.get() == 4:
677 sprayMode = "User as Password"
678 else:
679 messagebox.showerror("Error", message="Something wrong happened.")
680 self.writeCredsWindow.lift()
681 result.createCommandSpraying()
682 with open("{}/credsWrite.txt".format(rootDir), "w+") as f:
683 f.write(self.writeCredsWindow.sprayList.get("1.0", END))
684 f.close()
685
686
687 def lol(self):
688 pass
689
690 def run(self):
691 self.mainwindow.mainloop()
692
693
694def on_exit(root):
695 global spList
696 if messagebox.askokcancel("Quit", "Are you sure you want to quit? Stuff might break"):
697 for service in spList:
698 service.terminate()
699 root.destroy()
700
701def doNikto(logfile, url):
702 global niktoList
703 newlogfile = logfile.replace('dirbust','nikto')
704 rootfile = logfile.split("dirbust")[0]
705 #print(rootfile)
706 #print(newlogfile)
707 try:
708 os.mkdir("{}/nikto".format(rootfile))
709 except:
710 pass
711 #cords =cordsManager("nikto")
712 command = "nikto -host={} -o {}".format(url,newlogfile)
713 niktoList.append(command)
714 #os.system("xterm -T 'Nikto!' -geometry {} -e {}".format(cords,command))
715
716def commentGrabber(logfile, host, dir):
717 global commentsExists
718 try:
719 os.mkdir("{}/html".format(dir)) # Creates the "HTML" directory
720 except:
721 pass
722 fileComments = os.path.join("{}/html/".format(dir), "comments.txt") # the comments.txt path
723
724 with open(logfile) as a: # Puts every gobusted findings from the file inside a list
725 content = a.readlines()
726
727 content = [x.strip() for x in content]
728 urls = []
729
730 for file in content: # Creates the urls (appends gobusted findings to url) for requests
731 fileFormat = file.split(' ')[0]
732 urls.append("{}{}".format(host, fileFormat))
733
734 if commentsExists == False:
735 f = open(fileComments, "w+") # Creates the comments.txt file
736 f.write("ALL THE COMMENTS EXTRACTED :\n\n")
737 f.close()
738 commentsExists = True
739 else:
740 pass
741 for url in urls: # Grabs all comments and writes it to comments.txt
742 r = requests.get(url, verify=False)
743 content = r.text
744 soup = BeautifulSoup(content, 'html.parser')
745 f = open(fileComments, "a")
746 f.write("{} :\n\n".format(url))
747 f.close()
748 for x in soup.findAll(text=lambda text: isinstance(text, Comment)):
749 f = open(fileComments, "a")
750 f.write(x)
751 f.close()
752
753
754def bust(url, wordlist, logfile, dir): # THIS IS THE THREADED FUNCTION
755 global busterList
756 command = "python3 ./busterScript.py --url {} --wordlist {} --output {} --rootDir {}".format(url, wordlist, logfile,dir)
757 busterList.append(command)
758 #cords = cordsManager("dirbust")
759 #os.system("xterm -T 'dirbuster!' -geometry {} -e {}".format(cords,command))
760
761
762def dirbuster(urls, wordlist, logfiles, dir): # This starts the threads, passing it all it needs.
763 i = 0
764 for url in urls:
765 tnikto = threading.Thread(target=doNikto, args=(logfiles[i], url,)) # FOR NIKTO!
766 tdirbust = threading.Thread(target=bust, args=(url, wordlist, logfiles[i], dir)) # FOR DIRBUST!
767 tdirbust.start()
768 tnikto.start()
769 i += 1
770'''
771def bruteSSH(rootDir, host):
772 try:
773 os.mkdir("{}/brute".format(rootDir)) # Creates the "brute" directory
774 except:
775 pass
776 cords = cordsManager("brute")
777 command = "hydra -s 22 -L ./wordlist/top-usernames-shortlist.txt -P ./wordlist/UserPassCombo-Jay.txt -V ssh://{} -o {}/brute/SSH.txt -I ".format(
778 host, rootDir)
779 os.system("xterm -T 'bruteforcing SSH!' -geometry {} -e {}".format(cords,command))
780
781def bruteSMB(rootDir, host):
782 try:
783 os.mkdir("{}/brute".format(rootDir)) # Creates the "brute" directory
784 except:
785 pass
786 cords = cordsManager("brute")
787 command = "hydra -t 1 -L ./wordlist/top-usernames-shortlist.txt -P ./wordlist/UserPassCombo-Jay.txt -V {} smb -o {}/brute/SMB.txt -I".format(host,rootDir)
788 os.system("xterm -T 'bruteforcing SMB!' -geometry 100x100 -hold -e {}".format(cords,command))
789
790'''
791def smbCheck(host,rootDir):
792 global smbCheckCmd
793 command = "python3 smbCheck.py --host {} --output {}".format(host,rootDir)
794 smbCheckCmd = command
795 #os.system("xterm -T 'SMB Checker!' -geometry 90x30+0+1080 -hold -e {}".format(command))
796'''
797def bruteFTP(rootDir, host):
798 try:
799 os.mkdir("{}/brute".format(rootDir)) # Creates the "brute" directory
800 except:
801 pass
802 command = "hydra -s 21 -t 20 -L ./wordlist/top-usernames-shortlist.txt -P ./wordlist/UserPassCombo-Jay.txt -vV ftp://{} -o {}/brute/FTP.txt -I ".format(host,rootDir)
803 os.system("xterm -T 'bruteforcing FTP!' -geometry 90x30+1920+1080 -e {}".format(command))
804
805'''
806
807class nmapScan:
808 '''
809 __INIT__ :
810 Initiate the nmap3 object and host variable.
811 Do an -sV scan and save it to self.result.
812 Format the result into a list self.openPorts.
813
814 '''
815
816 def __init__(self, host, rootDir, *args, **kwargs):
817 global debug # Boolean to skip nmap scan
818 try:
819 os.mkdir(os.path.join(rootDir, "nmap"))
820 except:
821 pass
822 self.rootDir = rootDir # This is where all the files of the scan will be outputed
823 #self.webServices = ["Microsoft IIS httpd", "Apache httpd", "nginx", "Apache Tomcat", "MiniServ",
824 # "lighttpd","Microsoft HTTPAPI httpd","http-proxy",'httpd','http']
825 self.webServices = ["http-proxy",'httpd','http']
826 # Let's only do common webservices.
827 self.host = host
828 self.nmap = nmap3.Nmap()
829 if debug == 1:
830 self.result = {'192.168.174.55': {'osmatch': {}, 'ports': [{'protocol': 'tcp', 'portid': '21', 'state': 'open', 'reason': 'syn-ack', 'reason_ttl': '127', 'service': {'name': 'ftp', 'product': 'FileZilla ftpd', 'version': '0.9.41 beta', 'ostype': 'Windows', 'method': 'probed', 'conf': '10'}, 'cpe': [{'cpe': 'cpe:/o:microsoft:windows'}], 'scripts': []}, {'protocol': 'tcp', 'portid': '80', 'state': 'open', 'reason': 'syn-ack', 'reason_ttl': '127', 'service': {'name': 'http', 'product': 'Apache httpd', 'version': '2.4.43', 'extrainfo': '(Win64) OpenSSL/1.1.1g PHP/7.4.6', 'method': 'probed', 'conf': '10'}, 'cpe': [{'cpe': 'cpe:/a:apache:http_server:2.4.43'}], 'scripts': []}, {'protocol': 'tcp', 'portid': '135', 'state': 'open', 'reason': 'syn-ack', 'reason_ttl': '127', 'service': {'name': 'msrpc', 'product': 'Microsoft Windows RPC', 'ostype': 'Windows', 'method': 'probed', 'conf': '10'}, 'cpe': [{'cpe': 'cpe:/o:microsoft:windows'}], 'scripts': []}, {'protocol': 'tcp', 'portid': '139', 'state': 'open', 'reason': 'syn-ack', 'reason_ttl': '127', 'service': {'name': 'netbios-ssn', 'product': 'Microsoft Windows netbios-ssn', 'ostype': 'Windows', 'method': 'probed', 'conf': '10'}, 'cpe': [{'cpe': 'cpe:/o:microsoft:windows'}], 'scripts': []}, {'protocol': 'tcp', 'portid': '443', 'state': 'open', 'reason': 'syn-ack', 'reason_ttl': '127', 'service': {'name': 'http', 'product': 'Apache httpd', 'version': '2.4.43', 'extrainfo': '(Win64) OpenSSL/1.1.1g PHP/7.4.6', 'tunnel': 'ssl', 'method': 'probed', 'conf': '10'}, 'cpe': [{'cpe': 'cpe:/a:apache:http_server:2.4.43'}], 'scripts': []}, {'protocol': 'tcp', 'portid': '445', 'state': 'open', 'reason': 'syn-ack', 'reason_ttl': '127', 'service': {'name': 'microsoft-ds', 'method': 'table', 'conf': '3'}, 'scripts': []}, {'protocol': 'tcp', 'portid': '3306', 'state': 'open', 'reason': 'syn-ack', 'reason_ttl': '127', 'service': {'name': 'mysql', 'servicefp': 'SF-Port3306-TCP:V=7.91%I=7%D=6/1%Time=60B66D74%P=x86_64-pc-linux-gnu%r(RTSPRequest,4D,"I\\0\\0\\x01\\xffj\\x04Host\\x20\'192\\.168\\.49\\.174\'\\x20is\\x20not\\x20allowed\\x20to\\x20connect\\x20to\\x20this\\x20MariaDB\\x20server")%r(DNSStatusRequestTCP,4D,"I\\0\\0\\x01\\xffj\\x04Host\\x20\'192\\.168\\.49\\.174\'\\x20is\\x20not\\x20allowed\\x20to\\x20connect\\x20to\\x20this\\x20MariaDB\\x20server")%r(Help,4D,"I\\0\\0\\x01\\xffj\\x04Host\\x20\'192\\.168\\.49\\.174\'\\x20is\\x20not\\x20allowed\\x20to\\x20connect\\x20to\\x20this\\x20MariaDB\\x20server")%r(TLSSessionReq,4D,"I\\0\\0\\x01\\xffj\\x04Host\\x20\'192\\.168\\.49\\.174\'\\x20is\\x20not\\x20allowed\\x20to\\x20connect\\x20to\\x20this\\x20MariaDB\\x20server");', 'method': 'table', 'conf': '3'}, 'scripts': []}, {'protocol': 'tcp', 'portid': '5040', 'state': 'open', 'reason': 'syn-ack', 'reason_ttl': '127', 'service': {'name': 'unknown', 'method': 'table', 'conf': '3'}, 'scripts': []}, {'protocol': 'tcp', 'portid': '7680', 'state': 'open', 'reason': 'syn-ack', 'reason_ttl': '127', 'service': {'name': 'tcpwrapped', 'method': 'probed', 'conf': '8'}, 'scripts': []}], 'hostname': [], 'macaddress': None, 'state': {'state': 'up', 'reason': 'echo-reply', 'reason_ttl': '127'}}, 'stats': {'scanner': 'nmap', 'args': '/usr/bin/nmap -oX - -sV -p- -oN /home/Kyand/testing/reconScript/nmap/nmap_scan.txt 192.168.174.55', 'start': '1622568153', 'startstr': 'Tue Jun 1 13:22:33 2021', 'version': '7.91', 'xmloutputversion': '1.05'}, 'runtime': {'time': '1622568463', 'timestr': 'Tue Jun 1 13:27:43 2021', 'summary': 'Nmap done at Tue Jun 1 13:27:43 2021; 1 IP address (1 host up) scanned in 309.55 seconds', 'elapsed': '309.55', 'exit': 'success'}}
831 else:
832 print("[!] nmap scan is running...\n")
833 self.result = self.nmap.nmap_version_detection(self.host, args="-p- -oN {}/nmap/nmap_scan.txt".format(
834 rootDir)) # -sV -p- -oN (rootDir/nmap_scant.txt) scan
835 print(self.result)
836 print("[!] nmap scan has completed!\n")
837 #print(self.result)
838 self.openPorts = []
839 for ports in self.result[self.host]["ports"]:
840 self.openPorts.append(ports)
841
842 def createCommandSpraying(self):
843 global sprayingCmd
844 global sprayMode
845 services = []
846 for port in self.openPorts:
847 try: # If dictionary does not have "product" key, skip. (Theres probably a better way to do this)
848 services.append(port['service']['name'])
849 except:
850 pass
851 stringServices = ""
852 for service in services:
853 stringServices+="{},".format(service)
854 #print(stringServices)
855
856 #print(services)
857 sprayingCmd = "python3 sprayer.py {}/credsWrite.txt {} {} {} '{}'".format(rootDir,self.host,stringServices,rootDir,sprayMode)
858 print(sprayingCmd)
859 #print(sprayingCmd)
860
861 def tbruteSMB(self):
862 global bruteSMBcmd
863 try:
864 os.mkdir("{}/brute".format(rootDir)) # Creates the "brute" directory
865 except:
866 pass
867 bruteSMBcmd = "hydra -t 1 -L ./wordlist/top-usernames-shortlist.txt -P ./wordlist/UserPassCombo-Jay.txt -V {} smb -o {}/brute/SMB.txt -I".format(
868 host, rootDir)
869 #print(bruteSMBcmd)
870 #os.system("xterm -T 'bruteforcing SMB!' -geometry 100x100 -hold -e {}".format(cords, command))
871
872 def tsmbCheck(self):
873 global smbCheckCmd
874 smbCheckCmd = "python3 smbCheck.py --host {} --output {} 2>/dev/null".format(self.host, self.rootDir)
875
876 '''
877 Runs funct
878 '''
879
880 def check(self, dWordList):
881 global SSL
882 global allBrute
883 for port in self.result[self.host]['ports']:
884 number = port['portid']
885 if number == "443":
886 SSL = True
887 else:
888 SSL = False
889
890 self.dirbust(dWordList) # Does dirbust AND extracts comments
891 for port in self.result[self.host]['ports']:
892 number = port['portid']
893 if number == "21":
894 self.checkFTP()
895 elif number == "22":
896 if allBrute == 1:
897 self.tBruteSSH()
898 else:
899 answ = input("[!] Do you wish to bruteforce SSH? (y/n)\n")
900 if answ == "y":
901 self.tBruteSSH()
902 else:
903 pass
904 pass
905
906 elif number == "445":
907 if allBrute == 1:
908 self.tbruteSMB()
909 else:
910 answ = input("[!] Do you wish to bruteforce SMB? (y/n)\n")
911 if answ == "y":
912 self.tbruteSMB()
913 else:
914 pass
915 self.tsmbCheck()
916 pass
917 else:
918 pass
919
920 '''
921 portScan:
922 Simply returns the list of openPorts
923
924 Example use :
925
926 host = "10.10.10.204"
927 result = nmapScan(host).listOpenPorts()
928 for r in result:
929 print(r)
930 '''
931
932 def listOpenPorts(self):
933 return self.openPorts
934
935 def tBruteSSH(self):
936 global bruteSSHcmd
937 try:
938 os.mkdir("{}/brute".format(self.rootDir)) # Creates the "brute" directory
939 except:
940 pass
941 bruteSSHcmd = "hydra -t 1 -L ./wordlist/top-usernames-shortlist.txt -P ./wordlist/UserPassCombo-Jay.txt -V {} ssh -o {}/brute/SSH.txt -I".format(
942 self.host, self.rootDir)
943 #os.system("xterm -T 'bruteforcing SMB!' -geometry 100x100 -hold -e {}".format(cords, command))
944
945 def tBruteFTP(self):
946 global bruteFTPcmd
947 try:
948 os.mkdir("{}/brute".format(self.rootDir)) # Creates the "brute" directory
949 except:
950 pass
951 bruteFTPcmd = "hydra -s 21 -t 20 -L ./wordlist/top-usernames-shortlist.txt -P ./wordlist/UserPassCombo-Jay.txt -vV ftp://{} -o {}/brute/FTP.txt -I ".format(
952 self.host, self.rootDir)
953 #print(bruteFTPcmd)
954 #os.system("xterm -T 'bruteforcing FTP!' -geometry 90x30+1920+1080 -e {}".format(command))
955 '''
956 Do regular FTP checks (check anon login, check perms)
957
958 '''
959
960 def checkFTP(self):
961 global allBrute
962 #print("ALLBRUTE : {}".format(allBrute))
963 rootDir = os.path.join(self.rootDir, "ftp") # /ftp directory
964 try:
965 os.mkdir(os.path.join(self.rootDir, "ftp")) # Create /ftp directory
966 except:
967 pass
968 f = open("{}/results.txt".format(rootDir), "w+") # Create results.txt file
969 ftp = FTP(self.host) # initate ftp object
970 try: # Check anonymous login
971 ftp.login()
972 f.write("Ftp anonymous : [WORKS]\n")
973 f.close()
974 if allBrute == 1:
975
976 self.tBruteFTP()
977 else:
978 answ = input("[!] FTP anonymous works, do you still want to bruteforce it? (y/n)\n")
979 if answ == "y":
980 self.tBruteFTP()
981 else:
982 pass
983 try: # test file upload (creates test.jpg, trys to upload it, removes it, writes in results.txt)
984 fileTest = open('test.jpg', 'w+')
985 ftp.storbinary('STOR kitten.jpg', fileTest)
986 fileTest.close()
987 os.remove('test.jpg')
988 f = open("{}/results.txt".format(rootDir), "a")
989 f.write("File upload : [WORKS]\n")
990 f.close()
991
992 except:
993 f = open("{}/results.txt".format(rootDir), "a")
994 f.write("File upload : [FAILED]\n")
995 f.close()
996
997
998
999 except Exception as e:
1000 if allBrute == 1:
1001 self.tBruteFTP()
1002 else:
1003 answ = input("[!] FTP anonymous works, do you still want to bruteforce it? (y/n)\n")
1004 if answ == "y":
1005 self.tBruteFTP()
1006 else:
1007 pass
1008 f.write("Ftp anonymous : [FAILED]\n")
1009 f.close()
1010 pass
1011
1012 '''
1013 Returns dictionary of PORT:SERVICE_NAME
1014
1015 Example use :
1016
1017 host = "10.10.10.204"
1018 result = nmapScan(host).services()
1019 print(result)
1020 '''
1021
1022 def listServices(self):
1023 self.servicesDict = {}
1024 for port in self.openPorts:
1025 try: # If dictionary does not have "product" key, skip. (Theres probably a better way to do this)
1026 self.servicesDict[port['portid']] = port['service']['name']
1027 except:
1028 pass
1029 return self.servicesDict # dictionary PORT:SERVICE_NAME
1030
1031 '''
1032 Used by dirbust function, creates log files. (Full path + name which is PORT_dirbust.txt)
1033
1034 '''
1035
1036 def createLogFiles(self, dir):
1037 self.logFiles = [] # list of full path
1038 try:
1039 os.mkdir(os.path.join(dir, "dirbust"))
1040 except:
1041 pass
1042 for url in self.urls: # Creates full path
1043 if SSL == True:
1044 port = "SSL"
1045 else:
1046 port = url.split(":")[2]
1047 name = "{}.txt".format(port)
1048 self.logFiles.append("{}/dirbust/{}".format(dir, name))
1049 return self.logFiles # Return list
1050
1051 '''
1052 This is the function that when called, will run a dirbuster on each webservice.
1053
1054 It needs a wordlist file, thats it!
1055
1056 Needs https support to be added.
1057 '''
1058
1059 def dirbust(self, wordfile):
1060 self.webServicePorts = [] # list of ports that are running http services
1061 self.urls = [] # list of url + port ready to dirbust.
1062 serviceList = self.listServices() # Gets a list of the services.
1063 for port in serviceList:
1064 if serviceList[port] in self.webServices: # If service_name is a web service
1065 self.webServicePorts.append(port) # append the port to list
1066 else:
1067 pass
1068 for port in self.webServicePorts: # Create url for dirbust.
1069 if SSL == True:
1070 if port == "80":
1071 url = "https://{}".format(self.host)
1072 else:
1073 url = "https://{}:{}".format(self.host, port)
1074 else:
1075 url = "http://{}:{}".format(self.host, port)
1076 self.urls.append(url)
1077 logFiles = self.createLogFiles(self.rootDir) # Creates logFile Paths
1078 dirbuster(self.urls, wordfile, logFiles, self.rootDir) # Starts the threads
1079
1080
1081if __name__ == '__main__':
1082 global allBrute
1083 global host
1084 global debug
1085 global result
1086 '''
1087 Argparse stuff (Comment out when debugging)
1088
1089 '''
1090
1091 parser = argparse.ArgumentParser(description="ReconScript")
1092 parser.add_argument('-I', '--host', type=str, metavar='', required=True, help='IP Address of the host')
1093 parser.add_argument('-o', '--output', type=str, metavar='', required=True,
1094 help='Output directory for scan (Full Path) (Example : /home/user/)')
1095 parser.add_argument('-w', '--wordlist', type=str, metavar='', required=True, help='Wordlist to use for dirbust')
1096 parser.add_argument('-a', '--all', action="store_true", required=False,
1097 help='--all if you want to bruteforce all (Does not prompt)')
1098 parser.add_argument('-d', '--debug', action="store_true", required=False,
1099 help='--debug to skip nmap (requires hardcoded nmap dict)')
1100 args = parser.parse_args()
1101 if args.all:
1102 allBrute = 1
1103 print("[!] Will bruteforce everything that is bruteforcable! Good luck :)\n")
1104 else:
1105 allBrute = 0
1106
1107 if args.debug:
1108 debug = 1
1109 print("[!!!] Debug mode enabled\n")
1110 else:
1111 debug = 0
1112
1113 host = args.host
1114 rootDir = os.path.join(args.output, "reconScript") # path to create directory
1115 try: # Check if it exists (THeres a better way to do it!)
1116 os.mkdir(rootDir)
1117 except:
1118 print("[!] {} Already exists, will output everything there.\n".format(rootDir))
1119 pass
1120 wordlist = args.wordlist
1121 result = nmapScan(host, rootDir)
1122 result.check(wordlist)# Regular portScan
1123
1124
1125
1126 import tkinter as tk
1127 root = tk.Tk()
1128 root.protocol("WM_DELETE_WINDOW", lambda arg=root: on_exit(arg)) # Overwrite exit function for tkinter
1129 app = NewprojectApp(root)
1130 app.run()
1131
1132