APIの脆弱性を学んでみる②

前回、OWASP API3に該当の例を試しましたが、ビジネスロジックの不備をログからどうやって判断したら良いのでしょうか？

APIの脆弱性って他と何が違うの？他のと同じでしょ？脆弱性のないモジュールにUpすればいいのでしょ？？

それでは解決せず・・・データ抜かれます・・

前回を読み直していただければと思います-> https://qiita.com/TSA2019/items/16df724104a8b893be7e
直近の代表事件例としてはこれです。
https://www.itmedia.co.jp/news/articles/2407/04/news103.html

何のことやら？かもしれませんが、まだまだ有名になっていないAPIの作りについての問題です。

戻ります。
ログから検知となれば、アノマリー検知を使えば引っ掛けられそうですが、他のAPI1やら7やらは？ちょっといつもと違ったぐらいで誤検知も嫌ですよと言われそうです？設備も多いのでログが1日だけで○○GB・・・もはや人間ではできません。

そこで使いたいのがNoname Avdanced security for API connectです。
アプリかSaaSでの提供です。
AIもつかって人の代わりに判断してくれます。
便利なところはOWASP APIのこれに該当！と具体期に示します。
他にNIST SP800-53のXX-NNなどもあります。

使い方はAPI gatewayといったAPIが稼働するアプリケーションサーバーのログをNonameへ転送します。今回はNginxを使います。Nginxの設置、Noname向けの設定を行います。

０）Nonameのアカウントの作成

先にこちらを実行し、ログインできる状態にしておく必要があります。
インストールスクリプトの取得で必要となります。
※Debianパッケージ、Dockerコンテナ、rpmパッケージから選択できます。

１）Nginxの導入
同じサーバー上に、Nginxは普通にパッケージからインストールします。
8888へ転送するように設定します。
※今回は、8088に着地したら8888（前回作成したcrAPI）へ転送します

導入
```
$sudo apt install nginx
```
Config変更
```
sudo vi /etc/nginx/sites-available/default 
```

変更箇所１
変更前：
```
listen 80 default_server;
listen [::]:80 default_server;
```
変更後：
```
listen 8088 default_server;
listen [::]:8088 default_server;
```

変更箇所２
変更前：
```
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
```

変更後：
```
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
proxy_pass http://localhost:8888/;
```

Noname上からNginxのインストールスクリプトを入手

NginxへのNoname導入のため実行
Nonameポータルへアクセスし、IntegraionメニューよりNginxを選択します。ここで導入スクリプトが提示されます。これをコピーしてNginxの稼働するサーバー上で実行します。
取得する場所ですが、Nonameへログイン後、右上の歯車マークをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399809/cb9cc341-a9e8-9141-f0c7-2cc28bcd7062.png)

遷移先の画面では、左側の「Integrations」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399809/31b2b411-e4f0-546a-d396-c2c15f06ccad.png)

あらに画面上部中央「Add Integration」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399809/a3662b52-caa5-a627-4187-50b4c0994570.png)

すると選択可能な対象サーバーが表示されます。
Moduleを「All」に変更し「Nginx community」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399809/2e794323-11b0-0814-ac9d-a67f5ee5004f.png)

この選択により以下の画面が表示されます。
Name部分は識別しやすい名前を記載します。
Destination Engineは「Default-Engine」を選択します。
Deployement Methodsは、OSがUbuntuのため、DebianPackageを選択します。
完了したら「Create」を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399809/3139229f-0431-c0c2-07bc-f4feec518a58.png)

「Create」により、DebianPackage導入のスクリプトが提示されます。
これをコピーして、Nginxの動作するサーバー上で実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399809/e03afd58-07bc-0a70-1069-e6a7cec398b9.png)

