Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
maurosoria
GitHub Repository: maurosoria/dirsearch
Path: blob/master/lib/view/terminal.py
896 views
1
# -*- coding: utf-8 -*-
2
# This program is free software; you can redistribute it and/or modify
3
# it under the terms of the GNU General Public License as published by
4
# the Free Software Foundation; either version 2 of the License, or
5
# (at your option) any later version.
6
#
7
# This program is distributed in the hope that it will be useful,
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
# GNU General Public License for more details.
11
#
12
# You should have received a copy of the GNU General Public License
13
# along with this program; if not, write to the Free Software
14
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
15
# MA 02110-1301, USA.
16
#
17
# Author: Mauro Soria
18
19
import sys
20
import shutil
21
22
from lib.core.data import options
23
from lib.core.decorators import locked
24
from lib.core.settings import IS_WINDOWS
25
from lib.view.colors import set_color, clean_color, disable_color
26
27
if IS_WINDOWS:
28
from colorama.win32 import (
29
FillConsoleOutputCharacter,
30
GetConsoleScreenBufferInfo,
31
STDOUT,
32
)
33
34
35
class CLI:
36
def __init__(self):
37
self.last_in_line = False
38
self.buffer = ""
39
40
if not options["color"]:
41
disable_color()
42
43
@staticmethod
44
def erase():
45
if IS_WINDOWS:
46
csbi = GetConsoleScreenBufferInfo()
47
line = "\b" * int(csbi.dwCursorPosition.X)
48
sys.stdout.write(line)
49
width = csbi.dwCursorPosition.X
50
csbi.dwCursorPosition.X = 0
51
FillConsoleOutputCharacter(STDOUT, " ", width, csbi.dwCursorPosition)
52
sys.stdout.write(line)
53
sys.stdout.flush()
54
55
else:
56
sys.stdout.write("\033[1K")
57
sys.stdout.write("\033[0G")
58
59
@locked
60
def in_line(self, string):
61
self.erase()
62
sys.stdout.write(string)
63
sys.stdout.flush()
64
self.last_in_line = True
65
66
@locked
67
def new_line(self, string="", do_save=True):
68
if self.last_in_line:
69
self.erase()
70
71
if IS_WINDOWS:
72
sys.stdout.write(string)
73
sys.stdout.flush()
74
sys.stdout.write("\n")
75
sys.stdout.flush()
76
77
else:
78
sys.stdout.write(string + "\n")
79
80
sys.stdout.flush()
81
self.last_in_line = False
82
sys.stdout.flush()
83
84
if do_save:
85
self.buffer += string
86
self.buffer += "\n"
87
88
def status_report(self, response, full_url):
89
target = response.url if full_url else "/" + response.full_path
90
# Get time from datetime string
91
time = response.datetime.split()[1]
92
message = f"[{time}] {response.status} - {response.size.rjust(6, ' ')} - {target}"
93
94
if response.status in (200, 201, 204):
95
message = set_color(message, fore="green")
96
elif response.status == 401:
97
message = set_color(message, fore="yellow")
98
elif response.status == 403:
99
message = set_color(message, fore="blue")
100
elif response.status in range(500, 600):
101
message = set_color(message, fore="red")
102
elif response.status in range(300, 400):
103
message = set_color(message, fore="cyan")
104
else:
105
message = set_color(message, fore="magenta")
106
107
if response.redirect:
108
message += f" -> {response.redirect}"
109
110
for redirect in response.history:
111
message += f"\n--> {redirect}"
112
113
self.new_line(message)
114
115
def last_path(self, index, length, current_job, all_jobs, rate, errors):
116
percentage = int(index / length * 100)
117
task = set_color("#", fore="cyan", style="bright") * int(percentage / 5)
118
task += " " * (20 - int(percentage / 5))
119
progress = f"{index}/{length}"
120
121
grean_job = set_color("job", fore="green", style="bright")
122
jobs = f"{grean_job}:{current_job}/{all_jobs}"
123
124
red_error = set_color("errors", fore="red", style="bright")
125
errors = f"{red_error}:{errors}"
126
127
progress_bar = f"[{task}] {str(percentage).rjust(2, chr(32))}% "
128
progress_bar += f"{progress.rjust(12, chr(32))} "
129
progress_bar += f"{str(rate).rjust(9, chr(32))}/s "
130
progress_bar += f"{jobs.ljust(21, chr(32))} {errors}"
131
132
if len(clean_color(progress_bar)) >= shutil.get_terminal_size()[0]:
133
return
134
135
self.in_line(progress_bar)
136
137
def new_directories(self, directories):
138
message = set_color(
139
f"Added to the queue: {', '.join(directories)}", fore="yellow", style="dim"
140
)
141
self.new_line(message)
142
143
def error(self, reason):
144
message = set_color(reason, fore="white", back="red", style="bright")
145
self.new_line("\n" + message)
146
147
def warning(self, message, do_save=True):
148
message = set_color(message, fore="yellow", style="bright")
149
self.new_line(message, do_save=do_save)
150
151
def header(self, message):
152
message = set_color(message, fore="magenta", style="bright")
153
self.new_line(message)
154
155
def print_header(self, headers):
156
msg = []
157
158
for key, value in headers.items():
159
new = set_color(key + ": ", fore="yellow", style="bright")
160
new += set_color(value, fore="cyan", style="bright")
161
162
if (
163
not msg
164
or len(clean_color(msg[-1]) + clean_color(new)) + 3
165
>= shutil.get_terminal_size()[0]
166
):
167
msg.append("")
168
else:
169
msg[-1] += set_color(" | ", fore="magenta", style="bright")
170
171
msg[-1] += new
172
173
self.new_line("\n".join(msg))
174
175
def config(self, wordlist_size):
176
177
config = {}
178
config["Extensions"] = ", ".join(options["extensions"])
179
180
if options["prefixes"]:
181
config["Prefixes"] = ", ".join(options["prefixes"])
182
if options["suffixes"]:
183
config["Suffixes"] = ", ".join(options["suffixes"])
184
185
config.update({
186
"HTTP method": options["http_method"],
187
"Threads": str(options["thread_count"]),
188
"Wordlist size": str(wordlist_size),
189
})
190
191
self.print_header(config)
192
193
def target(self, target):
194
self.new_line()
195
self.print_header({"Target": target})
196
197
def log_file(self, file):
198
self.new_line(f"\nLog File: {file}")
199
200
201
class QuietCLI(CLI):
202
def status_report(self, response, full_url):
203
super().status_report(response, True)
204
205
def last_path(*args):
206
pass
207
208
def new_directories(*args):
209
pass
210
211
def warning(*args, **kwargs):
212
pass
213
214
def header(*args):
215
pass
216
217
def config(*args):
218
pass
219
220
def target(*args):
221
pass
222
223
def log_file(*args):
224
pass
225
226
227
class EmptyCLI(QuietCLI):
228
def status_report(*args):
229
pass
230
231
def error(*args):
232
pass
233
234
235
interface = EmptyCLI() if options["disable_cli"] else QuietCLI() if options["quiet"] else CLI()
236
237