君は心理学者なのか?

大学時代に心理学を専攻しなぜかプログラマになった、サイコ(心理学)プログラマかろてんの雑記。

盗み聞きしてみた(コンテナ上のnginxプロセスと、ホスト間の通信パケットをtcpdumpでキャプチャしてみた〜CoreOS toolboxを使ってみる〜)

f:id:karoten512:20180112224543p:plain

パケットキャプチャとは

サーバさんたちがどんなおはなしをしているのか、

ぬすみぎきすることだよ(白目)

いきさつ

ホスト間とコンテナ上のnginxがどういう通信をしているのか気になった。

普通のサーバへの通信と変わらないのかな。

こういうときは実験だ。

盗み聞きまでの手順

nginxコンテナを起動

$ docker pull nginx:latest
$ docker run --name nginx_test -d -p 8080:80 nginx:latest

CoreOSにtcpdumpを入れる

qiita.com

CoreOS toolboxを使用すると、tcpdumpが使えるみたい。

盗み聞きする

Docker上で走っているコンテナとホスト間は、

docker0という仮想ブリッジでつながっている。

(ホスト上でifconfigをするとdocker0があることがわかるよ)

なのでdocker0を盗みぎきするNICに設定。

$ tcpdump -i docker0

結果

14:06:21.082183 IP 172.17.8.1.55248 > 172.18.0.6.http: Flags [S], seq 584948487, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1315360133 ecr 0,sackOK,eol], length 0
14:06:21.082237 IP 172.18.0.6.http > 172.17.8.1.55248: Flags [S.], seq 636172623, ack 584948488, win 28960, options [mss 1460,sackOK,TS val 3302158741 ecr 1315360133,nop,wscale 7], length 0
14:06:21.083531 IP 172.17.8.1.55248 > 172.18.0.6.http: Flags [.], ack 1, win 4117, options [nop,nop,TS val 1315360133 ecr 3302158741], length 0
14:06:21.083662 IP 172.17.8.1.55248 > 172.18.0.6.http: Flags [P.], seq 1:587, ack 1, win 4117, options [nop,nop,TS val 1315360134 ecr 3302158741], length 586: HTTP: GET / HTTP/1.1
14:06:21.083677 IP 172.18.0.6.http > 172.17.8.1.55248: Flags [.], ack 587, win 236, options [nop,nop,TS val 3302158743 ecr 1315360134], length 0
14:06:21.083835 IP 172.18.0.6.http > 172.17.8.1.55248: Flags [P.], seq 1:181, ack 587, win 236, options [nop,nop,TS val 3302158743 ecr 1315360134], length 180: HTTP: HTTP/1.1 304 Not Modified
14:06:21.084186 IP 172.17.8.1.55248 > 172.18.0.6.http: Flags [.], ack 181, win 4112, options [nop,nop,TS val 1315360134 ecr 3302158743], length 0

ちょっと見てみる。

パケット解析

3 way hand shake

サーバ同士でお話するときはいきなり話しかけない。

「ちょっとお話しませんか?」

「いいですよ。こっちもちょっと話していいですか?」

「いいですよ」

という紳士的なやり取りをして、はじめてお話が始まる。

それを

3 way hand shake

という。

↓ その痕跡がこれ

(1)IP 172.17.8.1.55248 > 172.18.0.6.http: Flags [S]
(2)IP 172.18.0.6.http > 172.17.8.1.55248: Flags [S.], ack
(3)IP 172.17.8.1.55248 > 172.18.0.6.http: Flags [.], ack

ここで大事なのはFlags[S]ack

(1)接続元が接続先に対して「ちょっとお話しませんか?」と聞いている

Flags [S]は、

SYN(コネクション確立要求)の先頭文字。

相手に対して、

「ちょっとお話しませんか?」と聞いてる感じ。

(2)接続先が接続元へ「いいですよ。私も話していいですか?」と聞いている

ack が「いいですよ」

S が「私も話していいですか?」

(3)接続元が接続先へ「いいですよ」いってる。

ack が「いいですよ」

この3つの過程を経て、ようやく通信ができるようになる。

GETリクエス

IP 172.17.8.1.55248 > 172.18.0.6.http: (省略) HTTP: GET / HTTP/1.1

/ ディレクトリへアクセス。

確認応答

IP 172.18.0.6.http > 172.17.8.1.55248: Flags [.], ack 587

ここは勉強不足で、どこらへんが確認応答なのかわかっていない…

レスポンス

172.18.0.6.http > 172.17.8.1.55248: (省略) HTTP: HTTP/1.1 304 Not Modified

何度か通信していたので、取得したコンテンツが更新されていないことが確認できた。

まとめ

