Skip to content

OpenVAS Aux scripts to guess password against OTP/OMP/WWW interfaces #1072

Merged
merged 7 commits into from Nov 24, 2012

4 participants

@kost
kost commented Nov 15, 2012

OpenVAS Aux scripts to guess password against OTP/OMP/WWW interfaces

@brandonprry

This is cool, this will work great with the remote code exec vuln just found.

@brandonprry brandonprry and 1 other commented on an outdated diff Nov 15, 2012
modules/auxiliary/scanner/openvas/openvas_gsad_login.rb
+ end
+
+ if not res
+ vprint_error("#{msg} #{datastore['URI']} - No response")
+ return
+ end
+ if res.code != 200
+ vprint_error("#{msg} - Expected 200 HTTP code - not gsad?")
+ return
+ end
+ if res.body !~ /Greenbone Security Assistant \(GSA\)/
+ vprint_error("#{msg} - Expected GSA keyword on page - not gsad?")
+ return
+ end
+
+ each_user_pass { |user, pass|
@brandonprry
brandonprry added a note Nov 15, 2012

do / end blocks are preferred over curly braces.

@kost
kost added a note Nov 16, 2012

fixed. As well as in other modules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@brandonprry brandonprry and 1 other commented on an outdated diff Nov 15, 2012
modules/auxiliary/scanner/openvas/openvas_gsad_login.rb
+ return
+ end
+ if res.body !~ /Greenbone Security Assistant \(GSA\)/
+ vprint_error("#{msg} - Expected GSA keyword on page - not gsad?")
+ return
+ end
+
+ each_user_pass { |user, pass|
+ do_login(user, pass)
+ }
+ end
+
+ def do_login(user='openvas', pass='openvas')
+ vprint_status("#{msg} - Trying username:'#{user}' with password:'#{pass}'")
+ headers = {}
+ data = 'cmd=' << datastore['OMP_cmd'] << '&text=' << datastore['OMP_text'] << '&login=' << user << '&password=' << pass
@brandonprry
brandonprry added a note Nov 15, 2012

So, I am curious why you implemented it to use GSA instead of OMP. OMP is more likely to be running than GSA. OMP should be faster as well, is tcp/xml and not http. Just a thought, willing to be wrong too.

@brandonprry
brandonprry added a note Nov 15, 2012

Good point, missed the modules below :)

@jlee-r7
jlee-r7 added a note Nov 20, 2012

Interpolation is a better way to deal with this kind of idiom.

  data = "cmd=#{datastore['OMP_cmd']}&text=#{datastore['OMP_text']}&login=#{user}&password=#{pass}"

Better still would be to take advantage of the library code that builds query strings for you. See wchen-r7's comment below about using 'vars_post'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kost
kost commented Nov 15, 2012

Have any public references?

BTW There are standalone guessers for quite some time now: https://github.com/kost/vulnscan-pwcrack

@kost
kost commented Nov 15, 2012

I have implemented OMP, GSA and OTP - no preference over each of the protocol.

OAP is only missing. Will implement OAP in future.

@brandonprry

So far so good on both the gsad and omp bruteforcers. However, if I am not using a DB, I have no easy way of knowing which creds worked on which hosts in the end. If I am using many threads (I used up to 50) and scanning a /24, It is very difficult to see the real results. With a db is fine, you just type creds, but a small printout at the end with successful attempts would be useful if no db is connected.

msf auxiliary(openvas_omp_login) > run

[] 192.168.1.42:9390 OpenVAS OMP - Connecting and checking username and passwords
[
] 192.168.1.42:9390 OPENVAS_OMP - [1/2] - OpenVAS OMP - Trying user:'admin' with password:'admin'
[-] 192.168.1.42:9390 OPENVAS_OMP - [1/2] - OpenVAS OMP - Rejected user: 'admin' with password: 'admin':
[] 192.168.1.42:9390 OPENVAS_OMP - [2/2] - OpenVAS OMP - Trying user:'admin' with password:'password'
[+] 192.168.1.42:9390 OpenVAS OMP - SUCCESSFUL login for 'admin' : 'password'
[
] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(openvas_omp_login) >

@brandonprry

Or, perhaps the real solution is to make some of the messages viewed only when VERBOSE is true.

Not sure.

@kost
kost commented Nov 16, 2012

This is what I found troublesome on almost all aux/login modules in msf (for example: ssh_login). Try turning off verbose. Then you will get only success ones.

@brandonprry

