1. 背景介绍
我们在渗透测试中长做的第一步就是找到目标的真实IP,随着网络环境、软件体系架构的越来越复杂,找到真实的主机IP也越来越变得复杂困难。CDN 负载均衡器都可以混淆目标主机的真实IP地址。
这里我们将把重点放在反向代理特性上,也就是你指向域的情况。而不是从实际的IP接收数据,而是从Cloudflare的IP获取响应。这个特性也可以作为反ddos的功能,但是我们不关心它。
虽然这里我们的对象是cloudflare,但是技术是通用的,也可以用在其他服务上。因为我们不会利用Cloudflare系统中的一个bug,而是利用我们的目标的错误配置。
2. CDN简介
CDN的全称是Content Delivery Network,即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。
2.1 CDN的用处
1. 跨运营商加速:我们自己的网站常常只属于一个运营商(比如:电信),而加速节点遍布每家运营商,于是和网站不同运营商(比如:联通)的用户访问起来就不会那么慢了。
2. 缓存加速:很多的静态资源以及一部分页面更新都是比较慢的(比如首页),这个时候CDN就会根据浏览器的max-age和last-modified值以及管理员的预设值来进行缓存,于是很多流量CDN节点就不会每次都来向网站请求,CDN节点可以直接自作主张地将命中的缓存内容返回。
3. 恶意流量过滤:这是CDN非常重要的一个作用,也是很多网站会用CDN的原因,因为CDN能为我们抵挡攻击大流量攻击、普通的攻击(比如注入等),只有正常流量才会转发给网站。
2.2 域名解析过程
- 传统访问:用户访问域名-->解析IP-->访问目标主机
- 简单模式:用户访问域名-->CDN节点-->真实IP-->目标主机
- WAF:用户访问域名-->CDN节点(云WAF)-->真实IP-->目标主机
2.3 CDN配置方法
- 1、将域名的NS记录指向CDN厂商提供的DNS服务器。
- 2、给域名设置一个cname记录,将它指向CDN厂商提供的另一个域名
2.4 CDN检测方法
利用“全球Ping”快速检测目标网址是否存在CDN,如果得到的IP归属地是某CDN服务商,或者每个地区得到的IP地址都不一样则说明可能存在CDN
可以使用以下几个网站进行检测:
https://wepcc.com/
http://ping.chinaz.com
3. 查找真实IP方法
3.1 使国外DNS
这个方法主要就是针对一些cdn只对国内的ip部署了cdn,对于国外的ip并没有部署,这样就会得到真实IP。
工具: https://asm.ca.com/en/ping.php
3.2 DNS历史解析记录
查询目标域名历史解析记录可能会找到部署CDN前的解析记录,可用以下几个网站查询。
https://domain.8aq.net //基于Rapid7 Open Data
https://x.threatbook.cn
https://webiplookup.com
https://viewdns.info/iphistory
https://securitytrails.com/#search
https://toolbar.netcraft.com/site_report
注: 境外网站的话我强烈建议您使用RiskIQ(需要用GMail注册)。对于一个域,您可以看到谁注册了它,使用哪个注册,您可以看到承载该域的所有服务器的IP和许多其他有趣的信息
3.4 网站邮件
很多网站支持RSS订阅,或者信息提醒还有注册邮箱验证等功能,每一封邮件其实都是带有ip地址的,我们只要查看源码就能看到
3.5 使用shodan
3.5.1 直接查找
3.5.2 favicon图标来查找IP
我意识到你可以通过HTTP Title在Shodan和Censys上搜索。我想强调的是,这两个方法只有在favicon图标和标题是唯一的情况下才有效。例如,如果favicon是由样板文件生成的,而标题是“Home”,那么它可能是一个完整的图标。在这种情况下,您可以通过ISP、国家等过滤掉结果。这可能有助于打击钓鱼攻击。
工具:https://github.com/pielco11/fav-up
这个需要shodan的账号
3.6 Censys查询SSL证书找到真实IP
利用“Censys网络空间搜索引擎”搜索网站的SSL证书及HASH,在https://crt.sh上查找目标网站SSL证书的HASH,然后再用Censys搜索该HASH即可得到真实IP地址。
第一步:查看网站的SSL证书,获取指纹
第二步:使用https://crt.sh/查询
第三步:在网站https://censys.io/上用SHA-256的值查询
3.7 其他工具
使用哪个工具或查找服务取决于您要查找的是什么,但是由于我们还不知道应该查找什么,所以我只命名一些服务。有些是免费的,有些是付费的,有些需要你登录,有些则不需要。下面是第三方的查找工具来搜集情报:
- ViewDNS.info
- CrimeFlare
- CloudFail
- DNSlytics
- RiskIQ
- Shodan
- Censys
- FavUP
- … and many many others
3.8 使用浏览器查找真实IP
打开你喜欢的浏览器,打开开发工具栏,切换到网络。
首先,让我们添加一些列来查看一些有趣的信息。我建议您添加Remote IP,另一个您可能感兴趣的是set - cookie。请不要将Set-Cookies与Cookies混淆。Cookies是关于发送到服务器的内容,而Set-Cookies是关于从服务器获得的内容。
不管怎样,我们还有很多请求要过滤掉。现在该做什么?而不是根据类型(像所有的CSS请求)隐藏请求,这是完全超出范围,我们将过滤出域,哪个域?目标的一个!我们已经知道它的远程ip不是真实的。
例如,如果我们访问GitHub,我们想要过滤掉所有对该域的请求,我们可以简单地添加-domain:github.com。
正如你所看到的,GitHub使用不同的子域名,我们可以用-domain:*.github.com来排除它们。如果许多资源是从相同的IP但不同的域获取的,我们可以排除带有-remote-ip:185.199.109.154的IP。
可以在这里找到完整的过滤-输入/输出选项列表(用于Firefox)。有些过滤器(如果不是全部的话)与基于Chromium的web浏览器的过滤器类似。https://developer.mozilla.org/en-US/docs/Tools/Network_Monitor/request_list?utm_source=mozilla&utm_medium=devtools-netmonitor&utm_campaign=default#Filtering_by_properties
如果筛选阶段需要很多时间,可以将发出的所有请求(包括所有头文件、cookie、响应等)导出到一个HAR (HTTP Archive)文件(读取JSON文件),这样使用简单的Python/GO脚本就可以进行进一步的分析。
要将所有请求保存到一个HAR文件,您可以:
- 右键点击一个请求,然后点击“保存所有内容为HAR”
- 点击标签上方的“下载箭头”
在Firefox上,您可以在右侧看到“Export to HAR”按钮,或者再次右键单击某个请求。
处理HAR文件
让我们假设(在实际情况中不需要)我们有很多请求,但是没有那么多时间,因此我们希望自动化统计分析过程。我们还必须考虑必须处理至少5MB的新文件类型。
使用一个python脚本来处理:
代码语言:javascript复制# extension is HAR, but we can read it as JSON
import json
# read the data
raw_data = open('github.har', 'r').read() # replace 'github.har' with the correct name
json_data = json.loads(raw_data) # guess what
# now the first kick on the shins
# we don't know the structure of the data
# we know that the type of the data is dict
# since all the requests are similar to the others (every request has its cookies, ...)
# we expect a list of requests as value of a key
# indeed that's what we have
for k1 in json_data:
for k2 in json_data[k1]:
if json_data[k1][k2].__class__.__name__ == 'list':
print(f"{k1} {k2} {len(json_data[k1][k2])} :: {len(json_data[k1][k2][0])}")
print('--> ' ' '.join(k3 for k3 in json_data[k1][k2][0]))
# it turns out that the list with the most contents is 'entries'
requests = json_data['log']['entries']
# after exploring a few dicts/lists, you can find out that we need
# request.url, serverIPAddress and connection (port number)
ips = {}
urls = {}
ports = {}
for i in range(len(requests)):
_url = requests[i]['request']['url']
_ip = requests[i]['serverIPAddress']
_port = requests[i]['connection']
try:
ips[_ip] = 1
except KeyError:
ips.update({_ip:1})
try:
urls[_url] = 1
except KeyError:
urls.update({_url:1})
try:
ports[_port] = 1
except KeyError:
ports.update({_port:1})
for ip in ips:
print(f"{ip} :: {ips[ip]}")
for url in urls:
print(f"{url} :: {urls[url]}")
for port in ports:
print(f"{port} :: {ports[port]}")
# as you may see in the output, everything is about GitHub
# so there's no data leaking here
#
# you could try with another website, add some if/else statements
# and check wether or not all the data comes from the expected source
4. 引用
https://pielco11.ovh/posts/cloud-hunting/
https://cloud.tencent.com/developer/news/83440
https://mp.weixin.qq.com/s/_qHGB3l58KU01tBOki5uag