Closed KINGSABRI closed 8 years ago
A new pull request has been created due creating PR from a new branch :)
The original pull request is #6209
Is there any observations here to fix?
@wchen-r7 Thanks for make things clear to me here
@KINGSABRI I think one of the things to do here is to convert this module to a LoginScanner. Like what wordpress_xmlrpc_login does, but you can replace that completely because yours is smarter and faster. I personally don't see the point of having both.
We have some wiki docs about how to write a LoginScanner module. For you, you can start with step 3 in this wiki: https://github.com/rapid7/metasploit-framework/wiki/How-to-write-a-HTTP-LoginScanner-Module
Other docs you can read: https://github.com/rapid7/metasploit-framework/wiki/Creating-Metasploit-Framework-LoginScanners
And then of course, you can use wordpress_xmlrpc_login as a reference: https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/scanner/http/wordpress_xmlrpc_login.rb
You will see that the auxiliary module part is just passing arguments and parsing results. The actual login code is in lib/metasploit/framework/login_scanner/wordpress_rpc.rb.
Note that the Metasploit::Framework::LoginScanner::WordpressRPC class is on top of Metasploit::Framework::LoginScanner::HTTP, so you probably wanna look at the HTTP class too to see what methods you can use: https://github.com/rapid7/metasploit-framework/blob/master/lib/metasploit/framework/login_scanner/http.rb
Hope this helps.
One suggestion related to @wchen-r7's comment -- I agree on the lack of a need for two separate modules that do nearly the same thing, but I think it would be nice to have the option to have the slower option available should your situation require it. I only looked at the code briefly, but I could see this being implemented by offering a CHUNKSIZE
option which when set to 0 or anything about that ~1500-1700 threshold, you send as many logins as you can at once, and with any value in between, you try that many. That way, a user could set CHUNKSIZE 1
and get the same low and slow but easily detectable attack. My $0.02.
Yeah, adjustable speed would be a nice thing to have :+1:
That's really encouraging!.
@wchen-r7 I tried to build it as LoginScanner
as I saw in wordpress_xmlrpc_login
module put I really got confused since I need the user and password lists as arrays to play around them but it wasn't clear how to do so through Metasploit::Framework::CredentialCollection
and Metasploit::Framework::LoginScanner::WordpressRPC
so I missed some flixability there (because of lake of my knowledge of these modules)
That's why I didn't do it that way, I need to take control of arrays, requests and responses
@jhart-r7 I like your idea, I'll add CHUNKSIZE
as user configurable right now, it's more elegant too
Thanks guys for your support!
@KINGSABRI Yeah I understand. I will try to help you. I will try to submit a pull request to you sometime this or next week. If you don't wanna wait, feel free to ask me anything and we will try to help you get there. You are doing great so far :-)
I'll try to understand that modules more and see more examples then I'll feed you back. Hopefully I can make it LoginScanner with elegant code.
In the meantime, should be we keep this issue open (and keep pushing to it) or what do you advice?
@wchen-r7 appreciated man!
You're welcome.
Yeah we can keep the PR open :-) I'll add the Delayed label so people know we are still working on it :-)
I would love to test this one on some of my targets :P
@FireFart I would love to hear a w00t from you using it! ;)
In a legal way of course ;P
Sorry for the delay. I am still working on it.... need to change the way loginscanner gives me creds to match what this module is doing...
Ohh, I'm sorry for delay @wchen-r7 , I didn't notice the PR :(
ok I'm getting the following error
msf auxiliary(wordpress_xmlrpc_login) > run
[*] 172.17.0.3:80 WORDPRESS_XMLRPC - status!
[*] Target 172.17.0.3:80 is running Wordpress
[*] XMLRPC enabled, Hello message received!
[*] 172.17.0.3:80 - Starting XML-RPC login sweep...
[-] Auxiliary failed: NoMethodError undefined method `compile' for #<Rex::Proto::Http::Response:0x005646293d5228>
Did you mean? completed?
[-] Call stack:
[-] /usr/local/lib/ruby/gems/2.3.0/gems/activesupport-4.0.13/lib/active_support/callbacks.rb:369:in `__define_callbacks'
[-] /usr/local/lib/ruby/gems/2.3.0/gems/activesupport-4.0.13/lib/active_support/callbacks.rb:79:in `run_callbacks'
[-] /usr/local/lib/ruby/gems/2.3.0/gems/activemodel-4.0.13/lib/active_model/validations.rb:373:in `run_validations!'
[-] /usr/local/lib/ruby/gems/2.3.0/gems/activemodel-4.0.13/lib/active_model/validations.rb:314:in `valid?'
[-] /home/KING/Code/MSF/metasploit-framework/lib/metasploit/framework/login_scanner/base.rb:248:in `valid!'
[-] /home/KING/Code/MSF/metasploit-framework/lib/metasploit/framework/login_scanner/base.rb:194:in `scan!'
[-] /home/KING/Code/MSF/metasploit-framework/modules/auxiliary/scanner/http/wordpress_xmlrpc_login.rb:107:in `run_host'
[-] /home/KING/Code/MSF/metasploit-framework/lib/msf/core/auxiliary/scanner.rb:116:in `block (2 levels) in run'
[-] /home/KING/Code/MSF/metasploit-framework/lib/msf/core/thread_manager.rb:100:in `block in spawn'
[*] Auxiliary module execution completed
msf auxiliary(wordpress_xmlrpc_login) >
@KINGSABRI Hmmm that is interesting. I have actually never seen that error before. It looks like the error occurs in the valid!
call... not sure why. I will look into it. Thanks!
@KINGSABRI I am not able to reproduce this problem:
msf auxiliary(wordpress_xmlrpc_login) > run
[*] 192.168.1.123:80:/wordpress/xmlrpc.php - Sending Hello...
[+] XMLRPC enabled, Hello message received!
[*] 192.168.1.123:80 - Starting XML-RPC login sweep...
[+] 192.168.1.123:80 WORDPRESS_XMLRPC - Success: 'admin:goodpassword'
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(wordpress_xmlrpc_login) >
Travis keeps failing too, but I don't actually get any of that locally:
Finished in 2 minutes 25.8 seconds (files took 9.35 seconds to load)
11057 examples, 0 failures, 34 pending
@KINGSABRI could you please do this?
$ git checkout upstream-master
$ git pull
$ git checkout wordpress_xmlrpc_massive_bruteforce
$ git checkout -b test_wordpress
$ git merge upstream-master
Note: You might not have a "upstream-master" branch, but this is supposed to be your master branch that is sync'd with the latest commit from metasploit-framework.
And then test your Wordpress login module again? Do you still get that exception? Thanks.
It actually fails locally exactly as it does for him. I pulled latest upstream master, branched, merged in his branch, then began working on it and received the error.
msf auxiliary(wordpress_xmlrpc_login) > run
[*] 192.168.0.19:80 WORDPRESS_XMLRPC - status!
[*] Target 192.168.0.19:80 is running Wordpress
[*] XMLRPC enabled, Hello message received!
[*] 192.168.0.19:80 - Starting XML-RPC login sweep...
[-] Auxiliary failed: NoMethodError undefined method `compile' for #<Rex::Proto::Http::Response:0x007fabd10f4b30>
[-] Call stack:
[-] /Users/bperry/.rvm/gems/ruby-2.1.6/gems/activesupport-4.0.13/lib/active_support/callbacks.rb:369:in `__define_callbacks'
[-] /Users/bperry/.rvm/gems/ruby-2.1.6/gems/activesupport-4.0.13/lib/active_support/callbacks.rb:79:in `run_callbacks'
[-] /Users/bperry/.rvm/gems/ruby-2.1.6/gems/activemodel-4.0.13/lib/active_model/validations.rb:373:in `run_validations!'
[-] /Users/bperry/.rvm/gems/ruby-2.1.6/gems/activemodel-4.0.13/lib/active_model/validations.rb:314:in `valid?'
[-] /Users/bperry/projects/metasploit-framework/lib/metasploit/framework/login_scanner/base.rb:248:in `valid!'
[-] /Users/bperry/projects/metasploit-framework/lib/metasploit/framework/login_scanner/base.rb:194:in `scan!'
[-] /Users/bperry/projects/metasploit-framework/modules/auxiliary/scanner/http/wordpress_xmlrpc_login.rb:107:in `run_host'
[-] /Users/bperry/projects/metasploit-framework/lib/msf/core/auxiliary/scanner.rb:116:in `block (2 levels) in run'
[-] /Users/bperry/projects/metasploit-framework/lib/msf/core/thread_manager.rb:100:in `call'
[-] /Users/bperry/projects/metasploit-framework/lib/msf/core/thread_manager.rb:100:in `block in spawn'
[*] Auxiliary module execution completed
msf auxiliary(wordpress_xmlrpc_login) >
@brandonprry Did you do: rake spec
?
I did not, let me do that.
rake spec:
Brandons-iMac:metasploit-framework bperry$ rake spec
rake aborted!
TypeError: no implicit conversion of nil into String
/Users/bperry/.rvm/gems/ruby-2.1.6/gems/railties-4.0.13/lib/rails/paths.rb:189:in `expand_path'
/Users/bperry/.rvm/gems/ruby-2.1.6/gems/railties-4.0.13/lib/rails/paths.rb:189:in `block in expanded'
/Users/bperry/.rvm/gems/ruby-2.1.6/gems/railties-4.0.13/lib/rails/paths.rb:163:in `each'
/Users/bperry/.rvm/gems/ruby-2.1.6/gems/railties-4.0.13/lib/rails/paths.rb:163:in `each'
/Users/bperry/.rvm/gems/ruby-2.1.6/gems/railties-4.0.13/lib/rails/paths.rb:188:in `expanded'
/Users/bperry/.rvm/gems/ruby-2.1.6/gems/railties-4.0.13/lib/rails/paths.rb:139:in `first'
/Users/bperry/projects/metasploit-framework/lib/metasploit/framework/require.rb:52:in `optionally_active_record_railtie'
/Users/bperry/projects/metasploit-framework/Rakefile:10:in `<top (required)>'
/Users/bperry/.rvm/gems/ruby-2.1.6/bin/ruby_executable_hooks:15:in `eval'
/Users/bperry/.rvm/gems/ruby-2.1.6/bin/ruby_executable_hooks:15:in `<main>'
(See full trace by running task with --trace)
Brandons-iMac:metasploit-framework bperry$
I can hop on IRC if you want to try and dig into this, am available to help figure it out
My local might be messed up. Checking out upstream master results in the same spec failure. Looking to fix.
@brandonprry the rspec error is due to a missing database connection. You need a working db connection for rspec to work (I once opened an issue for this, but it looks like it's a requirement now)
Bah, I see. OK.
I wiped my framework directory, recloned, branched, then merged in kingsabri's code, can reproduce still.
For me, it only breaks when it has successfully found an XMLRPC instance.
msf auxiliary(wordpress_xmlrpc_login) > run
[*] 192.168.0.0:80 WORDPRESS_XMLRPC - status!
[-] 192.168.0.0:80:80/wordpress does not appear to be running Wordpress or you got blocked! (Do Manual Check)
[-] XMLRPC is not enabled! Aborting
[*] 192.168.0.1:80 WORDPRESS_XMLRPC - status!
[-] 192.168.0.1:80:80/wordpress does not appear to be running Wordpress or you got blocked! (Do Manual Check)
[-] XMLRPC is not enabled! Aborting
[*] 192.168.0.2:80 WORDPRESS_XMLRPC - status!
[-] 192.168.0.2:80:80/wordpress does not appear to be running Wordpress or you got blocked! (Do Manual Check)
[-] XMLRPC is not enabled! Aborting
[ ... SNIP ... ]
[*] 192.168.0.18:80 WORDPRESS_XMLRPC - status!
[-] 192.168.0.18:80:80/wordpress does not appear to be running Wordpress or you got blocked! (Do Manual Check)
[-] XMLRPC is not enabled! Aborting
[*] 192.168.0.19:80 WORDPRESS_XMLRPC - status!
[*] Target 192.168.0.19:80 is running Wordpress
[*] XMLRPC enabled, Hello message received!
[*] 192.168.0.19:80 - Starting XML-RPC login sweep...
[-] Auxiliary failed: NoMethodError undefined method `compile' for #<Rex::Proto::Http::Response:0x007feb30ed4e00>
[-] Call stack:
[-] /Users/bperry/.rvm/gems/ruby-2.1.6/gems/activesupport-4.0.13/lib/active_support/callbacks.rb:369:in `__define_callbacks'
[-] /Users/bperry/.rvm/gems/ruby-2.1.6/gems/activesupport-4.0.13/lib/active_support/callbacks.rb:79:in `run_callbacks'
[-] /Users/bperry/.rvm/gems/ruby-2.1.6/gems/activemodel-4.0.13/lib/active_model/validations.rb:373:in `run_validations!'
[-] /Users/bperry/.rvm/gems/ruby-2.1.6/gems/activemodel-4.0.13/lib/active_model/validations.rb:314:in `valid?'
[-] /Users/bperry/projects/metasploit-framework/lib/metasploit/framework/login_scanner/base.rb:248:in `valid!'
[-] /Users/bperry/projects/metasploit-framework/lib/metasploit/framework/login_scanner/base.rb:194:in `scan!'
[-] /Users/bperry/projects/metasploit-framework/modules/auxiliary/scanner/http/wordpress_xmlrpc_login.rb:107:in `run_host'
[-] /Users/bperry/projects/metasploit-framework/lib/msf/core/auxiliary/scanner.rb:116:in `block (2 levels) in run'
[-] /Users/bperry/projects/metasploit-framework/lib/msf/core/thread_manager.rb:100:in `call'
[-] /Users/bperry/projects/metasploit-framework/lib/msf/core/thread_manager.rb:100:in `block in spawn'
[*] Auxiliary module execution completed
msf auxiliary(wordpress_xmlrpc_login) >
Same as @brandonprry error here
msf auxiliary(wordpress_xmlrpc_login) > run
[*] 172.17.0.3:80 WORDPRESS_XMLRPC - status!
[*] Target 172.17.0.3:80 is running Wordpress
[*] XMLRPC enabled, Hello message received!
[*] 172.17.0.3:80 - Starting XML-RPC login sweep...
[-] Auxiliary failed: NoMethodError undefined method `compile' for #<Rex::Proto::Http::Response:0x007feaa58fa8f8>
Did you mean? completed?
[-] Call stack:
[-] /usr/local/lib/ruby/gems/2.3.0/gems/activesupport-4.0.13/lib/active_support/callbacks.rb:369:in `__define_callbacks'
[-] /usr/local/lib/ruby/gems/2.3.0/gems/activesupport-4.0.13/lib/active_support/callbacks.rb:79:in `run_callbacks'
[-] /usr/local/lib/ruby/gems/2.3.0/gems/activemodel-4.0.13/lib/active_model/validations.rb:373:in `run_validations!'
[-] /usr/local/lib/ruby/gems/2.3.0/gems/activemodel-4.0.13/lib/active_model/validations.rb:314:in `valid?'
[-] /home/KING/Code/MSF/metasploit-framework/lib/metasploit/framework/login_scanner/base.rb:248:in `valid!'
[-] /home/KING/Code/MSF/metasploit-framework/lib/metasploit/framework/login_scanner/base.rb:194:in `scan!'
[-] /home/KING/Code/MSF/metasploit-framework/modules/auxiliary/scanner/http/wordpress_xmlrpc_login.rb:107:in `run_host'
[-] /home/KING/Code/MSF/metasploit-framework/lib/msf/core/auxiliary/scanner.rb:116:in `block (2 levels) in run'
[-] /home/KING/Code/MSF/metasploit-framework/lib/msf/core/thread_manager.rb:100:in `block in spawn'
[*] Auxiliary module execution completed
Thanks!
@brandonprry For testing purposes, did you merge from the latest master to your wordpress branch?
Yes, I merged latest master into my formed master before branching to merge in kingsabri's code.
The commit I have before merging in kingsabri's code is:
$ git log | head -n30
commit a03017957717ba97576fd26c0db55cac3e51875c
Author: Metasploit <metasploit@rapid7.com>
Date: Fri Jan 15 15:17:13 2016 -0800
Bump version of framework to 4.11.8
@brandonprry @wchen-r7 I created a PR for the rspec issue so it's more clear https://github.com/rapid7/metasploit-framework/pull/6484.
The error looks like we are passing a res
instead of a res.body
somewhere in the code
@brandonprry @KINGSABRI I am finally seeing this error now... ok looking into it.
In testing this, it looks like this was partially mitigated between 4.3.2 and 4.4.1.
In 4.4.1, if the first command you specify has invalid credentials, even if the second command has correct creds, it will report an authentication failure.
In 4.3.2, I do not see this behaviour and the authentication is performed as expected across each method sent in the system.multicall request.
Just FYI for testing. I would love to see someone confirm this.
If I remove valid!
then it works fine...... but it shouldn't be removed :-/
Well guys, I am able to tell the problem is caused by my bad code in Metasploit::Framework::LoginScanner::WordpressRPC... sorry about that, I will try to figure out and fix it.
So @KINGSABRI, expect a patch from me... hopefully soon.
Hi @KINGSABRI, I have submitted another PR to your branch, hopefully that solves the problem: https://github.com/KINGSABRI/metasploit-framework/pull/2
Thanks @wchen-r7 it works very well!, however, the script doesn't iterate over all password list, it takes the very first password only. As you can see below, STOP_ON_SUCCESS
is false
msf auxiliary(wordpress_xmlrpc_login) > show options
Module options (auxiliary/scanner/http/wordpress_xmlrpc_login):
Name Current Setting Required Description
---- --------------- -------- -----------
BLOCKEDWAIT 6 yes Time(minutes) to wait if got blocked
BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5
CHUNKSIZE 1500 yes Number of passwords need to be sent per request. (1700 is the max)
DB_ALL_CREDS false no Try each user/password couple stored in the current database
DB_ALL_PASS false no Add all passwords in the current database to the list
DB_ALL_USERS false no Add all users in the current database to the list
PASS_FILE /home/KING/Code/MSF/metasploit-framework/data/wordlists/http_default_pass.txt no File containing passwords, one per line
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 172.17.0.3 yes The target address range or CIDR identifier
RPORT 80 yes The target port
STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host
TARGETURI / yes The base path to the wordpress application
THREADS 1 yes The number of concurrent threads
USERNAME no A specific username to authenticate as
USER_FILE /home/KING/Code/MSF/metasploit-framework/data/wordlists/http_default_users.txt no File containing usernames, one per line
VERBOSE true yes Whether to print output for all attempts
VHOST no HTTP server virtual host
msf auxiliary(wordpress_xmlrpc_login) > run
[*] 172.17.0.3:80 WORDPRESS_XMLRPC - status!
[*] Target 172.17.0.3:80 is running Wordpress, XMLRPC is enabled!
[*] 172.17.0.3:80 - Starting XML-RPC login sweep...
[+] 172.17.0.3:80 WORDPRESS_XMLRPC - SUCCESSFUL: admin:admin
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(wordpress_xmlrpc_login) >
Ok, that's really confusing ;/
I've a some users on my docker wrodpress
admin, root, system, user
I'm really confused
if the first user is correct and the correct password is the first password, it finds the password and go to other users
Yes, this is the expected behavior. Normally each account should only have one password, so even though you set STOP_ON_SUCCESS to false, once that password is found, the account will not be tried again.
if the other users have the same password (the first password), it finds i, if not the first password, it doesn't find it!
hmmmm..... I will have to try this in a bit.
if the first user's password is not the first password, the script doesn't find his password and the other users as well
So in this test, I have 4 accounts. The first one is correct, the other 3 are not:
And then I put the correct password for the first account in the middle of the password list:
And the module is able to find the correct password for that user:
Could you please double check this scenario? Thanks!
please try to bruteforce more than one user
and it works for you but it didn't for me My case is
If the user exists and the password is not at the top of the password list, the script can't find the password
Note: I'm using the default msf lists and I've admin:password
credentials and the password
word is the second password in the list and it fails to get it
something missing in the iteration :(
Like I said, the default XMLRPC behaviour has been mitigated in 4.4.1. The behaviour kingsabri is describing is exactly this mitigation. It is not a problem with the code or with Metasploit.
Download 4.3.2, set up the same users, then run the bruteforce module again and you will see that all of your users, regardless of where they are in the XML, will be able to have the username/password bruteforced.
Should there be a version check or some sort to prevent the module from running against Wordpress with that mitigation? It seems to make bruteforcing difficult to a point it's not so effective?
Right, the mitigation essentially neuters any way to use the system.multicall to be useful for massive bruteforcing, you can only test a single username/password pair with it, which doesn't buy you much.
I think a version check is likely a good idea. Should be easy enough, right @FireFart?
That being said, I don't know exactly when this mitigation was introduced.
@brandonprry that's sad I'll try to find an easy way to install an older version on docker since I'm using the official which install the latest version yet
@KINGSABRI Another quick PR for you for the version check: https://github.com/KINGSABRI/metasploit-framework/pull/3
Great, it's working fine now
Thank you! I will continue improving this. It looks like I still need to make sure the options are taken care of, and rspec. I will try to send another PR in a day or two :-)
Enhanced password
method for reading huge password, making it lazy
speeds it up to 2.97x times faster for a 1.2G password file
:+1:
@KINGSABRI Quick question for you. There are other datastore options that are used as password sources, such as: PASSWORD, USERPASS_FILE, USER_AS_PASS, DB_ALL_CREDS, and DB_ALL_PASS... do you actually want to skip supporting them and only allow PASS_FILE, or you think we should do those too?