lib/rex/parser/net_sarang.rb
module Rex
module Parser
module NetSarang
# @author Kali-Team
class NetSarangCrypto
attr_accessor :version
attr_accessor :username
attr_accessor :sid
attr_accessor :master_password
attr_accessor :key
# This class implements encryption and decryption of NetSarang
#
# @param type [String] only Xshell or Xftp.
# @param version [String] Specify version of session file. e.g.:5.3
# @param username [String] Specify username. This parameter will be used if version > 5.2.
# @param sid [String] Specify SID. This parameter will be used if version >= 5.1.
# @option master_password [String] Specify user's master password.
#
# @return [Rex::Parser::NetSarang::NetSarangCrypto] The NetSarangCrypto object
def initialize(type, version, username, sid, master_password = nil)
self.version = version.to_f
self.username = username
self.sid = sid
self.master_password = master_password
md5 = OpenSSL::Digest.new('MD5')
sha256 = OpenSSL::Digest.new('SHA256')
if (self.version > 0) && (self.version < 5.1)
self.key = (type == 'Xshell') ? md5.digest('!X@s#h$e%l^l&') : md5.digest('!X@s#c$e%l^l&')
elsif (self.version >= 5.1) && (self.version <= 5.2)
self.key = sha256.digest(self.sid)
elsif (self.version > 5.2)
if self.master_password.nil?
self.key = sha256.digest(self.username + self.sid)
else
self.key = sha256.digest(self.master_password)
end
else
raise 'Invalid argument: version'
end
end
# Encrypt
#
# @param string [String]
# @return [String] ciphertext
def encrypt_string(string)
cipher = Rex::Crypto.rc4(key, string)
if (version < 5.1)
return Rex::Text.encode_base64(cipher)
else
sha256 = OpenSSL::Digest.new('SHA256')
checksum = sha256.digest(string)
ciphertext = cipher
return Rex::Text.encode_base64(ciphertext + checksum)
end
end
# Decrypt
#
# @param string [String]
# @return [String] plaintext failed return nil
def decrypt_string(string)
if (version < 5.1)
return Rex::Crypto.rc4(key, Rex::Text.decode_base64(string))
else
data = Rex::Text.decode_base64(string)
ciphertext = data[0, data.length - 0x20]
plaintext = Rex::Crypto.rc4(key, ciphertext)
if plaintext.is_utf8?
return plaintext
else
return nil
end
end
end
end
# Parse xsh session file provided as a string.
#
# @param input [String] XSH Session file as a string
# @return [Array] An array containing the version, host,
# port, username, and password obtained from the XSH session file.
def parser_xsh(input)
ini = Rex::Parser::Ini.from_s(input)
version = ini['SessionInfo']['Version']
port = ini['CONNECTION']['Port']
host = ini['CONNECTION']['Host']
username = ini['CONNECTION:AUTHENTICATION']['UserName']
password = ini['CONNECTION:AUTHENTICATION']['Password'] || nil
[version, host, port, username, password]
end
# parser xfp session file
#
# @param ini [String]
# @return [version, host, port, username, password]
def parser_xfp(file)
ini = Rex::Parser::Ini.from_s(file)
version = ini['SessionInfo']['Version']
port = ini['Connection']['Port']
host = ini['Connection']['Host']
username = ini['Connection']['UserName']
password = ini['Connection']['Password']
[version, host, port, username, password]
end
end
end
end