实战 | 目录扫描器开发-泄露漏洞
2024-1-9 22:47:14 Author: 渗透安全团队(查看原文) 阅读量:11 收藏

起因

有时候目录扫描,我们会顺便扫描是否存在备份的情况,这时候就自己简单的写了一个python的脚本

主要想做到的是 例如我扫 http://xxx.cn 的站点目标的时候

会根据域名自动的去匹配以下这种基于域名生成的文件备份路径

  1. http://a.xxx.cn/zkap.zip

  2. http://a.xxx.cn/a.zip

第一步-大大的logo

  1. from colorama import init #cmd终端带颜色

  2. init(autoreset=True)

  3. def title():

  4. print('+------------------------------------------')

  5. print('+ 33[34m......初始化开始...... 33[0m')

  6. print('+ 33[34m杳若出品 33[0m')

  7. print('+ 33[34mTitle: 用于文件备份扫描~ 33[0m')

  8. print('+ 33[36m使用格式: 输入必要的参数 33[0m')

  9. print('+------------------------------------------')

第二步-随机的请求头

当然是为了减少被ban的几率了

  1. from faker import Faker # 随机请求头的库

  2. import random # 为了增加随机的ip

  3. # 随机请求头

  4. def header():

  5. headers = {

  6. 'Accept': '*/*',

  7. 'Referer': 'http://www.baidu.com',

  8. 'User-Agent': Faker().user_agent(),

  9. 'Cache-Control': 'no-cache',

  10. 'X-Forwarded-For': '127.0.0.{}'.format(random.randint(1, 255)),

  11. }

  12. return headers

利用库做到了UA请求头随机,用random做到了xff的伪随机,当然Referer也可以换

第三步-确认传入的内容是否带协议以及切割URL

传入的内容可能带http可能https也可能不带,就要自己添加,这里写一个检测

  1. from urllib.parse import urlparse # 协议分离的库

  2. import requests # http协议请求的库

  3. def urlpar(url):

  4. # 这里是检测传入是否带http,不带的话就会自动去拼接

  5. if 'http' not in url:

  6. if url[-1] == '/':

  7. url, p2, p3 = url.partition('/')

  8. # 拼接的话会请求http,如果访问失败那就添加https

  9. try:

  10. requests.head(url='http://' + url, headers=header(), verify=False, timeout=(3, 8))

  11. return 'http://' + url

  12. except Exception as e:

  13. return 'https://' + url

  14. # 不然就是带协议头啦

  15. else:

  16. url_Doman = urlparse(url).netloc

  17. url_http = urlparse(url).scheme

  18. url_main = "{}{}{}".format(url_http, '://', url_Doman)

  19. return url_main

  20. # url域名分割

  21. def tldex(url):

  22. url = tldextract.extract(urlpar(url))

  23. one = url.subdomain

  24. three = url.suffix

  25. two = url.domain

  26. # 切割成了三个部分,顶级域名、主域和尾

  27. return one, two, three

第四步-做成字典

首先需要一个分割好的字典集合,然后添加对应的后缀

  1. # 组合自定义字典

  2. def dith(one, two, three):

  3. urls = []

  4. urls = urls + diy(one)

  5. urls = urls + diy(two)

  6. urls = urls + diy(three)

  7. urls = urls + diy(two + '.' + three)

  8. urls = urls + diy(one + '.' + two)

  9. urls = urls + diy(one + '.' + two + '.' + three)

  10. # 返回就是一个字典集合了

  11. return urls

  12. # 自定义字典内容

  13. def diy(ci):

  14. url = []

  15. url.append('/' + ci + '.rar')

  16. url.append('/' + ci + '.zip')

  17. url.append('/' + ci + '.txt')

  18. url.append('/' + ci + '.apk')

  19. url.append('/' + ci + '.gz')

  20. return url

  21. 这里都可以自定义各种内容

第五步-发起http请求

发起请求的话就是不断的将url以及对应的路由进行拼接判定,这里利用了Content-Length来判断大小,大于一定的值就证明存在文件备份

