[TryHackMe] Ninja Skills - Walkthrough -

本稿では、[TryHackMe](https://tryhackme.com/)にて提供されている「[Ninja Skills](https://tryhackme.com/room/ninjaskills)」ルームに関する攻略方法（Walkthrough）について検証します。
「Ninja Skills」は「free room」（**無料**）で提供されています。購読を必要とせずに仮想マシンを「展開（Deploy）」することができます。

>「Ninja Skills」ルームに取り組むにあたり、事前に次のルームを修了させておくことをオススメします。
>
>- [Learn Linux](https://tryhackme.com/room/zthlinux) - A guided room designed to teach you the Linux basics!
>- [The find command](https://tryhackme.com/room/thefindcommand) - A learn-by-doing approach to the find command

「Ninja Skills」ルームにて学ぶことのできるコマンドは次のとおりです。

- find
- touch
- ls
- grep
- cat
- sha1sum
- wc
- bashスクリプト（whileループ処理）
- 正規表現（Regular expression）

はじめに、`[Deploy]`ボタンをクリックし、課題となっているマシンを起動します。

![Ninja_Skills.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/ebff454f-d87e-0abe-0a28-ca61921c4838.png)

「Ninja Skills」ルームでは、Webベースのマシンが提供されています。ブラウザのみでこのルームを攻略することが可能です。`[Access in browser]`ボタンをクリックすると全画面表示されます。
![browser.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/c50bfb04-2edf-ecb2-80c4-f48130b4de7b.png)

また、自身のマシン（ここでは、`Kali Linux`）を用意して攻略することも可能です。
あらかじめ、`TryHackMe`が提供するネットワークとVPN接続を行った上で、SSH接続します。このとき使用するアカウントは「new-user; new-user」です。

>OpenVPNを使用したネットワークの接続方法については、次のルームにて学ぶことができます。
>
>- [OpenVPN](https://tryhackme.com/room/openvpn) - A guide to connecting to our network using OpenVPN.

```
kali@kali:~$ ssh new-user@10.10.50.177
new-user@10.10.50.177's password:new-user
```

![SSH.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/a8c3db91-3bdd-b832-581b-f1db3aa207d0.png)

「Ninja Skills」ルームではTASKにて指定された条件のファイルを「`find`」コマンドを駆使して探し出す課題が出題されています。

# TASK 1
>Which of the above files are owned by the best-group group(enter the answer separated by spaces in alphabetical order)

どのファイルが`best-group`グループに所属しているの探し出す課題です。

グループに基づいてファイルを検索するために`-group`オプションを指定します。すべてのディレクトリ（ルートディレクトリ）「`/`」に対して`best-group`に所属しているファイルを「`find / -group best-group`」コマンド構文で検索します。
検索ルートディレクトリ「`/`」を指定した場合、コマンド構文の実行ユーザーアカウントにて権限を有していない場所も検索することになります。このような場合、大量のエラーメッセージが表示されます。そこで、「`2>/dev/null`」コマンド構文を付け加え、エラーメッセージを「捨てる」指定を行っています。

```
[new-user@ip-10-10-50-177 ~]$ find / -group best-group 2>/dev/null
/mnt/D8B3
/home/v2Vb
```

「Ninja Skills」ルームでは、複数の場所に存在する12ファイルが解答となるようにTASKが設計されています。
以降のTASKでは、次の2通りの方法で解答を行います。

- リストファイルを使用した検索
- ワンライナーを利用した検索

いずれの検索方法でも得られる結果は同じです。

## リストファイルを使用した検索
次の手順にて`best-group`グループに所属しているファイルを検索します。

<ol><li> `touch`コマンドでサイズが「0」のファイル（`search.txt`）を作成します。

```
[new-user@ip-10-10-50-177 ~]$ touch search.txt
```

<li>エディタにて、`search.txt`ファイルを編集します。「Ninja Skills」ルームにて指定されている12件のファイル名を書き写します。

```search.txt
8V2L
bny0
c4ZX
D8B3
FHl1
oiMO
PFbD
rmfX
SRSq
uqyw
v2Vb
X1Uy
```

<li>`find`コマンドでルートディレクトリを検索します。このとき、`grep`コマンドを使って検索範囲を指定します。「`-f search.txt`」オプションにて、`search.txt`ファイルに書かれているパターンを検索します。
最後に「`> found.txt`」にてコマンドの実行結果を **リダイレクト** します。このコマンド構文により、`found.txt`ファイルが新規作成されます。既存のファイルを指定した場合、新しい内容でファイルが上書きされるため注意が必要です。

```
[new-user@ip-10-10-50-177 ~]$ find / 2>/dev/null | grep -F -f search.txt > found.txt
[new-user@ip-10-10-50-177 ~]$ cat found.txt 
/mnt/D8B3
/mnt/c4ZX
/var/FHl1
/var/log/uqyw
/opt/PFbD
/opt/oiMO
/media/rmfX
/etc/8V2L
/etc/ssh/SRSq
/home/v2Vb
/X1Uy
```

<li>`cat`コマンドで`found.txt`ファイルの内容を表示します。表示結果を「`|`」（**パイプ**）で後段のコマンド構文に渡します。
`while`コマンドを使って同じ処理を繰り返し実行します。今回は、「`read`」コマンドにて、`cat`コマンドの表示結果（標準入力）から受け取った内容を1行単位で変数「`line`」に格納しています。
`while`コマンドでは、「条件が成立している間」繰り返し処理を行います。今回は、`found.txt`の全ての行を読み取れる間、コマンド「`do ls -al $line`」を実行します。

```
[new-user@ip-10-10-50-177 ~]$ cat found.txt | while read line; do ls -al $line; done
-rw-rw-r-- 1 new-user best-group 13545 Oct 23  2019 /mnt/D8B3
-rw-rw-r-- 1 new-user new-user 13545 Oct 23  2019 /mnt/c4ZX
-rw-rw-r-- 1 new-user new-user 13545 Oct 23  2019 /var/FHl1
-rw-rw-r-- 1 new-user new-user 13545 Oct 23  2019 /var/log/uqyw
-rw-rw-r-- 1 new-user new-user 13545 Oct 23  2019 /opt/PFbD
-rw-rw-r-- 1 new-user new-user 13545 Oct 23  2019 /opt/oiMO
-rw-rw-r-- 1 new-user new-user 13545 Oct 23  2019 /media/rmfX
-rwxrwxr-x 1 new-user new-user 13545 Oct 23  2019 /etc/8V2L
-rw-rw-r-- 1 new-user new-user 13545 Oct 23  2019 /etc/ssh/SRSq
-rw-rw-r-- 1 new-user best-group 13545 Oct 23  2019 /home/v2Vb
-rw-rw-r-- 1 newer-user new-user 13545 Oct 23  2019 /X1Uy
```

![task1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/fbfd5dc7-6a75-2b3a-4815-7160cd561500.png)

これにて、課題で出題されているファイルすべてのファイル属性情報を取得することができました。
なお、課題で指定されている`bny0`ファイルはどこのディレクトリにも存在しないようです。

## ワンライナーを利用した検索
「**ワンライナー**（one liner）」とは、何か特定の処理を「1行のプログラム」だけで実現する方法です。
リストファイルを使用した検索では、TASK 1を攻略するために、4つの工程を経ています。
ここでは、同様の処理を次のとおり役割を分けて、1行のプログラムで実現させます。

|コマンド & オプション|解説|
|:---|:---|
|`find / -type f`|`-type`で`f`を指定しファイルのみ検索対象とする。|
|`\( -name 8V2L -o -name bny0 ... -o -name X1Uy \)`|ファイル名などの複数の条件でマッチしたい場合`-or(-o)`で繋げる。|
|`-exec ls -la \;`|`-exec`で指定したコマンドを実行する。|
|`{}`|複数コマンドの出力を`{}`にてコマンドのグルーピング機能を使用しリダイレクトする。|
|`2>>/dev/null`|不要な `標準エラー出力` の表示を抑制する。|

`find`コマンドでは、検索式の他に「**アクション**」を指定して、コマンドを実行させることができます。
ここでは、`exec`アクションを使用します。
`exec`アクションは「`-exec コマンド オプション {} ;`」のように指定します。`{}`部分には、検索されたファイル名が入ります。
最後の「`;`」で、`exec`アクションに対するコマンドの終わりを示します。コマンドラインでは「`;`」がコマンドの区切りとして機能します。そこで、実行する際は「`\;`」と指定します。直前に空白文字が必要な点も注意してください。

```
[new-user@ip-10-10-82-158 ~]$ find / -type f \( -name 8V2L -o -name bny0 -o -name c4ZX -o -name D8B3 -o -name FHl1 -o -name oiM0 -o -name PFbD -o -name rmfX -o -name SRSq -o -name uqyw -o -name v2Vb -o -name X1Uy \) -exec ls -la {} \; 2>>/dev/null
-rw-rw-r-- 1 new-user best-group 13545 Oct 23  2019 /mnt/D8B3
-rw-rw-r-- 1 new-user new-user 13545 Oct 23  2019 /mnt/c4ZX
-rw-rw-r-- 1 new-user new-user 13545 Oct 23  2019 /var/FHl1
-rw-rw-r-- 1 new-user new-user 13545 Oct 23  2019 /var/log/uqyw
-rw-rw-r-- 1 new-user new-user 13545 Oct 23  2019 /opt/PFbD
-rw-rw-r-- 1 new-user new-user 13545 Oct 23  2019 /media/rmfX
-rwxrwxr-x 1 new-user new-user 13545 Oct 23  2019 /etc/8V2L
-rw-rw-r-- 1 new-user new-user 13545 Oct 23  2019 /etc/ssh/SRSq
-rw-rw-r-- 1 new-user best-group 13545 Oct 23  2019 /home/v2Vb
-rw-rw-r-- 1 newer-user new-user 13545 Oct 23  2019 /X1Uy
[new-user@ip-10-10-82-158 ~]$ 
```

![Task1'.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/7b394456-b576-d7fd-87f6-b0013e7c81de.png)

ワンライナーにて、リストファイルを使用した検索と同様の結果を得ることができました。

# TASK 2
>Which of these files contain an IP address?

どのファイルがIPアドレスを含むのか探し出す課題です。

この課題では、「IPアドレス」という規則性のある「文字の並び」を指定する表記法を検討する必要があります。このようなときに使われるのが、「**正規表現**（Regular Expression）」です。

IPv4アドレス形式に一致させるには、番号`[0-9]{1,3}`をピリオドで区切り、3回`{3}`チェックする必要があります`\.`別の番号で終わります。
[Regulex](https://jex.im/regulex/#!flags=&re=(%5B0-9%5D%7B1%2C3%7D%5B%5C.%5D)%7B3%7D%5B0-9%5D%7B1%2C3%7D)ツールで視覚化すると次のとおりです。

![Regulex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/eb6b6882-a6fb-1fb3-b423-099ce4dd5863.png)

## リストファイルを使用した検索
`echo`コマンドにて、個々のファイルの内容を出力します。
`grep`コマンドにて、出力結果と、前述の正規表現ルールとの照合を行います。このとき、「`-E`」オプションにて検索に拡張正規表現を使うように指定しています。また、「`-o`」オプションにて、一致した箇所だけを表示する指定をしています。

```
[new-user@ip-10-10-50-177 ~]$ cat found.txt | while read line; do echo $line; cat $line | grep -Eo "([0-9]{1,3}[\.]){3}[0-9]{1,3}"; done
/mnt/D8B3
/mnt/c4ZX
/var/FHl1
/var/log/uqyw
/opt/PFbD
/opt/oiMO
1.1.1.1
/media/rmfX
/etc/8V2L
/etc/ssh/SRSq
/home/v2Vb
/X1Uy
```

![task2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/37366674-55da-44ec-9687-228647cc4386.png)

## ワンライナーを利用した検索
TASK 1における`exec`アクションの指定内容を次のとおり変更します。

```
grep -Eo "([0-9]{1,3}[\.]){3}[0-9]{1,3}"
```

# TASK 3
> Which file has the SHA1 hash of 9d54da7584015647ba052173b84d45e8007eba94

どのファイルの`SHA1`ハッシュ値が`9d54da7584015647ba052173b84d45e8007eba94`であるのか探し出す課題です。

## リストファイルを使用した検索
`sha1sum`コマンドにて、個々のファイルのSHA1ハッシュ値を計算します。
`grep`コマンドにて、指定のハッシュ値と一致するファイルを照合します。

```
[new-user@ip-10-10-50-177 ~]$ cat found.txt | while read line; do echo $line; sha1sum $line | grep 9d54da7584015647ba052173b84d45e8007eba94; done
/mnt/D8B3
/mnt/c4ZX
9d54da7584015647ba052173b84d45e8007eba94  /mnt/c4ZX
/var/FHl1
/var/log/uqyw
/opt/PFbD
/opt/oiMO
/media/rmfX
/etc/8V2L
/etc/ssh/SRSq
/home/v2Vb
/X1Uy
```

![task3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/9e48619e-1957-3f3f-38c7-bee567c1812e.png)

## ワンライナーを利用した検索
TASK 1における`exec`アクションの指定内容を次のとおり変更します。

```
-exec sha1sum {} \;
```

```
[new-user@ip-10-10-82-158 ~]$ find / -type f \( -name 8V2L -o -name bny0 -o -name c4ZX -o -name D8B3 -o -name FHl1 -o -name oiM0 -
o -name PFbD -o -name rmfX -o -name SRSq -o -name uqyw -o -name v2Vb -o -name X1Uy \) -exec sha1sum {} \; 2>>/dev/null
2c8de970ff0701c8fd6c55db8a5315e5615a9575  /mnt/D8B3
9d54da7584015647ba052173b84d45e8007eba94  /mnt/c4ZX
d5a35473a856ea30bfec5bf67b8b6e1fe96475b3  /var/FHl1
57226b5f4f1d5ca128f606581d7ca9bd6c45ca13  /var/log/uqyw
256933c34f1b42522298282ce5df3642be9a2dc9  /opt/PFbD
4ef4c2df08bc60139c29e222f537b6bea7e4d6fa  /media/rmfX
0323e62f06b29ddbbe18f30a89cc123ae479a346  /etc/8V2L
acbbbce6c56feb7e351f866b806427403b7b103d  /etc/ssh/SRSq
7324353e3cd047b8150e0c95edf12e28be7c55d3  /home/v2Vb
59840c46fb64a4faeabb37da0744a46967d87e57  /X1Uy
```

# TASK 4
>Which file contains 230 lines?

どのファイルが230行で構成されているのか探し出す課題です。

## リストファイルを使用した検索
`wc`コマンドにて`-l`オプションを指定し、改行の数を表示します。230行で構成されたファイルは見つかりませんでした。

>HINT：TASK 1にて、課題で指定されている`bny0`ファイルはどこのディレクトリにも存在しないことが明らかになっています。TASK 4は消去法でファイルを特定します。

```
[new-user@ip-10-10-50-177 ~]$ cat found.txt | while read line; do echo $line; wc -l $line; done
/mnt/D8B3
209 /mnt/D8B3
/mnt/c4ZX
209 /mnt/c4ZX
/var/FHl1
209 /var/FHl1
/var/log/uqyw
209 /var/log/uqyw
/opt/PFbD
209 /opt/PFbD
/opt/oiMO
209 /opt/oiMO
/media/rmfX
209 /media/rmfX
/etc/8V2L
209 /etc/8V2L
/etc/ssh/SRSq
209 /etc/ssh/SRSq
/home/v2Vb
209 /home/v2Vb
/X1Uy
209 /X1Uy
```

![task4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/7cb8ff8d-713b-1c25-1b2a-5210aa47c461.png)

## ワンライナーを利用した検索
TASK 1における`exec`アクションの指定内容を次のとおり変更します。

```
-exec wc -l 230 {} \;
```

```
[new-user@ip-10-10-50-177 ~]$ find / -type f \( -name 8V2L -o -name bny0 -o -name c4ZX -o -name D8B3 -o -name FHl1 -o -name oiM0 -
o -name PFbD -o -name rmfX -o -name SRSq -o -name uqyw -o -name v2Vb -o -name X1Uy \) -exec wc -l 230 {} \; 2>>/dev/null
```

# TASK 5
> Which file's owner has an ID of 502?

どのファイルがID 502の所有者に所属しているのか探し出す課題です。

TASK 5と6は同じ解法にて指定されたファイルを探し出すことが可能な課題です。

# TASK 6
> Which file is executable by everyone?

どのファイルがすべての利用者によって実行権限が付与されているのか探し出す課題です。

TASK 5と6は同じ解法にて指定されたファイルを探し出すことが可能な課題です。

## リストファイルを使用した検索

`ls`コマンドにて`-l`オプションを指定し、ディレクトリ内のファイルの情報を表示します。
また、`-n`オプションを指定し、所有者とグループ名の代わりに`UID`と`GID`を数値で表示します。

```
[new-user@ip-10-10-50-177 ~]$ cat found.txt | while read line; do ls -n $line; done
-rw-rw-r-- 1 501 502 13545 Oct 23  2019 /mnt/D8B3
-rw-rw-r-- 1 501 501 13545 Oct 23  2019 /mnt/c4ZX
-rw-rw-r-- 1 501 501 13545 Oct 23  2019 /var/FHl1
-rw-rw-r-- 1 501 501 13545 Oct 23  2019 /var/log/uqyw
-rw-rw-r-- 1 501 501 13545 Oct 23  2019 /opt/PFbD
-rw-rw-r-- 1 501 501 13545 Oct 23  2019 /opt/oiMO
-rw-rw-r-- 1 501 501 13545 Oct 23  2019 /media/rmfX
-rwxrwxr-x 1 501 501 13545 Oct 23  2019 /etc/8V2L
-rw-rw-r-- 1 501 501 13545 Oct 23  2019 /etc/ssh/SRSq
-rw-rw-r-- 1 501 502 13545 Oct 23  2019 /home/v2Vb
-rw-rw-r-- 1 502 501 13545 Oct 23  2019 /X1Uy
```

![task6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/9ee7c8b8-3c12-c78c-50b4-17606742e714.png)

## ワンライナーを利用した検索
TASK 1における`exec`アクションの指定内容を次のとおり変更します。

```
-exec ls -n {} \;
```

```
find / -type f \( -name 8V2L -o -name bny0 -o -name c4ZX -o -name D8B3 -o -name FHl1 -o -name oiM0 -o -name PFbD -o -name rmfX -o -name SRSq -o -name uqyw -o -name v2Vb -o -name X1Uy \) -exec ls -n {} \; 2>>/dev/null
```

# まとめ
これで「Ninja Skills」ルームのTASKが修了です。すべてのTASKが攻略できると「**Linux Ninja**」Badgeが付与されます。
![badge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294810/38ca4f32-e80a-735a-06c4-28d5db6f3920.png)

# 参考情報
## findコマンド 
- TechMint, [35 Practical Examples of Linux Find Command](https://www.tecmint.com/35-practical-examples-of-linux-find-command/)
- FOSS Linux, [Top 5 advanced uses of ‘Find’ command (used by Hackers)](https://www.fosslinux.com/19893/top-5-advance-uses-of-find-command-used-by-hackers.htm)
- ＠IT, Linux基本コマンドTips, [【 find 】コマンド（基本編）――ファイルをさまざまな条件で検索する](https://www.atmarkit.co.jp/ait/articles/1607/12/news021.html)
- ex1-lab, [findのAND検索・OR検索 [ 論理演算子 ]](https://ex1.m-yabe.com/archives/1563)
- 兜町 金融エンジニアの成果物, [Linux｜findコマンドでファイル名を検索する方法とexecオプションの使い方](https://lanchesters.site/linux-find-exec/)

## grepコマンド
- ＠IT, Linux基本コマンドTips, [【 grep 】コマンド（応用編その1）――空白を含む文字列を検索する／正規表現を使って検索する](https://www.atmarkit.co.jp/ait/articles/1604/13/news022.html)

## シェルスクリプト
- ＠IT, Linux基本コマンドTips, [【 while 】コマンド――繰り返し処理を行う](https://www.atmarkit.co.jp/ait/articles/1806/28/news037.html)
- UNIX & Linux コマンド・シェルスクリプト リファレンス, [入力と出力](https://shellscript.sunone.me/input_output.html)
- 兜町 金融エンジニアの成果物, [【Linux】/dev/nullをエンジニアが使う２つの目的](https://lanchesters.site/linux-dev-null/)

## 正規表現
- RegExr, https://regexr.com/
- Regex DB, https://rgxdb.com/
- RIP Tutorial, [Regular Expressions IPアドレスに一致する](https://riptutorial.com/ja/regex/example/14146/ipアドレスに一致する)

# Walkthrough
- Erakrypton, [TryHackMe — Ninja Skills writeup :](https://medium.com/@erakrypton/tryhackme-ninja-skills-writeup-9c6aa090e9f6)
- Alex Chong, [TryHackMe — Ninja Skills Writeup](https://medium.com/@dendrobates.auratus.55/tryhackme-ninja-skills-writeup-44ee8de3e92e)
- Wantedlink, [TryHackMe – Writeup – Ninja Skills](https://blog.wantedlink.de/?p=11613), 2020/08/22

# CUIの学習
- [UNIX系OSのコマンドラインインターフェイス操作を克服できる学習サイト](https://qiita.com/v_avenger/items/a8b96852ce8c7d7e1e19)