Ah, I see. np

@kost
kost commented Nov 16, 2012

By code exec, you mean this http://www.openvas.org/OVSA20121112.html or there is something newer? :)

@brandonprry

Yes ,but don't steal it, I plan on finishing the metasploit module tomorrow night. :P

@brandonprry

This is a great addition since that code exec requires authentication into greenbone

@kost
kost commented Nov 16, 2012

No worries. If you need any help writting it - let me know :)

@brandonprry

Sorry, forgot to paste the output of gsad

msf auxiliary(openvas_gsad_login) > run

[] 192.168.1.43:443 OPENVAS_GSAD - [1/1] - OpenVAS gsad - - Trying username:'admin' with password:'adm'
[-] 192.168.1.43:443 OPENVAS_GSAD - [1/1] - OpenVAS gsad - FAILED LOGIN. 'admin' : 'adm'
[
] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(openvas_gsad_login) > set USER_AS_PASS true
USER_AS_PASS => true
msf auxiliary(openvas_gsad_login) > run

[] 192.168.1.43:443 OPENVAS_GSAD - [1/2] - OpenVAS gsad - - Trying username:'admin' with password:'admin'
[+] 192.168.1.43:443 OpenVAS gsad - SUCCESSFUL LOGIN. 'admin' : 'admin'
[
] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(openvas_gsad_login) >

@brandonprry

These are probably OK to merge. I setup an old openvas install in a VM and successfully ran it.

EDIT: BTW I had to change RPORT from 9391 to 9390. I installed from the ubuntu 12.04 repos.

msf auxiliary(openvas_otp_login) > run

[] 192.168.1.44:9390 OpenVAS OTP - Connecting and checking username and passwords
[
] 192.168.1.44:9390 OPENVAS_OTP - [1/2] - OpenVAS OTP - Trying user:'admin' with password:'admin'
[-] 192.168.1.44:9390 OPENVAS_OTP - [1/2] - OpenVAS OTP - Rejected user: 'admin' with password: 'admin': Bad login attempt !
[] 192.168.1.44:9390 OPENVAS_OTP - [2/2] - OpenVAS OTP - Trying user:'admin' with password:'password'
[+] 192.168.1.44:9390 OpenVAS OTP - SUCCESSFUL login for 'admin' : 'password'
[
] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(openvas_otp_login) >

@kost
kost commented Nov 19, 2012

By the new convention (AFAIK): 9390 is for OMP and 9391 is for NTP (and this is how I made defaults in these modules).

@wchen-r7 wchen-r7 and 1 other commented on an outdated diff Nov 19, 2012
modules/auxiliary/scanner/openvas/openvas_omp_login.rb
+ ], self.class)
+
+ register_advanced_options(
+ [
+ OptBool.new('SSL', [ true, "Negotiate SSL for outgoing connections", true]),
+ OptString.new('SSLVersion', [ true, " Specify the version of SSL that should be used", "TLS1"])
+ ], self.class)
+ end
+
+ def run_host(ip)
+ begin
+ print_status("#{msg} Connecting and checking username and passwords")
+ each_user_pass do |user, pass|
+ do_login(user, pass)
+ end
+ end
@wchen-r7
wchen-r7 added a note Nov 19, 2012

This 'end' looks odd. Did you actually mean here, or after the ::Exception => e handling??

@kost
kost added a note Nov 23, 2012

Thanks - fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@wchen-r7 wchen-r7 and 1 other commented on an outdated diff Nov 19, 2012
modules/auxiliary/scanner/openvas/openvas_otp_login.rb
+ ], self.class)
+
+ register_advanced_options(
+ [
+ OptBool.new('SSL', [ true, "Negotiate SSL for outgoing connections", true]),
+ OptString.new('SSLVersion', [ true, " Specify the version of SSL that should be used", "TLS1"])
+ ], self.class)
+ end
+
+ def run_host(ip)
+ begin
+ print_status("#{msg} Connecting and checking username and passwords")
+ each_user_pass do |user, pass|
+ do_login(user, pass)
+ end
+ end
@wchen-r7
wchen-r7 added a note Nov 19, 2012

Same question as above for this line.

@kost
kost added a note Nov 23, 2012

