wpscanteam / wpscan

WPScan WordPress security scanner. Written for security professionals and blog maintainers to test the security of their WordPress websites. Contact us via contact@wpscan.com
https://wpscan.com/wordpress-cli-scanner
Other
8.62k stars 1.27k forks source link

Bruteforcing via XMLRPC #837

Closed hydhyd closed 8 years ago

hydhyd commented 9 years ago

Hello there.

There's a lot of standalone tools for leveraging xmlrpc.php authentication brute-force attacks (https://blog.sucuri.net/2014/07/new-brute-force-attacks-exploiting-xmlrpc-in-wordpress.html et al).

Wouldn't it be fun to add this particular attack vector to wpscan, seeing as how it's basically a Swiss Army Knife towards all things Wordpress? The /wp-login.php is oftentimes blocked with a captcha or somesuch.

I don't know enough Ruby to actually contribute, just throwing it out there.

Thanks.

firefart commented 9 years ago

We implemented this method some time ago in metasploit, but it's still missing in wpscan. It would require a change to this line https://github.com/wpscanteam/wpscan/blob/master/lib/common/models/wp_user/brute_forcable.rb#L40 and changes to valid_password https://github.com/wpscanteam/wpscan/blob/master/lib/common/models/wp_user/brute_forcable.rb#L105

hydhyd commented 9 years ago

Thanks a bunch, there's actually auxiliary/scanner/http/wordpress_xmlrpc_login indeed.

Would that be a whole lot of trouble to actually merge the code into wpscan? I mean, both are Ruby scripts.

It's just that it would've been that much more convenient to just deal with wpscan alone, rather than firing up msfconsole.

I mean, one could argue that most of the wpscan functionality is already there in Metasploit, but then again it kinda defeats the purpose of having a separate wpscan.rb.

What I mean is sometimes you need to do a quick scan and you don't want to deal with Metasploit proper.

firefart commented 9 years ago

jeah it's on my todo list for wpscan. I think I also opened an issue for this some time ago

hydhyd commented 9 years ago

Thanks for considering the issue.

erwanlr commented 9 years ago

@FireFart Assuming that you want to brute force via the xmlrpc directly and not as a fallback when the usual wp-login.php method is blocked or whatever.

