whip1ash

初窥Wordpress中文章密码保护功能

2017-11-14

Introduction

最近冥冥之中总跟wordpress进行接触.那天在在一个blog里看到一篇密码保护的文章,开始还以为是个题目,后来发现是Wordpress自带的功能,就大概看了一眼,发现这个密码保护功能还是蛮有意思的.

Content

刚开始一抓包,发现这个form表单发给wp-login.php?action=postpass

Jietu20171114-152829

返回回来一个302
wp-loginaction=postpass做了如下操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
switch ($action) {

case 'postpass' :
if ( ! array_key_exists( 'post_password', $_POST ) ) {
wp_safe_redirect( wp_get_referer() );
exit();
}

require_once ABSPATH . WPINC . '/class-phpass.php';
$hasher = new PasswordHash( 8, true );

/**
* Filters the life span of the post password cookie.
*
* By default, the cookie expires 10 days from creation. To turn this
* into a session cookie, return 0.
*
* @since 3.7.0
*
* @param int $expires The expiry time, as passed to setcookie().
*/
$expire = apply_filters( 'post_password_expires', time() + 10 * DAY_IN_SECONDS );
$referer = wp_get_referer();
if ( $referer ) {
$secure = ( 'https' === parse_url( $referer, PHP_URL_SCHEME ) );
} else {
$secure = false;
}
setcookie( 'wp-postpass_' . COOKIEHASH, $hasher->HashPassword( wp_unslash( $_POST['post_password'] ) ), $expire, COOKIEPATH, COOKIE_DOMAIN, $secure );

wp_safe_redirect( wp_get_referer() );

exit();

看完这很疑惑啊,wordpress没有对post过来的密码做任何的验证啊,只不过把它unslash了一下,做了hash写到cookie里了!
后来仔细一想,wordpress这里返回一个302,只要wordpress检验cookie是否有效是不是就可以判断用户输入的密码是否正确的.

Wordpress在这里接受密码后计算hash后写到cookie里其实是非常高明的一手

  1. 这里输入密码没有验证码,我在这里第一反应是可以爆破,结果发现不过结果正确与否,返回的302除了set-cookiewp-postpass_COOKIEHASHwp-postpass_COOKIEHASHvalue不同外,其他内容都一样,所以基本无法爆破.
  2. 我们输入的参数不带到sql语句中进行查询,有效抵抗sql注入
  3. 只要cookie生成的算法足够强大,这里基本不可能碰撞出来,经过验证,Wordpress的这个算法真的很强大…….

Wordpress hook机制

我在这里最头疼的问题就是,Wordpress在返回一个带有 set-cookie 的302后就exit();了,又因为我的referrer是根路径,所以在localhost/index.php进行加载(渲染)的时候一定对cookie进行了某种验证.
由于Wordpress加载了大量的文件,定位起来相当的麻烦,在其中加载了大量的do_action(),apply_filters(),从源码中可以看出来这是在调用用户自定义函数,在网上搜了一下,对这个机制有比较模糊的理解.

Wordpress定义了一系列的事件(Event)/钩子(Hook),当程序执行到某一事件/钩子的时触发这一事件/钩子的一系列函数.

1
2
add_action(Event/Hook,functon)
do_action(Event/Hook)

关于wordpress的hook机制就在这里不再赘述了,但确实在这里绕了很久.刚开始从字面上理解do_action()以为这个里面的event是用户定义的函数,通过全局搜索怎么也搜不出来,简直是要崩溃了.后来发现add_action()才是函数的执行.

PasswordHash::CheckPassword()

通过查看源代码,发现wp-login.php中,通过HashPassword()对输入进行加密,与之对应的CheckPassword()对hash进行认证,所以通过给CheckPassword()打断点来确定根路径加载的调用栈,在这里强推phpstorm,可以清晰的查看调用栈.

Jietu20171115-224839
一目了然了

Summry

等什么时候用到Wordpress的hook机制的时候再详细研究一下,感觉这个hook机制做的挺巧妙的.

扫描二维码,分享此文章