Skip to content

Commit

Permalink
v2.9 - See CHANGELOG.md
Browse files Browse the repository at this point in the history
  • Loading branch information
xnl-h4ck3r committed Feb 19, 2024
1 parent 431a072 commit 8e73535
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 5 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
## Changelog

- v2.9

- New

- Add `DISCORD_WEBHOOK` to `config.yml` to specify Discord webhook URL for alerts. If a webhook has been given, details of a successful XSS will be sent to Discord.
- Add `-dw`/`--discord-webhook` argument. This can be passed in the command to specify a Discord webhook and will override the value in the `config.yml` file.

- v2.8

- New
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<center><img src="https://github.com/xnl-h4ck3r/knoxnl/blob/main/knoxnl/images/title.png"></center>

## About - v2.8
## About - v2.9

This is a python wrapper around the amazing [KNOXSS API](https://knoxss.me/?page_id=2729) by Brute Logic.
To use this tool (and the underlying API), you must have a valid KNOXSS API key. Don't have one? Go visit https://knoxss.me and subscribe!
Expand Down Expand Up @@ -51,6 +51,7 @@ The `config.yml` file (in the global location based on the OS, e.g. `~/.config/k

- `API_URL` - This can be set to the KNOXSS API endpoint, if and when it is changed
- `API_KEY` - Your KNOXSS API key that you will have generated on https://knoxss.me/
- `DISCORD_WEBHOOK` - Your discord webhook URL if you want to be notified of successful XSS

## Important Notes from KNOXSS API Guidelines

Expand Down Expand Up @@ -169,6 +170,10 @@ File of URLs checked with GET and POST:
<center><img src="https://github.com/xnl-h4ck3r/knoxnl/blob/main/knoxnl/images/example2.png"></center>
Example Discord notification:
<center><img src="https://github.com/xnl-h4ck3r/knoxnl/blob/main/knoxnl/images/discord.png"></center>
Good luck and good hunting!
If you really love the tool (or any others), or they helped you find an awesome bounty, consider [BUYING ME A COFFEE!](https://ko-fi.com/xnlh4ck3r) ☕ (I could use the caffeine!)
Expand Down
1 change: 1 addition & 0 deletions config.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
API_URL: https://api.knoxss.pro
API_KEY: YOUR_API_KEY
DISCORD_WEBHOOK: YOUR_WEBHOOK
2 changes: 1 addition & 1 deletion knoxnl/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__="2.8"
__version__="2.9"
Binary file added knoxnl/images/discord.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 47 additions & 3 deletions knoxnl/knoxnl.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
# Yaml config values
API_URL = ''
API_KEY = ''
DISCORD_WEBHOOK = ''

# Object for an KNOXSS API response
class knoxss:
Expand Down Expand Up @@ -87,7 +88,8 @@ def showOptions():
print(colored('Selected config and settings:', 'cyan'))

print(colored('KNOXSS API Url:', 'magenta'), API_URL)
print(colored('KNOXSS API Key:', 'magenta'), API_KEY)
print(colored('KNOXSS API Key:', 'magenta'), API_KEY)
print(colored('Discord Webhook:', 'magenta'), DISCORD_WEBHOOK)

if args.burp_piper:
print(colored('-i: ' + args.input, 'magenta'), 'Request passed from Burp Piper Extension')
Expand Down Expand Up @@ -140,7 +142,7 @@ def needApiKey():

def getConfig():
# Try to get the values from the config file, otherwise use the defaults
global API_URL, API_KEY
global API_URL, API_KEY, DISCORD_WEBHOOK
try:

# Put config in global location based on the OS.
Expand Down Expand Up @@ -176,6 +178,16 @@ def getConfig():
print(colored('Unable to read "API_KEY" from config.yml; We need an API key! - ' + str(e), 'red'))
needApiKey()
quit()

# Set the Discord webhook. If passed with argument -dw / --discord-webhook then this will override the config value
if args.discord_webhook != '':
DISCORD_WEBHOOK = args.discord_webhook
else:
try:
DISCORD_WEBHOOK = config.get('DISCORD_WEBHOOK').replace('YOUR_WEBHOOK','')
except Exception as e:
DISCORD_WEBHOOK = ''

except Exception as e:
try:
if args.api_key == '':
Expand All @@ -186,7 +198,7 @@ def getConfig():
API_URL = DEFAULT_API_URL
API_KEY = args.api_key
print(colored('Unable to read config.yml; using default API URL and passed API Key', 'cyan'))

DISCORD_WEBHOOK = args.discord_webhook
except Exception as e:
print(colored('ERROR getConfig: ' + str(e), 'red'))

Expand Down Expand Up @@ -402,6 +414,27 @@ def processInput():
def process_batch(urls):
with multiprocessing.Pool(processes=args.processes) as pool:
pool.map(processUrl, urls)

def discordNotify(target,poc):
global DISCORD_WEBHOOK
try:
embed = {
"description": "```\n"+poc+"\n```",
"title": "KNOXSS POC for "+target
}
data = {
"content": "XSS found by knoxnl! 🤘",
"username": "knoxnl",
"embeds": [embed],
}
try:
result = requests.post(DISCORD_WEBHOOK, json=data)
if 300 <= result.status_code < 200:
print(colored('WARNING: Failed to send notification to Discord - ' + result.json(), 'yellow'))
except Exception as e:
print(colored('WARNING: Failed to send notification to Discord - ' + str(e), 'yellow'))
except Exception as e:
print(colored('ERROR discordNotify 1: ' + str(e), 'red'))

def processOutput(target, method, knoxssResponse):
global latestApiCalls, successCount, outFile
Expand Down Expand Up @@ -454,6 +487,10 @@ def processOutput(target, method, knoxssResponse):
else:
print(colored(xssText, 'green'), colored('['+latestApiCalls+']','white'))
successCount = successCount + 1
# Send a notification to discord if a webook was provided
if DISCORD_WEBHOOK != '':
discordNotify(target,knoxssResponse.PoC)
# Write the successful XSS details to file
if fileIsOpen:
outFile.write(xssText + '\n')
else:
Expand Down Expand Up @@ -605,6 +642,13 @@ def main():
action='store_true',
help='Set if called from the Burp Piper extension.',
)
parser.add_argument(
'-dw',
'--discord-webhook',
help='The Discord Webhook to send successful XSS notifications to. This will be used instead of the value in config.yml',
action='store',
default='',
)
parser.add_argument('-v', '--verbose', action='store_true', help="Verbose output")
parser.add_argument('--version', action='store_true', help="Show version number")
args = parser.parse_args()
Expand Down

0 comments on commit 8e73535

Please sign in to comment.