コンテナ - ホスト間の通信は、

普通のhttp通信と同じようにみえる。

違うのは、docker0という仮想ブリッジを通した通信だ、ということくらいかな。

CoreOS toolboxに入れない〜Failed to allocate scope: Unit core-fedora-latest.scope already exists.〜

f:id:karoten512:20180112225511p:plain

CoreOS toolbox使ってたらこんなエラーがでた

CoreOSでtoolboxコンテナを使い、

Ctrl-wで無理やりコンテナを抜けた。

そしていつものようにtoolboxを起動したら、

$ /usr/bin/toolbox

らこんなエラーがでた。

Failed to allocate scope: Unit core-fedora-latest.scope already exists.

困ったぞ。

stack overflowの記事

github.com

Fedra25だと起こる問題みたい。

対処

dockerホスト上で、以下のコマンド実行。

$ echo "TOOLBOX_DOCKER_TAG=24" >>$HOME/.toolboxrc

その上でもいちど

$ /usr/bin/toolbox

いつものtoolboxコンテナに入れた。

Dockerでたてたコンテナにtelnet-serverを入れて、telnetでコンテナ間通信ができるようにしてみた

f:id:karoten512:20180110003655p:plain

いきさつ

networkやセキュリティ、telnetデーモンを叩き起こすxintedの勉強がてらやってみた。

手順

0. 準備

0-1. telnet-server用のコンテナを走らせる

$ docker pull centos:centos7
$ docker run --privileged -d --name centos_test centos:centos7 /sbin/init

なお、telnet-serverコンテナでは、

後程systemdを用いてサービスを走らせるので、

--privilegedと/sbin/initが必要になってくる。

qiita.com

0-2 telnet-client用のコンテナを走らせる

$ docker run -d --name telnet-client centos:centos7

1. telnet-serverコンテナの設定

1-1. telnet-serverのinstall

$ docker exec -it telnet-server /bin/bash
# yum -y install telnet-server

1-2. リモートホストからのアクセス制御の設定をする

他のサーバからのアクセスを制御します。

すべてのhost/すべてのサービスからのアクセスを拒否します。

# echo 'ALL: ALL' >> /etc/hosts.deny

特定のサービス/特定のホストからのアクセスを許可します。

# echo 'in.telnetd: 172.18.0.5' >> /etc/hosts.allow

telnetデーモンに対して、172.18.0.5からアクセスがあった場合は許可します。

なお、172.18.0.5はtelnet-clientコンテナのipアドレス

1-3. xinetdの設定

# vi /etc/xinetd.d/telnet

以下を追記します。

service telnet
{
    flags       = REUSE
    socket_type = stream
    wait        = no
    user        = root
    server      = /usr/sbin/in.telnetd
    log_on_failure  += USERID
    disable     = no
}

2. telnet-serverの起動

# systemctl status telnet.socket

3. telnet接続用のuserを作成する

# useradd telnet-user
# passwd telnet-user
Changing password for user telnet-user.
New password:
Retype new password: 

4. telnet-clinentコンテナの設定

4-1. telnet-clinentのinstallをする

$ docker exec -it telnet-client /bin/bash
# yum install -y telnet

4-2. 接続

いちおう、サーバ側のポートが空いていることを確認してみる。

