Hatena::ブログ(Diary)

お前の血は何色だ!! 4 このページをアンテナに追加 RSSフィード Twitter

2017-03-24

ソース管理等を使った改ざん検知

最近、サイトに侵入して、

クレカのフォームを改ざんし、自サイトにカード番号を送信するといういたずらが流行っているようです。

一見正しく動いているプログラムが、実は改ざんされていることになかなか気が付きにくいものです。

運営されている会社も、クレジットカード会社から連絡があったりして発覚しているようです。

一方で、最近の開発環境はソース管理が導入されています。

デプロイツールも導入されているところがあるでしょう。

正しいソースコードがあるならば、それと比較して改ざんを簡単に検知できるのではないだろうか?

と、いうことで、ソース管理等を使った改ざん検知システムを作ってみた。

案1 ソース管理そのものを使った diff(ただしあまり安全ではない)

とても簡単な改ざん検知

例えば、SVN とかのソース管理で、サーバを管理している場合

(たぶん GITでも同じことができるはず)

#!/bin/sh
DIRGET_DIRECTORY="/var/www/vhost/example.com"
MAIL_TO="alert@example.com"
SUBJECT="[DIFF ERROR!]"
SCS_PROGRAM="svn"

#IS_ALIVE=`ps aux | grep "${SCS_PROGRAM} " | grep -v grep  | wc -l`
#if [ $IS_ALIVE -ge 1 ]; then
#	exit 1
#fi

cd $DIRGET_DIRECTORY
DF=`${SCS_PROGRAM} diff | wc -l`
if [ $DF -eq 0 ] ; then
	exit 0
fi

MAILTEMPFILE=`mktemp`
echo "To: ${MAIL_TO}"  >> $MAILTEMPFILE
echo "Subject: ${SUBJECT} ${HOSTNAME} ${DIRGET_DIRECTORY}"  >> $MAILTEMPFILE
echo "" >> $MAILTEMPFILE
echo "${SUBJECT} ${HOSTNAME} ${DIRGET_DIRECTORY}"  >> $MAILTEMPFILE
echo "-------------------------------------------" >> $MAILTEMPFILE
${SCS_PROGRAM} diff >> $MAILTEMPFILE

sendmail $MAIL_TO < $MAILTEMPFILE

/bin/rm $MAILTEMPFILE
exit 100

これで、改ざん者がサイトを改ざんしたら、

変更点が発生し、メールで通知を投げることが出来ます。

ただし、この方法では、本番のwebディレクトリにソース管理機能があるので、あまりよくありません。

まずは、apacheの設定等で、 .svn や .git などへのアクセスを遮断しないと危険です。

次に、逆流して侵入者に commitされないように、ユーザ権限を振らないといけないでしょう。

案2 deployツールを使った場合

deployツールをつかった場合はどうか?

1日1回ならともかく、10分に1回などの場合は、

毎回デプロイツールがチェックに行くのは現実的ではありません。

別のディレクトリにも同一内容をデプロイして、

そこと比較することが考えられます。

ただ、別のディレクトリにもデプロイできるか?というデプロイツールの制約の壁があります。

例えば、

本番
/var/www/vhost/example.com

デプロイしたときについでに取ったコピー
/var/backup/example.com

だったとすれば、以下のようなシェルスクリプトで、diffを使って比較できます。

#!/bin/sh
DIRGET_DIRECTORY="/var/www/vhost/example.com"
COPY_DIRECTORY="/var/backup/example.com"
MAIL_TO="alert@example.com"
SUBJECT="[DIFF ERROR!]"

#Ignore when deploying.
#IS_ALIVE=`ps aux | grep "rsync " | grep -v grep  | wc -l`
#if [ $IS_ALIVE -ge 1 ]; then
#	exit 1
#fi

LANG=C
DF=`diff -rq ${COPY_DIRECTORY} ${DIRGET_DIRECTORY} | grep '^Files' | wc -l`
if [ $DF -eq 0 ] ; then
	exit 0
fi

