尝试获取cdn背后的真实ip
来源:互联网 发布:中学生网络教学 编辑:程序博客网 时间:2024/05/07 17:55
http://3xp10it.cc/web/2016/11/05/%E5%B0%9D%E8%AF%95%E8%8E%B7%E5%8F%96cdn%E8%83%8C%E5%90%8E%E7%9A%84%E7%9C%9F%E5%AE%9Eip/
0x01 requirement
1.use masscan but not nmap,code will install it if doesn’t exist
2.linux,ubuntu best,flushdns func test on ubuntu only
3.usage:
eg.python3 xcdn.py www.baidu.com
4.need vpn on[some domain will be blocked by GFW,and this will make the result wrong]
0x02 pycode
download:xcdn.py
################################################################ ### ▄▄▄▄ ▄▄▄ ▄▄▄▄ ▀ ▄ ### ▀ ▀█ ▄ ▄ ▄▄▄▄ █ ▄▀ ▀▄ ▄▄▄ ▄▄█▄▄ ### ▄▄▄▀ █▄█ █▀ ▀█ █ █ ▄ █ █ █ ### ▀█ ▄█▄ █ █ █ █ █ █ █ ### ▀▄▄▄█▀ ▄▀ ▀▄ ██▄█▀ ▄▄█▄▄ █▄▄█ ▄▄█▄▄ ▀▄▄ ### █ ### ▀ ### ### name: xcdn.py### function: try to get the actual ip behind cdn### date: 2016-11-05### author: quanyechavshuo### blog: https://3xp10it.cc#############################################################import timeimport osos.system("pip3 install exp10it -U --no-cache") from exp10it import figlet2filefiglet2file("3xp10it",0,True)time.sleep(1)from exp10it import CLIOutputfrom exp10it import get_root_domainfrom exp10it import get_string_from_commandfrom exp10it import get_http_or_httpsfrom exp10it import post_requestfrom exp10it import get_requestfrom exp10it import checkvpnimport sysimport reclass Xcdn(object): def __init__(self,domain): #必须保证连上了vpn,要在可以ping通google的条件下使用本工具,否则有些domain由于被GFW拦截无法正常访问会导致 #本工具判断错误,checkvpn在可以ping通google的条件下返回1 while 1: if checkvpn()==1: break else: time.sleep(1) print("vpn is off,connect vpn first") #首先保证hosts文件中没有与domain相关的项,有则删除相关 domainPattern=domain.replace(".","\.") #下面的sed的正则中不能有\n,sed匹配\n比较特殊 #http://stackoverflow.com/questions/1251999/how-can-i-replace-a-newline-n-using-sed command="sed -ri 's/.*\s+%s//' /etc/hosts" % domainPattern os.system(command) self.domain=domain self.http_or_https=get_http_or_https(self.domain) print('domain的http或https是:%s' % self.http_or_https) result=get_request(self.http_or_https+"://"+self.domain,'seleniumPhantomJS') self.domain_title=result['title'] #下面调用相当于main函数的get_actual_ip_from_domain函数 actual_ip = self.get_actual_ip_from_domain() if actual_ip != 0: print("恭喜,%s的真实ip是%s" % (self.domain, actual_ip)) #下面用来存放关键返回值 self.return_value=actual_ip def domain_has_cdn(self): # 检测domain是否有cdn # 有cdn时,返回一个字典,如果cdn是cloudflare,返回{'has_cdn':1,'is_cloud_flare':1} # 否则返回{'has_cdn':1,'is_cloud_flare':0}或{'has_cdn':0,'is_cloud_flare':0} import re CLIOutput().good_print("现在检测domain:%s是否有cdn" % self.domain) has_cdn = 0 # ns记录和mx记录一样,都要查顶级域名,eg.dig +short www.baidu.com ns VS dig +short baidu.com ns result = get_string_from_command("dig ns %s +short" % get_root_domain(self.domain)) pattern = re.compile( r"(cloudflare)|(cdn)|(cloud)|(fast)|(incapsula)|(photon)|(cachefly)|(wppronto)|(softlayer)|(incapsula)|(jsdelivr)|(akamai)", re.I) cloudflare_pattern = re.compile(r"cloudflare", re.I) if re.search(pattern, result): if re.search(cloudflare_pattern, result): print("has_cdn=1 from ns,and cdn is cloudflare") return {'has_cdn': 1, 'is_cloud_flare': 1} else: print("has_cdn=1 from ns") return {'has_cdn': 1, 'is_cloud_flare': 0} else: # 下面通过a记录个数来判断,如果a记录个数>1个,认为有cdn result = get_string_from_command("dig a %s +short" % self.domain) find_a_record_pattern = re.findall(r"((\d{1,3}\.){3}\d{1,3})", result) if find_a_record_pattern: ip_count = 0 for each in find_a_record_pattern: ip_count += 1 if ip_count > 1: has_cdn = 1 return {'has_cdn': 1, 'is_cloud_flare': 0} return {'has_cdn': 0, 'is_cloud_flare': 0} def get_domain_actual_ip_from_phpinfo(self): # 从phpinfo页面尝试获得真实ip CLIOutput().good_print("现在尝试从domain:%s可能存在的phpinfo页面获取真实ip" % self.domain) phpinfo_page_list = ["info.php", "phpinfo.php", "test.php", "l.php"] for each in phpinfo_page_list: url = self.http_or_https + "://" + self.domain + "/" + each CLIOutput().good_print("现在访问%s" % url) visit = get_request(url,'seleniumPhantomJS') code = visit['code'] content = visit['content'] pattern = re.compile(r"remote_addr", re.I) if code == 200 and re.search(pattern, content): print(each) actual_ip = re.search(r"REMOTE_ADDR[^\.\d]+([\d\.]{7,15})[^\.\d]+", content).group(1) return actual_ip # return 0代表没有通过phpinfo页面得到真实ip return 0 def flush_dns(self): # 这个函数用来刷新本地dns cache # 要刷新dns cache才能让修改hosts文件有效 CLIOutput().good_print("现在刷新系统的dns cache") command = "/etc/init.d/dns-clean start && /etc/init.d/networking force-reload" os.system(command) import time time.sleep(3) def modify_hosts_file_with_ip_and_domain(self,ip): # 这个函数用来修改hosts文件 CLIOutput().good_print("现在修改hosts文件") exists_domain_line = False with open("/etc/hosts", "r+") as f: file_content = f.read() if re.search(r"%s" % domain.replace(".", "\."), file_content): exists_domain_line = True if exists_domain_line == True: os.system("sed -ri 's/.*%s.*/%s %s/' %s" % (self.domain.replace(".", "\."), ip, self.domain, "/etc/hosts")) else: os.system("echo %s %s >> /etc/hosts" % (ip, self.domain)) def check_if_ip_is_actual_ip_of_domain(self,ip): # 通过修改hosts文件检测ip是否是domain对应的真实ip # 如果是则返回True,否则返回False CLIOutput().good_print("现在通过修改hosts文件并刷新dns的方法检测ip:%s是否是domain:%s的真实ip" % (ip, self.domain)) os.system("cp /etc/hosts /etc/hosts.bak") self.modify_hosts_file_with_ip_and_domain(ip) self.flush_dns() hosts_changed_domain_title= get_request(self.http_or_https + "://%s" % self.domain,'seleniumPhantomJS')['title'] os.system("rm /etc/hosts && mv /etc/hosts.bak /etc/hosts") #这里要用title判断,html判断不可以,title相同则认为相同 if self.domain_title== hosts_changed_domain_title: print("是的!!!!!!!!!!!!") return True else: print("不是的!!!!!!!!!!!!") return False def get_c_80_or_443_list(self,ip): # 得到ip的整个c段的开放80端口或443端口的ip列表 if "not found" in get_string_from_command("masscan"): #这里不用nmap扫描,nmap扫描结果不准 os.system("apt-get install masscan") if self.http_or_https=="http": scanPort=80 CLIOutput().good_print("现在进行%s的c段开了80端口机器的扫描" % ip) if self.http_or_https=="https": scanPort=443 CLIOutput().good_print("现在进行%s的c段开了443端口机器的扫描" % ip) masscan_command = "masscan -p%d %s/24 > /tmp/masscan.out" % (scanPort,ip) os.system(masscan_command) with open("/tmp/masscan.out", "r+") as f: strings = f.read() #os.system("rm /tmp/masscan.out") import re allIP=re.findall(r"((\d{1,3}\.){3}\d{1,3})",strings) ipList=[] for each in allIP: ipList.append(each[0]) print(ipList) return ipList def check_if_ip_c_machines_has_actual_ip_of_domain(self,ip): # 检测ip的c段有没有domain的真实ip,如果有则返回真实ip,如果没有则返回0 CLIOutput().good_print("现在检测ip为%s的c段中有没有%s的真实ip" % (ip,self.domain)) target_list=self.get_c_80_or_443_list(ip) for each_ip in target_list: if True == self.check_if_ip_is_actual_ip_of_domain(each_ip): return each_ip return 0 def get_ip_from_mx_record(self): # 从mx记录中得到ip列表,尝试从mx记录中的c段中找真实ip print("尝试从mx记录中找和%s顶级域名相同的mx主机" % self.domain) import socket # domain.eg:www.baidu.com from exp10it import get_root_domain root_domain = get_root_domain(self.domain) from exp10it import get_string_from_command result = get_string_from_command("dig %s +short mx" % root_domain) sub_domains_list = re.findall(r"\d{1,} (.*\.%s)\." % root_domain.replace(".", "\."), result) ip_list = [] for each in sub_domains_list: print(each) ip = socket.gethostbyname_ex(each)[2] if ip[0] not in ip_list: ip_list.append(ip[0]) return ip_list def check_if_mx_c_machines_has_actual_ip_of_domain(self): # 检测domain的mx记录所在ip[或ip列表]的c段中有没有domain的真实ip # 有则返回真实ip,没有则返回0 CLIOutput().good_print("尝试从mx记录的c段中查找是否存在%s的真实ip" % self.domain) ip_list = self.get_ip_from_mx_record() if ip_list != []: for each_ip in ip_list: result = self.check_if_ip_c_machines_has_actual_ip_of_domain(each_ip) if result != 0: return result else: continue return 0 def get_ip_value_from_online_cloudflare_interface(self): # 从在线的cloudflare查询真实ip接口处查询真实ip # 如果查询到真实ip则返回ip值,如果没有查询到则返回0 CLIOutput().good_print("现在从在线cloudflare类型cdn查询真实ip接口尝试获取真实ip") url = "http://www.crimeflare.com/cgi-bin/cfsearch.cgi" post_data = 'cfS=%s' % self.domain content = post_request(url, post_data) findIp = re.search(r"((\d{1,3}\.){3}\d{1,3})", content) if findIp: return findIp.group(1) return 0 def get_actual_ip_from_domain(self): # 尝试获得domain背后的真实ip,前提是domain有cdn # 如果找到了则返回ip,如果没有找到返回0 CLIOutput().good_print("进入获取真实ip函数,认为每个domain都是有cdn的情况来处理") import socket has_cdn_value = self.domain_has_cdn() if has_cdn_value['has_cdn'] == 1: CLIOutput().good_print("检测到domain:%s的A记录不止一个,认为它有cdn" % self.domain) pass else: CLIOutput().good_print("Attention...!!! Domain doesn't have cdn,I will return the only one ip") true_ip = socket.gethostbyname_ex(self.domain)[2][0] return true_ip # 下面尝试通过cloudflare在线查询真实ip接口获取真实ip if has_cdn_value['is_cloud_flare'] == 1: ip_value = self.get_ip_value_from_online_cloudflare_interface() if ip_value != 0: return ip_value else: pass # 下面尝试通过可能存在的phpinfo页面获得真实ip ip_from_phpinfo = self.get_domain_actual_ip_from_phpinfo() if ip_from_phpinfo == 0: pass else: return ip_from_phpinfo # 下面通过mx记录来尝试获得真实ip result = self.check_if_mx_c_machines_has_actual_ip_of_domain() if result == 0: pass else: return result print("很遗憾,在下认为%s有cdn,但是目前在下的能力没能获取它的真实ip,当前函数将返回0" % self.domain) return 0if __name__ == '__main__': import sys domain=sys.argv[1] Xcdn(domain)
I feedback.
Let me know what you think of this article on twitter @quanyechavshuo!
Let me know what you think of this article on twitter @quanyechavshuo!
最新最早最热
- 2条评论
- hxxh
大神你好,没学过py,把这脚本运行后,说的
from: too many arguments
./xcdn.py:行19: 未预期的符号 `"3xp10it",0,True' 附近有语法错误
./xcdn.py:行19: `figlet2file("3xp10it",0,True)'
问下这是怎么回事啊 - 「&」
回复 hxxh: 可以把figlet2file("3xp10it",0,True)这行代码注释掉,也就是:
#figlet2file("3xp10it",0,True)
【这行代码是一个打印功能,对于代码的功能来说无关紧要,如果系统不是ubuntu,可能会出错】
0 0
- 尝试获取cdn背后的真实ip
- 如何找到真实CDN背后的IP
- CDN获取真实IP
- CDN获取真实IP
- 获取使用CDN网站的真实IP
- 绕过cdn获取网站的真实ip
- Nginx获取CDN转发的访客真实IP
- 使用CDN后,获取真实IP 办法
- 用于获取因用cdn无法获取用户真实IP的方法
- Nginx在CDN加速之后,获取用户真实IP做并发访问限制的方法
- Nginx在CDN加速之后,获取用户真实IP做并发访问限制的方法
- Discuz!论坛运营之使用CDN后无法获取真实IP的解决方法
- 以cdn为前导,使用Nginx服务器反向代理,获取客户端真实ip的办法
- nginx做负载CDN加速获取端真实ip
- nginx做负载CDN加速获取端真实ip
- 使用了cdn,如何获取客户端真实ip?
- 如何查询使用了CDN的网站的真实IP
- asp.net取CDN用户真实IP的方法,仅供参考!
- C++初级,想问一下下之,学VC++和Linux C++哪个好
- LED广告屏
- 【Leetcode】Stock Buy and Sell 系列问题 终极分析!
- 实验吧—奇怪的短信
- BZOJ 4036([HAOI2015]按位或-子集和变换)
- 尝试获取cdn背后的真实ip
- 18th Feb: Bloomberg字符串题延伸
- HeadFirst iPhone and iPad Development
- 实验吧—求解
- YII查询
- Leetcode-Algorithms Nested List Weight Sum
- 实验吧—考考你的程序功底
- GOTURN-(达到100FPS的深度学习跟踪算法代码)
- Java语言基础组成:关键字、标识符、注释、常量和变量、运算符、语句、函数、数组