$ nmap -sV -PE -p 23 172.18.0.4
Starting Nmap 6.40 ( http://nmap.org ) at 2018-01-09 16:00 UTC
Nmap scan report for 172.18.0.4
Host is up (0.000039s latency).
PORT   STATE SERVICE VERSION
23/tcp open  telnet  Linux telnetd

あいてた。

$ telnet 172.18.0.4 23
Trying 172.18.0.4...
Connected to 172.18.0.4.
Escape character is '^]'.

Kernel 4.14.11-coreos on an x86_64
f71734bf26ca login: telnet-user
Password: 
Last login: Tue Jan  9 16:07:51 from 172.18.0.5

入れた!

感想

コンテナからコンテナにtelnetログインするだけでそれなりの作業量となる。

色々勉強になった。

参考

kajuhome.com

apt-get updateは何を行っているのか調べてみた〜パッケージインデックスファイルとは何か〜

f:id:karoten512:20180109003450p:plain

結論

$ apt-get update

は、パッケージリストの更新を行う。

具体的に言うと、

/etc/apt/sources.list

にかかれているURLから、

パッケージインデックスファイルを引っ張ってきて、

$ cd /var/lib/apt/lists

に格納している。

いきさつ

1. Dockerで構築したubuntuにてfileコマンドが使えない

$ file
bash: file: command not found

2. fileコマンドをinstallしてみる

$ apt-get install file
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package file

まじか。。 installできない。

3. fileコマンドがないことをdpkgコマンドで確かめる

$ dpkg -K file
dpkg-query: package 'file' is not installed

やっぱりないね。

なんでや

apt-getについて調べてみると、

以下の記事が見つかった。

kledgeb.blogspot.jp

つまり、

apt-get install package_name

を実行した際には、

$ cd /var/lib/apt/lists

にある

パッケージインデックスファイルを参照して、

その中に含まれるパッケージがinstallされる。

対処

1. パッケージインデックスファイルがあるかどうか確認

$ cd /var/lib/apt/lists
$ ls

パッケージインデックスファイルが、空。

参照されるインデックスファイルがないので、

このままではinstallできない。

2. パッケージインデックスファイルのダウンロード

つまり、パッケージリストの更新を行う。

$ apt-get update
/etc/apt/sources.list

に指定されているリストにもとづいて、

パッケージインデックスファイルがダウンロードされる。

3. パッケージインデックスファイルを確認

$ ls
archive.ubuntu.com_ubuntu_dists_xenial-backports_InRelease
archive.ubuntu.com_ubuntu_dists_xenial-backports_main_binary-amd64_Packages.lz4
archive.ubuntu.com_ubuntu_dists_xenial-backports_universe_binary-amd64_Packages.lz4
archive.ubuntu.com_ubuntu_dists_xenial-updates_InRelease
archive.ubuntu.com_ubuntu_dists_xenial-updates_main_binary-amd64_Packages.lz4
archive.ubuntu.com_ubuntu_dists_xenial-updates_multiverse_binary-amd64_Packages.lz4
archive.ubuntu.com_ubuntu_dists_xenial-updates_restricted_binary-amd64_Packages.lz4
archive.ubuntu.com_ubuntu_dists_xenial-updates_universe_binary-amd64_Packages.lz4
archive.ubuntu.com_ubuntu_dists_xenial-updates_universe_source_Sources.lz4
archive.ubuntu.com_ubuntu_dists_xenial_InRelease
archive.ubuntu.com_ubuntu_dists_xenial_main_binary-amd64_Packages.lz4
archive.ubuntu.com_ubuntu_dists_xenial_multiverse_binary-amd64_Packages.lz4
archive.ubuntu.com_ubuntu_dists_xenial_restricted_binary-amd64_Packages.lz4
archive.ubuntu.com_ubuntu_dists_xenial_universe_binary-amd64_Packages.lz4
archive.ubuntu.com_ubuntu_dists_xenial_universe_source_Sources.lz4
lock
partial
security.ubuntu.com_ubuntu_dists_xenial-security_InRelease
security.ubuntu.com_ubuntu_dists_xenial-security_main_binary-amd64_Packages.lz4
security.ubuntu.com_ubuntu_dists_xenial-security_multiverse_binary-amd64_Packages.lz4
security.ubuntu.com_ubuntu_dists_xenial-security_restricted_binary-amd64_Packages.lz4
security.ubuntu.com_ubuntu_dists_xenial-security_universe_binary-amd64_Packages.lz4
security.ubuntu.com_ubuntu_dists_xenial-security_universe_source_Sources.lz4

たしかにパッケージインデックスファイルがダウンロードされた。

4. fileコマンドをinstall

$ apt-get install file

今度はinstallできた。

5. fileコマンドを実行

$ file
Usage: file [-bcEhikLlNnprsvzZ0] [--apple] [--extension] [--mime-encoding] [--mime-type]
            [-e testname] [-F separator] [-f namefile] [-m magicfiles] file ...
       file -C [-m magicfiles]
       file [--help]

fileコマンドが入った。

まとめ

installしたばかりのubuntuには、

パッケージをinstallする際に参照するインデックスファイルが存在しない。

なので、パッケージをinstallすることができない。

よって、

はじめにインデックスファイルをダウンロード(更新)する必要がある。

そのために用いられるのが

$ apt-get update

であり、

その結果

$ cd /var/lib/apt/lists

にあるパッケージインデックスファイルが更新される。

間違えてリモートにpushしたcommitを元に戻す

手順

$ git log

して、取り消したいコミットのハッシュをコピー

$ git revert ハッシュ

して、

コミットを取り消すコミットをする(ややこしい)

$ git push origin master

remoteにpush

まとめ

自分のブランチならいいけど、

他の人も使っているブランチならやらないほうが良いよね。

pushするまえならgit resetを使用すること。

【ホワイトハッカー入門】サーバの開いているポートとサービスをnmapで特定する。ついでにOS情報も拾ってくる

f:id:karoten512:20180108114234j:plain

ホワイトハッカーとは

ハッキングの手法を熟知し、それを防御のために使ういいハッカー

対義語はブラックハットハッカーとかクラッカーとか言われる。

ハッカーの攻撃手法

ハッカーの攻撃手法は、だいたい以下の用な手順になる。

  • 偵察

  • スキャニング

  • アクセス権の取得

  • アクセスの維持

  • 痕跡の消去

今回はこのスキャニングにチャレンジしてみる。

※ くれぐれも公開されているサーバに対してこれを行わないように

はじめてのポートスキャン

立ち上げているVMにたいしてポートスキャンを行う。

nmap -sV -O -PE 192.168.33.0/24

-sVオプション

バナー情報(サービスのバージョンなど)を収集する。

-Oオプション

OSの種類とバージョンを教えてくれる。

結果

Starting Nmap 7.60 ( https://nmap.org ) at 2018-01-08 11:28 JST
Nmap scan report for 192.168.33.50
Host is up (0.00051s latency).
Not shown: 998 closed ports
PORT    STATE SERVICE VERSION
22/tcp  open  ssh     OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0)
111/tcp open  rpcbind 2-4 (RPC #100000)
MAC Address: 08:00:27:7F:5E:D0 (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.8
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Nmap scan report for 192.168.33.91
Host is up (0.00037s latency).
Not shown: 996 closed ports
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 5.3 (protocol 2.0)
80/tcp   open  http    Apache httpd 2.2.15 ((CentOS))
111/tcp  open  rpcbind 2-4 (RPC #100000)
3306/tcp open  mysql   MySQL (unauthorized)
MAC Address: 08:00:27:F4:E4:AA (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 2.6.X|3.X
OS CPE: cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3
OS details: Linux 2.6.32 - 3.10

攻撃者にとって何が嬉しいか

ポートで動いているサービスがわかるので、

バージョンなどから脆弱性が判明する。

そうすると攻撃ができる。

防御するためにはどうしたらよいか

nmapはICMPプロトコルを使用しているので、

ICMPプロトコルを拒否するような設定を

サーバにしてやれば良いと思う(まだやったことないので後々調べます)

ハッキングがテーマのノベルゲーム「CyberRebeat」に触発されて、CTFの練習問題「Basic is secure?」を解くためにパケットキャプチャを使ってみた【CTF入門】

CyberRebeatとは

ハッキングを題材したノベルゲーム。

f:id:karoten512:20180107195427p:plain

CyberRebeat -The Fifth Domain of Warfare-

作中、とあるハッカーはこう言います。
"僕らにとって、世界は不安なほどに穴だらけだ"、と。
ボタン一つでネットに繋がっているOA機器が検索でき、
10ドル出せばハッキングツールが説明書付きで手に入るこの時代。
本作では"CTF"と呼ばれる、現実に存在しているハッキング競技を皮切りに、
彼らの世界、その一端を描き出します。

CTFとは

コンピュータ・セキュリティ技術を用いた競技。

すごく簡単に言うと、ハッキング大会。

最近少し興味が湧いてきた。

CTF競技内容

主に2つある。

  • attack/defense style

攻防戦形式(英語:attack/defense style)では、 各チームに守るべきコンピュータ(または小規模なネットワーク)が割り当てられ、 自チームのコンピュータに対する相手からの攻撃の防御成功、 及び相手のコンピュータに対する攻撃の成功に対し得点が与えられる。 個々のCTFのルールによって、 相手のコンピュータに侵入して情報を奪う(相手の旗を奪う)又は情報を書き込む(自分の旗を立てる)ことを企図する。

  • jeopardy style

クイズ形式。出題された問題に隠されたFlagを手に入れ、

提出してポイントを貰う。

キャプチャー・ザ・フラッグ - Wikipedia

※「Capture The Flag」の略がCTF

入門として

以下のサイトに練習用の問題がある。

ksnctf.sweetduet.info

今回チャレンジした問題

ksnctf.sweetduet.info

手順

リンクからq8.pcapをダウンロード

wiresharkで読み込む

f:id:karoten512:20180107195955p:plain

パケットがいっぱい出てきた(小並感)

気になるところを読む

f:id:karoten512:20180107200818p:plain

この問題はBasic認証

レスポンスヘッダに200 OKとでていることから、

Basic認証が成功したことがわかる。

4(レスポンス)をみてみる

実際のパケットのHTTPレイヤを見てみるとこんな感じ。

f:id:karoten512:20180107200956p:plain

成功してるっぽい。

「The flag is q8's password.」とある。

3(リクエスト)を見てみる

f:id:karoten512:20180107201543p:plain

あ。。あった。

感想

パケットキャプチャとBasic認証の知識があれば何となくいける問題だった。

この調子で他の問題も解いていこうと思う(networkとかwebを中心に)