MAILTEMPFILE=`mktemp`
echo "To: ${MAIL_TO}"  >> $MAILTEMPFILE
echo "Subject: ${SUBJECT} ${HOSTNAME} ${DIRGET_DIRECTORY}"  >> $MAILTEMPFILE
echo "" >> $MAILTEMPFILE
echo "${SUBJECT} ${HOSTNAME} ${DIRGET_DIRECTORY}"  >> $MAILTEMPFILE
echo "-------------------------------------------" >> $MAILTEMPFILE
diff -rq ${COPY_DIRECTORY} ${DIRGET_DIRECTORY} | grep '^Files' >> $MAILTEMPFILE

sendmail $MAIL_TO < $MAILTEMPFILE

/bin/rm $MAILTEMPFILE
exit 100

diff | grep '^Files' と、しているのは、

webroot以下に本番にしか無いデータファイルがある場合を考慮してです。

アップロードされた画像とかがおいてあると、片方にしかないよという暴発がありえるので、このようにしています。

あとはcronで定期実行するようにすると、

改ざん検知ができるようになると思います。

どれくらいの頻度でチェックするべきかは、

負荷と相談してやるべきですね。


これで、万が一にもサイトが改ざんされたとしても、早期に気がつけるようになります。

早期に気がつけるということは、被害が拡大する前に即サイトを修正することもできるでしょう。

場合によって、改ざんした人が改ざんをしていろいろ試している時に、止められて被害ゼロということもあるかもしれません。

2017-02-18

フューチャーホームコントローラー(FHC)の複数台構成の実装の裏側

f:id:rti7743:20170218184003j:image

フューチャーホームコントローラー(FHC)の複数台構成について、裏側の実装をあまりに語っていないのでちょっと解説したいと思います。

https://rti-giken.jp/fhc/help/howto/multiroom.html


目指したのは、それぞれの部屋に置かれた端末がP2Pな関係で寄り添い通信して家全体のホームネットワークを自動で構築するというものです。

FHCには、webapiという機能があり、いわゆる共有キーのフレーズを使ってAPIを呼び出すことができます。

webapiは、 HTTP GETで要求を送り、返信は jsonで返ってくるシンプルなものです。

これを使えば自由に好きなアプリと連携できます。

https://rti-giken.jp/fhc/help/ref/setting_webapi.html

また、弊社サーバとhttps通信することで、リモートからでもWebAPIを呼び出せるようになっており、

外部webサービスと家の連携も可能になっています。

FHCの複数台連携は、このwebapiを利用する形で作られています。

具体的には、最初に相手を追加する時(信頼関係を結ばせる時)に、端末間でwebapiキーを交換します。

以後は、相手のwebapiキーを使ってそれぞれがそれぞれの機能を呼び出すというものです。

sshのキー認証みたいなものですね。

ただ、これは共有鍵なのでRSAとかに比べては弱いですが、ホームネットワークLAN内限定なのでまあ信頼しています。

もし、何か理由でキーを記録しているファイルが流出した場合、

webapiキーをリセットすれば問題ありません。

流失キーは即時無効になります。

そしてキーの変更はホームネットワークで自動適応されます。

ユーザは何も考えずにキーをリセットしてOKです。

機能としても、いろいろ頑張っていて、

1:Nの複数台とリンクできるし、

複数の部屋に置かれたFHC群へのアクセスもとても容易です。

信頼端末の信頼端末(友達友達)とも一度にコネクションできます。

自分<-->信頼端末(友達)<--->信頼端末の信頼端末(友達の友達)
自分<-->信頼端末(友達)で信頼関係を結ぶと、
自分<-->信頼端末の信頼端末(友達の友達)
友達の友達とも信頼関係を自動で結べます。

つまり、新しく部屋にFHCを設置したとしても、どこかの部屋においたFHCと信頼関係を結べば、新しく部屋に設置したFHCは、すべての部屋にアクセスできるというものです。

いちいち、すべての部屋へ信頼関係を手動で結ばせるのは手間ですからね。

信頼関係を結ぶには、自端末にログインでき、信頼関係を結びたい相手端末のIDとパスワードが必要です。

当然ながら、これらがわからないと信頼関係は結べません。

いたずらで侵入しようとしても無駄です。

正規に使うのは簡単でもイタズラは難しいを目指しています。

さらには、

DHCPで相手のIPが変わったとしても自動追従してネットワークを維持します。

webapiキーが変わっても同様です。

同時にすべての端末の電源が同時に切れて、相手のIPが変動しない限り追跡でき、

