大柚子

这世界不过如此

应用场景

访问目标网站时,使用IP访问无法访问,但是通过域名又无法直接访问,这是因为配置了nginx反向代理,禁止IP直接访问且限制了通过server_name 通过域名区别网站。

主要应用场景:

  • 测试环境或预生产环境,将公网的域名解析清除了,但是 Nginx 配置没有及时清除,绑定正确的 host 才能正常访问到。
  • 出于安全性考虑,外网 Nginx 和内网 Nginx 是需要做严格区分,但当使用同一个 Nginx 完成内网和外网服务配置时,通过公网域名解析到公网,内网 DNS 解析到内网。这个时候,绑定正确的 host 就可以访问到内网系统。

HOST碰撞原理

带host的请求直接到反代服务器的ip,反代服务器上面的对应host配置如果还在,就会把请求转发到后面即内网中的对应host业务服务器上,导致网站的域名删除了A记录的情况下也能访问/直接访问内网业务系统。

环境搭建

这里为了便捷直接使用phpstudy直接搭建,将反代网站和业务网站搭建在一台服务器上(其实就是搭建了3个网站,其中两个只开放在本地)

nginx反代服务器配置

#实际就是搭建一个网站,对外开放,但是server_name为空时,返回400页面
server {
	listen 8888;
	server_name _;
	return 400;
}

#下面配置为做网站反向代理,分别对应本地的两个网站:http://127.0.0.1:80和http://127.0.0.1:81,每个网站对应3个域名
server {
        listen        8888;
        server_name www.kkcms.com www.kk2.com www.kk.com;
        location / {
			proxy_pass http://127.0.0.1:80;
			proxy_redirect off;
			proxy_set_header Host $host:$server_port;
				root	"C:/phpstudy_pro/WWW/kkcms";
			index index.php index.html;
        }		

}


server {
		listen 8888;
		server_name www.zzcms22.com www.test22.com www.test33.com;
		location / {
			proxy_pass http://127.0.0.1:81;
			proxy_redirect off;
			proxy_set_header Host $host:$server_port;
				root zzcms22;
			index index.php index.html;
		}
}

nginx业务服务器配置文件

www.kkcms.com_80.conf

server {
        listen        80;
        server_name  localhost;
        root   "C:/phpstudy_pro/WWW/kkcms";
        location / {
            index index.php index.html error/index.html;
            error_page 400 /error/400.html;
            error_page 403 /error/403.html;
            error_page 404 /error/404.html;
            error_page 500 /error/500.html;
            error_page 501 /error/501.html;
            error_page 502 /error/502.html;
            error_page 503 /error/503.html;
            error_page 504 /error/504.html;
            error_page 505 /error/505.html;
            error_page 506 /error/506.html;
            error_page 507 /error/507.html;
            error_page 509 /error/509.html;
            error_page 510 /error/510.html;
            include C:/phpstudy_pro/WWW/kkcms/nginx.htaccess;
            autoindex  off;
        }
        location ~ \.php(.*)$ {
            fastcgi_pass   127.0.0.1:9001;
            fastcgi_index  index.php;
            fastcgi_split_path_info  ^((?U).+\.php)(/?.+)$;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  PATH_INFO  $fastcgi_path_info;
            fastcgi_param  PATH_TRANSLATED  $document_root$fastcgi_path_info;
            include        fastcgi_params;
        }
}

www.zzcms22.com_81.conf

server {
        listen        81;
        server_name  localhost;
        root   "C:/phpstudy_pro/WWW/zzcms2022";
        location / {
            index index.php index.html error/index.html;
            error_page 400 /error/400.html;
            error_page 403 /error/403.html;
            error_page 404 /error/404.html;
            error_page 500 /error/500.html;
            error_page 501 /error/501.html;
            error_page 502 /error/502.html;
            error_page 503 /error/503.html;
            error_page 504 /error/504.html;
            error_page 505 /error/505.html;
            error_page 506 /error/506.html;
            error_page 507 /error/507.html;
            error_page 509 /error/509.html;
            error_page 510 /error/510.html;
            include C:/phpstudy_pro/WWW/zzcms2022/nginx.htaccess;
            autoindex  off;
        }
        location ~ \.php(.*)$ {
            fastcgi_pass   127.0.0.1:9001;
            fastcgi_index  index.php;
            fastcgi_split_path_info  ^((?U).+\.php)(/?.+)$;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  PATH_INFO  $fastcgi_path_info;
            fastcgi_param  PATH_TRANSLATED  $document_root$fastcgi_path_info;
            include        fastcgi_params;
        }
}

如何利用

  • 搜集指向目标内网IP的域名
  • 搜集目标IP资产
  • 进行碰撞

展示验证

只用IP访问,不改变host头

改变host访问,成功访问到隐藏业务

自动化脚本

这里对网上的脚本稍微做了下修改,对同IP不同host返回同样内容的记录做过滤,只展示第一条

#!/usr/bin/python
# -*- coding: UTF-8 -*-
#这是一个用于IP和域名碰撞匹配访问的小工具

import requests
import re


lists=[]
files = open('hosts_ok.txt','w+')
#读取IP地址
print("====================================开 始 匹 配====================================")
for iplist in open("ip.txt"):
    ip = iplist.strip('\n')
    #读取host地址
    http_s = ['http://','https://']
    for h in http_s :
        titles = [] #每换一个请求IP或请求协议就将titles列表置空
        Hosts = []  #针对同一个host返回相同标题的包做收集
        for hostlist in open("host.txt",'r'):
            host = hostlist.strip('\n')
            headers = {'Host':host,'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}
            try:
                r = requests.session()
                requests.packages.urllib3.disable_warnings()
                rhost = r.get(h + ip,verify=False,headers=headers,timeout=5)
                rhost.encoding='utf-8'
                title = re.search('<title>(.*)</title>', rhost.text).group(1) #获取标题
                #如果当前标题已经存在,则退出此次循环,进入下一次循环
                if title in titles:
                    Hosts.append(host) 
                    continue
                titles.append(title)    #标题不存在则将标题加入titles列表
                info = '%s%s -- %s 协议:%s 数据包大小:%d  状态码:%s 标题:%s' % (h,ip,host,h,len(rhost.text),rhost.status_code,title)
                lists.append(info)
                files.write(info + "\n")
                print(info)
#                print("输出hosts")
#                print("".join(map(str,Hosts)))
            except Exception :
                error = h + ip + " --- " + host + " --- 访问失败!~"
                print(error)

print("====================================匹 配 成 功 的 列 表====================================")
for i in lists:
    print(i)

修复方式

  • 测试环境或预生产环境,将公网的域名解析清除了,但是 Nginx 配置也要及时清除,
  • 出于安全性考虑,外网 Nginx 和内网 Nginx 是需要做严格区分
Print Friendly, PDF & Email

发表回复

您的电子邮箱地址不会被公开。