文章总结: 本文梳理信息收集常用工具,包括HaE、RouteVulScan等Burp插件。重点介绍了OSS遍历工具ossx、MQTT监听工具MQTT-Explorer及阿里云ossbrowser的实战案例与下载脚本,助力安全人员高效发现敏感数据泄露与云资源风险。 综合评分: 82 文章分类: 渗透测试,WEB安全,安全工具,云安全
【工具箱梳理】信息收集篇-第一期
xxxh
安全驾驶舱
2025年12月25日 09:33 广东
背景
下一阶段计划对使用或使用过的工具、插件的逐步进行梳理统合,逐步积累形成一定的工具库,本期主要介绍信息收集与敏感数据发现的工具。
工具清单
-
burp插件-HaE
-
burp插件-RouteVulScan
-
浏览器插件-trufflehog
-
jar-heapdump堆存储文件分析-heapdump_tool
-
python-打包js敏感信息分析工具-Packer-Fuzzer
-
W/L-指纹识别工具-Ehole
-
python-存储桶遍历工具-ossx
-
W/L-MQTT监听工具-MQTT-Explorer
-
W/L-阿里云存储桶可视化工具-oss browser
主题总结
1、往期文章介绍过的工具回顾
2、ossx、MQTT-Explorer、oss browser使用案例
使用介绍/案例
01 HaE
品种: burp插件
主要功能: 请求/响应包敏感信息识别
衍生功能: 指纹识别、特定信息高亮
往期案例:
《【web安全】获取webpack打包器后端接口清单思路分享》/《【web安全】云密钥泄露排查与利用思路》
02 RouteVulScan
品种: burp插件
主要功能: 未授权访问递归遍历、管理页查找
衍生功能: get型POC验证
往期案例:
《【Web安全】heapdump实战利用案例》
03 trufflehog
品种: 浏览器插件
主要功能: 高熵字符串识别,敏感信息识别
往期案例:
《【web安全】云密钥泄露排查与利用思路》
04 heapdump_Tool
品种: jar工具
主要功能: heapdump堆存储文件分析
往期案例:
《【web安全】actuator实战利用思路》/《【Web安全】heapdump实战利用案例》
05 Packer-Fuzzer
品种: python工具
主要功能: webpack打包js敏感信息扫描
往期案例:
《【web安全】获取webpack打包器后端接口清单思路分享》
06 Ehole
品种: 应用程序
主要功能: 指纹识别
往期案例:
《【web安全】短信轰炸排查思路分享》
07 ossx
品种: python脚本
主要功能: 存储桶遍历
出处:
https://github.com/sourcexu7/ossx
AI改编版:
import csvimport timeimport warningsimport xml.etree.ElementTree as ETimport requestsimport urllib3# 忽略InsecureRequestWarning警告warnings.filterwarnings("ignore", category=urllib3.exceptions.InsecureRequestWarning)# 用来统计所有key的列表totoal_keys = []# 获取存储桶页面默认显示条数max-keys,默认最大不超过1000def get_info(url): response = requests.get(url, verify=False) # 解析XML内容 xml_content = response.content # 解析XML root = ET.fromstring(xml_content) maxkey = root.findtext(f".//MaxKeys") nextmarker = root.find(f".//NextMarker") xpath_expr = ".//Contents" # 检查是否存在命名空间,存在命名空间的索引写法需要改变 has_namespace = root.tag.startswith("{") if has_namespace: # 获取命名空间 namespace = root.tag.split('}')[0].strip('{') xpath_expr = f".//{{{namespace}}}Contents" maxkey = root.findtext(f".//{{{namespace}}}MaxKeys") nextmarker = root.find(f".//{{{namespace}}}NextMarker") # 获取所有子标签的名称 child_tags = set() for contents_element in root.findall(xpath_expr): for child_element in contents_element: if has_namespace: child_tags.add(child_element.tag.replace(f"{{{namespace}}}", "")) else: child_tags.add(child_element.tag) # 创建csv文件写入表头也就是各列名称 filename = write_csv_header(child_tags) # 返回PageSize、下一页索引、创建的CSV文件名称、以及列名集合 return maxkey, nextmarker, filename, child_tagsdef getdata(baseurl, max_keys, csv_filename, child_tags, marker='', page=0): if int(max_keys) < 1000: max_keys = 1000 baseurl = baseurl url = baseurl + f'?max-keys={max_keys}&marker={marker}' response = requests.get(url, verify=False) xml_content = response.content root = ET.fromstring(xml_content) # 检查是否存在命名空间 namespace = '' xpath_expr = ".//Contents" nextmarker = root.findtext(f".//NextMarker") has_namespace = root.tag.startswith("{") if has_namespace: # 获取命名空间 namespace = root.tag.split('}')[0].strip('{') xpath_expr = f".//{{{namespace}}}Contents" nextmarker = root.findtext(f".//{{{namespace}}}NextMarker") datas = root.findall(xpath_expr) # 写入数据 nums, is_repeate, repeate_nums, total_nums = write_csv_content(csv_filename, datas, has_namespace, namespace, child_tags) page += 1 print(f"[+] 第{page}页检测到{nums}条数据,共计发现{total_nums}个文件") # 是否存在nextmarker存在则说明还有下一页需要迭代进行遍历,不存在则说明以及遍历完成退出 if nextmarker is None or is_repeate == 1: print(f"[√] 数据结果已写入文件:{csv_filename},请查看😀") return getdata(baseurl, max_keys, csv_filename, child_tags, nextmarker, page)def write_csv_header(child_tags): # 获取当前时间戳 timestamp = int(time.time()) # 将时间戳转换为字符串 timestamp_str = str(timestamp) # 创建CSV文件并写入数据 csv_filename = f'xml_data{timestamp_str}.csv' with open(csv_filename, 'w', newline='') as csv_file: # 写入表头,另外增加完整的url和文件类型列 writer = csv.writer(csv_file) list_tags = list(child_tags) list_tags.append("url") list_tags.append("filetype") writer.writerow(list_tags) return csv_filenamedef write_csv_content(csv_filename, datas, has_namespace, namespace, child_tags): # 提取数据并写入CSV文件 with open(csv_filename, 'a', newline='') as csv_file: nums = 0 repeate_nums = 0 is_repeate = 0 # 写入数据 for contents_element in datas: if has_namespace: row = [contents_element.findtext(f"{{{namespace}}}{tag}") for tag in child_tags] key = contents_element.findtext(f"{{{namespace}}}Key") else: row = [contents_element.findtext(tag) for tag in child_tags] key = contents_element.findtext(f"Key") if str(key) not in totoal_keys: nums += 1 totoal_keys.append(key) url = str(baseUrl) + str(key) parts = str(key).split(".") if len(parts) > 1: # 如果分割后的列表长度大于1,说明存在文件后缀名 file_extension = parts[-1] else: # 否则,文件后缀名不存在 file_extension = "" row.append(url) row.append(file_extension) writer = csv.writer(csv_file) writer.writerow(row) else: repeate_nums += 1 if repeate_nums > 2: is_repeate = 1 return nums, is_repeate, repeate_nums, len(totoal_keys)if __name__ == '__main__': # 发送HTTP请求获取响应 url = input("[*] 请输入存储桶遍历url:").strip() baseUrl = input("[*] 请输入存储桶根路径(不输入则和上述url保持一致):").strip() if baseUrl == '': baseUrl = url if not baseUrl.endswith('/'): baseUrl += '/' # 获取存储桶基本信息包括默认的PageSize、下一页索引,同时创建csv文件根据字段写表头 try: maxkey, nextmarker, csv_filename, child_tags = get_info(url) if len(child_tags) != 0: print("[+] xml数据提取成功!✨") # 未指定maxkey则默认1000 if maxkey == None: maxkey = 1000 print(f"[o] 该存储桶默认每页显示{maxkey}条数据") if nextmarker == None: print("[-] 该存储桶不支持Web翻页遍历😢") else: print("[+] 该存储桶支持遍历,正在获取文件及数量😀") getdata(url, max_keys=maxkey, child_tags=child_tags, csv_filename=csv_filename) else: print("[-] 该存储桶不支持遍历,或检查网址是否有误!") except Exception as e: print(e) print("[-] XML解析有误,无法遍历😢")
配套文件下载脚本
#!/usr/bin/env python# -*- coding: UTF-8 -*-'''@Project :PyCharm@File :download.py@IDE :PyCharm@Author :xxxxh@Date :2025/11/4 11:27@Info :"基于ossx输出的csv进行文件下载"'''import osimport csvimport requestsimport tracebackfrom urllib.parse import urlparseimport datetimeblack_filetype = ["war","zip","jar"]white_filetype = ["doc","docx","pdf","ppt","pptx","png","jpg","jpeg","gif"]def download_files_from_csv(csv_file): key = input("是否下载所有文件?(Y/N)(如选择N则每下载100M文件询问是否继续下载)").upper() if key == "Y": flag = True else: flag = False # 读取CSV文件 with open(csv_file, 'r', encoding='utf-8-sig', errors="ignore") as f: reader = csv.DictReader(f) size = 0 download_size = 0 i = 0 line_number = 0 try: line_number += 1 for row in reader: print(row) i += 1 url = row['url'] filetype = row['filetype'] last_modified = row['LastModified'] key = row['Key'] # 解析 URL 的路径部分 parsed_url = urlparse(url) path_parts = parsed_url.path.strip('/').split('/') first_level_dir = path_parts[0] if path_parts else "None" # 解析域名 # domain = urlparse(url).netloc domain = parsed_url.netloc # 构造保存路径 save_path = os.path.join( domain, first_level_dir, filetype, f"{last_modified}-{os.path.basename(key)}" ).replace(":", "-") # 创建目录结构 os.makedirs(os.path.dirname(save_path), exist_ok=True) # 检查文件是否过大################################自定义筛选条件填充点 # if filetype in black_filetype and int(row['Size']) > 40000000: # continue # # if filetype not in ["doc","docx","pdf","ppt","pptx","png","jpg","jpeg","gif"]: # continue # 检查文件是否存在 if os.path.exists(save_path): print(f"File {save_path} already exists, skipping download.") else: try: # 下载文件 size += int(row['Size']) print(f"Downloading {url} -> {save_path}") response = requests.get(url, stream=True) response.raise_for_status() # 保存文件 with open(save_path, 'wb') as out_file: for chunk in response.iter_content(chunk_size=8192): out_file.write(chunk) print("Download completed\n") except requests.exceptions.RequestException as e: print(f"Download failed: {str(e)}\n") if not flag: # 每下载100MB文件询问是否继续下载 if int(size / 100000000) > download_size: download_size = int(size / 100000000) flag_continue = input("已下载{}个文件是否继续下载(Y/N)".format(i)).upper() if flag_continue == "N": break else: continue except UnicodeDecodeError as e: error_str = f"UnicodeDecodeError occurred at line {line_number}: {e}" print(error_str) # 获取当前的调用栈信息 tb = traceback.extract_tb(e.__traceback__) current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 输出详细的调用栈信息 with open('error.csv', 'a', newline='', encoding='utf-8') as error_file: writer = csv.writer(error_file) for frame in tb: print(f"File: {frame.filename}, Line: {frame.lineno}, Function: {frame.name}, Code: {frame.line}") writer.writerow([ current_time, frame.filename, frame.lineno, frame.name, frame.line ]) writer.writerow([current_time, 'Exception:', error_str])if __name__ == "__main__": # download_files_from_csv('your_file.csv') # 替换为你的CSV文件路径 download_files_from_csv(input('your_file.csv'))
使用案例:
根据RouteVulScan发现的oss未授权
使用ossx进行文件遍历记录
使用download.py进行下载
08 MQTT-Explorer
品种: 应用程序
主要功能: MQTT端口监听
出处:
https://github.com/thomasnordquist/MQTT-Explorer
使用案例:
端口探测到有MQTT 1883端口存活,尝试访问发现无密码认证
监听,发现个人信息与秘钥陆陆续续接收
09 oss browser
品种: 应用程序
主要功能: 阿里云存储桶可视化
出处:
https://github.com/aliyun/oss-browser
使用案例:
trufflehog和HaE发现阿里云aksk明文泄露,使用oss browser进行泄露文件的可视化查看。
正文内容
END
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:安全驾驶舱 xxxh《【工具箱梳理】信息收集篇-第一期》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论