実行中のメッセージはこちら。
```
[sudo] password for : 
Get:1 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB]                            
Hit:2 http://jp.archive.ubuntu.com/ubuntu jammy InRelease                                            
Get:3 http://jp.archive.ubuntu.com/ubuntu jammy-updates InRelease [128 kB]     
Get:4 https://us-central1-apt.pkg.dev/projects/noname-artifacts jammy-main-ebpf InRelease [1,073 B]
Ign:4 https://us-central1-apt.pkg.dev/projects/noname-artifacts jammy-main-ebpf InRelease              
Get:5 https://us-central1-apt.pkg.dev/projects/noname-artifacts jammy-main-ebpf/main amd64 Packages [7,591 B]
Get:6 http://security.ubuntu.com/ubuntu jammy-security/main amd64 DEP-11 Metadata [43.3 kB]
Get:7 http://jp.archive.ubuntu.com/ubuntu jammy-backports InRelease [127 kB] 
Get:8 http://security.ubuntu.com/ubuntu jammy-security/restricted amd64 DEP-11 Metadata [208 B]
Get:9 http://security.ubuntu.com/ubuntu jammy-security/universe amd64 DEP-11 Metadata [125 kB]
Get:10 http://security.ubuntu.com/ubuntu jammy-security/multiverse amd64 DEP-11 Metadata [208 B]         
Get:11 http://jp.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [2,193 kB]
Get:12 http://jp.archive.ubuntu.com/ubuntu jammy-updates/main amd64 DEP-11 Metadata [103 kB]
Get:13 http://jp.archive.ubuntu.com/ubuntu jammy-updates/restricted amd64 DEP-11 Metadata [212 B]
Get:14 http://jp.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 DEP-11 Metadata [356 kB]
Get:15 http://jp.archive.ubuntu.com/ubuntu jammy-updates/multiverse amd64 DEP-11 Metadata [940 B]
Get:16 http://jp.archive.ubuntu.com/ubuntu jammy-backports/main amd64 DEP-11 Metadata [5,332 B]
Get:17 http://jp.archive.ubuntu.com/ubuntu jammy-backports/restricted amd64 DEP-11 Metadata [212 B]
Get:18 http://jp.archive.ubuntu.com/ubuntu jammy-backports/universe amd64 DEP-11 Metadata [17.7 kB]
Get:19 http://jp.archive.ubuntu.com/ubuntu jammy-backports/multiverse amd64 DEP-11 Metadata [212 B]
Fetched 3,238 kB in 4s (892 kB/s)                                    
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
238 packages can be upgraded. Run 'apt list --upgradable' to see them.
W: GPG error: https://us-central1-apt.pkg.dev/projects/noname-artifacts jammy-main-ebpf InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY C0BA5CE6DC6315A3
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
  noname-sensor
0 upgraded, 1 newly installed, 0 to remove and 238 not upgraded.
Need to get 36.9 MB of archives.
After this operation, 72.9 MB of additional disk space will be used.
Get:1 https://us-central1-apt.pkg.dev/projects/noname-artifacts jammy-main-ebpf/main amd64 noname-sensor amd64 3.3.29 [36.9 MB]
Fetched 36.9 MB in 9s (3,968 kB/s)                                                                                                                                    
Selecting previously unselected package noname-sensor.
(Reading database ... 209379 files and directories currently installed.)
Preparing to unpack .../noname-sensor_3.3.29_amd64.deb ...
Unpacking noname-sensor (3.3.29) ...
Setting up noname-sensor (3.3.29) ...
Installing cron job.
Created symlink /etc/systemd/system/multi-user.target.wants/noname-sensor.service → /lib/systemd/system/noname-sensor.service.
Processing triggers for libc-bin (2.35-0ubuntu3.8) ...
```
noname-sensorというサービスが入ったようです。
systemctl status noname-sensorで確認してみます。

```
# systemctl status noname-sensor
● noname-sensor.service - This is Noname Sensor.
     Loaded: loaded (/lib/systemd/system/noname-sensor.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2024-12-15 21:54:25 JST; 12h ago
   Main PID: 1523155 (ebpf_entry_poin)
      Tasks: 12 (limit: 4612)
     Memory: 649.6M (max: 1.0G available: 374.3M)
        CPU: 24min 20.732s
     CGroup: /system.slice/noname-sensor.service
             ├─1523155 /bin/bash /usr/bin/noname-sensor/ebpf_entry_point.sh
             ├─1523157 sudo -E LD_LIBRARY_PATH=/usr/bin/noname-sensor/ bash -c "run_sensor_ebpf () \n{ \n    setcap cap_sys_ptrace,cap_sys_admin,cap_sys_nice,cap_net_>
             ├─1523160 bash -c "run_sensor_ebpf () \n{ \n    setcap cap_sys_ptrace,cap_sys_admin,cap_sys_nice,cap_net_raw,cap_net_admin=eip sensor;\n    setcap cap_sy>
             ├─1523164 /bin/bash ./libs_finder.sh
             ├─1523166 ./sensor
             └─2994239 sleep 3600

12月 16 09:54:11 api01 ebpf_entry_point.sh[1523166]: I20241216 09:54:11.167881 1523166 cycle_cached_config_player.h:75] Successfully read Sensor configs from data orc>
12月 16 09:54:21 api01 ebpf_entry_point.sh[1523166]: I20241216 09:54:21.363782 1523166 SystemProfilerCyclePlayer.cpp:178] {"processes":[{"pid":2,"exe_filename":"","cm>
12月 16 09:54:21 api01 ebpf_entry_point.sh[1523166]: I20241216 09:54:21.364352 1523166 CycleManager.cpp:102] Finished cycle get_ready.
12月 16 09:54:21 api01 ebpf_entry_point.sh[1523166]: I20241216 09:54:21.364385 1523166 CycleManager.cpp:30] Starting Sync Table Deleter and Telemetry Printer
12月 16 09:54:21 api01 ebpf_entry_point.sh[1523166]: I20241216 09:54:21.372378 1523166 CycleManager.cpp:39] Starting Sync Table Deleter
12月 16 09:54:21 api01 ebpf_entry_point.sh[1523166]: I20241216 09:54:21.372407 1523166 CycleManager.cpp:52] Finished Sync Table Deleter
12月 16 09:54:21 api01 ebpf_entry_point.sh[1523166]: I20241216 09:54:21.372426 1523166 CycleManager.cpp:61] Telemetry: {"constructed_packetpairs": 0, "irrelevant_pack>
12月 16 09:54:21 api01 ebpf_entry_point.sh[1523166]: I20241216 09:54:21.372570 1523166 CycleManager.cpp:65] Performance Stats: {"cpu":{"system": {"cpu_usage_percent":>
12月 16 09:54:31 api01 ebpf_entry_point.sh[1523166]: I20241216 09:54:31.372666 1523166 CycleManager.cpp:100] Executing cycle get_ready.
12月 16 09:54:31 api01 ebpf_entry_point.sh[1523166]: I20241216 09:54:31.765972 1523166 cycle_cached_config_player.h:75] Successfully read Sensor configs from data orc>
lines 1-25/25 (END)
```
「Active: active (running)」となっているので問題なく動作しているようです。


