├── CREDAX.gif ├── README.md ├── credax.py ├── credax.sh ├── image_credax.png ├── notification_slack.png ├── requirements.txt ├── slack_notifications.png └── slack_variables.py /CREDAX.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notmarshmllow/credax/5e40c596a7993b76f27e81ae0f7bd142b60d0d79/CREDAX.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CREDAX - FUZZING TOOL with SLACK NOTIFICATIONS 2 | **CREDAX - WHEN THE HEAT IS ON, YOU GOTTA CALL THE FUZZ.** 3 | 4 | 5 | Credax is a lite-weight Smart, efficient Fuzzing Tool built in Python. 6 | 7 | CREDAX auto removes all consecutive result that respond with same length, thus removing almost all consecutive false positives, providing better output and also sends Notifications on Slack. 8 | 9 | ![alt text](https://github.com/notmarshmllow/credax/blob/main/CREDAX.gif) 10 | 11 | # INSTALLATION 12 | 13 | **Credax requires Python3.7 + to run. Please upgrade your Python version to 3.7 or higher to use Credax.** 14 | 15 | 1. Clone the Credax reporitory. 16 | 17 | `git clone https://github.com/notmarshmllow/credax.git` 18 | 19 | 2. Install the Requirements 20 | 21 | `pip install -r requirements.txt` 22 | 23 | `chmod +x credax.sh` 24 | 25 | `python3 credax.py -h` 26 | 27 | # EXAMPLE USAGE 28 | 29 | The following usage examples show the simplest task you can accomplish with `Credax`. 30 | 31 | 32 | ![alt text](https://github.com/notmarshmllow/credax/blob/main/image_credax.png?raw=True) 33 | 34 | 35 | 36 | # BASIC USAGE 37 | 38 | `python3 credax.py -d https://example.com/ -w wordlist.txt` 39 | 40 | # SEND NOTIFICATIONS TO SLACK 41 | Use `-s` switch to send notifications on your Slack wordspace. Add your slack webhook URL in **slack_variables.py** file. 42 | 43 | `python3 credax.py -d https://example.com/ -w wordlist.txt -s` 44 | 45 | ![alt text](https://github.com/notmarshmllow/credax/blob/main/notification_slack.png) 46 | 47 | # MATCHING STATUS CODES 48 | Use `-c` switch to filter HTTP Status Code from response. This switch accepts one single Status Code only. 49 | 50 | `python3 credax.py -d https://example.com/ -w wordlist.txt -c 200` 51 | 52 | # OUTPUT RESULTS TO A FILE 53 | Write output to a file using `-o` switch. 54 | 55 | `python3 credax.py -d https://example.com/ -w wordlist.txt -o filename.txt` 56 | 57 | # FUZZ LIST OF URLS 58 | 59 | Fuzz a list of URLs, store output in file and activate slack notifications with following command. 60 | 61 | `./credax.sh urllist wordlist` 62 | 63 | # POST REQUESTS 64 | 65 | Use `-POST` to send POST Requests. By default Credax sends GET Requests for Fuzzing. 66 | 67 | `python3 credax.py -d https://example.com/ -w wordlist.txt -POST` 68 | 69 | # BYPASSING 403 RESPONSES 70 | 71 | CREDAX by default tries to **bypass 403 Resopnse** using a list of custom Headers. Just run credax against a domain name and let CREDAX do all the work for you. 72 | Credax uses **127.0.0.1 IP Address** to bypass 403 response. 73 | 74 | You can also set Custom IP Address, Host Address or Path to Bypass 403 Resposne using `-HOST` Switch. 75 | 76 | `python3 -d https://google.com/ -w wordlists.txt -HOST 8.8.8.8` 77 | 78 | `python3 -d https://google.com/ -w wordlists.txt -HOST localhost` 79 | 80 | `python3 -d https://google.com/ -w wordlists.txt -HOST yourdomain.com` 81 | 82 | `python3 -d https://google.com/ -w wordlists.txt -HOST /admin` 83 | 84 | 85 | 86 | 87 | # COMMANDS 88 | 89 | COMMAND | DESCRIPTION | USAGE 90 | --------|-------------|------- 91 | -d | Target URL | -d https://example.com/ 92 | -w | File containing list of words to FUZZ | -w wordlist.txt 93 | -c | Matching Custom Status Code (Accepts Single Status Code) | -c 200 94 | -s | Enable Slack Notofications | -s 95 | -o | Write output to a file | -o filename 96 | -POST | Send POST Request (Default GET) | -POST 97 | -HOST | Custom IP Address, Host Address or Path to Bypass 403 | -HOST 8.8.8.8 **or** -HOST yourdomain.com **or** -HOST /admin 98 | 99 | 100 | 101 | # SLACK NOTIFICATIONS 102 | 103 | 1. Create your own Slack App. 104 | 2. Go to api.slack.com 105 | 3. Select your App 106 | 4. Select `Add features and functionality` > `Incoming Webhooks`. 107 | 5. Below on the page you will find your `Slack Webhook URL`. 108 | 6. Copy and Paste you Slack Webhook URL in place of `_slack_webhook_url_here_` inside `slack_variables.py` file. 109 | 110 | 111 | All developments to the tool are welcomed and highly appreciated ! 112 | 113 | Please open an issue to keep track of bugs, enhancements, or other requests. 114 | 115 | 116 | 117 | 118 | 119 | **CREDAX - Developed by [@notmarshmllow](https://twitter.com/notmarshmllow) [@Shivang0](https://github.com/Shivang0)** :sparkles: 120 | -------------------------------------------------------------------------------- /credax.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import aiohttp 3 | import asyncio 4 | import json 5 | import requests 6 | from slack_variables import slack_webhook_url 7 | from colorama import init 8 | from termcolor import colored 9 | from datetime import datetime 10 | 11 | init() 12 | 13 | print(colored("""\n 14 | 15 | _/_/_/ _/_/_/ _/_/_/_/ _/_/_/ _/_/ _/ _/ 16 | _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ 17 | _/ _/_/_/ _/_/_/ _/ _/ _/_/_/_/ _/ 18 | _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ 19 | _/_/_/ _/ _/ _/_/_/_/ _/_/_/ _/ _/ _/ _/ 20 | v1.0\n""", 'green')) 21 | 22 | print(colored(""" When the heat is on, you gotta call the fuzz 23 | Developed by notmarshmllow 24 | 25 | \n""", 'red')) 26 | 27 | 28 | 29 | my_parser = argparse.ArgumentParser() 30 | my_parser.add_argument('-d', type=str, required=True, help="Provide Target Name") 31 | my_parser.add_argument('-o', required=False, help="Specify your Output File Name") 32 | my_parser.add_argument('-w', required=True, help="Custom Wordlist") 33 | my_parser.add_argument('-c', help="Match Custom Status Codes") 34 | my_parser.add_argument('-s', required=False, action='count', help="Send notifications to slack.") 35 | my_parser.add_argument('-POST', required=False, action="count", help="POST METHOD") 36 | my_parser.add_argument('-HOST', required=False, default="127.0.0.1", help="Cutsom Address") 37 | 38 | 39 | args = my_parser.parse_args() 40 | 41 | base_url = args.d 42 | base_url = str(base_url) 43 | 44 | headers = { 45 | "X-Forwarded-For": "http://" + args.HOST, 46 | "X-Forwarded-For": args.HOST, 47 | "X-Originating-IP": args.HOST, 48 | "X-Forwarded-For": args.HOST, 49 | "X-Remote-IP": args.HOST, 50 | "X-Client-IP": args.HOST, 51 | "X-Host": args.HOST, 52 | "X-Forwared-Host": args.HOST, 53 | "X-Remote-Addr": args.HOST, 54 | "X-ProxyUser-Ip": args.HOST, 55 | } 56 | 57 | if args.c: 58 | user_c = args.c 59 | user_c = int(user_c) 60 | 61 | if args.HOST: 62 | ip11 = "IP ADDRESS/HOST : " + colored(args.HOST, 'red') 63 | if args.POST: 64 | p11 = "METHOD : " + colored(" POST", 'red') 65 | else: 66 | p11 = "METHOD : " + colored(" GET", 'red') 67 | if args.s: 68 | s11 = "SLACK NOTIFICATION :" + colored(" ON", 'red') 69 | else: 70 | s11 = "SLACK NOTIFICATION :" + colored(" OFF", 'red') 71 | if args.c: 72 | c11 = "Matching Status Codes : " + colored(args.c, 'red') 73 | else: 74 | c11 = "Matching Status Codes : " + colored(" 200 , 301, 302, 401, 403", 'red') 75 | if args.o: 76 | o11 = "OUTPUT TO : " + colored(args.o, 'red') 77 | else: 78 | o11 = "OUTPUT TO : " + colored(" NONE", 'red') 79 | u11 = "URL : " + colored(base_url, 'red') 80 | w11 = "Wordlist : " + colored(args.w, 'red') 81 | 82 | print(f'{u11} | {w11} | {p11} | {s11} | {c11} | {ip11} | {o11}\n') 83 | 84 | 85 | async def main(): 86 | l1 = [] 87 | num_words = 0 88 | 89 | async with aiohttp.ClientSession(headers=headers) as session: 90 | try: 91 | with open(args.w, encoding='ISO-8859-1', errors='ignore') as filex: 92 | 93 | for line in filex: 94 | l = [] 95 | word = line.strip() 96 | word = str(word) 97 | words = line.split() 98 | num_words += len(words) 99 | 100 | fuzz = base_url + word 101 | l.append(fuzz) 102 | 103 | if args.POST: 104 | 105 | async with session.post(fuzz) as resp: 106 | for i in range(num_words): 107 | print("Total Requests : {}".format(i), end="\r") 108 | status = resp.status 109 | l.append(status) 110 | 111 | result = await resp.text() 112 | result = str(result) 113 | size = len(result) 114 | l.append(size) 115 | l1.append(l) 116 | else: 117 | async with session.get(fuzz) as resp: 118 | 119 | for i in range(num_words): 120 | print("Total Requests : {}".format(i), end="\r") 121 | status = resp.status 122 | l.append(status) 123 | 124 | result = await resp.text() 125 | result = str(result) 126 | 127 | size = len(result) 128 | l.append(size) 129 | l1.append(l) 130 | 131 | except: 132 | pass 133 | 134 | 135 | 136 | existing = [] 137 | for lst in l1: 138 | if len(existing) > 0: 139 | if args.c: 140 | for i in lst: 141 | if i == user_c: 142 | if lst[-1] != existing[-1]: 143 | output_list = lst 144 | output_list_to_string = str(output_list).replace("'", " ") 145 | output_list_to_string1 = output_list_to_string.replace(",", " - ") 146 | output_list_to_string2 = output_list_to_string1[1:-1] 147 | print(output_list_to_string2) 148 | 149 | if args.s: 150 | lst1 = str(lst) 151 | 152 | lst_slack1 = lst1.replace("'", "") 153 | lst_slack2 = lst_slack1.replace(",", " - ") 154 | lst_slack2 = lst_slack2[1:-1] 155 | slack_data = {'text': lst_slack2} 156 | response = requests.post(slack_webhook_url, data=json.dumps(slack_data)) 157 | if response.status_code != 200: 158 | raise ValueError( 159 | 'Request to slack returned an error %s, the response is:\n%s' 160 | % (response.status_code, response.text) 161 | ) 162 | 163 | if args.o: 164 | file = open(args.o, 'a') 165 | file.write(output_list_to_string2 + '\n') 166 | 167 | 168 | else: 169 | if lst[1] != 404: 170 | if lst[-1] != existing[-1]: 171 | output_list = lst 172 | output_list_to_string = str(output_list).replace("'", " ") 173 | output_list_to_string1 = output_list_to_string.replace(",", " - ") 174 | output_list_to_string2 = output_list_to_string1[1:-1] 175 | print(output_list_to_string2) 176 | 177 | if args.s: 178 | lst1 = str(lst) 179 | 180 | lst_slack1 = lst1.replace("'", "") 181 | lst_slack2 = lst_slack1.replace(",", " - ") 182 | lst_slack2 = lst_slack2[1:-1] 183 | slack_data = {'text': lst_slack2} 184 | response = requests.post(slack_webhook_url, data=json.dumps(slack_data)) 185 | if response.status_code != 200: 186 | raise ValueError( 187 | 'Request to slack returned an error %s, the response is:\n%s' 188 | % (response.status_code, response.text) 189 | ) 190 | 191 | if args.o: 192 | file = open(args.o, 'a') 193 | file.write(output_list_to_string2 + '\n') 194 | 195 | 196 | 197 | 198 | existing.append(lst[-1]) 199 | 200 | asyncio.get_event_loop().run_until_complete(main()) 201 | -------------------------------------------------------------------------------- /credax.sh: -------------------------------------------------------------------------------- 1 | cat $1 | while read domain;do python3 credax.py -d $domain -w $2 -s -o $domain_credax.txt; done 2 | -------------------------------------------------------------------------------- /image_credax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notmarshmllow/credax/5e40c596a7993b76f27e81ae0f7bd142b60d0d79/image_credax.png -------------------------------------------------------------------------------- /notification_slack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notmarshmllow/credax/5e40c596a7993b76f27e81ae0f7bd142b60d0d79/notification_slack.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp==3.7.2 2 | async-timeout==3.0.1 3 | asyncio==3.4.3 4 | requests==2.24.0 5 | slack-sdk==3.0.0rc1 6 | slackclient==2.9.3 7 | urllib3==1.25.11 8 | colorama 9 | -------------------------------------------------------------------------------- /slack_notifications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notmarshmllow/credax/5e40c596a7993b76f27e81ae0f7bd142b60d0d79/slack_notifications.png -------------------------------------------------------------------------------- /slack_variables.py: -------------------------------------------------------------------------------- 1 | #Go to api.slack.com 2 | #Select your App 3 | #Select Add features and functionality > Incoming Webhooks 4 | #Below on the page you will find your Slack webhook url 5 | #Copy and Paste you Slack Webhook URL in place of _slack_webhook_url_here 6 | #slack_webhook_url = 'https://hooks.slack.com/services/XXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXX' 7 | 8 | 9 | slack_webhook_url = '_slack_webhook_url_here' 10 | --------------------------------------------------------------------------------