clamav で Pdf.Exploit とかで誤検出する場合の対応方法

ClamAV を運用していると,何年も前に入手し通常はアクセスしない PDF ファイルの中から,Pdf.Exploit 系の検出がなされる場合がある.
普通に clamdscan を走らせると発見されると同時に消されてしまうので,たまに困ることがある.

検出しても削除しないようにする

私の環境では,clamdscanだとうまく制御できなかったので,crontab で clamscan を呼ぶことにした.
メールの宛先とかは自分でいじってちょ.
あと freshclam はデーモン化して走らせておくこと.

#!/bin/sh

SCAN=/usr/bin/clamscan
OPT='-ri'
ROOT=/
LOG=/root/clamav.log
MAIL=/usr/bin/mail
FROM=root@HOSTNAME
TO=USERNAME@HOSTNAME

ALART_S="MALWARE was found on $(hostname)!"
ALART_B='see the log file attached.'

MSG_S="last scan log on $(hostname)"
MSG_B="last scan was finished at $(date)"


$SCAN $OPT $ROOT > $LOG

MALWARE=$(tail "$LOG"|grep Infected|cut -d" " -f3)

if [ "$MALWARE" -ne "0" ]; then
    echo "$ALART_B"|$MAIL -a $LOG -s "$ALART_S" -r "$FROM" "$TO"
else
    echo "$MSG_B"|$MAIL -a $LOG -s "$MSG_S" -r "$FROM" "$TO"
fi

特定のシグネチャを無視させる

検出されるシグネチャが増えると誤検出もメールに記載されるため分かりづらくなってくる.
そのシグネチャ自体を無視したい場合は,/var/lib/clamav/hogehoge.ign2とign2ファイルを作ってシグネチャ名をリストしておく.

$ echo Pdf.Exploit.CVE_2016_4207-1 | tee -a /var/lib/clamav/local.ign2

なお,上のシグネチャを無視するかは,貴方の判断で行なうこと.

特定のファイルを無視させる

明らかに問題ないと自分で思っているファイルだけ,あらゆる検出から無視させる場合は,/var/lib/clamav/hogehoge.fpとfpファイルを作ってファイルのシグネチャをリストしておく.

$ sigtool --sha256 /path/to/file | sudo tee -a /var/lib/clamav/local.fp

どっちのがリスクが高いかは使い方次第なので,やっぱし貴方の判断で設定すること.

wordpress でクォートが全角になったりする問題

再々追記
wordpress 4.0 から, run_wptexturize フィルターが追加され,簡単に止められるようになった.
もはやプラグイン公開の価値があるかは知らないけど,いちおうアップデートしておいた.
また,機能に合わせて,プラグインの名前を変えた → Disable wptexturize

再追記
リンクのパスを間違えていた…すみません。以下、復旧済です。

追記
とりあえず作ったよ。
下記を解決するプラグインは、機能を殺す部分だけなら簡単に実装できたが、plugin の体裁にするのに手がかかった。公式にアップするのもまだちょっとかかりそう。
とりあえずすぐ解決したい人は、どうぞ → [Disable Auto Replacement]
解凍してできるディレクトリを、wp-content/plugins へ配置すれば OK。
これを使うと、クォーテーションもハイフネーションもアスキー文字のまま出力されるが、三連ピリオドを三点リーダーへ置換する機能も死ぬので、注意すること。

私は、プログラムのコードを本文中に書くことが多い。
しかし wordpress を使うと勝手に全角に置き換えられるのが不満で、回避策として " などを使うようにしていた。これは面倒くさい。
まだ文字実体参照の用意されている文字コードなどなら良いが、ハイフンみたく用意されてないと (正確には、ndash と mdash はあるが、これはハイフンではない)、不便で仕方がない。
(wordpress は二連ハイフンを mdash か何かに置き換えてくれる)

さっきも NOOK の記事を書こうとしていい加減に腹が立ってきたので、そういうのを抑制する plugin でもないか検索したら、原因が見付かった。
wordpressで”ダブルクォーテーションが全角になっちゃう” | IT勉強するコタツネコ
この人、置換行をコメントアウトしているので他の問題が出そうだなー、と思いつつそれはさておき、この記事にある

$curl = preg_replace($dynamic_characters, $dynamic_replacements, $curl);

というのが問題の行で、dynamic_replacements の中身を見れば簡単に分かるはず…

小足見てから昇龍余裕でした。
例えば、シングルクォートは ’ に置き換えちゃ、だめだろ JK
’引用符 - Wikipedia が詳しい。
どうダメかというと、' と比較するとこんな感じくらいダメ。
ダメさが伝わりやすいように、MS Pゴシックにフォントを変えてみる。
apos版 → He's a student.
8217版 → He’s a student.