念の為、Nginxを再起動させておきます。
```
sudo systemctl restart nginx
```

Nginx動作確認をします。Port番号から確認します。
```
sudo lsof -i:8088

$ sudo lsof -i:8088
[sudo] password for : 
COMMAND     PID     USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
nginx   1521769     root    6u  IPv4 7327258      0t0  TCP *:omniorb (LISTEN)
nginx   1521769     root    7u  IPv6 7327259      0t0  TCP *:omniorb (LISTEN)
nginx   1521770 www-data    6u  IPv4 7327258      0t0  TCP *:omniorb (LISTEN)
nginx   1521770 www-data    7u  IPv6 7327259      0t0  TCP *:omniorb (LISTEN)
nginx   1521771 www-data    6u  IPv4 7327258      0t0  TCP *:omniorb (LISTEN)
nginx   1521771 www-data    7u  IPv6 7327259      0t0  TCP *:omniorb (LISTEN
```
上記のようにいくつか出てくれば確認OK。

２）Noname上での設定

　１）で導入したスクリプト以外では、設定手順は特にありません。

３）確認

前回、実行したcurlを実行します。今回Nginxを通りNonameで検知したいので、ポート番号を8088に変更します（以前は8888）
```
$ curl -H "Authorization: Bearer (省略) " http://192.168.200.150:8088/identity/api/v2/vehicle/4bae9968-ec7f-4de3-a3a0-ba1b2ab5e5e5/location
```

```
{"carId":"4bae9968-ec7f-4de3-a3a0-ba1b2ab5e5e5","vehicleLocation":{"id":3,"latitude":"37.746880","longitude":"-84.301460"},"fullName":"Robot","email":"robot001@example.com"}
```
前回と同じ結果が出ています。
Nonameの方ではどうでしょうか？

ダッシュボードから確認します。
SecurityのFindingsから時系列で探します。
時間的に上から5つ目を確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399809/5470e2e6-7036-272c-b98b-33e5b2db0529.png)

別に小窓が開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399809/43cf854d-219c-4cb2-5169-da375b6a484e.png)

API3:2023に該当することが改めて確認できます。
「＋３」とやらもクリックすると残りの情報が表示されます。
API3:2019にも該当し情報を提示しています。

このウインドの中の「API Information」を確認します。
```
http://192.168.200.150:8088/identity/api/v2/vehicle/<guid>/location
```
をクリックします（これが判明しているものの１つ。のこり６つを総合して利用することで情報取得が実現できてしまうと判定しています）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399809/3d82018b-edfa-85a6-2f2f-4b15ceefcf2d.png)

開く窓には詳細が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399809/6e9ddde2-39d9-6c14-70b6-f8643a4ef25f.png)
認識しているデータタイプのタグが表示されています。
Locationが漏れているという判定です。

もう少し下を見てみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399809/fa1b9f7b-17ef-b6ae-25f5-1a06b95e7c8b.png)
「Generate」により目的を説明させることができます。
ここではこのAPIにより車の位置情報が取得可能という説明です。GUIDがあれば表示できるとのことです。

ここに権限の確認や認証が見受けられないとNonameは認識したため危険度を上げています。

リストは掲示板のページにありました。
Impact値は数値からは中程度ですが、データの流出8.9なので、なるはやで調査・対処をお勧めすべきものと判断できます。

前回検証した以下のものを検知しています。
```
http://192.168.200.150:8088/identity/api/v2/vehicle/4bae9968-ec7f-4de3-a3a0-ba1b2ab5e5e5/location
```
ちょっとウインドウが多いですが、情報を出してくるので確認しながら進めると原因に辿り着くことができます。

今回、事象について見える化することができました。見えない通信のなかに意外に多くの問題が潜んでいることがわかりました。これがAPIを利用したクライアントアプリ・モバイルアプリ開発を行なうときによく発生します。
しかしこれだけ手早く見つけるツールは他にありましたか？
ビジネスロジックも含めて情報を出してくれるものはこれが初めての経験です。

次回は、答え合わせや検証というわけではありませんがPostmanを使って確認したいと思います。