但是考虑到了vue等框架的误报情况,做了一定的防误报处理

  1. import requests # http协议请求的库

  2. import requests.packages.urllib3.util.ssl_

  3. requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ALL'

  4. from urllib3.exceptions import InsecureRequestWarning

  5. # 防止无证书连接的报错

  6. requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

  7. # 进行备份扫描以及确认

  8. # 这里传入需要检测的url以及需要拼接的后缀urls做的字典

  9. def scan(url, urls):

  10. a = 0

  11. u = []

  12. b = 0

  13. # 传入了字典,进行遍历

  14. for url1 in urls:

  15. try:

  16. # time.sleep(random.randint(1,10))

  17. r = requests.head(url=url + url1, headers=header(), verify=False, timeout=(3, 30)) # 通过请求漏洞存在网址,获取其数据流的大小

  18. rarsize = int(r.headers.get('Content-Length')) # 是str格式-对数据流大小的获取

  19. if rarsize >= 1000 * 10:

  20. print('33[32m [o] 存在漏洞[>]%s[>]%skb33[0m' % (url + url1, str(rarsize)))

  21. a = a + 1

  22. u.append(url + url1 + '\t' + str(rarsize))

  23. if (a >= 5):

  24. print('33[31m [x] 存在误报[>]%s[>]%skb33[0m' % (url + url1, str(rarsize)))

  25. break

  26. pass

  27. else:

  28. print('33[31m [x] 不存在漏洞[>]%s[>]%skb33[0m' % (url + url1, str(rarsize)))

  29. except Exception as e:

  30. try:

  31. r = requests.head(url=url + url1, headers=header(), verify=False, timeout=(3, 30))

  32. if r.status_code == 404:

  33. b = b + 1

  34. except Exception as e:

  35. b = b +1

  36. # 如果请求了10个数据包都是404,那太慢了,直接提示url不行

  37. if b >= 10:

  38. break

  39. print(' [?] 存在问题>' + url + url1)

  40. # 如果存在漏洞的数量大于5个,极大可能就是误报了

  41. if a < 5 and u != []:

  42. for url in u:

  43. with open('cunzai.txt', 'a+', encoding='utf-8') as fp:

  44. fp.write(url + '\n')