もー! 半角文字を全角文字に置き換えるコーディングするやつは、コーディングやめちまえ!

といいたい。
でも本体に手を入れるとアップデートや鯖移行の度に面倒くさいので、plugin で何とかしたい。
この程度、どっかに転がってないかな。
PS Disable autoformatting ではダメだった。
これいじって、作るか…

以下、作っている間のテスト用文字列…
---He's a student.

ed25519で公開鍵認証

sshの鍵をrsaをやめてed25519にしてみたことについて.
オープンサーバにSSHで入れるようにして,色々な国からのハッキングっぽいアクセスログが残っている現状を鑑みれば,とりあえず強化しておくに越したことはないよね,っつー話.
あと,RSAの鍵長を伸ばして行くと,ログインにちょっと時間がかかる気がしており,ed25519はrsaより短い鍵長で同程度の強度を誇るらしいので,ちょっとは公開鍵認証の処理が早くならんかしらと期待しているのもある.

実行速度とかは,この辺を参照→自堕落な技術者の日記 : RSAとECDSA、署名生成と署名検証どっちが速い? - livedoor Blog(ブログ)

鍵の生成

とりあえずデフォルトで.

$ ssh-keygen -t ed25519 -C 'comment'

今んところできないのか,原理的なものによりできないのか,とりあえずビット長の指定はきかない.
できあがる鍵は ~/.ssh/id_ed25519[.pub]

LinkStation (LS-QVL) が時々ハングるので,中身を調べてみた

proxy配下に置いたLinkStationが,週に1回くらいハングってくれるので,ちょっといじってみたよ.
結果はどうなることやら.

sshで入れるようにする

LinkStation に ssh で root ログインできるようにする - maruko2 Note.
を参照した.
一般ユーザでログインできるようにしようとしたら,色々と抑止策が施されていて,リブートするごとに設定が巻き戻ったり(正確にはsshd再起動で巻き戻る)するので,rootでパスワードログインすることで良いことにした.
気になる人は公開鍵認証にしてはどうか.試してないけど.
あと,コマンドライン履歴にパスワードが残る運用は私の中ではあり得ないので,ファイルに書き出したのをコマンド内で呼んでいる.
あと,gつけるのは怖いので,私はsedにgはあんまつけない.ちゃんと動きそうか,catとかで確認すること.

  1. パスワード設定
    $ IP="192.168.1.X"
    $ Admin_PW=$(cat admin_passwd)
    $ ROOT_PW=$(cat root_passwd)
    $ java -jar acp_commander.jar -t $IP -ip $IP -pw $Admin_PW -c "(echo $ROOT_PW ; echo $ROOT_PW) | passwd"
    $ java -jar acp_commander.jar -t $IP -ip $IP -pw $Admin_PW -c "cat /etc/sshd_config"
    $ java -jar acp_commander.jar -t $IP -ip $IP -pw $Admin_PW -c "sed -i 's/UsePAM yes/UsePAM no/' /etc/sshd_config"
    $ java -jar acp_commander.jar -t $IP -ip $IP -pw $Admin_PW -c "sed -i 's/PermitRootLogin no/PermitRootLogin yes/' /etc/sshd_config"
    $ java -jar acp_commander.jar -t $IP -ip $IP -pw $Admin_PW -c "/etc/init.d/sshd.sh restart"
  2. ログイン
    $ ssh root@$IP

ログを探す1

どうも,/var/log/syslogがないなーと思ったら,/var/log/messagesに色々と書いてあった.
前回暴走直前の挙動を調べると,majishanzuかmDNSResponder辺りが怪しい.

  1. とりあえず,majishanzu を/etcで探しても見付からないので,頑張って探す.
    # which majishanzu
    /usr/local/sbin/majishanzu
    # grep majishanzu /usr/local/sbin/majishanzu
    /etc/melco/majishanzu
    majishanzu_state
    /var/lock/majishanzu_update
    /etc/melco/majishanzu/
    /tmp/majishanzu_dl
    %s/majishanzu_info
    /etc/melco/majishanzu/majishanzu_state
    majishanzu success
    majishanzu
    majishanzu start
    

    しかし,/etc/melco/majishanzu には情報はないのであった.

  2. 続いて,ログの直前にtwonkyのログが出ていたので,twonkyから呼び出されているのでは?と推測.
    検索したら出てきた.
    Linkstation Duo LS-WXL - how to access media server confguration page (port 9050)
    /usr/local/twonky-alt/ へ

    # cd /usr/local/twonky-alt/
    # grep majishanzu *
    twonky.sh:MS_DL_LOCK_FILE=/var/lock/majishanzu_update
    twonky.sh:MAJISHANZU_DIR=/etc/melco/majishanzu
    (略)
    

    grepをかけると,twonky.shで呼び出されているので,中を読む.
    /usr/local/sbin/majishanzu のある時,do_majishanzuが呼ばれているようなので,元ファイルをリネームして退避すれば,もう二度と呼ばれないはず.

    # mv /usr/local/sbin/majishanzu /usr/local/sbin/majishanzu.bak
  3. ちなみに,絶対どこかから呼び出されて動作しているはず,と思ってcrontab -lで出てくるスクリプトが置いてある/etc/cron/cron,d内をgrepしてみると,ms_checkversion.shの中にtwonky.shが書かれている.
    こいつは30分に1回呼ばれていた.

