2021-10-22 17:24:26 -04:00
module Metasploit
module Framework
module Ssh
module Platform
def self . get_platform ( ssh_socket )
info = get_platform_info ( ssh_socket , timeout : 10 )
get_platform_from_info ( info )
end
def self . get_platform_info ( ssh_socket , timeout : 10 )
info = ''
begin
Timeout . timeout ( timeout ) do
info = ssh_socket . exec! ( " id \n " ) . to_s
if ( info =~ / id= / )
info << ssh_socket . exec! ( " uname -a \n " ) . to_s
if ( info =~ / JUNOS / )
# We're in the SSH shell for a Juniper JunOS, we can pull the version from the cli
# line 2 is hostname, 3 is model, 4 is the Base OS version
2022-04-10 11:24:42 -04:00
info = ssh_socket . exec! ( " cli show version \n " ) . split ( " \n " ) [ 2 .. 4 ] . join ( ', ' ) . to_s
2021-10-22 17:24:26 -04:00
elsif ( info =~ / Linux USG / )
# Ubiquiti Unifi USG
info << ssh_socket . exec! ( " cat /etc/version \n " ) . to_s . rstrip
end
temp_proof = ssh_socket . exec! ( " grep unifi.version /tmp/system.cfg \n " ) . to_s . rstrip
if ( temp_proof =~ / unifi \ .version / )
info << temp_proof
# Ubiquiti Unifi device (non-USG), possibly a switch. Tested on US-24, UAP-nanoHD
# The /tmp/*.cfg files don't give us device info, however the info command does
# we dont call it originally since it doesnt say unifi/ubiquiti in it and info
# is a linux command as well
info << ssh_socket . exec! ( " grep board.name /etc/board.info \n " ) . to_s . rstrip
end
2022-04-10 11:24:42 -04:00
elsif info =~ / Unknown command or computer name /
2021-10-22 17:24:26 -04:00
# Cisco IOS
2022-04-10 11:24:42 -04:00
info = ssh_socket . exec! ( " ver \n " ) . to_s
2021-10-22 17:24:26 -04:00
# Juniper ScreenOS
2022-04-10 11:24:42 -04:00
elsif info =~ / unknown keyword /
info = ssh_socket . exec! ( " get chassis \n " ) . to_s
2021-10-22 17:24:26 -04:00
# Juniper JunOS CLI
2022-04-10 11:24:42 -04:00
elsif info =~ / unknown command: id /
info = ssh_socket . exec! ( " show version \n " ) . split ( " \n " ) [ 2 .. 4 ] . join ( ', ' ) . to_s
2021-10-22 17:24:26 -04:00
# Brocade CLI
2022-04-10 11:24:42 -04:00
elsif info =~ / Invalid input -> id / || info =~ / Protocol error, doesn't start with scp! /
info = ssh_socket . exec! ( " show version \n " ) . to_s
if info =~ / Version:(?<os_version>.+).+HW: (?<hardware>) /mi
info = " Model: #{ hardware } , OS: #{ os_version } "
end
2021-10-22 17:24:26 -04:00
# Arista
2022-04-10 11:24:42 -04:00
elsif info =~ / % Invalid input at line 1 /
info = ssh_socket . exec! ( " show version \n " ) . split ( " \n " ) [ 0 .. 1 ]
info = info . map { | item | item . strip }
info = info . join ( ', ' ) . to_s
2021-10-22 17:24:26 -04:00
# Windows
2025-05-12 12:38:45 +01:00
elsif info =~ / command not found|is not recognized as an internal or external command|is not recognized as the name of a cmdlet, function, script file, or operable /
2022-04-10 11:24:42 -04:00
info = ssh_socket . exec! ( " systeminfo \n " ) . to_s
/ OS Name: \ s+(?<os_name>.+)$ / =~ info
/ OS Version: \ s+(?<os_num>.+)$ / =~ info
if os_num . present? && os_name . present?
info = " #{ os_name . strip } #{ os_num . strip } "
2021-10-22 17:24:26 -04:00
else
2022-04-10 11:24:42 -04:00
info = ssh_socket . exec! ( " ver \n " ) . to_s . strip
2021-10-22 17:24:26 -04:00
end
2022-04-10 11:24:42 -04:00
# mikrotik
elsif info =~ / bad command name id \ (line 1 column 1 \ ) /
info = ssh_socket . exec! ( " / system resource print \n " ) . to_s
/ platform: \ s+(?<platform>.+)$ / =~ info
/ board-name: \ s+(?<board>.+)$ / =~ info
/ version: \ s+(?<version>.+)$ / =~ info
if version && platform && board
info = " #{ platform . strip } #{ board . strip } #{ version . strip } "
end
# esxi 6.7
elsif info =~ / sh: id: not found /
info = ssh_socket . exec! ( " vmware -v \n " ) . to_s
2024-11-03 14:47:40 -05:00
# vcenter 6.7 (photon)
2024-11-18 07:30:21 -05:00
# VMware vCenter Server 8.0.0.10000
2024-11-04 16:26:08 -05:00
# VMware VirtualCenter 6.7.0 build-19299595
2024-11-18 07:30:21 -05:00
elsif info =~ / Unknown command: `id' /
2024-11-04 16:26:08 -05:00
# eventually we'll want to try to shell in via 'shell'. On failure you see: "User 'user_operator' is not authorized to run this command"
# on succeess: "Shell access is granted to <username>"
2024-11-03 14:47:40 -05:00
info = ssh_socket . exec! ( " api com.vmware.appliance.version1.system.version.get \n \n " ) . to_s
/ Product: \ s+(?<product>.+)$ / =~ info
/ Version: \ s+(?<version>[ \ d \ .]+)$ / =~ info
if version && product
info = " #{ product . strip } #{ version . strip } "
end
2022-04-10 11:24:42 -04:00
else
info << ssh_socket . exec! ( " help \n ? \n \n \n " ) . to_s
2021-10-22 17:24:26 -04:00
end
end
rescue Timeout :: Error
end
info
end
2025-01-10 10:40:22 +11:00
def self . is_posix ( platform )
return [ 'unifi' , 'linux' , 'osx' , 'solaris' , 'bsd' , 'hpux' , 'aix' ] . include? ( platform )
end
2021-10-22 17:24:26 -04:00
def self . get_platform_from_info ( info )
case info
2022-04-10 11:24:42 -04:00
when / unifi \ .version|UniFiSecurityGateway /i # Ubiquiti Unifi. uname -a is left in, so we got to pull before Linux
2021-10-22 17:24:26 -04:00
'unifi'
2022-02-03 15:47:31 +00:00
when / Linux /i
2021-10-22 17:24:26 -04:00
'linux'
2022-04-10 11:24:42 -04:00
when / VMware ESXi /i
'linux'
2022-02-03 15:47:31 +00:00
when / Darwin /i
2021-10-22 17:24:26 -04:00
'osx'
2022-02-03 15:47:31 +00:00
when / SunOS /i
2021-10-22 17:24:26 -04:00
'solaris'
2022-02-03 15:47:31 +00:00
when / BSD /i
2021-10-22 17:24:26 -04:00
'bsd'
2022-02-03 15:47:31 +00:00
when / HP-UX /i
2021-10-22 17:24:26 -04:00
'hpux'
2022-02-03 15:47:31 +00:00
when / AIX /i
2021-10-22 17:24:26 -04:00
'aix'
2023-11-17 12:51:01 +00:00
when / MSYS_NT|cygwin|Win32|Windows|Microsoft /i
2021-10-22 17:24:26 -04:00
'windows'
2022-02-03 15:47:31 +00:00
when / Unknown command or computer name|Line has invalid autocommand /i
2021-10-22 17:24:26 -04:00
'cisco-ios'
2022-02-03 15:47:31 +00:00
when / unknown keyword /i # ScreenOS
2021-10-22 17:24:26 -04:00
'juniper'
2022-02-03 15:47:31 +00:00
when / JUNOS Base OS /i # JunOS
2021-10-22 17:24:26 -04:00
'juniper'
2022-02-03 15:47:31 +00:00
when / MikroTik /i
2021-10-22 17:24:26 -04:00
'mikrotik'
2022-02-03 15:47:31 +00:00
when / Arista /i
2021-10-22 17:24:26 -04:00
'arista'
2024-11-18 07:30:21 -05:00
when / VMware vCenter Server /i
2024-11-03 14:47:40 -05:00
'vcenter'
2021-10-22 17:24:26 -04:00
else
'unknown'
end
end
end
end
end
end