PageRenderTime 58ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/src/pentest/grabber/javascript.py

https://github.com/sullivanmatt/Raspberry-Pwn
Python | 182 lines | 168 code | 3 blank | 11 comment | 1 complexity | 8140ae72c78b80e62cddbc4650f473e8 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, MPL-2.0-no-copyleft-exception, GPL-2.0, GPL-3.0
  1. #!/usr/bin/env python
  2. """
  3. Simple JavaScript Checker Module for Grabber v0.1
  4. Copyright (C) 2006 - Romain Gaucher - http://rgaucher.info
  5. - Look at the JavaScript Source...
  6. """
  7. import sys, re, os
  8. from spider import htmlencode
  9. from xml.sax import * # Need PyXML [http://pyxml.sourceforge.net/]
  10. # JavaScript Configuration variables
  11. jsAnalyzerBin= None
  12. jsAnalyzerInputParam = None
  13. jsAnalyzerOutputParam = None
  14. jsAnalyzerConfParam = None
  15. jsAnalyzerConfFile= None
  16. jsAnalyzerExtension = None
  17. jsAnalyzerPattern = None
  18. # { 'FILENAME' : { 'line' : ['error 1', 'error 2'] } }
  19. jsDatabase = {}
  20. """
  21. <?xml version="1.0"?>
  22. <!-- JavaScript Source Code Analyzer configuration file -->
  23. <javascript version="0.1">
  24. <!--
  25. Analyzer information, here JavaScript Lint by Matthias Miller
  26. http://www.JavaScriptLint.com
  27. -->
  28. <analyzer>
  29. <path input="-process" output="">C:\server\jsl-0.3.0\jsl.exe</path>
  30. <configuration param="-conf">C:\server\jsl-0.3.0\jsl.grabber.conf</configuration>
  31. <extension>js</extension>
  32. </analyzer>
  33. </javascript>
  34. """
  35. def normalize_whitespace(text):
  36. return ' '.join(text.split())
  37. def clear_whitespace(text):
  38. return text.replace(' ','')
  39. # Handle the XML file with a SAX Parser
  40. class JavaScriptConfHandler(ContentHandler):
  41. def __init__(self):
  42. self.inAnalyzer = False
  43. self.string = ""
  44. def startElement(self, name, attrs):
  45. global jsAnalyzerInputParam, jsAnalyzerOutputParam, jsAnalyzerConfParam
  46. self.string = ""
  47. self.currentKeys = []
  48. if name == 'analyzer':
  49. self.inAnalyzer = True
  50. elif name == 'path' and self.inAnalyzer:
  51. # store the attributes input and output
  52. if 'input' in attrs.keys() and 'output' in attrs.keys():
  53. jsAnalyzerInputParam = attrs.getValue('input')
  54. jsAnalyzerOutputParam = attrs.getValue('output')
  55. else:
  56. raise KeyError("JavaScriptXMLConf: <path> needs 'input' and 'output' attributes")
  57. elif name == 'configuration' and self.inAnalyzer:
  58. # store the attribute 'param'
  59. if 'param' in attrs.keys():
  60. jsAnalyzerConfParam = attrs.getValue('param')
  61. else:
  62. raise KeyError("JavaScriptXMLConf: <configuration> needs 'param' attribute")
  63. def characters(self, ch):
  64. self.string = self.string + ch
  65. def endElement(self, name):
  66. global jsAnalyzerBin, jsAnalyzerConfFile, jsAnalyzerExtension,jsAnalyzerPattern
  67. if name == 'configuration':
  68. jsAnalyzerConfFile = normalize_whitespace(self.string)
  69. elif name == 'extension' and self.inAnalyzer:
  70. jsAnalyzerExtension = normalize_whitespace(self.string)
  71. elif name == 'path' and self.inAnalyzer:
  72. jsAnalyzerBin = normalize_whitespace(self.string)
  73. elif name == "analyzer":
  74. self.inAnalyzer = False
  75. elif name == "pattern":
  76. jsAnalyzerPattern = normalize_whitespace(self.string)
  77. def execCmd(program, args):
  78. buff = []
  79. p = os.popen(program + " " + args)
  80. buff = p.readlines()
  81. p.close()
  82. return buff
  83. def generateListOfFiles(localDB, urlGlobal):
  84. global jsDatabase
  85. """
  86. Create a ghost in ./local/crystal/current and /local/crystal/analyzed
  87. And run the SwA tool
  88. """
  89. regScripts = re.compile(r'(.*).' + jsAnalyzerExtension + '$', re.I)
  90. # escape () and []
  91. localRegOutput = jsAnalyzerPattern
  92. localRegOutput = localRegOutput.replace('(', '\(')
  93. localRegOutput = localRegOutput.replace(')', '\)')
  94. localRegOutput = localRegOutput.replace('[', '\[')
  95. localRegOutput = localRegOutput.replace(']', '\]')
  96. localRegOutput = localRegOutput.replace(':', '\:')
  97. localRegOutput = localRegOutput.replace('__LINE__', '(\d+)')
  98. localRegOutput = localRegOutput.replace('__FILENAME__', '(.+)')
  99. localRegOutput = localRegOutput.replace('__ERROR__', '(.+)')
  100. regOutput = re.compile('^'+localRegOutput+'$', re.I)
  101. print "Running the static analysis tool..."
  102. for file in localDB:
  103. print file
  104. file = file.replace(urlGlobal + '/', '')
  105. fileIn = os.path.abspath(os.path.join('./local', file))
  106. cmdLine = jsAnalyzerConfParam + " " +jsAnalyzerConfFile + " " + jsAnalyzerInputParam + " " + fileIn
  107. if jsAnalyzerOutputParam != "":
  108. cmdLine += " " + jsAnalyzerOutputParam + " " + fileIn+'.jslint'
  109. output = execCmd(jsAnalyzerBin, cmdLine)
  110. # Analyze the output
  111. for o in output:
  112. lO = o.replace('\n','')
  113. if regOutput.match(lO):
  114. out = regOutput.search(lO)
  115. if file not in jsDatabase:
  116. jsDatabase[file] = {}
  117. line = clear_whitespace(out.group(2))
  118. if line not in jsDatabase[file]:
  119. jsDatabase[file][line] = []
  120. jsDatabase[file][line].append(normalize_whitespace(out.group(3)))
  121. # sort the dictionary
  122. # + file
  123. # + lines
  124. def process(urlGlobal, localDB, attack_list):
  125. """
  126. Crystal Module entry point
  127. """
  128. print "JavaScript Module Start"
  129. try:
  130. f = open("javascript.conf.xml", 'r')
  131. f.close()
  132. except IOError:
  133. print "The javascript module needs the 'javascript.conf.xml' configuration file."
  134. sys.exit(1)
  135. parser = make_parser()
  136. js_handler = JavaScriptConfHandler()
  137. # Tell the parser to use our handler
  138. parser.setContentHandler(js_handler)
  139. try:
  140. parser.parse("javascript.conf.xml")
  141. except KeyError, e:
  142. print e
  143. sys.exit(1)
  144. # only a white box testing...
  145. generateListOfFiles(localDB,urlGlobal)
  146. # create the report
  147. plop = open('results/javascript_Grabber.xml','w')
  148. plop.write("<javascript>\n")
  149. plop.write("<site>\n")
  150. for file in jsDatabase:
  151. plop.write("\t<file name='%s'>\n" % file)
  152. for line in jsDatabase[file]:
  153. if len(jsDatabase[file][line]) > 1:
  154. plop.write("\t\t<line number='%s'>\n" % line)
  155. for error in jsDatabase[file][line]:
  156. plop.write("\t\t\t<error>%s</error>\n" % htmlencode(error))
  157. plop.write("\t\t</line>\n")
  158. else:
  159. plop.write("\t\t<line number='%s'>%s</line>\n" % (line, htmlencode(jsDatabase[file][line][0])))
  160. plop.write("\t</file>\n")
  161. plop.write("</site>\n")
  162. plop.write("</javascript>\n")
  163. plop.close()