こちらの記事の続編です。
ACS 1.1.9.10で追加されたIBM i サービス(セキュリティ関連)サンプル
1. 攻撃に対してオープンになっているライブラリーはいくつありますか?
How many libraries are OPEN for attack? こちらの記事を参照
2. 攻撃に対してオープンになっているライブラリーはいくつありますか? (所有者毎)
サンプル名:Security - How many libraries are OPEN for attack? (ownership perspective)
SQLスクリプト実行画面からサンプルを選択して、挿入します。

-- How many libraries are OPEN for attack? (ownership perspective)
--
SELECT owner, COUNT(*) AS library_count
FROM qsys2.object_privileges
WHERE system_object_schema = 'QSYS' AND object_type = '*LIB' AND object_name NOT LIKE 'QSYS%' AND
user_name = '*PUBLIC' AND data_execute = 'YES'
GROUP BY owner
ORDER BY library_count DESC;
実行結果です。ライブラリー(スキーマ)所有者毎の該当ライブラリー数が表示されます。PUBLICユーザーに対するデータ権限の実行権限がYES のライブラリー数を表示します。

3.誰でも使用できるコマンドはどれですか?
サンプル名:Which commands can anyone use?
オブジェクトタイプ *CMD について、PUBLICユーザーに対するop.object_authority権限がEXCLUDEでないものをリストします。
-- Which commands can anyone use?
--
SELECT command_library, command_name, op.object_authority AS public_authority
FROM qsys2.command_info, LATERAL (
SELECT *
FROM TABLE (
qsys2.object_privileges(
system_object_schema => command_library, system_object_name => command_name,
object_type => '*CMD')
)
) op
WHERE command_library not like 'QSYS%' AND op.authorization_user = '*PUBLIC' AND op.object_authority <> '*EXCLUDE'
ORDER BY 1, 2;
上記のようにユーザー作成コマンド以外で、システム提供のコマンドについても沢山違反が見つかりました。古いシステムからの移行環境の為でしょう。(当時は問題では無かった、最近のセキュリティ事情的にはアクセス権制限すべき、という例)
4. 誰でも使用できるコマンドが含まれているライブラリーはどれですか?
サンプル名: Which libraries contain commands that anyone use?
3.のサンプルをライブラリーでサマリーしたような結果を返します。
-- Which libraries contain commands that anyone use?
--
SELECT command_library, count(*) as command_count
FROM qsys2.command_info, LATERAL (
SELECT *
FROM TABLE (
qsys2.object_privileges(
system_object_schema => command_library, system_object_name => command_name,
object_type => '*CMD')
)
) op
WHERE op.authorization_user = '*PUBLIC' AND op.object_authority <> '*EXCLUDE' AND command_library not like 'QSYS%'
group by command_library
ORDER BY command_count desc;
5. どのようなデータベーストリガーがありますか?
サンプル名:What Database triggers exist?
Db2 for i のトリガーのリストを返します
-- What Database triggers exist?
--
SELECT trigger_schema, trigger_name, trigevent, sys_dname AS lib_name, sys_tname AS file_name,
enabled, definer, created, alteredts
FROM qsys2.systriggers
WHERE sys_dname NOT LIKE 'Q%'
ORDER BY created DESC;
実行例。トリガーの基本的な情報、作成者、作成日等を返します。

6. 所有者がホームディレクトリーと一致しない IFS ホームディレクトリーはどれですか?
サンプル名:What are the IFS home directories, where the owner doesn't match the home dir?
ユーザーのホームディレクトリ―(=通常はユーザーIDと同一)について所有者が別なユーザーIDのものをリスト
- description: Security - What are the IFS home directories, where the owner doesn't match the home dir?
-- Use Db2 for i to Inject more Security into your IBM i
-- minvrm: v7r4m0
--
-- What are the IFS home directories?
--
SELECT path_name, object_owner
FROM TABLE (
qsys2.ifs_object_statistics(
start_path_name => '/home',
subtree_directories => 'NO',
ignore_errors => 'YES')
) where object_type = '*DIR' and path_name not in ('/home');
stop;
--
-- What are the IFS home directories, where the owner doesn't match the home dir?
--
SELECT path_name,
UPPER(RTRIM(SUBSTR(path_name, LOCATE_IN_STRING(path_name, '/', -1) + 1, 10))) AS home_name,
object_owner, create_timestamp
FROM TABLE (
qsys2.ifs_object_statistics(
start_path_name => '/home', subtree_directories => 'NO', ignore_errors => 'YES')
)
WHERE object_type = '*DIR' AND path_name NOT IN ('/home') AND
UPPER(RTRIM(SUBSTR(path_name, LOCATE_IN_STRING(path_name, '/', -1) + 1, 10))) <> object_owner
ORDER BY path_name;
実行例。このようなミスマッチも設定ミス・メンテミス等の疑いがある、という事かと思います。
上記サンプルのうち、stop までを実行するとホームディレクトリの一覧が表示されます。
stop以降を続けて実行すると、ミスマッチのリストが表示されます。