ログを探す2

mDNSResponderも止めておこうと調べてみると,bonjour関係のプロセスだった.
そういえばiTunesを使ってた時にwindowsでも見たことある.

面倒臭いので結論から言うと,こいつはcronではなく/etc/init.d/bonjour.shから呼ばれていて,/etc/melco/infoの中を見るとbonjour=onの設定が書かれており,bonjour.shの中でこいつがonなら…という行がstart()にあるので,/etc/melco/infoを書き換えてbonjour=offとしてみた.

ログを日付別に行数カウントする

monthlyでlogrotateしているログが,ある月だけ突出してサイズが大きかったので,いつのログが問題なのかを見るためにちょっと書いたスクリプト.
ちょっと月を入力するところをサボった.
数字の0フィルは-wオプションらしい.

#!/bin/bash

for d in $(seq -w 1 31)
do
echo -n $d
echo -n ' '
echo `zcat $1 | grep $d/Nov/2015 | wc -l`
done

StartSSLでSHA2署名の証明書

最近のChromeはSHA1署名の証明書に厳しいので,SHA2署名の証明書を発行しようとしたが,StartSSLでうまく認識できなくて困っていた.
この記事の通りにやってみたら,うまくSHA2の証明書として認識された.→ StartSSLで取得した証明書がsha1で認証されてしまう - Qiita
なんか,公式が証明書出してたので修正しました→StartCom • View topic - can I use a SHA256 Intermediate certificate
なんか,crtのダウンロード形式が変わったので修正しました

以下,nginxでsslを使う場合.
apacheで使う場合は,中間証明書をリンク先のものと差し替えるだけなんだけど,apache2.4以降の設定をほとんど真面目にやったことないので,詳しくは分かんない.

$ openssl genrsa -aes256 2048 > server.key
$ openssl req -new -sha256 -key server.key -out server.csr

StartSSLで証明書を発行したあと…
fqdn.zip 的なアーカイブをダウンロードできるようになるので,落として,解凍すると有名なhttpdサーバ毎に必要ファイルをまとめたzipが入っているので,必要なやつを更に解凍する.
なければ,OtherServer.crtにルート・中間認証局の証明書と,fqdn用に発行された証明書があるので,それを使う.

dovecotとかならパスフレーズを指定できるらしいけど,nginxはできんかった気がするので

$ openssl rsa -in server.key.org > server.key

httpとhttpsで動作を分ける場合は両方に記述を追加すること(SPDYも注意)

nginx+uwsgiで80番ポートのあるアクセスにpythonスクリプトの出力を流すようにしていたのだが,443ポートでのアクセスは想定していなかったので,特に何も設定していなかった.
そうしたら,httpsでアクセスすると表示されないはずのindex.htmが表示されることに気付いた.
さらに,pythonスクリプトファイル名をダイレクトに指定すると,pythonスクリプトがダウンロードできることも判明した.
そのファイルにこそ,パスワードの類は入れていないものの,インポートしているファイルの一覧が見えてしまうし,これはかなり危険だ.

で,443ポートのserverディレクティブに80番と同じ設定をコピペしたが,動かない…
firefoxやchromeでアクセスしていたため,443ポートとは別に443 spdyが有効になっていたのだ!
二段の罠だった.

Webサーバのログを眺めてみよう

この記事を書いた頃は,apacheを使っていたが,今では使っていない.「apache のエラーログを真面目に読んでみた | hadacchi blog
存在しないURLを適当に入れたら出てしまうから書いちゃうけど,このウェブサイトは,nginxを使って運営している.

