• Earn real money by being active: Hello Guest, earn real money by simply being active on the forum — post quality content, get reactions, and help the community. Once you reach the minimum credit amount, you’ll be able to withdraw your balance directly. Learn how it works.

Perl Sqli Finder (perl)

Status
Not open for further replies.

sQuo

~ KillmeMories ~
Shadow
User
Joined
Oct 16, 2011
Messages
5,851
Reputation
0
Reaction score
22,904
Points
688
Credits
0
‎13 Years of Service‎
24%
Code:
>
#!/usr/bin/env python

####################################################################################
#
# sqlinject-finder.py
#
# Author: tdean87
# Date  : 12/02/2010
# Description: Simple python script that parses through a pcap and looks at the 
#              GET and POST request data for suspicious and possible SQL injects.
#
####################################################################################

import dpkt, re, urllib, sys, getopt

tab = False

#removes inline comments that can sometimes be used for obfuscating the sql
def removeComments(val):
       while True:
                       index = val.find("/*")
                       index2 = val.find("*/")
                       if index != -1 and index2 != -1:
                               #looks like there is some type of SQL obfuscation, let's remove the comments
                               remove = val[index:index2+2]
                               val = val.replace(remove, "")
                       else:
                               break
       
       return val

#checks for common sql injection tactics using all the variables from post or get data
def analyzeRequest(vals, sIP, page, frameno):
       var = vals[0] #the variable, i.e. in id=1, the var is id
       val = vals[1] #the value, i.e. in id=1, the val is 1
       val = val.decode('ascii') #not sure if this is really doing anything, but we need to deal with non ascii characters for analysis
       val = urllib.unquote(val) #removes url encodings like %20 for space, etc
       val = val.replace("+", " ") #sometimes in urls, instead of a space you can have a + . So, we want to remove those for analysis
       #print val
       display = [False, sIP, page, var, val]
       ##### Look for obfuscation techniques ######
       index = val.find("/*")
       if index != -1:
               display[0] = True
               display.append("Might be attempting to obfuscate a SQL statement with a comment")
               val = removeComments(val)

       ##### Look for commenting out the end of a MSSQL statement ######
       index = val.rfind("--")
       if index != -1:
               display[0] = True
               display.append("Might be attempting to end a SQL statement by commenting out the remaining statement")
       
       ##### Look for commenting out the end of a MySQL statement #####
       index = val.rfind("#")
       if index != -1:
               display[0] = True
               display.append("Might be attempting to end a SQL statement by commenting out the remaining statement")
       
       ##### Look for common SQL syntax in the values of a param #####
       sqlvals = ("cast(", "declare ", "select ", "union ", "varchar", "set(", "create ", " or ", " NULL,", " concat(")
       for sql in sqlvals:
               index = val.lower().find(sql)
               if index != -1:
                       display[0] = True
                       display.append("Possible use of SQL syntax in variable")
                       break

       if display[0] == True:
               if tab:
                       line = str(display[1]) + "\t" + str(display[2]) + "\t" + str(display[3]) + "=" + str(display[4]) + "\t" + str(frameno)
                       for i in range(len(display)-5):
                               line = line + "\t" + str(display[i+5])
                       print line
               else:
                       print "Source : " + str(display[1])
                       print "Page   : " + str(display[2])
                       print "Value  : " + str(display[3]) + "=" + str(display[4])
                       print "Frame  : " + str(frameno)
                       for i in range(len(display)-5):
                               print "Reason : " + str(display[i+5])
                       print ""

def octetIP(sIP):
       ip = ""
       for s in sIP:
               ip = ip + str(ord(s)) + "."
               
       return ip[:-1]
               
               
#reads the pcap file and parses out get and post requests for analysis
def parsepcap(filename):
       try:
               f = open(filename, 'rb')
       except:
               print "Error reading file. Please make sure the file exists"
               sys.exit()
               
       try:
               pcap = dpkt.pcap.Reader(f)
       except:
               print "Error reading file. Please make sure the file is a valid pcap file."
               sys.exit()
       sIP=""
       page=""
       frameno = 1
       for ts, buf in pcap:
               eth = dpkt.ethernet.Ethernet(buf)
               ip = eth.data
               #make sure we are dealing with ip (2048) and tcp (proto=6)
               if eth.type ==2048 and ip.p == 6: 
                       tcp = ip.data
                       #assuming http is running on port 80
                       if tcp.dport == 80 and len(tcp.data) > 0:
                               index = 1
                               getvals = ""
                               try:
                                       http = dpkt.http.Request(tcp.data)
                                       url = http.uri
                                       #deal with post data
                                       if http.method == "POST":
                                               getvals=http.body
                                               index = url.find("?")
                                               if index != -1:
                                                       page = url[:index]
                                               else:
                                                       page = url
                                       #deal with GET data
                                       elif http.method == "GET":
                                               index = url.rfind("?")
                                               if index != -1:
                                                       getvals = url[index+1:]
                                                       page = url[:index]

                               except:
                                       data = tcp.data
                                       index = str(data).find("POST")
                                       if index == 0:
                                               url = str(data).split(" ")
                                               page = url[1] #POST is usually always the second value in the POST
                                       index = str(data).count("\n") #need to look into this method a little more, basically, we want to get POST data out of other streams
                                       if index == 0:
                                               index = str(data).find("=")
                                               if index != -1:
                                                       getvals = str(data)
                                               
                               #split up each variable and its cooresponding value
                               if getvals != "":
                                       getvals = getvals.split("&")
                                       for val in getvals:
                                               i = val.find("=")
                                               val = (val[:i], val[i+1:])
                                               sIP = octetIP(ip.src)
                                               analyzeRequest(val, sIP, page, frameno)
               frameno += 1
       f.close()

#usage stuff
def usage():
       print ""
       print "This tool parses through a pcap file and looks for potential SQL injection attempts."
       print ""
       print "usage: sqlinject-finder.py -f filename [-t]"
       print "Options and arguments (and corresponding environment variables):"
       print "-f, --filename : valid pcap file"
       print "-t, --tab      : prints output in tab delimited format"
       print "-h, --help     : shows this screen"
       print ""
       print "Example: #python sqlinject-finder.py -f capture.pcap"
       print "         #python sqlinject-finder.py -f capture.pcap -t > capture.tsv"
       print ""

def main():
       try:    
               opts, args = getopt.getopt(sys.argv[1:], "f:th", ["filename=", "tab", "help"])
       except getopt.GetoptError, err:
               print str(err)
               usage()
               sys.exit(2)

       filename = ""
       for o, a in opts:
               if o in ("-f", "--filename"):
                       filename = a
               elif o in ("-t", "--tab"):
                               global tab
                               tab = True      
               elif o in ("-h", "--help"):
                       usage()
                       sys.exit()
               else:
                       usage()
                       sys.exit()
       if (filename == ""):
               print "please specify a filename"
               sys.exit()
       if tab:
               print "Source\tPage\tValue\tFrame\tReason(s)"
       parsepcap(filename)     
       
if __name__ == "__main__":
       main()
 
Status
Not open for further replies.
Back
Top