简易的备份扫描工具就做好啦

  1. # -*- coding:utf-8 -*-

  2. import random # 请求协议/域名分割/随机

  3. import re

  4. from urllib.parse import urlparse # 协议分离

  5. from colorama import init #cmd终端带颜色

  6. init(autoreset=True)

  7. import requests

  8. # import time

  9. # requests防止报错

  10. import requests.packages.urllib3.util.ssl_

  11. import tldextract

  12. #from fake_useragent import UserAgent # 随机请求头

  13. from faker import Faker # 随机请求头二代

  14. requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ALL'

  15. from urllib3.exceptions import InsecureRequestWarning

  16. requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

  17. # 随机请求头

  18. def header():

  19. headers = {

  20. 'Accept': '*/*',

  21. 'Referer': 'http://www.baidu.com',

  22. 'User-Agent': Faker().user_agent(),

  23. 'Cache-Control': 'no-cache',

  24. 'X-Forwarded-For': '127.0.0.{}'.format(random.randint(1, 255)),

  25. }

  26. return headers

  27. # url进行协议分割

  28. def urlpar(url):

  29. if 'http' not in url:

  30. if url[-1] == '/':

  31. url, p2, p3 = url.partition('/')

  32. try:

  33. requests.head(url='http://' + url, headers=header(), verify=False, timeout=(3, 8))

  34. return 'http://' + url

  35. except Exception as e:

  36. return 'https://' + url

  37. else:

  38. url_Doman = urlparse(url).netloc

  39. url_http = urlparse(url).scheme

  40. url_main = "{}{}{}".format(url_http, '://', url_Doman)

  41. return url_main

  42. # url域名分割

  43. def tldex(url):

  44. url = tldextract.extract(urlpar(url))

  45. one = url.subdomain

  46. three = url.suffix

  47. two = url.domain

  48. return one, two, three

  49. # 自定义字典内容

  50. def diy(ci):

  51. url = []

  52. url.append('/' + ci + '.rar')

  53. url.append('/' + ci + '.zip')

  54. url.append('/' + ci + '.txt')

  55. url.append('/' + ci + '.apk')

  56. url.append('/' + ci + '.gz')

  57. return url

  58. # 组合自定义字典

  59. def dith(one, two, three):

  60. urls = []

  61. urls = urls + diy(one)

  62. urls = urls + diy(two)

  63. urls = urls + diy(three)

  64. urls = urls + diy(two + '.' + three)

  65. urls = urls + diy(one + '.' + two)

  66. urls = urls + diy(one + '.' + two + '.' + three)

  67. return urls

  68. # 拼接比较常见的备份地址

  69. def dithadd(url):

  70. urls = ['/.git', '/.svn', '/新建文件夹.rar', '/新建文件夹.zip', '/备份.rar', '/wwwroot.rar', '/wwwroot.zip', '/backup.rar',

  71. '/bf.rar', '/beifen.rar', '/www.rar', '/vera_Mobile.zip', '/web.rar', '/zuixin.rar', '/最新.rar',

  72. '/test.rar', '/test.zip', '/web.zip', '/www.zip', '/最新备份.rar']

  73. url = url + urls

  74. return url

  75. # 拼接字典

  76. def adithaddadd(url):

  77. urls = []

  78. for urla in open('dict.txt', encoding='utf-8'):

  79. urla = urla.replace('\n', '')

  80. if len(urla) != 0:

  81. urls.append(urla)

  82. else:

  83. pass

  84. urls = urls + url

  85. return urls

  86. # 进行备份扫描以及确认

  87. def scan(url, urls):

  88. a = 0

  89. u = []

  90. b = 0

  91. for url1 in urls:

  92. try:

  93. # time.sleep(random.randint(1,10))

  94. r = requests.head(url=url + url1, headers=header(), verify=False, timeout=(3, 30)) # 通过请求漏洞存在网址,获取其数据流的大小

  95. rarsize = int(r.headers.get('Content-Length')) # 是str格式-对数据流大小的获取

  96. if rarsize >= 1000 * 10:

  97. print('33[32m [o] 存在漏洞[>]%s[>]%skb33[0m' % (url + url1, str(rarsize)))

  98. a = a + 1

  99. u.append(url + url1 + '\t' + str(rarsize))

  100. if (a >= 5):

  101. print('33[31m [x] 存在误报[>]%s[>]%skb33[0m' % (url + url1, str(rarsize)))

  102. break

  103. pass

  104. else:

  105. print('33[31m [x] 不存在漏洞[>]%s[>]%skb33[0m' % (url + url1, str(rarsize)))

  106. except Exception as e:

  107. try:

  108. r = requests.head(url=url + url1, headers=header(), verify=False, timeout=(3, 30))

  109. if r.status_code == 404:

  110. b = b + 1

  111. except Exception as e:

  112. b = b +1

  113. if b >= 10:

  114. break

  115. print(' [?] 存在问题>' + url + url1)

  116. if a < 5 and u != []:

  117. for url in u:

  118. with open('cunzai.txt', 'a+', encoding='utf-8') as fp:

  119. fp.write(url + '\n')

  120. def main(url, key):

  121. p1, p2, p3 = url.replace('http://', '').replace('https://', '').partition(':')

  122. if re.match(r"^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$", p1):

  123. add_url = dithadd([])

  124. else:

  125. one, two, three = tldex(url)

  126. urls = dith(one, two, three) # 自定义列表

  127. add_url = dithadd(urls)

  128. if key == 'yes':

  129. add_url = adithaddadd(add_url)

  130. scan(urlpar(url), add_url)

  131. # 这是标题~

  132. def title():

  133. print('+------------------------------------------')

  134. print('+ 33[34m......初始化开始...... 33[0m')

  135. print('+ 33[34m杳若出品 33[0m')

  136. print('+ 33[34mTitle: 用于文件备份扫描~ 33[0m')

  137. print('+ 33[36m使用格式: 输入必要的参数 33[0m')

  138. print('+------------------------------------------')

  139. if __name__ == "__main__":

  140. title()

  141. mode = input("请选择模式单个/多个:Please A/B ->")

  142. key = input("是否需要使用字典yes/no:")

  143. if mode == 'A':

  144. url = input("请输入需要目录扫描的url:")

  145. main(url, key)

  146. elif mode == 'B':

  147. txt = input("请输入需要目录扫描的TXT:")

  148. for url in open(txt, encoding='utf-8'):

  149. url = url.replace('\n', '')

  150. main(url, key)

  151. else:

  152. 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文本进行批量扫描,不过不是多线程

有时候出货就是这么简单~


付费圈子

欢 迎 加 入 星 球 !

代码审计+免杀+渗透学习资源+各种资料文档+各种工具+付费会员

进成员内部群

星球的最近主题和星球内部工具一些展示

加入安全交流群

                               

关 注 有 礼

关注下方公众号回复“666”可以领取一套领取黑客成长秘籍

 还在等什么?赶紧点击下方名片关注学习吧!


干货|史上最全一句话木马

干货 | CS绕过vultr特征检测修改算法

实战 | 用中国人写的红队服务器搞一次内网穿透练习

实战 | 渗透某培训平台经历

实战 | 一次曲折的钓鱼溯源反制

免责声明
由于传播、利用本公众号渗透安全团队所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号渗透安全团队及作者不为承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!
好文分享收藏赞一下最美点在看哦

文章来源: http://mp.weixin.qq.com/s?__biz=MzkxNDAyNTY2NA==&mid=2247513861&idx=2&sn=6e47876edd57a1d23cc5fa40b558a0bc&chksm=c00e329651ee837dd212e6373f14f8f5303da9a65b0af0051b7e27a167e259944bc57d8c14b6&scene=0&xtrack=1#rd
如有侵权请联系:admin#unsafe.sh