WordPress投稿パスワードの期限を設定

functions.phpに以下を追記。

0の部分に秒数を指定する。0の場合、ブラウザを閉じた時点でクッキーがクリアされるため、ブラウザを再度立ち上げるとフォームが出現する。

function login_form_postpass_time() {
require_once ABSPATH . 'wp-includes/class-phpass.php';
$hasher = new PasswordHash( 8, true );
setcookie( 'wp-postpass_' . COOKIEHASH, $hasher->HashPassword( wp_unslash( $_POST['post_password'] ) ), 0, COOKIEPATH );
wp_safe_redirect( wp_get_referer() );
exit();
}
add_action( 'login_form_postpass', 'login_form_postpass_time' );

WordPress uploads/のファイルを直リンク禁止にする

以下の内容で.htaccessを作成。”https?://example\.com/”の部分は自分のドメインに置換。拡張子はお好みで。wp-content/uploads/に放り込む。

<Files ~ "\.(gif|png|jpg|pdf|jpeg)$">
SetEnvIf Referer "https?://example\.com/" allow_ref
order deny,allow
deny from all
allow from env=allow_ref
</Files>

WordPress TinyMCEのビジュアルとテキストのデフォルトを設定

HTTP2を使用している一部サーバーでTinyMCE AdvancedでGutenbergを無効化して使用している環境において、ビジュアルモードとテキストモードの切り替えが保存されないという症状を確認しました。

根本的な修正方法は分かりませんでしたが、投稿タイプごとにデフォルトのモードを設定すれば解決する問題でした。

functions.phpに以下を追記すると、固定ページとMW WP Formではテキストモードがデフォルト、他の投稿タイプではTinyMCEがデフォルトになります。

function change_editor_default( $editor ) {
if ( get_current_screen()->post_type == 'page' || get_current_screen()->post_type == 'mw-wp-form' ) {
$editor = 'html';
} else {
$editor = 'tinymce';
}
return $editor;
}
add_filter( 'wp_default_editor', 'change_editor_default' );

phpのアップロードサイズを大きくする

php.iniを編集する方法

以下の数値を大きく設定する。
upload_max_filesize = 20M
post_max_size = 20M

もし次の項目が上記2つの数値より少なく設定されていたら上げておく。
memory_limit = 128M

.htaccessを編集する方法

許可されていれば.htaccessでも設定可能。

php_value upload_max_filesize 20M
php_value post_max_size 20M
php_value memory_limit 128M

Windows10のhostsファイルを編集する方法

コマンドプロンプトを右クリックで「管理者として実行」。

notepad C:\Windows\System32\drivers\etc\hosts
上記コマンドでメモ帳でhostsを開く

IPアドレス ドメイン名」で名前とIPアドレスの対応を指定する。ファイルを保存したらWindowsを再起動で反映させることを忘れずに。

nslookupではhostsファイルを参照しないため、確認の際はpingを使用する。
hosts書き換え後は、次のようなサイトで書き変わる前のIPアドレスを客観的に確認することができる。
https://www.cman.jp/network/support/nslookup.html

arp-scanやnmapでネットワークの構成を把握する

自分のIPとネットワークセグメントを確認

問題解決のために知らないネットワークに繋げた際にまずやることはネットワークマッピング。ネットワークに接続し、DHCPによって自動的に設定が行われた場合、自分のIPアドレスとデフォルトゲートウェイを知っておく。

ip addr
ip route

IPアドレスは192.168.1.2/24でデフォルトゲートウェイは192.168.1.1であることが分かる。

同じネットワークに居るホストを列挙

arp-scanで列挙

同じネットワークセグメントに所属するホストを列挙するにはarp-scanを使う。nmapでスキャンをするよりもarp-scanの方が速いしMACアドレスのベンダーコードからメーカーまでわかる。
arp-scan -I eth0 -l

nmapで列挙

ちなみにnmapで列挙するためには、-snオプションで”ping scan”を使う。ただし、pingに応答しないホストは列挙できない。ローカルネットへの”ping scan”でもDNS解決をしようとしてしまうので-nオプションを付けて無効にする。
nmap -n -sn 192.168.1.0/24

各ホストの情報を取得する

同ネットワークセグメント上のホスト一覧が分かったところで、各ホストが何のOSで何のサービスが稼働しているのか調べるにはnmapを使う。

192.168.1.110の詳細な情報を調べる場合:
nmap -nFA 192.168.1.110

-Aを付けて実行をするとOS検知、可動サービスのバージョン情報、スクリプトスキャンなどをしてくれる。-Fを付けると最高速になるが、ファイアーウォールにポートスキャンを検知される可能性が高くなる。-nはDNS解決を無効化するため少し早くなる。

192.168.1.110(Windows10のPC)をスキャンした結果:

このように、Apache2.4.41・PHP7.1.32・mysqlなどが動いていて、NetBIOS名は「ROOT-PC」であることが分かる。MACアドレスのベンダーコードからAsustek製のボードを使っていることも分かった。

このような情報は、技術者にとってトラブル等の解決のヒントになるが、逆に攻撃者にとってはクラッキングの為の有益な情報になってしまう。

もっと詳細に知りたい場合は以下の書籍がおすすめです。

httpでもセキュアになる?wp-login.phpにDigest認証を掛ける

httpで運用されているWordPressはログイン情報は生データでPOSTしているので、パケットが盗聴されたらログイン情報が漏洩してしまいます。