7. 名前と所有者が一致しないIFSディレクトリ(*PUBLIC *EXCLUDEを使用)
サンプル名:IFS directories with a name and owner mismatch not using *PUBLIC *EXCLUDE
-- What are the IFS home directories, where the owner doesn't match the home dir
-- and that home directory isn't using *PUBLIC *EXCLUDE.
--
SELECT ios.path_name, object_owner, iop.data_authority AS public_authority
FROM TABLE (
qsys2.ifs_object_statistics(
start_path_name => '/home', subtree_directories => 'NO', ignore_errors => 'YES')
) ios, TABLE (
qsys2.ifs_object_privileges(path_name => ios.path_name, ignore_errors => 'YES')
) iop
WHERE ios.object_type = '*DIR' AND ios.path_name NOT IN ('/home') AND UPPER(
RTRIM(SUBSTR(ios.path_name, LOCATE_IN_STRING(ios.path_name, '/', -1) + 1, 10))) <>
object_owner AND iop.authorization_name = '*PUBLIC' AND (iop.data_authority <> '*EXCLUDE')
ORDER BY ios.path_name;
--
SELECT path_name,
UPPER(RTRIM(SUBSTR(path_name, LOCATE_IN_STRING(path_name, '/', -1) + 1, 10))) AS home_name,
object_owner, create_timestamp
FROM TABLE (
qsys2.ifs_object_statistics(
start_path_name => '/home', subtree_directories => 'NO', ignore_errors => 'YES')
)
WHERE object_type = '*DIR' AND path_name NOT IN ('/home') AND
UPPER(RTRIM(SUBSTR(path_name, LOCATE_IN_STRING(path_name, '/', -1) + 1, 10))) <> object_owner
ORDER BY path_name;
8. - IFSホームディレクトリの内容とオブジェクトの所有権が一致しない(詳細レポート)
サンプル名:IFS home directory contents object ownership mismatch (detail report)
IFSホームディレクトリ―のオーナーと異なる所有者(オーナー)のファイルをリストする
-- For all IFS home directories, where the owner name matches the home directory name,
-- find any IFS objects within the home that are not owned by the home directory name
-- (detail report)
--
WITH ifs (homes, home_owner) AS (
SELECT path_name, object_owner
FROM TABLE (
qsys2.ifs_object_statistics(
start_path_name => '/home', subtree_directories => 'NO', ignore_errors => 'YES')
)
WHERE object_type = '*DIR' AND path_name NOT IN ('/home') AND UPPER(
RTRIM(SUBSTR(path_name, LOCATE_IN_STRING(path_name, '/', -1) + 1, 10))) = object_owner
ORDER BY path_name)
SELECT homes, object_type, home_owner, object_owner
FROM ifs, TABLE (
qsys2.ifs_object_statistics(
start_path_name => ifs.homes, subtree_directories => 'YES', ignore_errors => 'YES')
) ios
WHERE home_owner <> object_owner;
qsys2.ifs_object_statistics(
start_path_name => '/home', subtree_directories => 'NO', ignore_errors => 'YES')
)
WHERE object_type = '*DIR' AND path_name NOT IN ('/home') AND
UPPER(RTRIM(SUBSTR(path_name, LOCATE_IN_STRING(path_name, '/', -1) + 1, 10))) <> object_owner
ORDER BY path_name;
実行例 所有者SAKURAのホームディレクトリ―に所有者QSECOFRのファイルが存在しています。

9. IFSホームディレクトリの内容とオブジェクトの所有権が一致しない(概要レポート)
サンプル名:IFS home directory contents object ownership mismatch (summary report)
調べる条件は7.と同様です。結果がサマリー(オブジェクト数)で返される点が異なります。
WITH ifs (homes, home_owner) AS (
SELECT path_name, object_owner
FROM TABLE (
qsys2.ifs_object_statistics(
start_path_name => '/home', subtree_directories => 'NO', ignore_errors => 'YES')
)
WHERE object_type = '*DIR' AND path_name NOT IN ('/home') AND UPPER(
RTRIM(SUBSTR(path_name, LOCATE_IN_STRING(path_name, '/', -1) + 1, 10))) = object_owner
ORDER BY path_name)
SELECT homes, object_type, count(*) as object_count
FROM ifs, TABLE (
qsys2.ifs_object_statistics(
start_path_name => ifs.homes, subtree_directories => 'YES', ignore_errors => 'YES')
) ios
WHERE home_owner <> object_owner
group by homes, object_type
order by homes, object_type;
10. すべてのユーザーが値を参照できるデータエリア *DTAARA(詳細レポート)
サンプル名:Data areas where any user can see the value (detail report)
*PUBLICユーザーが参照可能なデータエリアをリストします。
- Data areas that anyone can see the data area value
--
select dtaara_lib, dtaara, "TYPE", "VALUE", bin_value
from qsys2.data_area_info, table(qsys2.object_privileges(dtaara_lib, dtaara, '*DTAARA')) b
where authorization_user = '*PUBLIC' and object_authority not in ('*EXCLUDE')
order by dtaara_lib, dtaara;
11.すべてのユーザーが値を参照できるデータエリア(概要レポート)
サンプル名:Data areas where any user can see the value (summary report)
10.と同じ対象のデータエリアを調べて、ライブラリー毎の数を返します。
-- Data areas that anyone can see the data area value
--
select dtaara_lib, dtaara, "TYPE", "VALUE", bin_value
from qsys2.data_area_info, table(qsys2.object_privileges(dtaara_lib, dtaara, '*DTAARA')) b
where authorization_user = '*PUBLIC' and object_authority not in ('*EXCLUDE')
order by dtaara_lib, dtaara;
12.すべてのユーザーがデータを変更できるデータエリア(詳細レポート)
サンプル名:Data areas where anyone can change data area value (detail report)
11.と同じ対象のデータエリアを検索して、詳細な情報を返します。
-- Data areas where anyone can change data area value
--
SELECT dtaara_lib, dtaara, op.*
FROM qsys2.data_area_info, TABLE (
qsys2.object_privileges(dtaara_lib, dtaara, '*DTAARA')
) op
WHERE authorization_user = '*PUBLIC' AND op.object_operational = 'YES' AND op.data_read = 'YES'
AND op.data_add = 'YES' AND op.data_update = 'YES' AND op.data_delete = 'YES' AND
op.data_execute = 'YES'
ORDER BY dtaara_lib, dtaara;









