众所周知,TOR是一种能够保护世界各地不同中继节点之间通信调度数据包的“软件”,由志愿者建立的网络进行运营。在过去的几年中,TOR已经被物理和网络***者广泛用于掩盖恶意操作。TOR也被视为最主要的进入暗网的方法,在暗网中,“恶意”的人可以通过黑市非法买卖东西。

网络里每个中继节点都能够根据自己的配置状态,决定是作为一个ExitPoint(在以下图片中用最后一台接触“Bob”的机器表示)或者只是一个中继节点(在下图中,TOR节点用“绿十字”突出显示)。如果中继节点决定成为一个ExitNode,就会向公众公开自己的IP地址,这通常是一个引起当地警方警觉的好办法。

过去一年中,电视节目,广播电台,youtube频道,Facebook这一类大众媒体披露出,许多黑市故意将人们引向DarkWeb,从而将他们暴露在许多新的***场景下。事实上新的***者会为了监视他们的通信流而设置退出节点或继电器节点。这种***可能会在许多单一的方式下发生,但最常用的今天写的这三个:

1.DNS中毒:这个技术主要在于将与知名网站有关的DNS调用重定向到一个假的页面上, 这个假的页面包含开发工具包,可以使用户的浏览器妥协。

2.文件修补:这个技术是改变请求的文件,在其到达目的地之前在其中添加恶意内容.这些步骤会在发给原始请求者之前直接在ExitPoint /中继节点上进行。

3.替换证明(SSL - MITM):这个技术是用假的证书替换网站真实的证书,这样就可以解密通信流,拦截凭证和参数。

致力于网络安全就意味着要及时意识到这样的***的存在,也要能够决定将在何时通过TOR中继节点。请注意,TOR不是DarkWeb中唯一的匿名网络.

我的目标是弄清楚我的TOR流通过恶意中继节点的时间。出于这样一个原因,我决定写一个能够对DNS Poison,文件修补和SSL-MITM做出一些快速检查的python脚本。这个脚本已经存在了2年, 直到现在仍是保密状态。自从科学研究应用了我的FindMalExit.py的高级版本之后,我决定公开这个脚本。

想法

实际上这是一个非常简单的想法:“让我们在不通过TOR网络(或通过可靠电路)的情况下拿到证书,IP地址和文件,然后重复这个过程,直到通过所有可用的中继节点。比较结果并进行检查。”

实现

以下请查收我的代码。请记住这是一个不是最终的代码 (这段代码只是一个更大的项目中的第一个版本,现在由Yoroi维护)。我决定发布HTML格式的代码。

