Linuxの認証ログと実行ユーザー
SSHのセッション42からsudo、SYSCALL、EXECVEへ進み、元のUID1001と実行時UID0を照合します。コマンド文字列だけでなく、実行成否と親子関係を根拠にする調査を学びます。
説明
Linuxでは、ログインした利用者と実行時のUIDが異なる場合があります。auditのauidはログイン時の主体を追う項目で、sudo後も元の利用者を示すことがあります。複数種類のaudit行は同じイベントのserialでまとめます。
SSHのセッション42からsudo、SYSCALL、EXECVEへ進み、元のUID1001と実行時UID0を照合します。コマンド文字列だけでなく、実行成否と親子関係を根拠にする調査を学びます。
1SSH接続とsudoを並べる
sessionはこの試料でauditセッションに対応させた識別子です。
from oplab import *
db=connect(4)
show(db, 'SELECTSSH接続とsudoを並べる * FROM auth ORDER BY t')aliceのセッション42とbobの43があります。時刻が近いだけでbobの実行までaliceの活動に混ぜないようにします。
2同じセッションのauditを探す
セッション42に絞って元のログ行を見ます。
show(db, 'SELECT同じセッションのauditを探す * FROM audit WHERE session=42 ORDER BY serial,type')serial900のSYSCALLとEXECVEが現れます。行が二つあっても実行が二回あったとは限りません。
3ログイン時と実行時のUIDを比較する
auidとuidを別々に表示します。UIDと利用者名の対応はこの試料では1001=aliceです。
show(db, 'SELECTログイン時と実行時のUIDを比較する id,serial,auid,uid,pid,ppid FROM audit WHERE type="SYSCALL"')r1は元の主体1001、実行時0です。r3は1002のままで、同じ権限変更の流れではありません。
4同じイベントの引数を結合する
同じserialのSYSCALLとEXECVEを結合して、実行結果と引数を一緒に読みます。
show(db, 'SELECT同じイベントの引数を結合する s.serial,s.text AS syscall,e.text AS argv FROM audit s JOIN audit e USING(serial) WHERE s.type="SYSCALL" AND e.type="EXECVE"')serial900ではidのexecveが成功しています。syscall=59という番号は、この試料のx86-64 Linuxの対応です。
5sudoから子プロセスへつなぐ
親PIDとセッションを合わせて検索します。実際の長期間の資料では端末と起動区間も含めます。
show(db, 'SELECTsudoから子プロセスへつなぐ a.id,a.user,r.id,r.pid,r.uid FROM auth a JOIN audit r ON a.pid=r.ppid AND a.session=r.session WHERE a.kind="sudo" AND r.type="SYSCALL"')a2のsudoからr1のPID711へ結び付きます。sudoの要求行だけより、実際のexecveを併せた方が実行の裏付けが増えます。
6別セッションの記録を残す
対象外にした記録を確認し、同じ端末の別活動を誤って含めていないか調べます。
show(db, 'SELECT別セッションの記録を残す id,session,auid,uid,text FROM audit WHERE session<>42')r3はbobの活動です。対象セッション、元の主体、実行時権限、実行引数を別々の列で説明できます。
まとめ
r3はbobの活動です。対象セッション、元の主体、実行時権限、実行引数を別々の列で説明できます。
表示された証拠IDと検索条件を残すと、調査結果を元の記録までたどれます。
操作履歴と解説を振り返れます。
Python 3.15 / SQLite・固定の調査記録
from oplab import *
db=connect(4)
show(db, 'SELECT * FROM auth ORDER BY t')id | t | host | pid | session | kind | user | detail a1 | 10 | linux7 | 700 | 42 | sshd | alice | Accepted publickey from 192.0.2.9 a2 | 12 | linux7 | 710 | 42 | sudo | alice | USER=root COMMAND=/usr/bin/id a3 | 14 | linux7 | 720 | 43 | sshd | bob | Accepted publickey from 192.0.2.8
show(db, 'SELECT * FROM audit WHERE session=42 ORDER BY serial,type')id | serial | type | session | auid | uid | pid | ppid | text r2 | 900 | EXECVE | 42 | 1001 | 0 | 711 | 710 | argc=1 a0=id r1 | 900 | SYSCALL | 42 | 1001 | 0 | 711 | 710 | syscall=59 success=yes exe=/usr/bin/id
show(db, 'SELECT id,serial,auid,uid,pid,ppid FROM audit WHERE type="SYSCALL"')id | serial | auid | uid | pid | ppid r1 | 900 | 1001 | 0 | 711 | 710 r3 | 901 | 1002 | 1002 | 721 | 720
show(db, 'SELECT s.serial,s.text AS syscall,e.text AS argv FROM audit s JOIN audit e USING(serial) WHERE s.type="SYSCALL" AND e.type="EXECVE"')serial | syscall | argv
show(db, 'SELECT a.id,a.user,r.id,r.pid,r.uid FROM auth a JOIN audit r ON a.pid=r.ppid AND a.session=r.session WHERE a.kind="sudo" AND r.type="SYSCALL"')id | user | id | pid | uid a2 | alice | r1 | 711 | 0
show(db, 'SELECT id,session,auid,uid,text FROM audit WHERE session<>42')id | session | auid | uid | text r3 | 43 | 1002 | 1002 | syscall=59 success=yes exe=/usr/bin/true
演習完了