HOST碰撞演示及脚本小修改

目录

应用场景

host碰撞原理

环境搭建

Nginx反代服务器配置

Nginx业务服务器配置文件

Www.Kkcms.Com_80.Conf

Www.Zzcms22.Com_81.Conf

如何利用

验证展示

自动化脚本

修复方式


应用场景

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

主要应用场景:

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

host碰撞原理

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

环境搭建

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

HOST碰撞演示及脚本小修改插图

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碰撞演示及脚本小修改插图2

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

HOST碰撞演示及脚本小修改插图4

自动化脚本

这里对网上的脚本稍微做了下修改,对同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 是需要做严格区分

原文链接:https://blog.csdn.net/youuzi/article/details/132165614

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享