Thanks - fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@wchen-r7 wchen-r7 and 1 other commented on an outdated diff Nov 19, 2012
modules/auxiliary/scanner/openvas/openvas_gsad_login.rb
+ OptString.new('URI', [true, "URI for OpenVAS omp login. Default is /omp", "/omp"]),
+ OptBool.new('BLANK_PASSWORDS', [false, "Try blank passwords for all users", false]),
+ OptBool.new('SSL', [ true, "Negotiate SSL for outgoing connections", true])
+ ], self.class)
+
+ register_advanced_options(
+ [
+ OptString.new('OMP_text', [true, "value for OpenVAS omp text login hidden field", "/omp?cmd=get_tasks&amp;overrides=1"]),
+ OptString.new('OMP_cmd', [true, "value for OpenVAS omp cmd login hidden field", "login"])
+ ], self.class)
+ end
+
+ def run_host(ip)
+ begin
+ res = send_request_cgi({
+ 'uri' => "#{datastore['URI']}",
@wchen-r7
wchen-r7 added a note Nov 19, 2012

or you can just do:

'uri' => datastore['URI']

@kost
kost added a note Nov 23, 2012

Thanks - fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@wchen-r7 wchen-r7 and 2 others commented on an outdated diff Nov 19, 2012
modules/auxiliary/scanner/openvas/openvas_gsad_login.rb
+ each_user_pass do |user, pass|
+ do_login(user, pass)
+ end
+ end
+
+ def do_login(user='openvas', pass='openvas')
+ vprint_status("#{msg} - Trying username:'#{user}' with password:'#{pass}'")
+ headers = {}
+ data = 'cmd=' << datastore['OMP_cmd'] << '&text=' << datastore['OMP_text'] << '&login=' << user << '&password=' << pass
+ begin
+ res = send_request_cgi({
+ 'encode' => true,
+ 'uri' => "#{datastore['URI']}",
+ 'method' => 'POST',
+ 'headers' => headers,
+ 'data' => data
@wchen-r7
wchen-r7 added a note Nov 19, 2012

If you're using send_request_cgi(), you should take advantage of 'vars_post' instead of 'post'.

@jlee-r7
jlee-r7 added a note Nov 20, 2012

I think wchen-r7 meant "'vars_post' instead of 'data'"

@kost
kost added a note Nov 23, 2012

Thanks - fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@wchen-r7 wchen-r7 and 1 other commented on an outdated diff Nov 19, 2012
modules/auxiliary/scanner/openvas/openvas_gsad_login.rb
+ return
+ end
+
+ each_user_pass do |user, pass|
+ do_login(user, pass)
+ end
+ end
+
+ def do_login(user='openvas', pass='openvas')
+ vprint_status("#{msg} - Trying username:'#{user}' with password:'#{pass}'")
+ headers = {}
+ data = 'cmd=' << datastore['OMP_cmd'] << '&text=' << datastore['OMP_text'] << '&login=' << user << '&password=' << pass
+ begin
+ res = send_request_cgi({
+ 'encode' => true,
+ 'uri' => "#{datastore['URI']}",
@wchen-r7
wchen-r7 added a note Nov 19, 2012

Can be just:

'uri' => datastore['URI']

@kost
kost added a note Nov 23, 2012

Thanks - fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jlee-r7 jlee-r7 and 1 other commented on an outdated diff Nov 20, 2012
modules/auxiliary/scanner/openvas/openvas_otp_login.rb
+ :pass => pass,
+ :source_type => "user_supplied",
+ :active => true
+ )
+ disconnect
+ @connected = false
+ return :next_user
+ else
+ if (@connected)
+ disconnect # Sometime openvas disconnect the client after wrongs attempts
+ @connected = false
+ end
+ vprint_error("#{msg} Rejected user: '#{user}' with password: '#{pass}': #{@result}")
+ return :fail
+ end
+ rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
@jlee-r7
jlee-r7 added a note Nov 20, 2012

All of these are ::Rex::ConnectionErrors, just rescue that instead of all these.

@kost
kost added a note Nov 23, 2012

Thanks! Fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@kost
kost commented Nov 23, 2012

Thanks on comments, I think I fixed all of them. Let me know if there's anything else I can do,

@wchen-r7

Code looks good to me. brandonprry, good to go?

@brandonprry

I am quite happy with the functionality.

@wchen-r7

Ok, cool. Thanks.

@brandonprry

AKA I think it is good to merge :)

@wchen-r7

Checked with msftidy, ruby 1.9 and 1.8... merging...

@wchen-r7 wchen-r7 merged commit ec3ce49 into rapid7:master Nov 24, 2012

1 check passed

Details default The Travis build passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.