FHCのホームネットワークはそう簡単には破綻しません。

相手のIPが一度に全部変動しても追跡する機能も理論上は可能です。

ただ少し面倒なのでそこまでは作っていません。

以上が、フューチャーホームコントローラーの複数台対応です。

それぞれの部屋に置かれた端末がP2Pな関係で寄り添い通信して家全体のホームネットワークを自動で構築するというのを実現しました。

また、侵入者によるイタヅラもはねのける防御機能と、

ユーザの利便性を上げる裏方の機能があります。

あなたも、複数の部屋にFHCを置いて、家全体のホームネットワークを作ってみましょう。

https://rti-giken.jp/fhc/help/howto/multiroom.html

これが21世紀の新しい家の姿です。

2017-02-13

AOK年貢の復旧

f:id:rti7743:20140725170131j:image

昔作った AOKシナリオMODの年貢を復旧させることが出来た。

ついでに、機械翻訳で英語版も作ってみた。

download準備中

しかし、aokの新しいシナリオファイルって容量が10倍以上にでかくなるんたけど、開発陣はどういうプログラムかいているんだ?

年貢の解説記事はこっち。

http://d.hatena.ne.jp/rti7743/20140725/1406275415


年貢(nengu)
nengu is mean tax in medieval japan.

シングルプレイ用のシナリオです。
It is a scenario for single play.

ひたすら内政をやりたい人に向いています。
It is suitable for those who just want to do internal affairs.