#!/usr/bin/env python2#========================================================================##               THIS IS NOT A PRODUCTION RELEASED SOFTWARE               ##========================================================================## Purpose of finMaliciousRelayPoints is to proof the way it's possible to## discover TOR malicious Relays Points. Please do not use it in          ## any production  environment                                            ## Author: Marco Ramilli                                                  ## eMail: XXXXXXXX                                                        ## WebSite: marcoramilli.blogspot.com                                     ## Use it at your own                                                     ##========================================================================##==============================Disclaimer: ==============================##THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR      ##IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED          ##WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  ##DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,      ##INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      ##(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      ##SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)      ##HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,     ##STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING   ##IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      ##POSSIBILITY OF SUCH DAMAGE.                                             ##========================================================================##-------------------------------------------------------------------------#------------------- GENERAL SECTION -------------------------------------#-------------------------------------------------------------------------import StringIOimport tempfileimport timeimport hashlibimport tracebackfrom   geoip         import  geolite2import stem.controlTRUSTED_HOP_FINGERPRINT = '379FB450010D17078B3766C2273303C358C3A442' #trusted hopSOCKS_PORT              = 9050CONNECTION_TIMEOUT      = 30  # timeout before we give up on a circuit#-------------------------------------------------------------------------#---------------- File Patching Section ----------------------------------#-------------------------------------------------------------------------import pycurlcheck_files               = {                             "http://live.sysinternals.com/psexec.exe",                             "http://live.sysinternals.com/psexec.exe",                             "http://live.sysinternals.com/psping.exe", }check_files_patch_results = []class File_Check_Results:    """    Analysis Results against File Patching    """    def __init__(self, url, filen, filepath, exitnode, found_hash):        self.url           = url        self.filename      = filen        self.filepath      = filepath        self.exitnode      = exitnode        self.filehash      = found_hash#------------------------------------------------------------------------#------------------- DNS Poison Section ---------------------------------#------------------------------------------------------------------------import dns.resolverimport socksimport socketcheck_domain_poison_results = []domains                     = {                                 "www.youporn.com",                                 "youporn.com",                                 "www.torproject.org",                                 "www.wikileaks.org",                                 "www.i2p2.de",                                 "torrentfreak.com",                                 "blockchain.info",}class Domain_Poison_Check:    """    Analysis Results against Domain Poison    """    def __init__(self, domain):        self.domain  = domain        self.address = []        self.path    = []    def pushAddr(self, add):        self.address.append(add)    def pushPath(self, path):        self.path = path#-----------------------------------------------------------------------#------------------- SSL Sltrip Section --------------------------------#-----------------------------------------------------------------------import OpenSSLimport sslcheck_ssl_strip_results   = []ssl_strip_monitored_urls = {                            "www.google.com",                            "www.microsoft.com",                            "www.apple.com",                            "www.bbc.com",}class SSL_Strip_Check:    """    Analysis Result against SSL Strip    """    def __init__(self, domain, public_key, serial_number):        self.domain        = domain        self.public_key    = public_key        self.serial_number = serial_number#----------------------------------------------------------------------#----------------     Starting Coding   -------------------------------#----------------------------------------------------------------------def sslCheckOriginal():    """    Download the original Certificate without TOR connection    """    print('[+] Populating SSL for later check')    for url in ssl_strip_monitored_urls:        try:            cert = ssl.get_server_certificate((str(url), 443))            x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)            p_k  = x509.get_pubkey()            s_n  = x509.get_serial_number()            print('[+] Acquired Certificate: %s' % url)            print('    |_________> serial_number %s' % s_n)            print('    |_________> public_key %s' % p_k)            check_ssl_strip_results.append(SSL_Strip_Check(url, p_k, s_n))        except Exception as err:            print('[-] Error While Acquiring certificats on setup phase !')            traceback.print_exc()    return time.time()def fileCheckOriginal():    """    Downloading file ORIGINAL without TOR    """    print('[+] Populating File Hasing for later check')    for url in check_files:        try:            data = query(url)            file_name = url.split("/")[-1]            _,tmp_file = tempfile.mkstemp(prefix="exitmap_%s_" % file_name)            with open(tmp_file, "wb") as fd:                fd.write(data)                print('[+] Saving File  \"%s\".' % tmp_file)                check_files_patch_results.append( File_Check_Results(url, file_name, tmp_file, "NO", sha512_file(tmp_file)) )                print('[+] First Time we see the file..')                print('    |_________> exitnode : None'       )                print('    |_________> :url:  %s' % str(url)     )                print('    |_________> :filePath:  %s' % str(tmp_file))                print('    |_________> :file Hash: %s' % str(sha512_file(tmp_file)))        except Exception as err:                print('[-] Error ! %s' % err)                traceback.print_exc()                pass    return time.time()def resolveOriginalDomains():    """        Resolving DNS For original purposes    """    print('[+] Populating Domain Name Resolution for later check ')    try:        for domain in domains:            response = dns.resolver.query(domain)            d = Domain_Poison_Check(domain)            print('[+] Domain: %s' % domain)            for record in response:                print(' |____> maps to %s.' % (record.address))                d.pushAddr(record)            check_domain_poison_results.append(d)        return time.time()    except Exception as err:        print('[+] Exception: %s' % err)        traceback.print_exc()        return time.time()def query(url):  """  Uses pycurl to fetch a site using the proxy on the SOCKS_PORT.  """  output = StringIO.StringIO()  query = pycurl.Curl()  query.setopt(pycurl.URL, url)  query.setopt(pycurl.PROXY, 'localhost')  query.setopt(pycurl.PROXYPORT, SOCKS_PORT)  query.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5_HOSTNAME)  query.setopt(pycurl.CONNECTTIMEOUT, CONNECTION_TIMEOUT)  query.setopt(pycurl.WRITEFUNCTION, output.write)  try:    query.perform()    return output.getvalue()  except pycurl.error as exc:    raise ValueError("Unable to reach %s (%s)" % (url, exc))def scan(controller, path):  """  Scan Tor Relays Point to find File Patching  """  def attach_stream(stream):    if stream.status == 'NEW':      try:        controller.attach_stream(stream.id, circuit_id)        #print('[+] New Circuit id (%s) attached and ready to be used!' % circuit_id)      except Exception as err:        controller.remove_event_listener(attach_stream)        controller.reset_conf('__LeaveStreamsUnattached')  try:    print('[+] Creating a New TOR circuit based on path: %s' % path)    circuit_id = controller.new_circuit(path, await_build = True)    controller.add_event_listener(attach_stream, stem.control.EventType.STREAM)    controller.set_conf('__LeaveStreamsUnattached', '1')  # leave stream management to us    start_time = time.time()    socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)    socket.socket = socks.socket    ip = query('http://ip.42.pl/raw')    if ip is not None:        country  = geolite2.lookup( str(ip) ).country        print('\n \n')        print('[+] Performing FilePatch,  DNS Spoofing and Certificate Checking\              passing through --> %s (%s) \n \n' % (str(ip), str(country))  )    time_FileCheck = fileCheck(path)    print('[+] FileCheck took: %0.2f seconds'  % ( time_FileCheck - start_time))    #time_CertsCheck  = certsCheck(path)    #print('[+] CertsCheck took: %0.2f seconds' % ( time_DNSCheck - start_time))    time_DNSCheck  = dnsCheck(path)    print('[+] DNSCheck took: %0.2f seconds'   % ( time_DNSCheck - start_time))  except Exception as  err:    print('[-] Circuit creation error: %s' % path)  return time.time() - start_timedef certsCheck(path):    """    SSL Strip detection    TODO: It's still a weak control. Need to collect and to compare public_key()    """    print('[+] Checking Certificates')    try:        socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)        socket.socket = socks.socket        for url in ssl_strip_monitored_urls:            cert = ssl.get_server_certificate((str(url), 443))            x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)            p_k  = x509.get_pubkey()            s_n  = x509.get_serial_number()            for stored_cert in check_ssl_strip_results:                if str(url) == str(stored_cert.domain):                    if str(stored_cert.serial_number) != str(s_n):                        print('[+] ALERT Found SSL Strip on uri (%s) through path %s ' % (url, path))                        break                    else:                        print('[+] Certificate Check seems to be OK for %s' % url)    except Exception as err:        print('[-] Error: %s' % err)        traceback.print_exc()    socket.close()    return time.time()def dnsCheck(path):    """    DNS Poisoning Check    """    try:        socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)        socket.socket = socks.socket        print('[+] Checking DNS ')        for domain in domains:            ipv4 = socket.gethostbyname(domain)            for p_d in check_domain_poison_results:                if str(p_d.domain) == str(domain):                    found = False                    for d_ip in p_d.address:                        if str(ipv4) == str(d_ip):                            found = True                            break                    if found == False:                        print('[+] ALERT:DNS SPOOFING FOUND: name: %s ip: %s  (path: %s )' % (domain, ipv4, path) )                    else:                        print('[+] Check DNS (%s) seems to be OK' % domain)    except Exception as err:        print('[-] Error: %s' % err)        traceback.print_exc()    socket.close()    return time.time()def fileCheck(path):    """    Downloading file through TOR circuits doing the hashing    """    print('[+] Checking For File patching ')    for url in check_files:        try:            #File Rereive            data = query(url)            file_name = url.split("/")[-1]            _,tmp_file = tempfile.mkstemp(prefix="exitmap_%s_" % file_name)            with open(tmp_file, "wb") as fd:                fd.write(data)                for i in check_files_patch_results:                    if str(i.url) == str(url):                        if str(i.filehash) != str(sha512_file(tmp_file)):                            print('[+] ALERT File Patch FOUND !')                            print('    | exitnode : %s' % str(i.exitnode)      )                            print('    |_________> url: %s' % str(i.url)        )                            print('    |_________> filePath: %s' % str(i.filepath)   )                            print('    |_________> fileHash: %s' % str(i.filehash)   )                            #check_files_patch_results.append( File_Check_Results(url, file_name, tmp_file, path, sha512_file(tmp_file)) )                        else :                            print('[+] File (%s) seems to be ok' % i.url)                        break        except Exception as err:                print('[-] Error ! %s' % err)                traceback.print_exc()                pass    return time.time()def sha512_file(file_name):    """    Calculate SHA512 over the given file.    """    hash_func = hashlib.sha256()    with open(file_name, "rb") as fd:        hash_func.update(fd.read())    return hash_func.hexdigest()if __name__ == '__main__':    start_analysis = time.time()    print("""  |=====================================================================|  | Find Malicious Relay Nodes is a python script made for checking 3   |  | unique kind of frauds such as:                                      |  | (1) File Patching                                                   |  | (2) DNS Poison                                                      |  | (3) SSL Stripping (MITM SSL)                                        |  |=====================================================================|         """)    print("""  |=====================================================================|  |                 Initialization Phase                                |  |=====================================================================|       """)    dns_setup_time             = resolveOriginalDomains()    print('[+] DNS Setup Finished: %0.2f' % (dns_setup_time - start_analysis))    file_check_original_time   = fileCheckOriginal()    print('[+] File Setup Finished: %0.2f' % (file_check_original_time - start_analysis))    ssl_checking_original_time = sslCheckOriginal()    print('[+] Acquiring Certificates  Setup Finished: %0.2f' % (ssl_checking_original_time - start_analysis))    print("""  |=====================================================================|  |                 Analysis  Phase                                     |  |=====================================================================|          """)    print('[+] Connecting and Fetching possible Relays ...')    with stem.control.Controller.from_port() as controller:      controller.authenticate()      net_status = controller.get_network_statuses()      for descriptor in net_status:        try:          fingerprint = descriptor.fingerprint          print('[+] Selecting a New Exit Point:')          print('[+] |_________> FingerPrint: %s ' % fingerprint)          print('[+] |_________> Flags: %s ' % descriptor.flags)          print('[+] |_________> Exit_Policies: %s ' % descriptor.exit_policy)          if 'EXIT' in (flag.upper() for flag in descriptor.flags):              print('[+] Found Exit Point. Performing Scan through EXIT: %s' % fingerprint)              if None == descriptor.exit_policy:                  print('[+] No Exit Policies found ... no certs checking')                  time_taken = scan(controller, [TRUSTED_HOP_FINGERPRINT, fingerprint])          else:              #print('[+] Not Exit Point found. Using it as Relay passing to TRUST Exit Point')              pass              #time_taken = scan(controller, [fingerprint, TRUSTED_HOP_FINGERPRINT])          #print('[+] Finished Analysis for %s finished  => %0.2f seconds' % (fingerprint, time_taken))        except Exception as exc:            print('[-] Exception on  FingerPrint: %s => %s' % (fingerprint, exc))            traceback.print_exc()            pass

