Brute force attack / user enumeration - wordpress

Since last week I keep getting alerts about failed login attempts on my wordpress site.
The first couple of days the attacker used wrong username and subsequently was locked out after 3 attempts. I use the sucuri free and wp-security plugins. The later one has a login lockdown function.
My surprise came when after a couple of days the attacker found and used my username. I immediately changed it to a new username thinking that I would be safe. I also used most of the hardening options on both plugins. I specifically checked that the string
?author=n, does not provide any results on my website.
Regardless, today I got 3 more alerts that someone tried to login with this new username, which means I am locked out of my own site for 24 hours.
This leaves me wondering:
a) how is it possible for someone to find my username?
b) is there any other plugin like cerber security that prevents these exploits?
c) is there any rule I can add to htaccess? (although I believe that sucuri and wp-security have added several rules)
many thanks!

listing users
A user can list your usernames using :
yoursite.com?author=1
Where the ID is a user_id.
You can prevent it by detecting the author page, and redirect it with this for example (put in your theme function.php):
// Disable access to author page
function remove_author_pages_page() {
global $wp_query;
if ( is_author() ) {
$wp_query->set_404();
status_header(404);
wp_redirect(get_option('home'));
}
}
add_action( 'template_redirect', 'remove_author_pages_page' );
Find username from wp-admin
A attacker can find username by tring to login on wp-admin
If a attacker enter a good username, even with a wrong password, wordpress error message changes so attacker knows that the username exist
You can add this code to your function.php to prevent wp-admin wrong login error messages giving any pieces of information.
code:
function no_wordpress_errors() {
return '<strong>Error</strong>: check your logins';
}
add_filter( 'login_errors', 'no_wordpress_errors' );
prevent wp-admin bruteforce
This is a solution I really like:
It use the wp-fail2ban plugin
Your server needs the fail2ban package installed and configured
This package allows you to ban (from iptables) IP that fails to many time to connect SSH, or brute-force a port
the wp-fail2ban plugin gives you a custom fail2ban jail to add to your fail2ban jails (wp plugin have a complete documentation about it)
with both installed, fail2ban will ban IP that fails too much on WP-admin (on the IPtable level, so PHP is not even reached. Attacker, in the end, won't use much server resources as the server will block his IP. He cannot even reach PHP)
Some other plugin (like Wordfence) also provides some security, but as it reaches PHP attacker use much more resources. But it needs less technical knowledge to implement.

Related

How to pass parameters from Wordpress Contact Form 7 to an external server?

I have a login form created in Wordpress using Contact form 7. I'm tryig to pass parameters from this form to an external server. But it is not happening.
I am a designer, and not much of a programmer. I understand code(sometimes) but can not write it from the scratch.
I have designed a website for a client. This client has a "Flying Returns" like logistic membership system in which members get lots of perks in shipping etc. This system is on their own server. They want the users to log in to that system from this website.
So I have created a login form using Contact Form 7. I have set skip_mail: on; I have tried a few plugins login, but either they dont log into different servers or are expensive, or does not yield correct URL and hence does not log into the system. Therefore I have finally decided to make it happen using code.
Their programmer has given me following JS code that will take the parameters from this form and pass on to their system. IF the parameters are correct, then the user is logged into the system and taken to the member's dashboard page on their server (not my website/server), else it returns an error message, {"error":"Login Data Incorrect.."}
I have tried to put this code with in the contact form. Here is the code (i've hidden the actual IP address, sorry):
<script>
document.addEventListener( 'wpcf7submit', function( event ) {
alert( "Fire!" );
document.location.href="http://49.XXX.XXX.202:XXXX/glslink/servlet/GPLogin?password="+$('#password').val()+"&emailid="+$('#emailid').val();
}, false );
</script>
If I remove the document.location line, it shows the alert. But the above, in its entirety does nothing. If I use the URL, replace variables with actual values and paste it browser, it logs me into the system without a hitch.
I have tried quite a few different codes which I could find as possible solution on internet, this site including, but to no avail.
Please help me out. I want the email and password to be passed to this external server, if they are correct then the user should log in and see their dashboard there. Else if it gives the above mentioned error message, then I should be able to reset the form and give an error message to the user.

How to proxy per-request WordPress user authentication data to another server in the same domain?

I’m using WordPress as my frontend for user administration, handling registration, logins, authentication and logouts. Users register and login using WordPress.
The site has URLs served by a backend mod_perl server in the same domain.
When a user clicks a link that proxies to the backend server, I would like for the frontend server, the proxy, to pass the authenticated user’s name or login credentials to the backend server. The backend server will use those credentials to do authorization.
I can imagine several ways to do this.
Maybe the backend server reads the username from the WordPress
cookie. The Cookie HTTP Header is visible in the backend server
logs (I configured intentionally this as a debugging aid.) Is it
possible to do this, one server read a cookie written by another
server (in the same domain)?
The frontend WordPress server might write the authenticated username
into an environment variable which mod_rewrite would tack on to the
URL proxiing to the backend server. Maybe using a WordPress plugin,
but I’ve not found such.
WordPress SSO/OAuth might be possible, but my OS X El Capitan
development environment presents another layer of challenges for
that.
The frontend is Apache2.4, PHP 5.5.34, WordPress 4.5.3. Apache modules can be added and removed as DSOs. The backend is Apache 2.4, mod_perl 2.0.10, MySQL 5.7.
Both servers run in the same AWS instance running AWS Linux. (I’m beginning to think AWS Linux was the wrong choice for me, but that’s a whole nother thread.)
I have Apache, MySQL and Perl skills. PHP and Javascript I never learnt.
The simplest way (perhaps it's also the only practicable one) would be to use PHP because wordpress is a PHP application, which indeed is a problem for you. Nevertheless, I have a simple example for you:
PHP page on your wordpress site:
<?php
require('path/to/wp-blog-header.php');
if (is_user_logged_in()) {
$user = wp_get_current_user();
header("Location:backend.php?user=".$user);
exit();
} else {
echo "User is not logged in!";
};
?>
PHP page on your backend server:
<?php
if (isset($_GET['user'])) {
$user = $_GET['user'];
// do something with $user.
} else {
echo "No user passed!";
}
?>
This simply uses two of Wordpress' built-in functions. First the is_user_logged_in() function is used to determine whether a user is logged in. If the function returns true, the wp_get_current_user() function is called to pass the username to the backend server's php page using the GET method. Then the backend server validates the passed variable.
Please note that this simple procedure is illustrative only and is extremely unsafe!

How to keep Wordpress logged in permanently

I'm trying to use WordPress as a website CMS for a kiosk. Each kiosk needs a unique username therefore it must be logged in to WordPress.
I believe WordPress does not use Session ID's therefore how can I ensure the user is never logged out of the site even after X days of inactivity?
Thanks in advance.
How about just simply using the auth_cookie_expiration filter
add_filter('auth_cookie_expiration', function(){
return YEAR_IN_SECONDS * 2;
});
There seems to be mixed accepted answers. First, you should never modify the wordpress core code. Ever. Secondly, per the wordpress developer codex, the "auth_cookie_expiration" filter is what needs to be used here.
add_filter ( 'auth_cookie_expiration', 'wpdev_login_session' );
function wpdev_login_session( $expire ) { // Set login session limit in seconds
return YEAR_IN_SECONDS;
// return MONTH_IN_SECONDS;
// return DAY_IN_SECONDS;
// return HOUR_IN_SECONDS;
}
I've actually created a plugin to deal with this very issue. It uses the idea of persistent login to actually keep users logged into your wordpress website all the time, kind of link how Facebook does it.
Check it out, hope it helps!
WP Persistent Login
You can try configuring the session time for Wordpress. Unfortunately, Wordpress doesn't allow you to easily manipulated this.
You can try out this plugin: http://wordpress.org/extend/plugins/configure-login-timeout/
You can use the plugin "WP Login Timeout Settings" to achieve this. Under "Settings → Login timeout", it then allows you to configure the login timeout for both a normal login and one with the "Remember Me" box ticked.
That's just the same as what the "configure-login-timeout" plugin does, which was already recommended. Just that "WP Login Timeout Settings" seems to be a bit more actively maintained at the moment.

Wordpress auth library for Codeigniter (or other framework)

I'm looking to build a library for Codeigniter that communicates with the Wordpress database to provide functions such as login, logout and register. Logging in through the Codeigniter app should not make a difference compared to logging in through the Wordpress site. So I can switch between the two of them without having to login twice.
I'm not looking to "integrate Wordpress with Codeigniter" and whatever else people are asking about. I just want to use the Wordpress DB to authenticate users and then create the right cookies etc.
If anybody knows of any projects already existing that would be helpful to me as I embark on this I would like to hear about them.
This is an example of the integration that seems to need. It is not CI, but it is only a couple of functions and can serve as a starting point.
EDITED
Revisiting the issue, it seems to me that you ask as it is cumbersome because you have to rewrite things that WP does very well.
Either way, the names of the cookies consist of a prefix and a compile id of the site, it's just a md5 of the URL of the blog. Are defined in the file "wp-includes/default-constants.php".
The one you're interested in could be used like this:
//$wp_url like this: http://domain.com, Exactly as written in the configuration
$cookie= "wordpress_logged_in_".md5($wp_url);
The contents of this cookie will be something like: admin|7C1314493656|7Cdd41a2cd52acbaaf68868c850f094f9f
$cookie_content= explode("|",$this->input->cookie($cookie,true));
if(count($cookie_content)>0){
$user_name= $cookie_content[0];
}else{
//No user identified, do something...
}
Bonus Pack
While studying the WP code was writing a small library that does just that, using the WP login and access levels directly in CI. Available in bitbucket GPL2 licensed (as WP): CiWp-Auth.
WordPress uses MD5 to encrypt their password so you can just query the wp_users table with the username and the password after you MD5 it. The query would look something like this:
$credentials = array(
'user_login' => $this->input->post('username'),
'user_pass' => md5($this->input->post('password'))
);
$this->db->where($credentials);
$user = $this->db->get('wp_users');
That should return the user account info you are looking for in the $user var, then you can work with it just like any other authentication method.

Drupal: customizing user registration workflow for communicating with another webapp

I'm new to Drupal6 and spent long time searching how to implement the following feature without success: I use Drupal as front-end/doc board for a web-app. I want to mirror all user account creation, update and deletion on this web-app, i.e. send user name and password.
I started coding a little module implementing hook_user (http://api.drupal.org/api/function/hook_user/6), but I am still wondering on several question concerning this hook:
1) I can't find a doc concerning the $account fields, and thus don't know how to retrieve the user name and password.
2) The insert operation informs that "The user account is being added". Is that triggered when the user query an account or when his/her pending account creation has been approved?
3) User management on the 'slave' webapp is done through a URL interface. I only know the header("Location: http://webapp/users/add?user=martin&pwd=bla") PHP primitive, but I fear this will make a redirection, instead of just hiting the target page and continue code flow. Any suggestion?
Maybe some of you already programmed such a module, or would have links for more documentation?
Thanks in advance,
Martin
Taking a step back and looking at the big picture, you have several options.
Use OpenID (there's a core Drupal module for it) for both sites
Use LDAP (there's a really good Drupal contrib module for it)
Look at other modules offer user login sharing with other apps (such as http://drupal.org/project/phpbb or http://drupal.org/project/moodle or many others) for inspiration
Have your web app use Drupal's user table. This is relatively easy as the username is there in plaintext and the password is just MD5'ed (so no salts or anything to muddy up the waters).
Basically, hook_user is wrong. What you need to do is use hook_form_alter to change the '#validate' parameter of the login form. That way, the validate is passed to your function in your module where you are getting $form_values['username'] and $form_values['password']. You pass that on to your URL via curl. If it returns correctly, return nothing. If it doesn't return, use form_set_error and it will deny the login.
Good luck!
In order to just retrieve a response from a page, you can use drupal_http_request()
And a general security note, make sure you're authenticating and validating the requests between applications. Passing passwords in plain text via GET parameters over HTTP also makes me a little queasy, but I don't know your application set up.
Here is the final piece of code that works. Note that the password is retrieved md5ified, so the slave webapp must be able to do so as well:
function mirror_registration_user($op, &$edit, &$account, $category = NULL) {
$cmd = 'http://www.example.com/register?name='.$account->name.'&pass='.$account->pass;
if($op == 'insert'){
$cmd .= '&op=insert';
drupal_http_request( $cmd );
}
else if($op == 'delete'){
$cmd .= '&op=delete';
drupal_http_request( $cmd );
}
else if($op == 'after_update'){ // 'update' is a "before update event"
$cmd .= '&op=update';
drupal_http_request( $cmd );
}
}
Remark: in our case, registration requires admin approval. In this case, there's an 'update' event. The 'insert' event is triggered as soon as the user queries an account.
Informations for other newbies:
When trying to debug the code, one can echo $cmd to have the content of $cmd writen on top left of the following page.
If you write crapy php code and get a blank page when using the hook, you may add to Drupal/index.php the following calls: error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE); that allow having debug info.

Resources