def retrieve_url(self, nextproto, nexturl, needresolve): #print ("====%s %r==="%(nexturl,needresolve)) if self.verbose: print('################### %s - %s - %r #######################' % (nextproto, nexturl, needresolve)) domain, port = getdomain(nexturl, nextproto) if needresolve: #ip = gethostbyname_or_timeout(domain, timeout_secs = 0.5) ip = _get_a_record(domain, self.timeout) if not ip or '0.0.0.0' in ip: return False if nextproto in ['http', 'https']: try: if os.path.isfile('cacert.pem'): try: page = requests.get(nexturl.replace("%20", " "), timeout=self.timeout, verify='cacert.pem').text except: print('') else: page = requests.get(nexturl.replace("%20", " "), timeout=self.timeout).text except Exception as e: return if not re.findall(r'%s' % self.regexp, page): opend.append(nexturl) log.warning(f"\n[f] Открылся: {nexturl}") elif nextproto in ['newcamd525', 'mgcamd525']: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if not sock.connect_ex((domain, int(port))): opend.append(nextproto + "://" + nexturl) else: print("Unknown proto: " + nextproto) return False
def retrieve_url(self,nextproto,nexturl,needresolve): #print ("====%s %r==="%(nexturl,needresolve)) if self.verbose:print ('################### %s - %s - %r #######################' % (nextproto,nexturl,needresolve)) domain, port = getdomain(nexturl,nextproto) if needresolve: #ip = gethostbyname_or_timeout(domain, timeout_secs = 0.5) ip = _get_a_record(domain, self.timeout) if not ip or '0.0.0.0' in ip: return False if nextproto in ['http','https']: try: if os.path.isfile('cacert.pem'): try: page = requests.get(nexturl.replace("%20", " "),timeout=self.timeout,verify='cacert.pem').text except: print('') else: page = requests.get(nexturl.replace("%20", " "),timeout=self.timeout).text except Exception as e: return if not re.findall(r'%s'%self.regexp,page): opend.append(nexturl) log.warning(f"\n[f] Открылся: {nexturl}") elif nextproto in ['newcamd525','mgcamd525']: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if not sock.connect_ex((domain, int(port))): opend.append(nextproto+"://"+nexturl) else: print("Unknown proto: "+nextproto) return False
def test_dpi(): log.info("[O] Тестируем обход DPI") dpiresults = [] for dpisite in dpi_list: site = dpi_list[dpisite] dpi_built_tests = _dpi_build_tests(site['host'], site['urn'], site['ip'], site['lookfor']) for testname in dpi_built_tests: test = dpi_built_tests[testname] log.info( colored(f"\tПробуем способ \"{testname}\" на {dpisite}", "white")) try: result = _dpi_send(test.get('ip'), 80, test.get('data'), test.get('fragment_size'), test.get('fragment_count')) except Exception as e: log.info(f"[ok] Ошибка: {repr(e)}") else: if result.split("\n")[0].find('200 ') != -1 and result.find( test['lookfor']) != -1: log.warning("[f] Сайт открывается") dpiresults.append(testname) elif result.split("\n")[0].find('200 ') == -1 and result.find( test['lookfor']) != -1: log.warning( "[!] Сайт не открывается, обнаружен пассивный DPI!") dpiresults.append('Passive DPI') else: log.info("[ok] Сайт не открывается") return list(set(dpiresults))
def _get_a_records(sitelist, timeout, dnsserver=None): result = [] for site in sitelist: try: records = _get_a_record(site, timeout, dnsserver) if not records: log.warning(f'No DNS answer! Return False') return False for item in records: result.append(item) except dns.resolver.NXDOMAIN: log.warning(f"[!] Невозможно получить DNS-запись для домена {site} (NXDOMAIN). Результаты могут быть неточными.") except dns.exception.DNSException: return "" return sorted(result)
def _get_a_records(sitelist, timeout, dnsserver=None): result = [] for site in sitelist: try: records = _get_a_record(site, timeout, dnsserver) if not records: return False for item in records: result.append(item) except dns.resolver.NXDOMAIN: log.warning( f"[!] Невозможно получить DNS-запись для домена {site} (NXDOMAIN). Результаты могут быть неточными." ) except dns.exception.DNSException: return "" return sorted(result)
def domains_check(domain_check_list: list, checker_name: str, n_threads=n_threads, regexp=regexp, timeout=timeout, verbose=verbose): ''' Запускает проверку списка сайтов и следит, чтобы не было lock ''' opend=[] total_num_sites = len(domain_check_list) log.info(f"[O] Количество {checker_name} для проверки: {str(total_num_sites)}") if total_num_sites == 0: log.critical("Nothing to do") input("Нажмите Enter чтобы выйти...") exit(0) url_list_lock = Lock() workerthreadlist=[] for x in range(0,n_threads-1): newthread = WorkerThread(domain_check_list,url_list_lock,regexp,timeout,verbose,total_num_sites) workerthreadlist.append(newthread) newthread.start() while len(workerthreadlist) > 0: try: workerthreadlist = [t.join(1) for t in workerthreadlist if t is not None and t.isAlive()] except KeyboardInterrupt: log.warning("\nCtrl-c! Остановка всех потоков...") for t in workerthreadlist: t.kill_received = True exit(0) print() perc = len(opend)*100/total_num_sites print(colored("[f]",'cyan'), end="") if perc else print(colored("[ok]",'cyan'),end="") print (colored(f" Процент открывшихся {checker_name}: {str(perc)}%", 'cyan')) if perc: log.warning(f"[f] Открывшиеся {checker_name}:") for url in opend: log.warning(f"\t[f] {url}")
def test_dns(): sites = dns_records_list sites_list = list(sites.keys()) log.info("[O] Тестируем DNS") log.info("[O] Получаем эталонные DNS с сервера") try: remote_dns = urllib.request.urlopen("http://tac.rdp.ru/pub/getdns.php", timeout=10).read() remote_dns = sorted(_decode_bytes(remote_dns).split()) log.info(f"\tЭталонные адреса:\t\t {str(remote_dns)}") except: remote_dns = None log.warning( "[f] Не удалось получить DNS с сервера, результаты могут быть неточными" ) resolved_default_dns = sorted(_get_a_records(sites_list, timeout)) if resolved_default_dns: log.info( f"\tАдреса через системные DNS:\t {str(resolved_default_dns)}") else: log.warning("\tНе удалось подключиться к системному DNS") resolved_google_dns = sorted( _get_a_records(sites_list, timeout, google_dns)) if resolved_google_dns: log.info(f"\tАдреса через Google DNS:\t {str(resolved_google_dns)}") else: loggint.warning("\tНе удалось подключиться к Google DNS") if not resolved_google_dns or not resolved_default_dns: log.critical( "Проблема с разрешением DNS на системном, либо google сервере") input("Нажмите Enter чтобы выйти...") exit(1) if (remote_dns): # Если получили IP с сервера, используем их dns_records = remote_dns else: dns_records = sorted( [item for sublist in sites.values() for item in sublist]) if resolved_default_dns == resolved_google_dns: if resolved_default_dns == dns_records: log.info("[ok] DNS-записи не подменяются") return 0 else: log.warning("[f] DNS-записи подменяются") return 2 log.warning("[?] Способ блокировки DNS определить не удалось") return 3
def test_dpi(): log.info("[O] Тестируем обход DPI") dpiresults = [] for dpisite in dpi_list: site = dpi_list[dpisite] dpi_built_tests = _dpi_build_tests(site['host'], site['urn'], site['ip'], site['lookfor']) for testname in dpi_built_tests: test = dpi_built_tests[testname] log.info(colored(f"\tПробуем способ \"{testname}\" на {dpisite}", "white")) try: result = _dpi_send(test.get('ip'), 80, test.get('data'), test.get('fragment_size'), test.get('fragment_count')) except Exception as e: log.info(f"[ok] Ошибка: {repr(e)}") else: if result.split("\n")[0].find('200 ') != -1 and result.find(test['lookfor']) != -1: log.warning("[f] Сайт открывается") dpiresults.append(testname) elif result.split("\n")[0].find('200 ') == -1 and result.find(test['lookfor']) != -1: log.warning("[!] Сайт не открывается, обнаружен пассивный DPI!") dpiresults.append('Passive DPI') else: log.info("[ok] Сайт не открывается") return list(set(dpiresults))
def test_dns(): sites = dns_records_list sites_list = list(sites.keys()) log.info("[O] Тестируем DNS") log.info("[O] Получаем эталонные DNS с сервера") try: remote_dns = urllib.request.urlopen("http://tac.rdp.ru/pub/getdns.php", timeout=10).read() remote_dns = sorted(_decode_bytes(remote_dns).split()) log.info(f"\tЭталонные адреса:\t\t {str(remote_dns)}") except: remote_dns = None log.warning("[f] Не удалось получить DNS с сервера, результаты могут быть неточными") resolved_default_dns = _get_a_records(sites_list, timeout) if resolved_default_dns != 'False': log.info(f"\tАдреса через системные DNS:\t {str(resolved_default_dns)}") else: log.warning("\tНе удалось подключиться к системному DNS") resolved_google_dns = _get_a_records(sites_list, timeout, google_dns) if resolved_google_dns != 'False': log.info(f"\tАдреса через Google DNS:\t {str(resolved_google_dns)}") else: loggint.warning("\tНе удалось подключиться к Google DNS") if resolved_google_dns == 'False' or resolved_default_dns == 'False': log.critical("Проблема с разрешением DNS на системном, либо google сервере") input("Нажмите Enter чтобы выйти...") exit(1) if (remote_dns): # Если получили IP с сервера, используем их dns_records = remote_dns else: dns_records = sorted([item for sublist in sites.values() for item in sublist]) if resolved_default_dns == resolved_google_dns: if resolved_default_dns == dns_records: log.info("[ok] DNS-записи не подменяются") return 0 else: log.warning("[f] DNS-записи подменяются") return 2 log.warning("[?] Способ блокировки DNS определить не удалось") return 3
def domains_check(domain_check_list: list, checker_name: str, n_threads=n_threads, regexp=regexp, timeout=timeout, verbose=verbose): ''' Запускает проверку списка сайтов и следит, чтобы не было lock ''' opend = [] total_num_sites = len(domain_check_list) log.info( f"[O] Количество {checker_name} для проверки: {str(total_num_sites)}") if total_num_sites == 0: log.critical("Nothing to do") input("Нажмите Enter чтобы выйти...") exit(0) url_list_lock = Lock() workerthreadlist = [] for x in range(0, n_threads - 1): newthread = WorkerThread(domain_check_list, url_list_lock, regexp, timeout, verbose, total_num_sites) workerthreadlist.append(newthread) newthread.start() while len(workerthreadlist) > 0: try: workerthreadlist = [ t.join(1) for t in workerthreadlist if t is not None and t.isAlive() ] except KeyboardInterrupt: log.warning("\nCtrl-c! Остановка всех потоков...") for t in workerthreadlist: t.kill_received = True exit(0) print() perc = len(opend) * 100 / total_num_sites print(colored("[f]", 'cyan'), end="") if perc else print( colored("[ok]", 'cyan'), end="") print(colored(f" Процент открывшихся {checker_name}: {str(perc)}%", 'cyan')) if perc: log.warning(f"[f] Открывшиеся {checker_name}:") for url in opend: log.warning(f"\t[f] {url}")
for domain_mask in domain_masks: tmp_domain_mask = domain_mask.findall('domain') if tmp_domain_mask: dott, no_asterisk_domain = tmp_domain_mask[ 0].text.split('*.') domain_mask_list.append(no_asterisk_domain) if __name__ == '__main__': test_dns() test_dpi() input("Нажмите Enter чтобы продолжить...") if f == '': if not os.path.isfile('dump.xml'): log.warning("Не могу найти dump.xml в этой директории") input("Нажмите Enter чтобы выйти...") exit(2) else: if not os.path.isfile(f): log.warning(f"Can't find {f}") input("Нажмите Enter чтобы выйти...") exit(3) opend = [] domain_mask_list = [] url_list = [] type_ip_list = [] #################################### ############ dump parse ############
url_list.append(['https',"https://" + str(ip)]+[False]) if domain_masks: for domain_mask in domain_masks: tmp_domain_mask = domain_mask.findall('domain') if tmp_domain_mask: dott, no_asterisk_domain = tmp_domain_mask[0].text.split('*.') domain_mask_list.append(no_asterisk_domain) if __name__ == '__main__': test_dns() test_dpi() input("Нажмите Enter чтобы продолжить...") if f=='': if not os.path.isfile('dump.xml'): log.warning("Не могу найти dump.xml в этой директории") input("Нажмите Enter чтобы выйти...") exit(2) else: if not os.path.isfile(f): log.warning(f"Can't find {f}") input("Нажмите Enter чтобы выйти...") exit(3) opend=[] domain_mask_list = [] url_list = [] type_ip_list = [] #################################### ############ dump parse ############
def getdomain(url, proto): res = re.findall(r"(?<=" + proto + ":\/\/)[^\/]+", url) if not len(res): return False if ':' in res[0]: return res[0].split(':') return [res[0], '80'] test_dns() test_dpi() input("Нажмите Enter чтобы продолжить...") if f == '': if not os.path.isfile('dump.xml'): log.warning("Не могу найти dump.xml в этой директории") input("Нажмите Enter чтобы выйти...") exit(2) else: if not os.path.isfile(f): log.warning(f"Can't find {f}") input("Нажмите Enter чтобы выйти...") exit(3) opend = [] url_list = [] type_ip_list = [] if f != '':