Capture The Flags 講座のアフターケア
子供が Capture The Flags の講座に参加したけど、簡単な説明後いきなりミニCTF大会だったので、さっぱり分からないだろうから、少し解き方の説明。
ドメインの秘密
ドメイン名とは、IPアドレスは覚えられないのでコンピュータにつけた名前。そのドメイン名とIPアドレスのデータベースがDNS。通常は、コンピュータ名からIPアドレスを調べる時に使う。unix や windows で DNS 情報を調べるコマンドが、nslookup。
最新の unix 環境では、nslookup ではなく、dig しか入っていないかもしれない。
その場合は、
$ sudo apt-get install dnsutils
((( 基本的使い方 ))) $ nslookup [オプション] ドメイン名 [DNSサーバ] ((( 問い合わせ例 ))) $ nslookup tsaitoh.net 8.8.8.8 # GoogleのDNSサーバに問い合わせる例(正引き) $ nslookup 64.33.3.150 8.8.8.8 # (逆引き=IPアドレスからドメイン名を調べる) $ nslookup -query=A tsaitoh.net # IPv4アドレスを調べる $ nslookup -query=AAAA www.yahoo.com # IPv6アドレスを調べる $ nslookup -query=MX tsaitoh.net 8.8.8.8 # メールサーバ情報を調べる $ nslookup -query=TXT tsaitoh.net 8.8.8.8 # SPF1というメールサーバの信頼性情報
我が家では、自宅専用のDNSサーバが動いている特殊な事例。インターネットのグローバルアドレス空間でどう見えているかを知りたい場合は、DNSサーバに 8.8.8.8 を使う。Google が、記憶しやすいIPアドレスで誰もが使っていい高速のDNSサーバを提供してくれている。
Webページを見つけろ
サーバとの通信では、IPアドレスで相手のコンピュータを見つけるけど、1台のコンピュータ内で複数のネットワークプログラムが動いていた時、どのプログラムと通信するのか区別する必要がある。そのための情報がポート番号。IPアドレスを電話番号に例えるなら、ポート番号は内線電話番号みたいなもの。
このポート番号は、プログラムによって番号は◯◯を使うべき…という値が決まっている(よく知られたポート番号)。Webサーバ(HTTP)は80番、Webサーバ暗号版(HTTPS)は443番、メールサーバ(SMTP)は25番….。
ポート番号で接続するサービスが決まるけど、学内だけで外に見せたくないWebサーバなどがある場合は、ファイアウォールで特定のポート番号を流通させないようにする場合もある。そういう場合には、通常のポート番号以外を使って通信することがある。
Webサーバに接続する時には、80番を使いたくない場合には、http://コンピュータ名:ポート番号/ と URL にポート番号付きで指定することもできる。
ポートスキャン
このポート番号が解らない時は、ポートスキャンというツールがある。ポート1番で通信してみる、ダメなら2番…という繰り返しをしてくれるツール。一番有名なツールが、nmap。ウィルスなどが仕掛けられて、外部からのネットワーク接続を受ける状態(バックドアが仕掛けられた状態)になったのを見つけるのが本来の使い方。
nmap は通常インストールされない(こんな危ないツール普通はシロートに使わせるものではない)。使いたい場合は、
$ sudo apt-get install nmap
((( 基本的使い方 ))) $ nmap [オプション] 接続先 $ sudo nmap tsaitoh.net # サーバ tsaitoh.net を調べる $ sudo nmap -A tsaitoh.net # ソフトの種類も調べてくれる。
ポート番号が解って、そのサーバソフトに接続してみる場合、telnet がよく使われる。
本来は、ネットワークの先のコンピュータを操作するためのソフト(リモート接続23番ポート)だけど、通信を暗号化しないため、セキュリティ的には危険なので、リモート接続用途で使うことは少ない。
Windowsでは、telnetは初期状態でインストールされない。unix で telnet を使いたい場合は、
$ sudo apt-get install telnet
((( 基本的使い方 ))) $ telnet コンピュータ名 [ポート番号] $ telnet tsaitoh.net 80 # 80番ポート(HTTP)に接続 GET / # トップページのHTMLが帰ってくる。 $ telnet tsaitoh.net 25 # 25番ポート(SMTP)に接続 QUIT # 接続を切る
隠れたデータ
ウィルスなどにコンピュータに感染させる場合、ファイル名などを偽っってあったりするので、ファイルの種別を調べたり、その中の命令を分析する必要がある。その場合によく用いる基本コマンド。
((( 基本的使い方 ))) $ file ファイル名 # 指定したファイルが何か簡単に調べてくれる。 $ file a.out # a.out の中身を調べる $ strings ファイル名 # ファイルの中身の文字として表示できるものを表示する。 $ strings a.out # a.out の中の文字情報を抽出 $ nm ファイル名 # オブジェクトファイルのシンボル(関数名や変数名)を表示 $ nm a.out # stripされたa.outでは抽出できない。
逆アセンブル
実行プログラムがどのような処理をしているのか内容を見たい場合は、逆アセンブル(機械語をアセンブリ言語に変換)する。ただし、一般的な実行プログラムでは、関数番地や変数名番地の情報が消されているので、OS の仕組みの知識が必要。
簡単に解析をするのであれば、objdump などを使うことが多い。ここでは、gdb を紹介する。
gdb(GNU Debugger)は、Cコンパイラ(gcc = GNU C Compiler)のためのデバッガ。linux だとプログラムが異常終了すると、coredump(実行時のメモリ内容を出力する機能) するので、この情報でプログラムの異常処理を探す時に使う。
デバッガは通常はインストールされないよな。
$ sudo apt-get install gdb
((( 基本的使い方 )))
a.out は、何らかのC言語のソースで事前に作っておくこと。
| // helloworld.c
| #include <stdio.h>
| int main() {
| printf( "Hello World¥n" ) ;
| return 0 ;
| }
$ gcc helloworld.c
$ gdb a.out
(gdb) break main # main にブレークポイントを設置
(gdb) run # プログラムを実行
(gdb) step 10 # 10行分処理を実行
(gdb) disas main # main 以降を逆アセンブル
(gdb) quit
((( 異常処理とその場所を見つける )))
異常終了するプログラムの例
| // segv.c
| #include <stdio.h>
| int main() {
| *((int*)NULL) = 123 ; # 0番地にデータを書き込む
| return 0 ;
| }
$ gcc -g segv.c # コンパイル時に名前情報を実行プログラムに埋め込む。
$ ulimit -c unlimited # coredump 機能を有効にする
$ ./a.out
Segmentation fault (コアダンプ)
$ gdb a.out core # 異常終了した行が表示される
Perl CPAN更新溜まってた
Perl の CPAN モジュールが溜まってた。
過去メモに沿って、更新
(( アップデート可能なモジュールを一覧 )) # perl -MCPAN -e 'CPAN::Shell->r' (( 全部をアップデート )) # perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'
iphoneの検知難しい
大学でアパート住まいの子供が、帰っているのか確認するために、LINE beacon を置いて検知を試したけど、bluetooth を切って既読スルーなヤツなので、ほとんど検知することができない。
そこで、アパートでは無線LANルータを使ってるし Raspberry-Pi で、arpalert を使えば簡単に検知できるだろうと、実験中。でも iPhone はセキュリティ対策なのか、 arp の返答は必要最小限なので同じサブネットとはいえ、そのままでは通信の必要の無い raspberry-pi には、ARP 情報が送られてこない。また ping には返答しないようで、単純に ping で確認も困難。ということで単純な arpalert では検知が難しいなぁ。
定時処理で、”arping -c 1 -I wlan0 IPHONEのIPアドレス” を実行させて、強制的に ARP を送ってもらうか…
cec-clientのデバイス番号とアドレス番号
自宅では、テレビやケーブルテレビチューナーやレコーダを赤外線リモコンで制御できるようにしているが、電源はトグル動作でON→OFFかOFF→ONという制御ができない。そこで、HDMI端子経由のチャンネル制御を行っている。
この際に、デバイス番号とcecのアドレス番号を使うが、デバイス番号が時々変化している。
しかたがないので、cecのscan処理でデバイス番号とアドレス番号の対応情報を保存するようにしてみた。
#!/usr/bin/perl
my $cec = "/usr/bin/cec-client -d 1 -s" ;
open( my $fd , "/bin/echo 'scan' | $cec |" )
|| die( "Can't open $cec\n" ) ;
open( my $ft , "> /home/xxxxxxxx/lib/cec-table.sh" )
|| die( "Can't open cec-table.sh\n" ) ;
my $device = "" ;
my $dev_str = "" ;
my $address = "" ;
my $osd_str = "" ;
print $ft "#!/bin/bash\n" ;
while( my $line = <$fd> ) {
if ( $line =~ /^device\s+#(\d+):\s+(.*?)$/ ) {
$device = $1 ;
$dev_str = $2 ;
} elsif ( $line =~ /^address:\s+(\d+)\.0\.0\.0$/ ) {
$address = $1 ;
} elsif ( $line =~ /^osd\s+string:\s+(.*?)$/ ) {
$osd_str = $1 ;
print $ft "DEV[$address]=$device\n" ;
print $ft "OSD[$address]=\"$osd_str\"\n" ;
}
}
close( $fd ) ;
close( $ft ) ;
stretchで起動しづらい
自宅で色々と動いている Raspberry-Pi 。OS更新はまめにやっているけど、外気温測定に使っているのが Jessie のままだったのに気づく。stretch に上げたけど、どうも起動に失敗する。更新に失敗したかと思ったけど、キーボードをつなぐために USB WiFi を抜いて起動すると、普通に動いている。
今までも、多少 boot が不安定なのはあったけど、stretch になって起動シーケンスが最適化されたのか、WiFi 有効化のタイミングが早まり、ブート時の電力不足が発生していると思われる。
ひとまず、改造面倒だし USB WiFi を抜いて、boot がそれなりに進んでから USB を指して対応。
アマチュア無線: aprx を動かしてみた
知り合いより譲り受けた、TH-D72を活用したいということで、APRS の iGate 局を動かしてみた。
我が家は、ロケーション的に福井市にあるリピータにも、ハンディ機では接続できず、無線機の位置情報などをインターネットに伝えることができる APRS や、インターネットを経由した通話ができる D-STAR などを、あまり活用することが難しい。
aprx を動かす
そこで、TH-D72 を APRS の iGate 局として動かすために、aprx をインストール。
以下のように設定したけど、まずい所がないか要チェックだな。ひとまず、データ流しまくりでaprsインターネット側には、迷惑をかけていないはず。ハンディ機なので、どのあたりまで電波が飛んでいるのか、チェックしてみよう。
$ sudo aptitude install aprx $ sudo vi /etc/aprx.conf $ sudo systemctl enable aprx.service $ sudo systemctl start aprx.service
# /etc/aprx.conf
mycall JR9PVZ-10
myloc lat 3553.48N lon 13613.33E
<aprsis>
passcode 22202
server rotate.aprs2.net
</aprsis>
<logging>
pidfile /var/run/aprx.pid
rflog /var/log/aprx/aprx-rf.log
aprxlog /var/log/aprx/aprx.log
dprslog /var/log/aprx/dprs.log
</logging>
<interface>
serial-device /dev/ttyUSB1 9600 8n1 KISS
initstring "HBAUD 9600\x0dKISS ON\x0dRESTART\x0d"
alias RELAY,WIDE,TRACE
callsign $mycall # callsign defaults to $mycall
tx-ok true # transmitter enable defaults to false
telem-to-is false # set to 'false' to disable
</interface>
<beacon>
beaconmode both
cycle-size 60m
beacon symbol "I#" $myloc comment "Tx-iGate + Digipeater"
</beacon>
<digipeater>
transmitter $mycall
<source>
source $mycall
</source>
</digipeater>
TH-D72の設定
| [TNC]-[TNC] | KISSモード | |
| [メニュー]-310 | データバンド | A-BAND |
| [メニュー]-311 | パケットスピード | 9600 bps |
| — | 無線周波数 | 144.640 MHz |
Postieでimap-ssl接続に失敗
職場のサーバでWordPressを動かす中、簡単な画像付きメールでのポストをするために、plugin の Postie を使っている。
状況確認
当初は、imap-ssl で動かしていたのだが、接続に失敗するようになった。
Postie (v 1.9.32) getemails: There was an error connecting to the server
メールサーバが、自宅メールサーバなので、FireWall 関連の設定のミスが考えられたが、nagios-plugins を入れて実験すると、以下のような結果なので、接続はできている。
$ /usr/lib/nagios/plugins/check_imap -p 993 -H xxxx -S IMAP OK - 0.146 second response time on xxxx port 993 [* OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ AUTH=PLAIN] Dovecot (Debian) ready.] |time=0.145649s;;;0.000000;10.000000
問題点
原因を確認ということで、syslog を確認すると、以下のように SSL のハンドシェークでエラーが出ている。
Mar 24 00:50:39 xxxx dovecot: imap-login: Disconnected (no auth attempts in 0 secs): user=<>, rip=xx.xx.xx.xx, lip=192.168.xx.xx, TLS handshaking: SSL_accept() failed: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca: SSL alert number 48, session=<xxxxxx>
暫定の解決法
しかたがないので、dovecot の ssl の設定を変更、TLSv1.2 になっていた部分を TLSv1 に修正
(( /etc/dovecot/conf.d/10-ssl.conf )) - ssl_min_protocol = TLSv1.2 + ssl_min_protocol = TLSv1
”TLS 1.0にはBEASTやPOODLEといった脆弱性があり、一定の条件下であれば暗号解読が可能であると言われています。”で、2018年6月30日以降は、TLSv1.0 は通常用途では勧められないとのことなので、多少心配ではあるけど…。
通常使っているメールソフトは、TLSv1.0 を使わないだろうし、実質このPostieだけの利用だろうし。
he.net を使った IPv6 トンネル
IPv6 の導入の実験として、IPv6トンネルを無料で利用できる he.net を使って設定してみた。
現在、自宅サーバ自体を IPv6 対応することはできたけど、サーバ配下のパソコンもこのトンネルを使うようにできていないので、まだ目標の半分。
he.netへの登録
Hurricane Electric(he.net)の接続方法を紹介しているサイトの記事を見ながら、he.net に利用者登録をして、トンネルの割り当てを受ける。
トンネル起動の設定
he.netのサイトで、上記の登録が終わると、”Example of Configuration”のタブで、OSを選べば、接続するための設定ファイルのサンプルが表示される。
ただ、Debian/Ubuntu を選ぶと、/etc/network/interfaces 用の設定が示された。自宅サーバは systemd を使っているので、このままでは使えない。ほかのサイトで調べて、最終的に以下に落ち着いた。
(( /etc/systemd/system/he-ipv6.service )) [Unit] Description=he.net IPv6 tunnel After=network.target [Service] Type=oneshot RemainAfterExit=yes ExecStart=/bin/ip tunnel add he-ipv6 mode sit remote 74.82.xx.xx local 192.168.yy.yy ttl 255 ExecStart=/bin/ip link set he-ipv6 up mtu 1480 ExecStartPost=/bin/sleep 0.3 ; /bin/ip -6 route add ::/0 dev he-ipv6 Execstop=-/bin/ip -6 route del ::/0 dev he-ipv6 ExecStop=/bin/ip link set he-ipv6 down ExecStop=/bin/ip tunnel del he-ipv6 [Install] WantedBy=multi-user.target
systemd の サービス として設定するために、he-ipv6.service ファイルを作成する。
systemd ではサービスの処理を起動/停止するためのコマンドは、ExecStart / ExecStop に記載する。
“ip tunnel add” の remote 欄は、割り当てられたhe.net のIPアドレス、localには自分のグローバルアドレスを指定する。ただし、自宅サイトはルータ内にサーバがあるので、ポートフォワードされたプライベートのアドレスを指定する。
トンネル開通後のIPv6のデフォルトゲートウェイを設定する “ip -6 route add” の実行は、少し間を置かないと失敗するようなので、若干の sleep を挟んだ。ExecStart 行は、通常1行1コマンドしか使えないが、ExecStartPost は、複数コマンドが書けるので、こういう時には便利。
ExecStop でのデフォルトゲートウェイ削除の処理 “ip -6 route del ::/0″では、前述のsleepが無い場合、エラーが出ることがあるので、コマンドの先頭に”-“をつけエラーで止まらないようにしておいた。
# サービスの登録 $ sudo systemctl enable he-ipv6.service # サービスの起動 $ sudo systemctl start he-ipv6.service # サービスの停止 $ sudo systemctl stop he-ipv6.service
ただし、後にも述べるように常時 IPv6 化は現状では問題があるので、systemctl enable は行わないでおく。
RAの設定(ルーティング広告)
ルータ周りの他のパソコンがグローバルなIPv6アドレスが割り当てられるように、RAの設定を行う。実は、リンクローカル”fe80::”での自宅内IPv6ネットワークの運用では、グローバルIPv6が無いので RA が不要だけど、IPv6の DNS をアナウンスが必要なので、今までは DHCPv6 を使っていた。でも、radvd.conf の設定を調べると、アナウンスするプレフィックス設定の欄を “prefix ::/64” と記載すれば、”fe80::”のリンクローカルはアナウンスされないようなので、radvd に変更。”RDNSS”の欄で、自宅内 IPv6 対応なDNSサーバを指定することで、IPv6経由で名前解決をできるようにしておく。
interface eth0
{
AdvSendAdvert on;
AdvManagedFlag on;
AdvOtherConfigFlag on;
# 非リンクローカルなアドレスだけアナウンス
prefix ::/64
{
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr on;
};
# DNSは、リンクローカルなDNSサーバをアナウンス
RDNSS fe80::xxxx:xxxx:xxxx:xxxx
{
AdvRDNSSLifetime 30;
};
DNSSL example.jp {
AdvDNSSLLifetime 30;
};
};
この段階で、IPv6 のファイアウォールの設定(ferm)の設定が間違っているのが判明したので、別途修正。
常時IPv6対外接続は問題あり
よく、IPv6 を使うとネット通信速度が速くなると言われているけど、現時点では IPv6 利用者が少ないので、上流が詰まらないだけ。今回のような、IPv4 を使ったIPv6トンネリングでは、IPv4 以上には速くなるはずもないし、IPv6 も無料でサービスを提供している he.net では、上流の輻輳もあるだろうし高速通信も期待できない。
このため、上記の IPv6 接続は単なる自分の勉強用で、必要な時だけ”systemctl start he-ipv6.service”でトンネル接続させる予定。。当面、常時 IPv6 運用はしないだろう。
emacsをsystemdで起動
Linux で OneDrive のクライアントを systemd で起動する方法を知って、”systemctl –user” でできることを調べてみたら、emacs server も systemd で使えるような設定がデフォルトで入ってた。
emacs server
emacs server とは、emacs を常に使いまくるような人向けに、emacs をサーバで起動しておき、emacsclient から起動させる機能。
emacsclient は、端末画面を割り当てるだけなので、emacs のプロセスを1つにできる。
(( emacs server 起動)) $ emacs --daemon (( emacs を使う )) $ emacsclient -nw # emacsエディタの起動 $ emacsclient -e "(kill-emacs)" # 起動したemacs serverを止める
systemd で起動
最近は、”/usr/lib/systemd/user/emacs.service” が書いてあるから、以下のコマンドで簡単にemacsサーバを起動できる。
$ systemctl --user enable emacs # emacs起動を登録しておく $ systemctl --user start emacs # emacs serverを起動
とはいえ、最近は emacs でなんでもする訳でもないし、サーバに無駄な常駐させたくないから、しないけど。
linuxでOneDriveを使う
macOS用のonedriveアプリも更新され、オンデマンド機能が便利。以前は、使わないファイルの同期を外したり、利用頻度の低いファイルのパソコン側のディスク容量圧迫の心配がなくなった。
利便性が上がったし、linux 環境でも改めて使いたくなってきた。以前は、onedrive-d というソフトがあったけど、同じように開発されていた、onedrive の完成度があがってる。
linux用のonedriveを使ってみる。
OneDriveのインストール
$ sudo aptitude install onedrive
認証設定
最初の認証設定を行う。以前のバージョンで設定が残っているようなら、”rm -rf ~/.config/onedrive/” で消せばいい。
$ onedrive Authorize this app visiting: ...URL... このURLをブラウザでアクセスし、OneDriveの認証を行う。 この後、真っ白なページが表示されるので、 このページのURLをコピーする。 Enter the response uri: ここにURLをペースト
これで、使える状態になり同期が始まるけど、OneDrive をサービスで起動させたままにしたいので、ひとまず Ctrl-C で停止させる。
常駐起動させる
新しいバージョンでは、通常ユーザ状態での systemctl 起動に対応しているので、以下のコマンドで、自動起動の登録、および起動を行う。
$ systemctl --user enable onedrive $ systemctl --user start onedrive