そこで、チャレンジレスポンス方式であるDigest認証をワンクッション置くことで、セキュリティを高めようという魂胆です。

httpsで運用している場合でもwp-login.phpに認証を掛けることでブルートフォースアタックによるログが減ってエコだと思います。

Digest認証用の.htpasswdファイルを作成

ウェブ上にBasic認証用の.htpasswd作成ツールはありましたが、Digest認証用は無かったのでLinux環境でhtdigestコマンドで作成します。

構文:htdigest -c パスワードファイル AuthName ユーザーID

$ htdigest -c .htpasswd lOgIn root

作成したファイルをWordPressのインストールディレクトリにアップします。

.htaccessを編集

WordPressのインストールディレクトリ直下の.htaccessに追記します。

<Files wp-login.php>
AuthType Digest
AuthName "lOgIn"
AuthUserFile /foo/bar/hoge/blog/.htpasswd
require valid-user
</Files>

「AuthUserFile」のディレクトリが分からない場合「<?php phpinfo(); ?>」と書いたphpファイルをアップしてアクセスすると「SCRIPT_FILENAME」が分かるのでそれを参考に設定します。phpinfo();を記述したファイルは忘れず削除しましょう。

※.htaccessや.htpasswd等の編集に絶対にnotepad.exeを使用しないでください。BOMが埋め込まれてInternal Server Errorになります。

成功していればwp-login.phpにアクセスするとパスワードのプロンプトが表示されます。

Digest認証自体は大昔からあるのに未だ普及していないのはなぜだ。

arpspoofで同セグメント上のパケットを盗聴

スタバなどのフリーwifiまたは、パスワードが脆弱なwifi環境から暗号化されていない認証を通るのは危険という話。

arp-scanやnmapでネットワークの構成を把握する

ARPテーブルを改ざん

TCP/IPにおいて通信するためには宛先MACアドレスが必要になる。その際にARPテーブルを参照するが、ARPテーブルに宛先MACアドレスが無い場合、ARPリクエストをブロードキャストで送信する。ARPリクエストを受け取った対象のIPアドレスが設定されている機器は、ARPリプライを返す仕様になっている。

arpspoofによって改ざんしたARPリプライを送信することでARPテーブルは簡単に改ざん可能であり、デフォルトゲートウェイとの間に割り込んでパケットを盗聴することができる。

詳細はこちらが大変参考になります。

https://netwiz.jp/arp-spoofing/

IPフォワードを有効化する

# sysctl -w net.ipv4.ip_forward=1

arpspoofで改ざんしたARPリプライを送信する。ゲートウェイ:192.168.1.1、ターゲット:192.168.1.110

# arpspoof -t ens33 -t 192.168.1.1 -r 192.168.1.110

別のシェルを立ち上げ、tcpdumpでパケットをcapture.pcapファイルにキャプチャする。

# tcpdump -i ens33 -w capture.pcap

試しに何かログインしてみる

攻撃者がキャプチャ中にターゲットPC:192.168.1.110から色々ログインしてみる。

WordPressにログインしてみる。

Basic認証にログインしてみる。

FTPにログインしてみる。

Wiresharkで見てみる

キャプチャしたファイルは後でじっくりWiresharkで見ることができる。

WordPressのIDとパスワードを見る。

WordPressはwp-login.phpにPOSTでIDとパスワードを送信していることから次のクエリで絞り込める。wp-login.phpの名前を変更していたとしてもキャプチャされてしまっては時間稼ぎでしかない。

ip.src == 192.168.1.110 and http.request.uri contains "/wp-login.php" and http.request.method == POST

対策:httpsにするコストが掛けられないのであれば、wp-login.phpにDigest認証を掛け、WordPressアカウント以上に強力なパスワードを設定する。(wp-cronが効かなくなるかも?)
ブルートフォースアタックによるログイン失敗ログの量が減るメリットもある。

Basic認証のIDとパスワードを見る。

Basic認証は平文でIDとパスワードをやり取りしているためこのように見えてしまう。

ip.src == 192.168.1.110 and http.request.method == GET

対策:Digest認証に変更する。

FTPのIDとパスワードを見る。

FTPもやはり平文でやり取りしているためこのように見えてしまう。

ip.src == 192.168.1.110 and ftp

対策:FTPsやSFTPなど暗号化された仕組みを使うのが一番だが、使用できないのであればvpnやsshのポート転送などと併用して信頼できるネットワークから接続する。

ARPスプーフィングされているか知るためには

攻撃を受けるとデフォルトゲートウェイのMACアドレスが変わる。tracertをするとデフォルトゲートウェイよりも手前に知らないアドレスが割り込まれている事が分かる。

ARPの仕様を突いた攻撃のため対策は難しいが、信頼できないwifiやLANは接続しないことと、暗号化されたプロトコルを使用することで傍受されても問題ないようにすることが大切。信頼できないネットワークを使用せざるを得ない場合はvpnやsshのポートフォワーディング等で信頼できるネットワークから利用する。

Ubuntuのパスワードが分からない場合の対処法

※rootのパスワードを設定していない場合に限る。

起動時にESCを連打。ブートメニューを表示。「Advanced options for Ubuntu」を選択。

「(recovery mode)」を選択

表示が崩れましたが、「root」を選択

「passwd 任意のユーザーID」で新たなパスワードを設定。testを設定してみました。

exit, Resumeで起動。設定したパスワードでログインできます。