で,まぁそのログを眺めようという前回に引き続いての企画.
思いも寄らぬエラーが出てたりするので,勉強になると思うよ.

access.log
  • 標準だと,多分/var/log/nginx/access.logあたりだと思う.
    生で見てもいいんだけど,アタックによく使われるphpmyadminあたりへのアクセスをひっかけるため,こんなコマンドでまずはIPとリクエストURL,サーバのレスポンスコード,ユーザエージェントを一覧する.

    # cut -d' ' -f1,7,9,12-  nginx/access.log | grep dmin | less

    そもそも,ここで200になっていたら,phpmyadminのログとか見た方がいいと思う.
    私は使ったことがないから知らない.

  • 次は,そこでひっかかったIPアドレスをひっかけて,他にヤバそうなアクセスを受けていないか確認する.
    # cut -d' ' -f1,7,9,12-  nginx/access.log | grep xxx.xxx.xxx.xxx | less

    そうすると,例えばこんなURLへのリクエストが飛びまくっていたので,この辺りに脆弱性のあるプログラムがあるんだろーなー,とか分かる.

    /w00tw00t.at.blackhats.romanian.anti-sec:)
    /muieblackcat
    /components/com_jinc/classes/graphics/php-ofc-library/ofc_upload_image.php?name=magic.php
    

    ぐぐってみると,1つ目と2つ目はよくひっかかる.
    3つ目は,なんかopen flash chartとかいうのが出てくる.
    あと,明らかにSMTPを狙ったログも出てきた.

    CONNECT 126mx00.mxmail.netease.com:25 HTTP/1.0

    ぐぐってみると,中国語っぽいサイトが出てくる.
    アクセス元IPアドレスをIP-HOST変換かけてドメインでぐぐると,台湾からのアクセスらしいという情報も出てくる.

error.log
基本は,access.logと同じだが,nginxの場合はphpへのアクセスを全てphp-fpmへ流していると,php-fpmからのエラーも全部記録される.
設置していないURLでの*.phpへのアクセスは,別にさばいてログを分けた方がいい…のかな?まだ考え中.
他には,設置をミスった証明書のエラーとかも出てくる.

# grep -v 'No such file or directory' nginx/error.log | less
php-fpm.logとか,unicorn.logとか
phpとかrubyとか使ってると,この辺りもチェックすることになると思う.pythonならuwsgi.logとかかしら.
この辺りを動かしている人は,自分の環境に併せて調べてみてね.

Redmine on Debian がアップデートでごちゃごちゃしたので整理

追記:
最近はrbenv+ruby-buildが流行りらしい.apt-getで入るけど,それで入れたら入れられるrubyは古いものしかなかった.

前提:サーバで動作している rubygems, ruby 系は全部消した上で,autoremove した状態.
それまで動いていた,redmine の環境はいじってない.

ruby
rvmでインストールする.
環境が整っていれば,webにあるように

root# curl -L https://get.rvm.io | bash -s stable

でいいんだけど,最初はうまくいかないので,インストール用のシェルスクリプトを落としてきて何度も実行することになる.

$ wget -L https://get.rvm.io
$ cat index.html | bash -s stable

そうしたら色々と足りないものを入れろと言われる.
RedmineをDebianに導入する - Qiita を見て入れたものは,これら.
make環境が入ってたので,少なめ.

root# apt-get install git
root# apt-get install libssl-dev
root# apt-get install libreadline-gplv2-dev
root# apt-get install libyaml-dev
root# apt-get install curl

んで,もういっかい,

$ cat index.html | bash -s stable

そしたら環境を読み込んでrubyを入れる.

$ source $HOME/.rvm/scripts/rvm
$ rvm install x.x.x # <- 入れたいバージョン

この辺りで,rootになってないことに気付いたけど,$HOME/.rvm 以下にインストールされてたので,いいやと思うことにする.

$ rvm list

として,インストールされたrubyが出てきたらOK.

mysql関連gems
これはスキップできなかった.

$ sudo apt-get install libmysqlclient-dev
$ gem install mysql2
bundler
$ gem install bundler --no-rdoc --no-ri

これでローカルに入るはず.

redmine用のgems
なんか gemset とか使って,環境を切り替えられるらしいんだけど,使わないことにする.

$ cd /path/to/redmine
$ bundle install --without development test postgresql sqlite3 rmagick

なぜか,sqlite3 はインストールされてしまう…

起動スクリプト
source コマンドでスクリプトを読み込めるbashにする.

#!/bin/bash
source /home/username/.rvm/scripts/rvm
cd /path/to/redmine
bundle exec unicorn_rails -D -E production -c config/unicorn.rb