プレイヤー(青)は、幕府のお代官様(赤)から出されるムチャな年貢(税金)をこなしていくゲームです。
The player (blue) is a game that carries out an unpleasant nengu(tax) from the odaikan-sama(red).
odaikan-sama is mean Governmental Executive officer(shogunate's officer). 

プレイヤー(青)は必死に働き、告知から10分以内に年貢を収めないといけません。
The Player(BLUE) must a work and must store a nengu by the term for 10 minutes. 

要求される年貢は毎回ひどくなります。
The nengu(tax) required is bad every time.

年貢は、食料500の要求から始まり、終盤には、金、徴兵になります。
It begins from the taxation of the food 500 at first, and there are a gold, and the conscriptionenlistment. 

もし、年貢を収めなければ、反逆者として、処刑されます。
If nengu is not stored, executed as traitor.

ゲームクリアには、合計12回の課税を収めきるか、または、年貢を払わずに反逆者となり、革命を起こします。
Game is clearable ,If all the 12 times taxation is paid, or taxation is disregarded and revolution is start.

年貢を納付するには、お代官様(赤)に資源を送信してください。
To pay the nengu, please send the resource to odaikan-sama(red).

日本語版(jpn)と英語版(eng)があります。
There are Japanese version (jpn) and English version (eng).

オリジナルが日本語版で、機械翻訳したものが英語版です。
Original is Japanese version, machine translated is English version.

created by @super_rti
http://d.hatena.ne.jp/rti7743/

2014年に作ったけど、utf対応パッチで壊れてしまったので、ツールを使って復旧させました。
Trigger Studio ( Trigger Studio 1.2.x for HD, UserPatch, AoFE, AoF + SWGB )を使ってな。
I made it in 2014, but it was destroyed by utf correspondence of patch update, I made a tool and restored it.

AOK FEの復旧

昔作った AOKシナリオMODFEを復旧させることが出来た。

download準備中

ファイアーエムブレムをAOEで強引に再現するMOD
MOD which forcibly reproduces Fire Emblem at AOE

ファイアーエムブレム 暗黒龍と光の剣を AOEで強引に再現しました。
Fire Emblem The dark dragon and the sword of light were forcibly reproduced with AOE.

このMODは、二次創作作品です。
This MOD is a Fan Fiction.

公式とは一切関係ありません。
It has nothing to do with official.

現在は日本語のみです。
Currently it is only Japanese.

全12ステージあります。
There are 12 stages in all.

ファイアーエムブレムのサントラを流しながらやると楽しいですよ。
It's fun to do it while sending Fire Emblem's soundtrack.

I made it in 2014, but it was destroyed by utf correspondence of patch update, I made a tool and restored it...
http://d.hatena.ne.jp/rti7743/20140812/1407829818

2017-01-15

ナノ秒単位の高性能な時刻がほしい時

beagleboneやraspberry piで、ナノ秒単位の正確な時間がほしい時について。

通常のtime関数とかでは遅すぎて困るときは、以下のようにすると、ナノ秒単位で時刻が取れます。

値は、CPUとかの動作クロックの影響をうけるので注意してください。

ボードメモリ位置バイト長
beaglebone0x4804003C4バイト
raspberry pi 2-30x3F0030044バイト

このメモリ位置は常にカウントアップされていきます。

値はunsigned int値で、オーバーフローすると0に戻ります。

ここを読みだすことでとても正確な時間を取得することができます。

今何時?という用途にはまったく使えませんが、処理時間の間隔を正確に測るとかの用途に向いています。


カーネルランドで読みだす場合は、 ioremapが便利だと思う。

//ナノ秒単位の高性能な時刻がほしい時。
//kernel land
void *g_timer = ioremap(0x4804003C,4); //beaglebone
void *g_timer = ioremap(0x3F003004,4); //raspberry pi 2-3

//一番オーバーヘッドを生まないであろうマクロ展開で読みだす.
#define dmtimer_get()  ((unsigned int)ioread32(g_timer))

printk(KERN_ALERT "timer: %u\n", dmtimer_get() );

iounmap(g_timer);

ユーザランドで読みだす場合は、 mmapするよろし。

//ナノ秒単位の高性能な時刻がほしい時。
//userland
int g_fd = open("/dev/mem", O_RDWR | O_SYNC);
if (g_fd < 0)
{
	printf("Could not open /dev/mem fd\n");
	return -1;
}

//mmap確保
//0x3F003004 とかを直接mmapすると落ちるので、ちょい手前から 0x100ぐらい適当に確保する.
//void* g_mmap = ( unsigned int*) mmap(NULL, 0x100, PROT_READ,MAP_SHARED,g_fd, 0x48040000); //beaglebone
unsigned int* g_mmap = ( unsigned int*) mmap(NULL, 0x100, PROT_READ,MAP_SHARED,g_fd, 0x3F003000); //raspberry pi 2-3
if (g_mmap == MAP_FAILED) {
	printf("Could not mmap %d\n",g_mmap);
	close(g_fd);
	g_fd=0;
	return -2;
}
//unsigned int* g_timer = &g_mmap[0x3C/sizeof(int)]; //0x4804003C
unsigned int* g_timer = &g_mmap[0x4/sizeof(int)]; //0x3F003004

//一番オーバーヘッドを生まないであろうマクロ展開で読みだす.
#define dmtimer_get()  (*g_timer)

for(int i = 0 ; i < 10 ;i++)
{
	printf("timer: %u\n", dmtimer_get() );
	sleep(1);
}

//unmap(g_mmap)を呼び出さなくてもプロセス終了時には自動解放される 
close(g_fd);

この高性能タイマー機能の名前がよくわからないのだが、dmtimer とか、high level timer とか、いろいろ名前があるらしい。

検索しにくいから統一させてほしいものである。

2017-01-13

最初にコンピュータに仕事を奪われた人たち

AIの発達で、コンピュータが仕事を奪うという人達がいる。

確かに、近年のAIの進化は素晴らしく、幾つかの分野で人間を超える成績を出すものがある。

だが、忘れてはいけない。はるか昔にコンピュータに仕事を奪われた人がいたことを。

はるか昔に、コンピュータに仕事を奪われた人たち、それはコンピュータだ。

何言っているんだお前と思うかもしれないが、weikipediaにもちゃんと載っている。

https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF

英語の 「computer(コンピューター)」は算術演算(数値計算)を行う人を指す言葉だった。

computer というのは、もともとは計算をする人をさす言葉だった。

それが機械の方のコンピュータが発達して、驚異的な演算能力があったためだろうか、いつしかコンピュータは機械の方のコンピュータをさす言葉になってしまった。

そして、もともとコンピュータというのが職業だったというのも忘れ去られようとしている。


コンピュータに最初に仕事を奪われた人たちは、コンピュータだった。

私たちにできることと言えば、コンピュータが仕事を奪うと言うが、最初にコンピュータに仕事を奪われた人たちって、コンピュータだよねみたいな、このことを知らないと意味不明な文章を言って遊ぶことぐらいだろうか。