转载于:https://blog.51cto.com/cxnic/1727685

查找恶意的TOR中继节点相关推荐

  1. linux启动中继服务器失败,Tor中继服务器在Linux里安装配置的流程

    系统平台为Fedora 8,Tor版本为tor-0.2.0.19-alpha. 第一步:下载并安装Tor 在官方网站下载最新版本的Tor,我下载的是tor-0.2.0.19-alpha.tar.gz, ...

  2. 神秘组织正在运行数百个恶意 Tor 中继

     聚焦源代码安全,网罗国内外最新资讯! 编译:代码卫士 至少从2017年起,威胁行动者就在 Tor 网络的入口.中间和出口位置运行着数千个恶意服务器,试图将 Tor 用户去匿名化. 该威胁组织被研究人 ...

  3. Tor 出口节点将运行在图书馆的电脑上

    Tor 匿名网络项目宣布与 Library Freedom Project合作,在图书馆的电脑上运行 Tor 出口节点.在Tor匿名网络中,出口节点是Tor用户访问目标网站的最后一个中继,也是法律风险 ...

  4. php恶意代码,php快速查找数据库中恶意代码的方法,快速查找恶意代码_PHP教程...

    php快速查找数据库中恶意代码的方法,快速查找恶意代码 本文实例讲述了php快速查找数据库中恶意代码的方法.分享给大家供大家参考.具体如下: 数据库被输入恶意代码,为了保证你的数据库的安全,你必须得小 ...

  5. java递归方法建立搜索二叉树,具备查找关键字,插入新节点功能

    二叉排序树的定义: 二叉排序树满足以下三个性质(BST性质): <1>若它的左子树非空,则左子树上所有节点的值均小于根节点的值 <2>若它的右子树非空,则右子树上所有节点的值均 ...

  6. 数据结构:二叉树的创建,打印前中后序遍历,节点个数,叶子节点数,销毁,第K层中节点的个数,查找值为x的节点

    二叉树遍历:按照某种特定的规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作一次.(采用递归思想) 先序遍历:先遍历根节点,再遍历根节点的左子树,最后遍历根节点的右子树. 中序遍历:先遍历左 ...

  7. m基于GA遗传优化算法的认知中继网络最优中继功率分配和最佳中继节点选择算法matlab仿真

    目录 1.算法概述 2.仿真效果预览 3.核心MATLAB代码预览 4.完整MATLAB程序 1.算法概述 如图1表示一个潜伏式认知中继网络,在这个场景中有一对主用户和一对次级用户,主用户由一个发射器 ...

  8. 使用simple transformation查找xml file内某个节点的attribute是否存在指定value

    Created by Jerry Wang on Jun 05, 2014 下列report实现通过simple transformation查找xml 文件内下列路径的节点ds其attribute ...

  9. c++ ptree判断是否存在节点_CTreeCtrl 查找 等于某值 的节点,并设置为高亮

    查找节点,并返回该节点 HTREEITEM GroupTree::FindTreeItem(HTREEITEM item,CString& strText) { HTREEITEM   hFi ...

  10. php 查找无限级,Ztree + PHP 无限级节点 递归查找节点法

    一.前言 简单的描述一下,实习几个原理,思想,其实写很多东西,思想算是最重要的. 1.目标:将写一个无限节点的树形目录结构,如下图 步骤: 1.你的下载 插件  ztree.然后布置在你的项目中. 2 ...

最新文章

  1. windows环境下跑hadoop自带的wordcount遇到的问题
  2. Linux 下 MediaWiki 的安装使用
  3. 支持的存储类型有_跟我一起看博途1200系统手册之数据类型的介绍
  4. 国内985副教授与行政人员一年能够拿到多少工资?
  5. ASP.NET导入Excel到数据库(SQL)
  6. UVA 10572 Black and White(插头DP)
  7. 【Landsat 8】遥感影像文件内容及命名规则
  8. matlab画图函数汇总(二)
  9. 能破解百度网盘提取码,云盘万能钥匙宣布关闭!
  10. Springboot JUnit5 Controller 单元测试
  11. linux键盘按键驱动
  12. 解决IDEA运行后报找不到应用程序错误
  13. 数据库MySQL(基础六)
  14. P3373 【模板】线段树1和P3373 【模板】线段树 2
  15. wifi热点创建和自动连接
  16. java set list map_Java中的Set,List,Map
  17. 新站4个月,新手做网站经验总结
  18. Flutter的android项目跳转谷歌市场
  19. bs84c12引脚_最新BS84B12A-3.pdf
  20. ngular12版本引入ng-alain报错

热门文章

  1. 计算机c盘能格式化吗,c盘可以直接格式化吗?C盘怎么格式化?
  2. 手持式网络性能测试仪
  3. Deepo:几乎包含所有主流深度学习框架的Docker镜像
  4. Android反射系统截图Api
  5. 哔哩哔哩电脑网页版怎么下载视频
  6. 超声波传感器测距实验
  7. win10系统下摄像头无法打开的解决方法
  8. 应用计算机测定线性电阻伏安特性实验结论,线性电阻和非线性电阻伏安特性曲线测定实验报告(共8篇).docx...
  9. bzoj 3332 旧试题
  10. redis实现队列的几种方式(LPUSH/BRPOP,发布/订阅模式,stream)