d2d (Data to Data) 这个工具的使命就是让数据本身成为产生新数据的基石
在使用资产测绘程序进行信息收集的时候,又遇到一个问题:以 fofa 为例,我现在通过其他手段,收集了一些分公司、全资公司名称、子域名、IP、icp备案号、网页title、电话号码等,信息量这么老大,怎么才能把这些数据都通过 fofa 过一遍呢?
于是,这个工具就出来了
d2d.py
d2d_results
文件夹用于保存结果fofa_data_source_dir
fofa 语句数据来源requirements.txt
依赖列表当然,你也可以通过只保留 d2d.py
和 requirements.txt
,通过以下两条指令来生成:
pip3 install -r requirements.txt
python3 d2d.py
这个工具基于 FOFA,需要使用 FOFA 高级会员,我看了几个网络空间测绘产品,FOFA的会员算是比较良心的一个了
FOFA_EMAIL
和 FOAF_APIKEY
THREADS
线程数,默认 100proxy
代理的设置,这个可以着重看一下末尾的章节JUST_GET_REAL_IP
如果只获取真实 IP,设置此项为 True ,默认为 FalseJUST_GEN_FOFA_WORDS
如果只生成 fofa 语句,设置此项为 True ,默认为 FalseFOFA_SYNX_AND_SUFFIX
在每一条生成的 fofa 语句中加上一个 &&
条件FOFA_SYNX_OR_SUFFIX
在每一条生成的 fofa 语句中加上一个 ||
条件fields
要获取的 fofa 字段FOFA_TIMES
进行 fofa 迭代查询的次数,默认为 0, 即不进行迭代查询,只做普通查询FOFA_DATA_COUNT
每条 fofa 语句要查询的数量,高级会员最大为 10000 条INVALID_TITLE_LIST
在进行迭代查询时判断是否为无效网页标题的依据INVALID_HOST
在进行迭代查询时判断是否为有效 host 和 ip 的判断依据JUST_GET_REAL_IP = True
fofa_data_source_dir
文件夹的各种文件中填入我们已有的信息python3 d2d.py
以百度为例,假如我们获取了部分域名和ip
JUST_GEN_FOFA_WORDS = True
fofa_data_source_dir
文件夹的各种文件中填入我们已有的信息python3 d2d.py
以百度为例,假如我们获取了部分域名和ip
./fofa_data_source_dir/fofa_synx.txt
放入我们自己的 fofa 语句,此时 d2d
就不会再去从其他的文件中读取数据组合成 fofa 语句了THREADS
proxy
FOFA_SYNX_AND_SUFFIX
FOFA_SYNX_OR_SUFFIX
fields
FOFA_TIMES
FOFA_DATA_COUNT
python3 d2d.py
当然,这里我们也看到了一些不相关的资产,我在 DataCenter.data_filter
进行了一些过滤,大家可以在后期使用中按照自己的想法去做过滤
./fofa_data_source_dir/fofa_synx.txt
的内容fofa_data_source_dir
文件夹的各种文件中填入我们已有的信息THREADS
proxy
FOFA_SYNX_AND_SUFFIX
FOFA_SYNX_OR_SUFFIX
fields
FOFA_TIMES
FOFA_DATA_COUNT
python3 d2d.py
写这个工具用了两周的时间,基本每天都到凌晨,但是其中编程只用了 3 天左右,剩下的 10 几天都是在做性能优化的工作。我本来是想让 fofa 查询的数据再作为输入,往复三次的,但是我写完之后运行 0 次就已经超过一天了,所以在做性能优化的时候,时间耗费非常长,有多长呢?我在等待程序运行这段时间又看完了一整部 DVD 版的 《人民的名义》
放两张同一组数据,优化前和优化后的截图吧
【优化前】
【优化后】
对无关数据的过滤是接下来大家可以着重考虑的问题,这给性能直接带来非常大的提升
我用了多线程后,发现每次运行结果都不一样,或多或少有点差异,这样我非常苦恼,我一直以为是多线程的原因,经过好几天的排查,顿悟了,是使用逻辑的问题
之前的使用方式是
domain="baidu.com" || host="baidu.com" || cert="baidu.com" || ip="xxx.xxx.xxx.xxx" || ip="xxx.xxx.xxx.xxx" || title="xxxx" || ...
也就是说恨不得一条指令把所有的项都加上,之后将结果导出来,但是这里涉及一个问题, FOFA 对于高级会员的限制是只能免费获取前 1w 条,如果这些命令单个来查,不超过 1w 条,但是组合起来就超过了 1w 条,就会造成结果丢失
再加上多线程,每次生成的 fofa 语句是不一样的,虽然都是那些元素,但是组合起来就很难说不超过 1w 条结果了,所以我在脚本中做了一些优化,在兼顾性能的同时,尽可能将组合后的结果控制在 1w 条以内
这两天 fofa api 更新了,似乎限制更多了
对性能影响很大,本来一次获取 1w 条数据,现在只能一次获取 500 条,通过发 20 次请求去获取 1w 条。而且还限制每秒请求的次数。请求速度过快会返回 <Response [429]>
错误
这里值得注意一下
假设现在的场景是:我的电脑上开放了一个 socks5://127.0.0.1:1080
这样的代理,没有设置为全局模式,但是设置为了系统代理
import requests
proxy = None # "socks5://192.168.1.104:20170"
proxies = {'http': proxy, 'https': proxy}
# 此时走的是系统代理,也就是 socks5://127.0.0.1:1080
resp1 = requests.get("https://www.baidu.com")
# 此时不走系统代理,就是本机 IP 出去的
resp2 = requests.get("https://www.baidu.com", proxies=proxies)
proxy = "socks5://192.168.1.104:20171"
proxies = {'http': proxy, 'https': proxy}
# 此时走的是我们指定的代理 proxy
resp3 = requests.get("https://www.baidu.com", proxies=proxies)
有一些网站通过 meta
标签中 http-equiv="refresh"
来设置网页跳转,requests 默认不会 follow 过去,就会导致获取 title 不准确
于是我写了一段比较复杂的获取方法,在 DataCenter.get_real_url
函数中,解决了这个问题,但这个过程很难搞,因为浏览器的兼容度比较高,于是需要先 fuzz 出可能可以进行跳转的语法,之后针对这个语法进行规则判断,非常非常糟心
xls 文件内容长度是有限制的,所以建议大家写工具时候使用 csv 格式
这个文件是通过命令 python3 -m pipreqs.pipreqs ./
生成的,如果大家安装后依赖依旧不完整,可以根据报错信息逐个安装, Ubuntu 18.04 测试没问题
做迭代查询,数据过滤尤为重要,至少有以下几个常见的点需要考虑
Welcome to nginx!
、 登录
、400 Bad Request
等
可以在全局变量 INVALID_TITLE_LIST
中添加要排除的 title0.0.0.0
、 127.0.0.1
可以在全局变量 INVALID_HOST
中添加要排除的host 和 ipwww.baidu.com.ahmhbl.cn
这个规则已经有了,可以在 DataCenter.data_filter
中看到,可以自行添加更多过滤条件为了方便修补代码,我分享一个目录,这样发现错误可以更新
https://pan.baidu.com/s/1SGB7WY-6rhDqUelhxrpHcA 提取码: enhl