class findBackdoor(baseDiscoveryPlugin): 00124 ''' 00125 Find web backdoors and web shells. 00126 @author: Andres Riancho ( andres.riancho@gmail.com ) 00127 ''' 00128 00129 def __init__(self): 00130 baseDiscoveryPlugin.__init__(self) 00131 00132 # Internal variables 00133 self._analyzed_dirs = disk_list() 00134 self._fuzzable_requests_to_return = [] 00135 00136 def discover(self, fuzzableRequest): 00137 ''' 00138 For every directory, fetch a list of shell files and analyze the response. 00139 00140 @parameter fuzzableRequest: A fuzzableRequest instance that contains 00141 (among other things) the URL to test. 00142 ''' 00143 domain_path = fuzzableRequest.getURL().getDomainPath() 00144 self._fuzzable_requests_to_return = [] 00145 00146 if domain_path not in self._analyzed_dirs: 00147 self._analyzed_dirs.append(domain_path) 00148 00149 # Search for the web shells 00150 for web_shell_filename in WEB_SHELLS: 00151 web_shell_url = domain_path.urlJoin(web_shell_filename) 00152 # Perform the check in different threads 00153 targs = (web_shell_url,) 00154 self._tm.startFunction(target=self._check_if_exists, 00155 args=targs, ownerObj=self) 00156 00157 # Wait for all threads to finish 00158 self._tm.join(self) 00159 00160 return self._fuzzable_requests_to_return 00161 00162 00163 def _check_if_exists(self, web_shell_url): 00164 ''' 00165 Check if the file exists. 00166 00167 @parameter web_shell_url: The URL to check 00168 ''' 00169 try: 00170 response = self._urlOpener.GET(web_shell_url, useCache=True) 00171 except w3afException: 00172 om.out.debug('Failed to GET webshell:' + web_shell_url) 00173 else: 00174 if self._is_possible_backdoor(response): 00175 v = vuln.vuln() 00176 v.setPluginName(self.getName()) 00177 v.setId(response.id) 00178 v.setName('Possible web backdoor') 00179 v.setSeverity(severity.HIGH) 00180 v.setURL(response.getURL()) 00181 msg = 'A web backdoor was found at: "%s"; this could ' \ 00182 'indicate that the server was hacked.' % v.getURL() 00183 v.setDesc(msg) 00184 kb.kb.append(self, 'backdoors', v) 00185 om.out.vulnerability(v.getDesc(), severity=v.getSeverity()) 00186 00187 fuzzable_requests = self._createFuzzableRequests(response) 00188 self._fuzzable_requests_to_return += fuzzable_requests 00189 00190 def _is_possible_backdoor(self, response): 00191 ''' 00192 Heuristic to infer if the content ofhas the pattern of a 00193 backdoor response. 00194 00195 @param response: httpResponse object 00196 @return: A bool value 00197 ''' 00198 if not is_404(response): 00199 body_text = response.getBody() 00200 dom = response.getDOM() 00201 if dom: 00202 for ele, attrs in BACKDOOR_COLLECTION.iteritems(): 00203 for attrname, attr_vals in attrs.iteritems(): 00204 # Set of lowered attribute values 00205 dom_attr_vals = \ 00206 set(n.get(attrname).lower() for n in \ 00207 (dom.xpath('//%s[@%s]' % (ele, attrname)))) 00208 # If at least one elem in intersection return True 00209 if (dom_attr_vals and set(attr_vals)): 00210 return True 00211 00212 # If no regex matched then try with keywords. At least 2 should be 00213 # contained in 'body_text' to succeed. 00214 times = 0 00215 for back_kw in KNOWN_OFFENSIVE_WORDS: 00216 if re.search(back_kw, body_text, re.I): 00217 times += 1 00218 if times == 2: 00219 return True 00220 return False 00221 00222 def getOptions(self): 00223 ''' 00224 @return: A list of option objects for this plugin. 00225 ''' 00226 ol = optionList() 00227 return ol 00228 00229 def setOptions(self, OptionList): 00230 ''' 00231 This method sets all the options that are configured using the user interface 00232 generated by the framework using the result of getOptions(). 00233 00234 @parameter OptionList: A dictionary with the options for the plugin. 00235 @return: No value is returned. 00236 ''' 00237 pass 00238 00239 def getPluginDeps(self): 00240 ''' 00241 @return: A list with the names of the plugins that should be runned before the 00242 current one. 00243 ''' 00244 return [] 00245 00246 def getLongDesc(self): 00247 ''' 00248 @return: A DETAILED description of the plugin functions and features. 00249 ''' 00250 return ''' 00251 This plugin searches for web shells in the directories that are sent as input. 00252 For example, if the input is: 00253 - http://host.tld/w3af/f00b4r.php 00254 00255 The plugin will perform these requests: 00256 - http://host.tld/w3af/c99.php 00257 - http://host.tld/w3af/cmd.php 00258 - http://host.tld/w3af/webshell.php 00259 ... 00260 '''
https://sourcecodebrowser.com/w3af/1.0.0/find_backdoor_8py_source.html
No comments:
Post a Comment