-
Notifications
You must be signed in to change notification settings - Fork 0
/
console.py
232 lines (190 loc) · 6.17 KB
/
console.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
import requests
import fire
import shlex
import platform
import os
import sys
import subprocess
import threading
import yaml
import config
import __main__
# Load new API modules here
APIS = ["store_api", "auth_api", "votes_api"]
ENDPOINT_MAP = {}
FUNCTION_MAP = {}
# Shell Information
PROMPT = "White Team >> "
HIST_FILE=".whiteteam_history"
HAS_READLINE = True
try:
import readline
except ImportError:
print("Warning: readline not installed. Limited shell capability.")
HAS_READLINE = False
def _api_request(endpoint, data=None, method='POST', token=None):
"""
Makes a request to our api and returns the response
:param endpoint: the api endpoint to hit
:param data: the data to send in dictionary format
:returns resp: the api response
"""
ENDPOINT_MAP = __main__.ENDPOINT_MAP
url = "{}/{}".format(ENDPOINT_MAP[endpoint], endpoint)
#print(url)
cookies = {'token': token}
if method == 'POST':
resp = requests.post(url, json=data, cookies=cookies)
else:
resp = requests.get(url, cookies=cookies)
if resp.status_code == 400:
print(resp.json())
raise Exception("Bad request sent to API")
if resp.status_code == 403:
raise Exception(resp.json()['error'])
elif resp.status_code != 200:
raise Exception("API returned {} for /{}".format(resp.status_code, endpoint))
resp_data = resp.json()
return resp_data
def _get_token():
"""
Gets an auth token for our white team account from the auth api
:returns token: the auth token for white team account
"""
data = dict()
data.update(config.get("creds", {}))
#data['username'] = config.get("creds", {}).get("username"
#data['password'] = AUTH_PASSWORD
endpoint = 'login'
resp = _api_request(endpoint, data=data)
if 'token' not in resp:
raise Exception('No token in AUTH_API response')
return resp['token']
def slackUpdate(msg):
"""
This function is used to log messages to slack.
"""
if not USE_SLACK:
return
requests.post(
URI,
json= {
"text": "{}:\t{}".format(NAME, msg),
"channel": CHANNEL,
"link_names": 1,
"username": USERNAME,
"icon_emoji": ICON_EMOJI
}
)
def banner():
"""
This function prints out the banner.
"""
print(
"""
██╗███████╗████████╗███████╗ ██╗███████╗
██║██╔════╝╚══██╔══╝██╔════╝ ███║╚════██║
██║███████╗ ██║ ███████╗ ╚██║ ██╔╝
██║╚════██║ ██║ ╚════██║ ██║ ██╔╝
██║███████║ ██║ ███████║ ██║ ██║
╚═╝╚══════╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝
""")
def exit():
"""
This function will be called when the console window is closed.
"""
sys.exit(0)
def clear():
"""
This function is used to clear the console window.
"""
p = subprocess.Popen( "cls" if platform.system() == "Windows" else "echo -e \\\\033c", shell=True)
p.wait()
class FireThread(threading.Thread):
"""
Run Fire in separate thread to prevent exiting.
"""
def __init__(self, cmd):
self._cmd = cmd
threading.Thread.__init__(self)
def run(self):
fire.Fire(FUNCTION_MAP, "{}".format(self._cmd))
# Tab completion for our console
class SimpleCompleter(object):
def __init__(self, options):
self.options = sorted(options)
return
def complete(self, text, state):
response = None
if state == 0:
# This is the first time for this text, so build a match list.
if text:
self.matches = [s
for s in self.options
if s and s.startswith(text)]
else:
self.matches = self.options[:]
# Return the state'th item from the match list,
# if we have that many.
try:
response = self.matches[state]
except IndexError:
response = None
return response
def main():
"""
Main Method
"""
# Build a map of all the endpoints and all the functions
global ENDPOINT_MAP
ENDPOINT_MAP = {}
global FUNCTION_MAP
FUNCTION_MAP = {}
for API in APIS:
api_module = __import__(API)
# Load all the endpoints and map them to the server
for endpoint in api_module._endpoints:
ENDPOINT_MAP[endpoint] = api_module._server
# Find all the callable functions for Fire
for func in dir(api_module):
if not func.startswith("_"):
FUNCTION_MAP[func] = getattr(api_module, func)
# Configure readline
if HAS_READLINE:
if os.path.exists(HIST_FILE):
readline.read_history_file(HIST_FILE)
readline.parse_and_bind('tab: complete')
readline.parse_and_bind('set editing-mode vi')
# Build Auto Complete
autocomplete = list(FUNCTION_MAP.keys())
completer = SimpleCompleter(autocomplete)
readline.set_completer(completer.complete)
# Loop for input
cleared = False
# Display the banner
banner()
while True:
if cleared:
cleared = False
continue
try:
cmd = input(PROMPT)
args = shlex.split(cmd)
if cmd.lower() == 'exit' or cmd.lower() == 'quit':
exit()
elif cmd.lower() == 'clear' or cmd.lower() == 'cls':
clear()
cleared = True
else:
t1 = FireThread(cmd)
t1.start()
t1.join()
if HAS_READLINE:
readline.write_history_file(HIST_FILE)
except EOFError as e:
exit()
except Exception as e:
print(e)
if __name__ == '__main__':
NAME = input("Please enter your name: ")
main()