起因
有时候目录扫描,我们会顺便扫描是否存在备份的情况,这时候就自己简单的写了一个python的脚本
主要想做到的是 例如我扫 http://xxx.cn 的站点目标的时候
会根据域名自动的去匹配以下这种基于域名生成的文件备份路径
http://a.xxx.cn/zkap.zip
http://a.xxx.cn/a.zip
from colorama import init #cmd终端带颜色
init(autoreset=True)
def title():
print('+------------------------------------------')
print('+ 33[34m......初始化开始...... 33[0m')
print('+ 33[34m杳若出品 33[0m')
print('+ 33[34mTitle: 用于文件备份扫描~ 33[0m')
print('+ 33[36m使用格式: 输入必要的参数 33[0m')
print('+------------------------------------------')
当然是为了减少被ban的几率了
from faker import Faker # 随机请求头的库
import random # 为了增加随机的ip
# 随机请求头
def header():
headers = {
'Accept': '*/*',
'Referer': 'http://www.baidu.com',
'User-Agent': Faker().user_agent(),
'Cache-Control': 'no-cache',
'X-Forwarded-For': '127.0.0.{}'.format(random.randint(1, 255)),
}
return headers
利用库做到了UA请求头随机,用random做到了xff的伪随机,当然Referer也可以换
传入的内容可能带http可能https也可能不带,就要自己添加,这里写一个检测
from urllib.parse import urlparse # 协议分离的库
import requests # http协议请求的库
def urlpar(url):
# 这里是检测传入是否带http,不带的话就会自动去拼接
if 'http' not in url:
if url[-1] == '/':
url, p2, p3 = url.partition('/')
# 拼接的话会请求http,如果访问失败那就添加https
try:
requests.head(url='http://' + url, headers=header(), verify=False, timeout=(3, 8))
return 'http://' + url
except Exception as e:
return 'https://' + url
# 不然就是带协议头啦
else:
url_Doman = urlparse(url).netloc
url_http = urlparse(url).scheme
url_main = "{}{}{}".format(url_http, '://', url_Doman)
return url_main
# url域名分割
def tldex(url):
url = tldextract.extract(urlpar(url))
one = url.subdomain
three = url.suffix
two = url.domain
# 切割成了三个部分,顶级域名、主域和尾
return one, two, three
首先需要一个分割好的字典集合,然后添加对应的后缀
# 组合自定义字典
def dith(one, two, three):
urls = []
urls = urls + diy(one)
urls = urls + diy(two)
urls = urls + diy(three)
urls = urls + diy(two + '.' + three)
urls = urls + diy(one + '.' + two)
urls = urls + diy(one + '.' + two + '.' + three)
# 返回就是一个字典集合了
return urls
# 自定义字典内容
def diy(ci):
url = []
url.append('/' + ci + '.rar')
url.append('/' + ci + '.zip')
url.append('/' + ci + '.txt')
url.append('/' + ci + '.apk')
url.append('/' + ci + '.gz')
return url
这里都可以自定义各种内容
发起请求的话就是不断的将url以及对应的路由进行拼接判定,这里利用了Content-Length来判断大小,大于一定的值就证明存在文件备份
但是考虑到了vue等框架的误报情况,做了一定的防误报处理
import requests # http协议请求的库
import requests.packages.urllib3.util.ssl_
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ALL'
from urllib3.exceptions import InsecureRequestWarning
# 防止无证书连接的报错
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
# 进行备份扫描以及确认
# 这里传入需要检测的url以及需要拼接的后缀urls做的字典
def scan(url, urls):
a = 0
u = []
b = 0
# 传入了字典,进行遍历
for url1 in urls:
try:
# time.sleep(random.randint(1,10))
r = requests.head(url=url + url1, headers=header(), verify=False, timeout=(3, 30)) # 通过请求漏洞存在网址,获取其数据流的大小
rarsize = int(r.headers.get('Content-Length')) # 是str格式-对数据流大小的获取
if rarsize >= 1000 * 10:
print('33[32m [o] 存在漏洞[>]%s[>]%skb33[0m' % (url + url1, str(rarsize)))
a = a + 1
u.append(url + url1 + '\t' + str(rarsize))
if (a >= 5):
print('33[31m [x] 存在误报[>]%s[>]%skb33[0m' % (url + url1, str(rarsize)))
break
pass
else:
print('33[31m [x] 不存在漏洞[>]%s[>]%skb33[0m' % (url + url1, str(rarsize)))
except Exception as e:
try:
r = requests.head(url=url + url1, headers=header(), verify=False, timeout=(3, 30))
if r.status_code == 404:
b = b + 1
except Exception as e:
b = b +1
# 如果请求了10个数据包都是404,那太慢了,直接提示url不行
if b >= 10:
break
print(' [?] 存在问题>' + url + url1)
# 如果存在漏洞的数量大于5个,极大可能就是误报了
if a < 5 and u != []:
for url in u:
with open('cunzai.txt', 'a+', encoding='utf-8') as fp:
fp.write(url + '\n')
# -*- coding:utf-8 -*-
import random # 请求协议/域名分割/随机
import re
from urllib.parse import urlparse # 协议分离
from colorama import init #cmd终端带颜色
init(autoreset=True)
import requests
# import time
# requests防止报错
import requests.packages.urllib3.util.ssl_
import tldextract
#from fake_useragent import UserAgent # 随机请求头
from faker import Faker # 随机请求头二代
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ALL'
from urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
# 随机请求头
def header():
headers = {
'Accept': '*/*',
'Referer': 'http://www.baidu.com',
'User-Agent': Faker().user_agent(),
'Cache-Control': 'no-cache',
'X-Forwarded-For': '127.0.0.{}'.format(random.randint(1, 255)),
}
return headers
# url进行协议分割
def urlpar(url):
if 'http' not in url:
if url[-1] == '/':
url, p2, p3 = url.partition('/')
try:
requests.head(url='http://' + url, headers=header(), verify=False, timeout=(3, 8))
return 'http://' + url
except Exception as e:
return 'https://' + url
else:
url_Doman = urlparse(url).netloc
url_http = urlparse(url).scheme
url_main = "{}{}{}".format(url_http, '://', url_Doman)
return url_main
# url域名分割
def tldex(url):
url = tldextract.extract(urlpar(url))
one = url.subdomain
three = url.suffix
two = url.domain
return one, two, three
# 自定义字典内容
def diy(ci):
url = []
url.append('/' + ci + '.rar')
url.append('/' + ci + '.zip')
url.append('/' + ci + '.txt')
url.append('/' + ci + '.apk')
url.append('/' + ci + '.gz')
return url
# 组合自定义字典
def dith(one, two, three):
urls = []
urls = urls + diy(one)
urls = urls + diy(two)
urls = urls + diy(three)
urls = urls + diy(two + '.' + three)
urls = urls + diy(one + '.' + two)
urls = urls + diy(one + '.' + two + '.' + three)
return urls
# 拼接比较常见的备份地址
def dithadd(url):
urls = ['/.git', '/.svn', '/新建文件夹.rar', '/新建文件夹.zip', '/备份.rar', '/wwwroot.rar', '/wwwroot.zip', '/backup.rar',
'/bf.rar', '/beifen.rar', '/www.rar', '/vera_Mobile.zip', '/web.rar', '/zuixin.rar', '/最新.rar',
'/test.rar', '/test.zip', '/web.zip', '/www.zip', '/最新备份.rar']
url = url + urls
return url
# 拼接字典
def adithaddadd(url):
urls = []
for urla in open('dict.txt', encoding='utf-8'):
urla = urla.replace('\n', '')
if len(urla) != 0:
urls.append(urla)
else:
pass
urls = urls + url
return urls
# 进行备份扫描以及确认
def scan(url, urls):
a = 0
u = []
b = 0
for url1 in urls:
try:
# time.sleep(random.randint(1,10))
r = requests.head(url=url + url1, headers=header(), verify=False, timeout=(3, 30)) # 通过请求漏洞存在网址,获取其数据流的大小
rarsize = int(r.headers.get('Content-Length')) # 是str格式-对数据流大小的获取
if rarsize >= 1000 * 10:
print('33[32m [o] 存在漏洞[>]%s[>]%skb33[0m' % (url + url1, str(rarsize)))
a = a + 1
u.append(url + url1 + '\t' + str(rarsize))
if (a >= 5):
print('33[31m [x] 存在误报[>]%s[>]%skb33[0m' % (url + url1, str(rarsize)))
break
pass
else:
print('33[31m [x] 不存在漏洞[>]%s[>]%skb33[0m' % (url + url1, str(rarsize)))
except Exception as e:
try:
r = requests.head(url=url + url1, headers=header(), verify=False, timeout=(3, 30))
if r.status_code == 404:
b = b + 1
except Exception as e:
b = b +1
if b >= 10:
break
print(' [?] 存在问题>' + url + url1)
if a < 5 and u != []:
for url in u:
with open('cunzai.txt', 'a+', encoding='utf-8') as fp:
fp.write(url + '\n')
def main(url, key):
p1, p2, p3 = url.replace('http://', '').replace('https://', '').partition(':')
if re.match(r"^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$", p1):
add_url = dithadd([])
else:
one, two, three = tldex(url)
urls = dith(one, two, three) # 自定义列表
add_url = dithadd(urls)
if key == 'yes':
add_url = adithaddadd(add_url)
scan(urlpar(url), add_url)
# 这是标题~
def title():
print('+------------------------------------------')
print('+ 33[34m......初始化开始...... 33[0m')
print('+ 33[34m杳若出品 33[0m')
print('+ 33[34mTitle: 用于文件备份扫描~ 33[0m')
print('+ 33[36m使用格式: 输入必要的参数 33[0m')
print('+------------------------------------------')
if __name__ == "__main__":
title()
mode = input("请选择模式单个/多个:Please A/B ->")
key = input("是否需要使用字典yes/no:")
if mode == 'A':
url = input("请输入需要目录扫描的url:")
main(url, key)
elif mode == 'B':
txt = input("请输入需要目录扫描的TXT:")
for url in open(txt, encoding='utf-8'):
url = url.replace('\n', '')
main(url, key)
else:
print("请输入正确的mode!")
在成品里面多了个附加的功能,哈哈(也就是选择A/B之类的)
单个
请选择模式单个/多个:Please A/B -> 第一步是选择要扫单个文件还是多个文件
如果选A
请选择模式单个/多个:Please A/B ->A
是否需要使用字典yes/no: #第二步是选择是否需要字典,不需要会使用基础的备份扫描功能
如果选yes 默认加载启动dict.txt
请选择模式单个/多个:Please A/B ->A
是否需要使用字典yes/no:yes
请输入需要目录扫描的url: #第三步是选择需要扫描的url地址
多个:
请选择模式单个/多个:Please A/B ->B
是否需要使用字典yes/no:no
请输入需要目录扫描的TXT: #前面与单个相同,这一步开始需要输入txt文本进行批量扫描,不过不是多线程
有时候出货就是这么简单~
★
欢 迎 加 入 星 球 !
代码审计+免杀+渗透学习资源+各种资料文档+各种工具+付费会员
进成员内部群
星球的最近主题和星球内部工具一些展示
加入安全交流群
关 注 有 礼
还在等什么?赶紧点击下方名片关注学习吧!
推荐阅读