Such implementation should be dealt with a Strategy Pattern (https://en.wikipedia.org/wiki/Strategy_pattern).

However, even with that, there are way too many exceptions/scenario that can occur. for example multiple xmlrpc method calls (e.g wp.getUsersBlogs etc) can be used to brute force, which one to select ? what if this method is blocked ? do we allow the user to supply one (also we will need to list the available ones) or automatically switch to another ?

On paper that looks good, but the complexity of such implementation is not an easy one. Especially as people will request (already did for the current brute force method) support for resuming/session saving and further throttle which are both not possible.

We discussed the brute forcing issues/features internally some time ago and decided to only have basic features. For more advance stuff, like save the session, use huge word-list etc, a proper brute forcing tool (like Hydra / Medusa) should be used.

If you really want a stand alone ruby script to brute force via the XMLRPC, there is this one I wrote some time ago https://gist.github.com/erwanlr/2ea10082148887ac1ae8

hydhyd commented 9 years ago

As luck would have it, I already came upon your script earlier this very evening:

root@foobar:~# ./wp_xmlrpc_brute_force.rb http://127.0.0.1 -u admin -P /usr/share/john/password.lst Found: admin / 12345

Needless to say, that wasn't a good guess. Again, I'm very much ignorant when it comes to Ruby, and probably a lot of things beyond Ruby, but that just didn't work as reliably as wpscan.rb usually does.

Speaking of wpscan, I don't feel it should be a fallback, rather a new option altogether. That implies more implicit control over what the tool actually does, hence I don't feel that the strategy pattern applies.

Stick with wp.getUserBlogs. It works. No need to embed some smart-ass Wizard-style code. If it's blocked, it's blocked. Just yet another attack vector.

Now I'm completely in the dark as to the mechanics of resuming cancelled sessions, but I can see how it could mess up the internal logic when there's more than one way to bruteforce.

Would you guys think of something? The tool itself is invaluable, even more so with the centralized vulnerability information hub that you set up.

However, I believe that leveraging xmlrpc.php is crucial towards being THE standard towards WP exploitation.

ethicalhack3r commented 9 years ago

I agree with @hydhyd. I think WPScan should support this kind of brute forcing. Probably even as a preference (default) over wp-login.php but have it also optional.

hydhyd commented 9 years ago

Now if only someone would have built the same database for Joomla.

All the scanners out there are very much out of their element and probably only applicable back in the '98.

I realize that's not the actually an issue with WPscan, rather with a fork of that. Seeing as how Joomla is somehow popular and the plugins are being deployed by people even more clueless than me, we need an up to date Joomla scanner.

There's joomscan but it hasn't been updated since the Y2K. Although it has its fair share of vulnerable plugins and themes.

Looking at wpscan, I can't help but seeing how it could be applied to Joomla. Obviously, that would take a lot of research as per the actual bugs, but the code, the options, would generally stay the same.

I realize that won't happen overnight, but you're pretty good at collecting WP bugs. Nothing much's stopping you from doing the same for Joomla. Or Drupal, for that matter.

Go beyond. Or so they say.

erwanlr commented 9 years ago

(I've updated https://gist.github.com/erwanlr/2ea10082148887ac1ae8)

hydhyd commented 9 years ago

Might be just me.

root@foobar:~# mysql -uroot -proot -hlocalhost wordpress -e 'select now()' +---------------------+ | now() | +---------------------+ | 2015-06-27 00:36:38 | +---------------------+ root@foobar:~# ruby ./wp_xmlrpc_brute_force.rb -p root -u root http://localhost/wordpress/xmlrpc.php root@foobar:~# ruby ./wp_xmlrpc_brute_force.rb -p root -u rootXXXX http://localhost/wordpress/xmlrpc.php

Both return true (echo $?) which is probably a bug.

root@foobar:~# ruby -v Ruby 2.2.0p0 (2014-12-25 revision 49005) [i686-linux]

root@foobar:~# curl http://localhost/wordpress/xmlrpc.php XML-RPC server accepts POST requests only.

There's probably a Ruby verbose mode as in /bin/sh -x, but it's 1AM and it's not readily available. To reiterate, I know shit all about Ruby.

Probably my mistake all along, still I can't get it to work.

erwanlr commented 9 years ago

if the root:root is not a valid combination, yep it's normal that you don't have any output.

You can add the -v option ruby ./wp_xmlrpc_brute_force.rb -p root -u root -v http://localhost/wordpress/xmlrpc.php to see the combinations tested.

I've updated the script again to add a 'Starting Brute Forcing' and 'Done' messages.

In you use Kali, have a look at https://gist.github.com/erwanlr/a7a7fd0958b2bdee0aab :)

hydhyd commented 9 years ago

Thing is, root:root is a valid combination, as shown above with the mysql client.

root@foobar:~# ./wp_xmlrpc_brute_force.rb -v -u root -p root http://localhost/wordpress/xmlrpc.php Trying root / root root@foobar:~# ./wp_xmlrpc_brute_force.rb -v -u root -p NOTAVALIDPASSWORD http://localhost/wordpress/xmlrpc.php Trying root / NOTAVALIDPASSWORD

That's with the older version. I've updated, yet still no dice:

root@foobar:~# ruby ./wp_xmlrpc_brute_force-new.rb -v -u root -p root http://localhost/wordpress/xmlrpc.php Starting Brute Forcing Trying root / root Done. root@foobar:~# ruby ./wp_xmlrpc_brute_force-new.rb -v -u root -p rootXXXX http://localhost/wordpress/xmlrpc.php Starting Brute Forcing Trying root / rootXXXX Done.

Do appreciate the hydra trick, thanks.

erwanlr commented 9 years ago

Seems like you have no idea of what you are doing :o

This script brute force the accounts created on the blog, not the MySQL or server ones.

hydhyd commented 9 years ago

Okay, I'm officially an idiot. I've been trying to apply mysql credentials to the Wordpress installation.

In my defense, I've had a bit of a lot of drinking last night and am still recuperating.

My apologies, really.

Will test with a valid user later today. Oh my.

hydhyd commented 9 years ago

root@foobar:~# ruby ./wp_xmlrpc_brute_force-new.rb -v -u root -p dumbass http://localhost/wordpress/xmlrpc.php Starting Brute Forcing Trying root / dumbass Found: root / dumbass Done. root@foobar:~# ruby ./wp_xmlrpc_brute_force-new.rb -v -u root -p poaksdfp http://localhost/wordpress/xmlrpc.php Starting Brute Forcing Trying root / poaksdfp Done.

It works!

hydhyd commented 9 years ago

Still, that earlier idea about merging wp_xmlrpc_brute_force into wpscan wasn't half bad, was it.

ethicalhack3r commented 9 years ago

New research shows that you can try multiple login attempts with just 1 HTTP request by using XML-RPC https://blog.sucuri.net/2015/10/brute-force-amplification-attacks-against-wordpress-xmlrpc.html

Would make brute forcing much faster

firefart commented 9 years ago

Wow the multicall method looks great! will have a look at it :)

ethicalhack3r commented 9 years ago

Think this is worth implementing into WPScan v2? If so, should it be along side the wp-login.php brute forcing? Let the user choose what they want to brute force and default to one?

firefart commented 9 years ago

https://github.com/zendoctor/wpbrute-rpc

ethicalhack3r commented 8 years ago

Please use the first issue created for this #407