kubota-dit
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    [HACK#1 セキュアなマウントポイントの設定](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack1-%E3%82%BB%E3%82%AD%E3%83%A5%E3%82%A2%E3%81%AA%E3%83%9E%E3%82%A6%E3%83%B3%E3%83%88%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%AE%E8%A8%AD%E5%AE%9A) [HACK#2 SUIDおよびSGIDプログラム](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack2-suid%E3%81%8A%E3%82%88%E3%81%B3sgid%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0) [HACK#3 書き込みパーミッション設定が甘いディレクトリの捜索](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack3-%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%81%BF%E3%83%91%E3%83%BC%E3%83%9F%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E8%A8%AD%E5%AE%9A%E3%81%8C%E7%94%98%E3%81%84%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AE%E6%8D%9C%E7%B4%A2) [HACK#4 POSIX ACL(Access Control List)で柔軟な権限を設定](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack4-posix-aclaccess-control--list%E3%81%A7%E6%9F%94%E8%BB%9F%E3%81%AA%E6%A8%A9%E9%99%90%E3%82%92%E8%A8%AD%E5%AE%9A) [HACK#5 ログの改ざん防止](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack5-%E3%83%AD%E3%82%B0%E3%81%AE%E6%94%B9%E3%81%96%E3%82%93%E9%98%B2%E6%AD%A2) [HACK#6 管理権限の分担化](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack6-%E7%AE%A1%E7%90%86%E6%A8%A9%E9%99%90%E3%81%AE%E5%88%86%E6%8B%85%E5%8C%96) [HACK#7 暗号シグネチャの自動検証](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack7-%E6%9A%97%E5%8F%B7%E3%82%B7%E3%82%B0%E3%83%8D%E3%83%81%E3%83%A3%E3%81%AE%E8%87%AA%E5%8B%95%E6%A4%9C%E8%A8%BC) [HACK#8 ネットワークサービスチェック](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack8-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF) [HACK#9 サービスのネットワーク利用を制御](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack9-%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E5%88%A9%E7%94%A8%E3%82%92%E5%88%B6%E5%BE%A1) [HACK#10 サンドボックスによる実行環境の制限](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack10-%E3%82%B5%E3%83%B3%E3%83%89%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%81%AB%E3%82%88%E3%82%8B%E5%AE%9F%E8%A1%8C%E7%92%B0%E5%A2%83%E3%81%AE%E5%88%B6%E9%99%90) [HACK#11 ProFTPDの認証にMySQLを利用](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack11-proftpd%E3%81%AE%E8%AA%8D%E8%A8%BC%E3%81%ABmysql%E3%82%92%E5%88%A9%E7%94%A8) [HACK#12 スタックへの攻撃防止](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack12-%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF%E3%81%B8%E3%81%AE%E6%94%BB%E6%92%83%E9%98%B2%E6%AD%A2) [HACK#13 コマンドバイナリの改ざんに備える](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack13-%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%90%E3%82%A4%E3%83%8A%E3%83%AA%E3%81%AE%E6%94%B9%E3%81%96%E3%82%93%E3%81%AB%E5%82%99%E3%81%88%E3%82%8B) [HACK#14 Systraceによるシステムコールの制限](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack14-systrace%E3%81%AB%E3%82%88%E3%82%8B%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%B3%E3%83%BC%E3%83%AB%E3%81%AE%E5%88%B6%E9%99%90) [HACK#15 Systraceポリシーの自動生成](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack15-systrace%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC%E3%81%AE%E8%87%AA%E5%8B%95%E7%94%9F%E6%88%90) [HACK#16 PAMによるログイン制御](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack16-pam%E3%81%AB%E3%82%88%E3%82%8B%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E5%88%B6%E5%BE%A1) [HACK#17 SCPとSFTPのユーザーを制限する](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack17-scp%E3%81%A8sftp%E3%81%AE%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%92%E5%88%B6%E9%99%90%E3%81%99%E3%82%8B) [HACK#18 ワンタイムパスワードによる認証を行う](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack18-%E3%83%AF%E3%83%B3%E3%82%BF%E3%82%A4%E3%83%A0%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%81%AB%E3%82%88%E3%82%8B%E8%AA%8D%E8%A8%BC%E3%82%92%E8%A1%8C%E3%81%86) [HACK#19 制限シェルの利用](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack19-%E5%88%B6%E9%99%90%E3%82%B7%E3%82%A7%E3%83%AB%E3%81%AE%E5%88%A9%E7%94%A8) [HACK#20 ユーザーやグループへのリソース制限](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack20-%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%84%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E3%81%B8%E3%81%AE%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E5%88%B6%E9%99%90) [HACK#21 システムのアップデートの自動化](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%80%E7%AB%A0-Unix%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack21-%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AE%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E3%81%AE%E8%87%AA%E5%8B%95%E5%8C%96) # HACK#1 セキュアなマウントポイントの設定 ## 概要 - マウントオプションを適切に設定してアクセス制御をする - 攻撃者によってコンピュータに侵入されてしまった時、その攻撃による被害の拡大を防ぐ ## 背景 ### マウントオプションとは + ファイルシステムへのアクセス方法を制御するためのオプションです ### マウントオプションを適切に設定することで攻撃による被害拡大を防ぐ + それぞれのパーティションに適切なマウントオプションを設定することで、攻撃者が コンピュータに侵入した後の活動を困難にすることが可能となる。 + ただし、攻撃者がマウントオプションによる制限を回避可能な方法も数多く存在し、 また、root権限を奪った攻撃者に対しては、これらのマウントオプションを与えた ファイルシステムでさえも無意味となる。したがってサーバを守るためには複数の手法を 組み合わせることが重要となる。 ### 例 + /tmpなどでファイルの実行を禁止(noexecオプション)しておくことで, ファイルを不正に作成されてしまったとしても,実行ができないので, データの流出や外部への攻撃を防ぐことができることが期待されます。 ## 前提知識 以下のコマンドでマウントオプションを設定することができる <pre> mount -o マウントオプション マウントするデバイス マウント先ディレクトリ(マウントポイント) </pre> | マウントオプション名 | 意味 | |----|----| | nodev | デバイスファイルを無効にする | | noexec | マウントしたファイルシステム上に存在するバイナリの実行を不可能にする | | nosuid | 「SUID」「SGID」ビットを無効にする | | ro | 読み込み専用でマウント | ※SUID、SGIDについてはHACK#2を参照 設定したマウントオプションは以下のコマンドで確認することができる <pre> mount </pre> ## 確認方法 (その1) (ro)のマウントオプションを試してみる(読み取り専用) mountコマンドでマウント状況を確認 <pre> # mount (中略) /dev/sda1 on /boot type ext4 (rw) </pre> 現在は(rw)というマウントオプションが指定されている(読み書き) 実際に読み書きできるかを以下でテストする <pre> # cd /boot (マウントされているディレクトリに移動) # vi *** (適当なファイルを編集し、保存できることを確認する) xxxxxx^_<8b>^H^@ü<9c>vX^B^C¬[Y<93>ã (中略) :wq (←何のエラーもなく実行できる) </pre> これで書き込みができることを確認したら、今度は実際にマウントオプション「ro」を付与して試してみる 「/dev/sda1」をアンマウント<sup>※</sup> <pre> # umount /dev/sda1 </pre> --- ※一度アンマウントしなくても、<br>下記のように`remount`オプションだけを設定してマウントすることで、初期化できます。 <pre> # mount -o remount /boot # mount /dev/sda1 on /boot type ext4 (rw) </pre> --- マウントオプションを指定して「/dev/sda1」をマウントし、mountコマンドで確認 <pre> # mount -o ro,nodev,noexec,nosuid /dev/sda1 /boot # mount (中略) /dev/sda1 on /boot type ext4 (r0,noexec,nosuid,nodev) </pre> これで(ro,noexec,nosuid,nodev)が付与されたのがわかる 実際に読み取り専用になっているか同じ手順で確認してみる <pre> # cd /boot (マウントされているディレクトリに移動) # vi *** (適当なファイルを編集する) xxxxxx(←追加)^_<8b>^H^@ü<9c>vX^B^C¬[Y<93>ã :wq (←実行すると以下のエラーメッセージが出る) E45: 'readonly' option is set (add ! to override) </pre> 上記のようにエラーが表示されればマウントオプション「ro」は適切に設定されている ことになる。 ※本では「hda」だが、現環境では「sda」になっている これは本と現環境のハードディスクに差異があり、デバイスファイルの命名規則が異なることが原因となっている。 デバイスファイルの命名規則 |規格|説明| |----|----| |SCSI/SATA|/dev/sd○として作成。○には1台目からa,b,cと付与される。| |IDE/ATA(PATA)|/dev/hd○として作成。○には1台目からa,b,cと付与される。| 上記の命名規則より、本ではプライマリIDEハードディスクの3番目のパーティションを指定していることがわかる。 「fdisk -l」コマンドを実行することで、現環境で作成済みのパーティションテーブルを表示できる。 また、df コマンド実行時、ディスクの使用量を確認できる。 上記コマンドの実行結果から、現環境ではSCSI/SATAの規格であることがわかる。 そのため、「sd」を記述する。 --- ## 確認方法(その2) その1では`ro`オプションでマウントしたので、`noexec`オプションを試してみる。<br> mountコマンドでマウント状況を確認<br> <pre> # mount (略) /dev/sda1 on /boot type ext4 (rw) (以下略) </pre> /bootディレクトリ がrw の読み込み・書き込み権限だけのオプションでマウントされていることが分かります。 <pre> # cd /boot # vim uname.sh #!/bin/sh uname -a </pre> /bootディレクトリ内に、適当なスクリプトファイルを作成します。<br> 今回はシステムの情報を表示するだけのスクリプトを用意。 <pre> # chmod +x uname.sh # ./uname.sh Linux dojo.local 2.6.32-642.13.1.el6.x86_64 #1 SMP Wed Jan 11 20:56:24 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux </pre> 現在、rwオプションだけが設定されているため、問題なく実行されます。 <pre> # mount -o remount,noexec,nosuid,nodev /boot # mount (略) /dev/sda1 on /boot type ext4 (rw,noexec,nosuid,nodev) (以下略) </pre> /bootをrw の読み込み・書き込み権限に加えて,noexec, nosuid, nodev のオプション込みでマウントします。 <pre> # ./uname.sh bash: ./uname.sh: 許可がありません </pre> noexecオプションが設定されているので、実行できない<br> <br> 余力があれば自力でnosuid,nodevオプションを排除して実行してみてください。<br> ※roオプションを設定しない限り、rwオプションは自動で設定されます。 <pre> # mount -o remount /boot # mount /dev/sda1 on /boot type ext4 (rw) </pre> remountオプションだけを設定してマウントすると、初期化されます。 <pre> # ./uname.sh Linux dojo.local 2.6.32-642.13.1.el6.x86_64 #1 SMP Wed Jan 11 20:56:24 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux </pre> 初期化したことでnoexecオプションがなくなったので、実行できます。 --- ## 確認方法(その3) 書籍に記載されていた下記の部分を実際に試してみる。 > 攻撃者が前述のようなマウントオプションによる制限を回避可能な方法も数多く存在します。例えばLinuxにおいて、noexecオプションを指定したファイルシステム上であっても、/lib/ld-linux.soを使用してファイルを実行することが可能です。 1.まず、準備としてidコマンドを/boot配下の任意のディレクトリにコピーし、コピーしたidが利用可能なことを確認する。 <pre> [root@dojo]# pwd /boot/sample [root@dojo]# cp /usr/bin/id . [root@dojo]# ./id uid=0(root) gid=0(root) 所属グループ=0(root) </pre> 2.次に、/bootをnoexecオプション付きでマウントする <pre> [root@dojo]# umount /dev/sda1 [root@dojo]# mount -o noexec /dev/sda1 /boot [root@dojo]# mount (省略) /dev/sda1 on /boot type ext4 (rw,noexec) (省略) </pre> 3.そして、ld-linux.soで実行してみる。 <pre> [root@dojo]# ./id bash: ./id: 許可がありません [root@dojo]# /lib64/ld-linux-x86-64.so.2 ./id ./id: error while loading shared libraries: ./id: failed to map segment from shared object: Operation not permitted </pre> この結果、書籍では実行することができると書いているが実行することはできなかった。 <br> ■ 調査 なぜ、書籍どおり実行することができなかったのかを調査したところ 下記のサイトが見つかった。 >noexec Do not allow direct execution of any binaries on the mounted file >system. (Until recently it was possible to run binaries anyway using a >command like /lib/ld*.so /mnt/binary. This trick fails since Linux 2.4.25 / 2.6.0.) [引用したサイト](https://rachelbythebay.com/w/2012/03/28/mount/) 上記の情報から自分が使っている端末でマニュアルを確認したところ、下記の情報が記載されていた。 <pre> [root@dojo]# man mount (省略) noexec マウントされたファイルシステム上の任意のバイナリの直接実行を禁止する。 (最近 になるまで /lib/ld*.so /mnt/binary のようなコマンドを使って、バイナリを何とか 実 行することが可能であった。このトリックは Linux 2.4.25 / 2.6.0 以降では失敗する。) (省略) </pre> なので、自分が使っている端末(CentOS6)のカーネルバージョンを確認してみた。 <pre> [root@dojo]# uname -r 2.6.32-642.13.1.el6.x86_6 </pre> 最終的にわかったことは、下記の2点。 + 最近のLinux(カーネル)ではすでにこの部分のセキュリティ対策が施されている。 + 書籍どおりにはいかなかった理由はセキュリティ対策が施されている端末で実行したためだった。 # HACK#2 SUIDおよびSGIDプログラム ## 概要 - root権限で実行できてしまう「SUID」「SGID」が付与されたプログラムを発見する - 悪意を持ったユーザーに簡単にroot権限を与えるべきではないので、調査して適切な権限を付与するため ## 背景 ### SUIDとは 通常の実行ファイルは実行者の権限で動作しますが、SUIDが設定されていると実行ファイルの所有者の権限で動作します。 SUIDの使用例として「**passwd**」コマンドが挙げられます。 passwdコマンドを実行するとユーザーのパスワードを変更することができます。パスワードの変更は誰でも実行可能なはずです。 しかし、実際は「**/etc/shadow**」ファイルを編集することになりますが、一般ユーザーにはこのファイルを変更する権限はありません。 そこで、passwdコマンドにSUID属性を設定することで、一般ユーザーがpasswdコマンドを実行しても、passwdコマンドの所有者であるrootの権限で/etc/shadowファイルを編集できるようになっています。 ### SGIDとは SUIDは所有者の権限で実行可能だったのに対し、 SGIDは実行ファイルの所有グループの権限でファイルを実行できる。 また、SGIDはディレクトリにも設定することが可能<sup>※</sup>。 ディレクトリに設定した場合、その設定したディレクトリ以下で作成したファイル・ディレクトリの所有グループが自動的に親ディレクトリと同じになる。 ※LinuxではディレクトリにSUIDを設定しても無視されます。 FreeBSDではディレクトリにSUIDを設定するとSGIDと同じものとして認識します。 よって、SUIDはディレクトリに対しては設定できません。 ### SUID・SGIDの脆弱性 SUIDやSGIDを使用すると一般ユーザーであってもrootの権限でプログラムを動作することができるため、 SUIDやSGIDが設定されているファイルが攻撃の対象になったり、 SUIDやSGIDが攻撃に利用されることがある。 すでにroot権限を奪取した攻撃者が、root権限で実行したいコマンドラインをスクリプトに記述し、そのスクリプトにroot権限のSUIDを設定しておく。 以降、攻撃者は作成しておいたスクリプトを実行することで、root権限を奪取しなくても、PCに侵入できた時点でroot権限が必要なコマンドを実行できてしまう。 この章では、SUID及びSGIDが設定されたファイルの検索方法を紹介している。 この方法で意図していないプログラムにSUID及びSGIDが設定されていないかを確認します。 ## 前提知識 ### SUID、SGIDとは? - SUIDはプログラムをファイル所有者の権限で動作させるパーミッション - SGIDはプログラムを所有グループの権限で動作させるパーミッション - SUID、SGIDが設定されたファイルは実行権限が「s」で表示される - SUID ex) drwsr-xr-x - SGID ex) drwxr-sr-x - あくまで、「ファイル所有者として実行する」という意味なので、そもそも実行権限は必要である ### SUID、SGIDの調査 以下コマンドで「SUID」「SGID」の権限が付与されたプログラムを調査できる <pre> find / \( -perm -4000 -o -perm -2000 \) -type f -exec ls -la {} \; </pre> | オプション名 | 意味 | |----|----| | -perm | 検索対象のパーミッションを指定 | | -4000 | SUIDを指定 | | -o, -or | 検索条件を OR で結ぶ。<br>上記コマンドでは「SUIDか、あるいはSGIDのパーミッション」という指定になる | | -2000 | SGIDを指定 | | -type | ファイルタイプを指定する (「f」 が通常ファイルタイプを指定) | | -exec | findコマンドを実行し終わった後に実行させるコマンドを指定できる(複数可)。 「+」 か 「;」で繋げられる | | {} | 実行結果を返す場所を指定 | | \ | findコマンドの終了を示す「;」として認識させるために「;」をエスケープさせる | これで、SUIDとSGIDが付与されているプログラムの一覧を表示することができる ## 確認方法 root権限になり、「/usr/share/」内で以下コマンドを実行する<br> ※/usr/ ディレクトリーは、複数マシンで共有されるファイル用に使われます。<br> 下記バイナリを別ユーザーで実行する必要があり、/usr/shareディレクトリにはその他ユーザーにも実行権限があるため、今回はこのディレクトリを使用します。<br> そのため、今回はその他ユーザーに実行検眼が付与されるディレクトリであればどこで作業しても構いません。 <br> 詳しくはFHSについて調べてください。([参考](https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/s1-filesystem-fhs.html)) <pre> # mkdir testSuid (ディレクトリ作成) # cd testSuid (ディレクトリ移動) # vi suid.c (C言語ファイルの作成) #include &lt;stdio.h&gt; #include &lt;unistd.h&gt; #include &lt;sys/types.h&gt; #include &lt;pwd.h&gt; int main() { uid_t uid = geteuid(); struct passwd *pw = getpwuid(uid); printf("%d %s\n", uid, pw->pw_name); return 0; } ※実行したユーザーがどのユーザーの権限で実行されたかを確認するためのプログラム # gcc suid.c -o hello (実行バイナリ「hello」にコンパイル) </pre> これで準備は整いました。 ちなみにスクリプト(.sh)の場合はセキュリティの関係上、suidを適用することができません。 スクリプトにsuidを設定する場合、多くのセキュリティホールを生み出す危険性があるため、多くのオペレーティングシステムではシェルスクリプト形式の実行ファイルへの setuid 属性付与を無視するようになっています。 <br>(参考サイト:<http://www.nurs.or.jp/~asada/FAQ/UNIX/section4.7.html>) そのため、実行バイナリで試さなければならないので、C言語を使用します。 では、本当にsuidが適用されているかを確認します。 <pre> # su dojo (root以外になること) $ ll hello -------------------------------------------------------- -rwxr-xr-x 1 root root 6717 2月 21 16:46 2017 hello -------------------------------------------------------- ※もし実行権限が付与されていない場合は「chmod 0755 hello」で付与する $ ./hello -------------------------------------------------------- 500 dojo -------------------------------------------------------- # chmod 4755 hello (root権限で実行すること) (「chmod u+rwxs,g+rx,o+rx hello」でも可) $ ./hello -------------------------------------------------------- 0 root -------------------------------------------------------- </pre> 実行者のユーザーIDが[500]のため、そのユーザーが実行したにも関わらず suidをセットしたことにより、実行権限が所有者であるroot(ユーザーID[0])になっていることがわかる これで正常にsuidをセットできたので、以下のコマンドで検索してみましょう。 <pre> # find / \( -perm -4000 -o -perm -2000 \) -type f -exec ls -la {} \; -rwsr-xr-x 1 root root 53472 11月 19 00:38 2016 /bin/umount -rwsr-x--- 1 root fuse 32368 5月 11 16:38 2016 /bin/fusermount (中略) -rwsr-xr-x 1 root root 6717 2月 21 16:46 2017 /usr/share/testrm/hello (以下略) -------------------------------------------------------- </pre> また、以下コマンドにより実行型バイナリファイルを検索することができる <pre> # find / \( -perm -4000 -o -perm -2000 \) -type f -exec file -i {} \; | grep binary </pre> ※本には以下の通りに記述されているが、バイナリ型のファイルに対して「file」コマンドを打っても結果が何も帰ってこないため、検索できない。 そのため、「file」コマンドにオプション「-i」を付けることで、バイナリ型ファイルの識別ができるようになる。 「find / \( -perm -4000 -o -perm -2000 \) -type f -exec file {} \; | grep ELF」 これを活用して、不適切なsuidが設定されている実行型バイナリファイルがないか調査しましょう。 # HACK#3 書き込みパーミッション設定が甘いディレクトリの捜索 ## 概要 - stickyビットが設定されているかを調査して、パーミッション設定が甘いディレクトリを発見する - stickyビットが設定されていないとすべてのユーザーが書き込み、変更、削除ができてしまうため ## 背景 ファイルやディレクトリにはパーミッションが設定されており、その設定によってファイルの読み込みや書き込み、実行を制御できる。もし、パーミッションが正しく設定されていなければ、すべてのユーザーが書き込み、変更、削除ができてしまう。また、ファイルの改ざんや不特定のユーザーからファイルが実行される可能性がある。そのため、各ファイルやディレクトリに対して正しいパーミッションを設定する必要がある。 ## 前提知識 ### umask ファイルやディレクトリを作成した際の、パーミッションの初期値を「umask」というコマンドで設定することができる。例えば、としては「666」で作成されることになっている。そこで、「umask」の値を設定することにより、パーミッションの初期値を変更することができる。ただし、umaskの設定が適切に設定されていない場合、セキュリティの低いファイルやディレクトリが作成される。 umaskの設定例:umask「0022」とした場合 - ファイル作成時のパーミッション:「0644」、「-rw-r--r--」 - 所有者以外にファイルの内容を変更されない - 全ユーザーに実行されない ### stickyビット stickyビットによって、特別な権限を付与することもできる。stickyビットを設定することで、実際に設定したパーミッションに関係なく、所有者とrootにのみ変更、削除権限を与えることができる。逆に、stickyビットが設定されていない場合、複数ユーザーが共有で使用するディレクトリ内のファイルが他ユーザーによって削除される可能性がある。そのため、複数ユーザーが共有でファイルを格納している「tmp」ディレクトリにはstikyビットが設定されている。 - stickyビットが設定されたディレクトリは実行権限が「t」で表示される - ex) drwxrwxrwt root root ### stickyビットの調査 以下コマンドで「グループ」と「その他ユーザー」に書き込み権限があるディレクトリを調査する <pre> find / -type d \( -perm -g+w -o -perm -o+w \) -exec ls -lad {} \; </pre> | オプション名 | 意味 | |----|----| | -g+w | グループの書き込み権限を指定 | | -o+w | その他ユーザーの書き込み権限を指定 | 以下のコマンドで「グループ」と「その他ユーザ」に書き込み権限があり、stickyビットが設定されていないディレクトリを調査する <pre> find / -type d \( -perm -g+w -o -perm -o+w \) -not -perm -a+t -exec ls -lad {} \; </pre> なお、stickyビットはファイルに設定しても意味がないので、検索する場合はディレクトリを対象にすること | オプション名 | 意味 | |------|-------| | -not | 後ろに続く条件式を否定する(反転させる) | | -a+t | 全てのユーザーのstickyビットを指定 | 「-not -prem -a+t」 を追加したことにより、最初のコマンドにstickyビットが設定されていないという条件が追加される。 これにより、書き込み権限があるにも関わらず、stickyビットが設定されていないディレクトリを抽出することができる ## 確認方法 root権限になり、「/usr/share/」内で以下コマンドを実行する <pre> # mkdir stickytest # chmod 777 stickytest # cd stickytest # touch test1 # touch test2 # chmod 777 test* </pre> これでstickyビットをテストするための環境が整いました。 まずは所有者(root)以外のユーザーになって、今の状態でtest1が削除できることを確認しましょう。 <pre> # ls -l 合計 0 -rwxrwxrwx 1 root root 0 2月 28 10:24 2017 test1 -rwxrwxrwx 1 root root 0 2月 28 10:24 2017 test2 # su {root以外} $ rm test1 </pre> 何もエラーが出ず、削除できればOK 次にstickyビットを設定して、所有者(root)以外のユーザーでは削除できないことを確認しましょう。 <pre> # chmod 1777 /usr/share/stickytest (stickyビットの設定) </pre> chmodで「1000」か「-a+t」と指定すればstickyビットを設定することができます。 では実際に正しく設定されているか試してみましょう。 <pre> # ls -l /usr/share/ (前略) drwxr-xr-x. 2 root root 4096 1月 31 11:34 2017 spamassassin drwxr-xr-x. 3 root root 4096 1月 31 12:38 2017 sssd drwxrwxrwt 2 root root 4096 2月 28 10:26 2017 stickytest drwxr-xr-x. 3 root root 4096 1月 31 11:36 2017 swig drwxr-xr-x. 3 root root 4096 1月 31 11:31 2017 system-config-date (後略) # su {root以外} $ rm test2 rm: remove write-protected 通常の空ファイル `test2'? y rm: cannot remove `test2': 許可されていない操作です </pre> test2は書き込み権限あるにも関わらず、削除が行えなくなっていると思います。 これで適切にstickyビットが設定されていることが確認できました。 では、findコマンドで確認しましょう。 <pre> # find / -type d \( -perm -g+w -o -perm -o+w \) -exec ls -lad {} \; </pre> このコマンドは「書き込み権限が付与されているディレクトリ」を抽出するので、「stickytest」は検索にヒットします。 <pre> # find / -type d \( -perm -g+w -o -perm -o+w \) -not -perm -a+t -exec ls -lad {} \; </pre> このコマンドは「書き込み権限が付与されているが、stickyビットが付与されていないディレクトリ」を抽出するので、「stickytest」は検索にヒットしないはずです。 これを活用して、stickyビットが設定されていないパーミッション設定が甘いディレクトリを検索して対処しましょう。 # HACK#4 POSIX ACL(Access Control List)で柔軟な権限を設定 ## 概要 - Unix系OS標準のファイルシステムへのアクセス制御機能に代えて、ACLを利用してファイルやディレクトリへのアクセス制御を行う - 標準のファイルシステムでは「所有者」、「グループ」、「その他」の3種類でしかアクセス制御できない - ACLを用いて特定のユーザーやグループに対して柔軟なルールでアクセス制御する ## 背景 ### パーミッション管理の煩わしさ 自身の管理するファイルを他人によって勝手に削除されたり、書き換えられたりできないようにするためパーミッションの設定が必要となる。 Linuxの場合、デフォルトでは「ユーザ」「グループ」「その他」の3種類でしかアクセス制御できない。そのため複数人でファイルを共有するには、グループを新規作成したり、ユーザをグループに追加する手順が必要となる。この時ファイルを共有する人数が多くなると、グループ管理が困難になってしまう。 結果パーミッション管理の煩わしさが発生してしまう。 この問題の解決方法としてPOSIX ACLがある。 ### POSIX ACLとは - UNIXの標準的なファイルパーミッション指定と比較すると、柔軟なアクセス制御を可能とする仕組み<br> - 特定のユーザやグループに対してパーミッションを設定することが可能<br> - 新規グループを作成したり、ユーザをグループに追加せず、既存状態のユーザやグループにパーミッションを設定することが可能<br> このようにPOSIX ACLを用いることで、パーミッション管理の煩わしさが軽減される ## 前提知識 ### デフォルトACLとは? - ディレクトリに対して設定できるディレクトリ下のファイルやサブディレクトリの初期ACL ### ACLマスクとは? - 所有者以外のすべてのユーザーとグループに許可される最大のパーミッション - このマスクの設定によって、強制的に事前に設定済みの権限が与えられる ### ACLの有効化 ACLは下記コマンドでファイルシステムをマウントする時にマウントオプションとして設定して有効化する <pre> mount -o acl マウントするデバイス マウント先ディレクトリ </pre> - 書籍では、オプション(o)の引数をaclsとしているが、aclsはFreeBSDでの設定方法であるため、Linuxではaclで設定する。 - CentOS6では、OSインストール時に設定されたデバイスかつext4を利用中であればACLが有効化されている 新しく接続したデバイスに自動でACLを設定したい場合は下記コマンドを実行する(デフォルトマウントオプションへの追加) <pre> tune2fs -o acl デバイス </pre> ### ACLの管理 ACL変更・削除には下記のようなsetfaclコマンドを用いる <pre> setfacl -m u:ユーザー名:モード(rwx),g:グループ名:モード,o:モード 対象 </pre> 左からユーザー、グループ、その他のACLを設定していて、それらは全て記述する必要はない また、ユーザー名やグループ名も省略可能である また、-mオプションの後を「d:」から始めると、デフォルトACLが設定できる さらに、-mオプションの後に「m:モード」を記述すると、ACLマスクが設定できる ACLの設定確認には下記のようなgetfaclコマンドを用いる <pre> getfacl -m 対象 </pre> ### カーネルコンフィグレーションとは 文字通りカーネルがサポートする内容を指定している ファイル内の設定ステータスは以下の通り ``` [Y] 機能を有効にする場合 [M] モジュールとして埋め込む [N] 無効にする ``` [Y]、[N]は文字通りですので、説明不要と思います。<br> `[M]モジュールとして埋め込む`は、カーネルそのものに組み込まれず、外部モジュールとして機能を提供する。<br> これは必要に応じてON OFFができる。<br> 現在有効にする必要はないが、今後必要となる可能性があるものに設定する。 参考 [Linuxサーバー構築ガイド](http://safe-linux.homeip.net/other/linux-kernel-04.html) <br> #### カーネルコンフィグレーションの確認方法<br> 下記のファイルの内容は膨大なため、`grep`の併用を推奨 <pre> # cd /boot<sup>※</sup> # cat config-$(uname -r) | grep ACL </pre> ※移動先のディレクトリはmountコマンドで調べてください<br> $(uname -r)はシステムのリリース番号を出力します。 ## 確認方法 acl はマウントオプションとして指定する まずはmountコマンドでマウント状況を確認 <pre> # mount (中略) /dev/sda1 on /boot type ext4 (rw) </pre> では実際にaclを付与してみる。 マウントオプション「acl」を指定してマウントし、mountコマンドで確認 <pre> # mount -o acl /dev/sda1 /boot # mount (中略) /dev/sda1 on /boot type ext4 (rw,acl) </pre> マウントオプションの所に(acl)が表示されればOK。 これでマウントされたディレクトリ内では自動でアクセス権限が付与される。 では試しにaclを設定してみましょう。 <pre> # cd /boot # touch test # ll test -rw-r--r-- 1 root root 0 2月 21 14:09 2017 test # setfacl -m u:dojo:rwx,g::---,o:--- test # ll test -rwxrwx---+ 1 root root 14 2月 21 14:20 2017 test </pre> 権限の最後尾に「+」があると思います。これでaclを設定することができました。 上記のコマンドで行ったaclの設定はユーザー「dojo」に権限「rwx」を付与するという設定です。 aclの設定は以下で確認できます。 <pre> # getfacl test # file: test # owner: root # group: root user::rwx user:dojo:rwx group::--- mask::rwx other::--- </pre> では実際に確認してみましょう。 <pre> # su {root,dojo以外} $ vi test -------------------------------------------------------- "test" [認可がありません] -------------------------------------------------------- $ exit # su dojo $ vi test (正常に開くことができ、書き込み保存ができる) </pre> これで「dojo」にだけ「rwx」を付与するということが確認できました。 今度はディレクトリのaclの設定をします。 <pre> # mkdir acltest # setfacl -m d:u:sfs:rwx,g::---,o:--- acltest </pre> aclの確認方法もファイルと同様、getfaclで確認できます <pre> # getfacl acltest # file: acltest # owner: root # group: root user::rwx group::--- other::--- default:user::rwx default:user:sfs:rwx default:group::--- default:mask::rwx default:other::--- </pre> これにより、ディレクトリ「acltest」内で自動的に作成されるファイルは自動的に「acltest」のdefaultのaclが設定されますが、注意すべき点があります。 <pre> # cd acltest # touch test # getfacl test # file: test # owner: root # group: root user::rw- user:sfs:rwx #effective:rw- group::--- mask::rw- other::--- # su {root,sfs以外} $ vi test "test" [認可がありません] # exit # su sfs $ vi test "test" [認可がありません] </pre> 上記のようにaclが適用されているはずなのですが権限がないと言われてしまいます。 ※「#effective:」は、ACLマスクによって変更された後のアクセス権の設定を表しています。「user:sfs:rwx」と設定されているが、ACLマスクの値である「mask::rw-」が反映されるため、実際には「#effective:rw-」のパーミッションが有効となります。 実は、上記の設定はあくまで「デフォルト」のaclを設定しただけで、「acltest」自体にはaclが設定されていません。 <pre> # getfacl acltest # file: acltest # owner: root # group: root ----------------------------------------------------------------- user::rwx ↑ group::--- この範囲がacltest設定されているacl other::--- ↓ ----------------------------------------------------------------- default:user::rwx ↑ default:user:sfs:rwx default:group::--- この範囲がacltest配下に設定されるacl default:mask::rwx default:other::--- ↓ ----------------------------------------------------------------- </pre> そのため「acltest」配下のaclの設定を行っただけで、「acltest」にはrootユーザ以外の実行権限がないため、「acltest」ディレクトリ配下のファイルを「sfs」ユーザで読み込みや書き込み実行が行えずに[認可がありません]のようなエラーが発生する なので、「acltest」自体にも「sfs」ユーザで実行できるようにaclを設定する必要があるので、注意しましょう。 <pre> # setfacl -m u:sfs:rwx,g::---,o:--- acltest # getfacl acltest # file: acltest/ # owner: root # group: root user::rwx user:sfs:rwx (←acltest自体に権限が付与された) group::--- mask::rwx other::--- default:user::rwx default:user:sfs:rwx default:group::--- default:mask::rwx default:other::--- </pre> これにより、「acltest」内のtestファイルを「sfs」ユーザーが書き換えられるようになっていると思います。 このようにして、aclの設定を行い、ファイルやディレクトリのアクセス制御をきちんと設定していきましょう。 ちなみに、前提知識にあるように以下のコマンドでマウント時にデフォルトでaclが設定されるようになります。 <pre> tune2fs -o acl /dev/sda1 </pre> これにより、指定したデバイス名は自動でaclが設定されるようになるので、マウントして試してみましょう。 また、デフォルトでaclが設定されているかを以下で確認することができます。 <pre> # tune2fs -l /dev/sda1 tune2fs 1.41.12 (17-May-2010) Filesystem volume name: <none> Last mounted on: /boot Filesystem UUID: 8a70af10-d21d-4fce-9b0e-1bdd8f84b4a3 Filesystem magic number: 0xEF53 Filesystem revision #: 1 (dynamic) Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize Filesystem flags: signed_directory_hash Default mount options: user_xattr acl (←ここ) Filesystem state: clean Errors behavior: Continue Filesystem OS type: Linux Inode count: 128016 Block count: 512000 Reserved block count: 25600 Free blocks: 420722 Free inodes: 127970 First block: 1 Block size: 1024 Fragment size: 1024 Reserved GDT blocks: 256 Blocks per group: 8192 Fragments per group: 8192 Inodes per group: 2032 Inode blocks per group: 254 Flex block group size: 16 Filesystem created: Thu Feb 16 20:31:04 2017 Last mount time: Tue Feb 21 14:15:56 2017 Last write time: Tue Feb 21 14:15:56 2017 Mount count: 21 Maximum mount count: -1 Last checked: Thu Feb 16 20:31:04 2017 Check interval: 0 (<none>) Lifetime writes: 88 MB Reserved blocks uid: 0 (user root) Reserved blocks gid: 0 (group root) First inode: 11 Inode size: 128 Journal inode: 8 Default directory hash: half_md4 Directory Hash Seed: 4342a120-53aa-4c0e-b111-52a4f4b59265 Journal backup: inode blocks </pre> --- ## 確認方法(その2) #### ACLのデフォルト値 本の内容で、特定のユーザーにACLを設定するときに、<br> 元のグループにパーミッションがすべて付与されていない箇所があります。<br> 普通にすると、ファイルの場合`group::r--`となるはずです #### 書籍のumask値に問題があると思われる。<br> 私の環境で試してみた結果を下記に載せます<br> <br> umask値はデフォルトのまま ``` # umask 0022 ``` ファイルfooを作成し、書籍の通りにACLを設定します。 ``` # touch foo # setfacl -m u:dojo:rwx,g:dojo:rwx,o:--- foo # getfacl foo # file: foo # owner: root # group: root user::rw- user:dojo:rwx group::r-- group:dojo:rwx mask::rwx other::--- ``` 書籍では下記の通り記述されています。 ``` # touch foo # setfacl -m u:jlope:rwx,g:wine:rwx,o:--- foo # getfacl foo # file: foo # owner: andrew # group: andrew user::rw- user:jlope:rwx group::--- group:wine:rwx mask::rwx other::--- ``` 確証は得られないが、恐らく書籍の環境下ではumask値が`0066`や`0077`等、<br> グループにパーミッションが設定されない値が設定されていると推測。<br> 推測したumask値に変更して、同じ手順を実行してみます。 ``` # umask 0077 # umask 0077 ``` ``` # touch foo # setfacl -m u:dojo:rwx,g:dojo:rwx,o:--- foo # getfacl foo # file: foo # owner: root # group: root user::rw- user:dojo:rwx group::--- group:dojo:rwx mask::rwx other::--- ``` 書籍と同じように元のグループにパーミッションが全て付与されていません。<br> <br> よって、ACLで設定していないパーミッションはumask値を基に設定されていることが分かる --- # HACK#5 ログの改ざん防止 ## 概要 - ファイルやディレクトリに拡張属性(追加のみ許可など)を設定してログが改ざんされるのを防ぐ - 攻撃者が残した痕跡(ログなど)を故意に消せないようにするため ## 背景 ### ログの重要性 ITシステムでは、多くのハードウェアやソフトウェアからログが出力される。これは、人間でいえば日記、企業でいえば事業報告書のようなものである。ITシステムでは安定稼働や運用管理のための重要な資料としてログが活用される。 システムに不具合が発生した場合、ログを見ることで原因が分かる。例えば、障害発生前に想定外のアクセスがあり、それが要因になって発生した場合、システムを改修して不具合をなくす。CPUの使用率が急増している場合は、負荷分散をする仕組みを講じる等の対策を講じることができる。 しかし、情報漏えいが社会的問題になってからは、ログは運用や安定稼働の維持管理のため用いるだけでなく、 誰がいつ持ち出したのかを探ることができる犯人捜しの証拠、あるいは監視を目的として活用されるようになった。 このようにログは時代とともに重要性が増してきた。 ### ログの改ざん - 通常一般ユーザーはログファイルに変更を加えたり、削除することができない - もし、root権限が奪われてしまうと、ログファイルからログを削除したり、ログファイル自体の削除が可能になる ※強力なパスワードを設定するだけではroot権限の奪取を完全に防げない そこで、ログファイルに既に記録されている内容の削除やログファイルの削除をできないようにする ## 前提知識 拡張属性が設定されているかどうかは下記のlsattrコマンドを実行する <pre> lsattr 対象 </pre> 拡張属性を設定するには下記のchattrコマンドを実行する <pre> charttr +拡張属性 対象 </pre> 下記表は拡張属性の例である | 拡張属性 | 意味 | |----|----| | a | 追加のみ許可 | | i | 変更禁止 | | u | 削除禁止 | ただし、root権限が奪われると拡張属性の前の「+」を「-」に変えることで簡単に削除できてしまう そこで、rootの権限を制限する(属性の変更を禁止する)ためにcapability機能を用いる capabilityの設定変更にはlcapなどのユーティリティツールを用いると良い ### capabilityとは rootの権限を細かく分けて、その細かい権限を必要最小限だけ与えることで、 セキュリティを向上しようというもの。<br> つまりrootか非rootかではなく、もっと細かい単位で権限を与えることが可能。 ### capbilityの設定確認方法 <pre> cat /usr/include/linux/capability.h | grep CAP </pre> ### capabilityの設定ステータス - permitted (許可) - 実行したときに許可されるケーパビリティセット。 - 実行前のプロセスの permitted と関係なく、プロセスに設定される。 - inheritable (継承可能) - 実行したときに継承されるケーパビリティセット。 - effective (実効) - これは、1ビットの情報で集合ではない。 - これが設定されていないと、実行したときにプロセスの permitted が設定されない。 詳しくは下記ページの「スレッドケーパビリティセット」、「ファイルケーパビリティ」を参照<br> [Man page of CAPABILITIES](https://linuxjm.osdn.jp/html/LDP_man-pages/man7/capabilities.7.html) 設定時はこれらの頭文字をとって「p」「i」「e」を各capabilityに設定します。<br> <br> ## 確認方法 適当なファイルを作成して「追加のみ許可」属性を設定します。 <pre> # touch chattrtest # chattr +a chattrtest </pre> これで設定することができました。 では実際にその属性が適用されているか確認してみましょう <pre> # echo "This is test" > chattrtest bash: chattrtest: 許可されていない操作です </pre> 「chattrtest」を上書きに失敗しました。 では今度は追記してみましょう。 <pre> # echo "This is test" >> chattrtest # cat chattrtest This is test </pre> 追記は成功したので、これで正常に「追加のみ許可」属性を設定することができました。 ### 確認方法(その2) rootでないと`cat`することができない`/etc/shadow`ファイルをユーザーで`cat`できるようにする<br> ※この設定は百害あって一利なしなので確認が終わり次第削除しましょう。 <br> ユーザー`dojo`用に `/bin/cat` をコピー <pre> # su - dojo $ cp /bin/cat ./mycat </pre> ファイルの読み出し権限のチェックとディレクトリの読み出しと実行の権限チェックを行うcapabilityを設定します。<br> 詳しいcapabilityの説明は [Man page of CAPABILITIES](https://linuxjm.osdn.jp/html/LDP_man-pages/man7/capabilities.7.html) を参照してください。<br> capabilityの設定には`setcap`コマンドを使用します。 <pre> $ sudo setcap cap_dac_read_search=eip ./mycat </pre> ※ここで、`dojoはsudoersファイル内にありません`と出た方は、<br> sudo設定ファイル内の`wheel ALL=(ALL) ALL`設定が無効になっているからだと思います。<br> 設定変更が面倒であれば、rootユーザーで`/home/dojo/mycat`に設定してください。<br> <br> 設定できたら確認します。<br> 設定の確認には`getcap`コマンドを使用します。 <pre> $ getcap ./mycat ./mycat = cap_dac_read_search+eip </pre> 上記のようになっていれば設定完了です。確認します。<br> まず、通常の`cat`コマンドで`/etc/shadow`ファイルが実行できないことを確認。 <pre> $ cat /etc/shadow cat: /etc/shadow: 許可がありません </pre> 設定した`./mycat`を使用して実行できることを確認します。 <pre> ./mycat /etc/shadow (略) bin:*:15980:0:99999:7::: daemon:*:15980:0:99999:7::: adm:*:15980:0:99999:7::: (以下略) </pre> capabilityの削除には`setcap`コマンドに`-r`オプションを指定します。<br> 設定を削除して、`./mycat`で`/etc/shadow`を実行できないことを確認します。 <pre> $ sudo setcap -r ./mycat $ getcap ./mycat $ ./mycat /etc/shadow ./mycat: /etc/shadow: 許可がありません </pre> 大まかな流れとしては、設定したいcapabilityを調べて、`setcap`コマンドで「permitted」「effective」を設定すれば、<br> capabilityの設定ができます。 # HACK#6 管理権限の分担化 ## 概要 - sudoコマンドを実行できるユーザーを制限して、様々なシステムコマンドへのアクセス許可を精密に行う - デフォルトのユーザーリストに記述された全ユーザーに無期限のroot権限を持たせる設定では、攻撃されたときに無制限の操作を許してしまう - 無制限の操作を許してしまうと、ユーザーリストに悪意のあるユーザーが記述されていた場合、システム上で不正なコマンド操作が行われる ## 背景 ### sudoコマンドとは - rootや他のユーザー権限で(自分と違うユーザーに変身して)コマンドを実行するときに使う - デフォルトでは、rootのみが全てのユーザーに変身できる設定になっている<br> → root以外のユーザーはrootに変身できないため、パッケージのインストールなどを全てrootに依頼しなければならない (管理者の負担が大きくなる) - root以外のユーザーにsudoコマンドの実行を許可することで管理者の負担を軽減する ### sudoコマンドの注意点 - sudoコマンドで完全にroot権限を渡してしまうと、誤ったコマンドを実行してデータが全て消去される などの重大な被害が発生する可能性がある - sudoコマンドの実行が許可されたユーザーが悪意あるユーザーだった場合、root権限を悪用してシステムが不正に改変 されてしまう可能性もある そこで、sudoコマンド実行できるコマンドを制限するなどして、安全にrootにしかできない作業を分担する ## 前提知識 sudoコマンドを実行できるユーザーを制限するためには/usr/sbin/visudoコマンドを実行して設定ファイルに下記のように記述する <pre> ユーザー名 ホスト名=(実際のユーザー名) コマンド </pre> 上記の記述でユーザー名のユーザーが()内のユーザーとしてコマンドを実行できるようになる ユーザー名の代わりにグループ名を指定する場合は先頭に「%」をつける コマンドの前に「NOPASSWD:」フラグを記述しておくと、パスワード要求がなくなる ## 確認方法 sudoの権限はデフォルトで以下の通りとなっている <pre> # visudo (中略) # Allow root to run any commands anywhere root ALL=(ALL) ALL (以下略) </pre> この設定は「rootが全てのコマンドをsudo(root権限)で実行できる」という設定になっています。 そのため、その他のユーザーは現在sudoコマンドが使えない状況になっていると思います。 <pre> # su dojo $ sudo yum install nmap [sudo] password for dojo: (←正しいパスワードの入力) dojo は sudoers ファイル内にありません。この事象は記録・報告されます。 </pre> このように正しいパスワードを入力しても、実行することはできません。 dojoに管理者権限で実行することを許可した場合は以下のようにして追加します。 <pre> # visudo (中略) # Allow root to run any commands anywhere root ALL=(ALL) ALL dojo ALL=(ALL) ALL (以下略) # su dojo $ sudo yum install nmap [sudo] password for dojo: (←正しいパスワードの入力) 読み込んだプラグイン:fastestmirror, refresh-packagekit, security インストール処理の設定をしています Loading mirror speeds from cached hostfile * base: centos.usonyx.net * extras: centos.usonyx.net * updates: centos.usonyx.net パッケージ 2:nmap-5.51-4.el6.x86_64 はインストール済みか最新バージョンです 何もしません </pre> このようにユーザー「dojo」で管理者権限で実行することができていると思います。 ただし、これではユーザー「dojo」は全てのコマンドを管理者権限で実行できてしまいます。管理者権限で実行させたいコマンドのみに絞りたい場合は以下のように記述します。 <pre> # visudo (中略) # Allow root to run any commands anywhere root ALL=(ALL) ALL dojo ALL=(ALL) /usr/bin/yum,/sbin/shutdown (以下略) </pre> これにより、ユーザー「dojo」はコマンド「yum」と「shutdown」のみ管理者権限で実行できるようになります。 <pre> # su dojo $ sudo yum install nmap [sudo] password for dojo: (←正しいパスワードの入力) 読み込んだプラグイン:fastestmirror, refresh-packagekit, security インストール処理の設定をしています Loading mirror speeds from cached hostfile * base: centos.usonyx.net * extras: centos.usonyx.net * updates: centos.usonyx.net パッケージ 2:nmap-5.51-4.el6.x86_64 はインストール済みか最新バージョンです 何もしません $ sudo /etc/init.d/httpd start ユーザー dojo は'/etc/init.d/httpd start' を root として dojo.local 上で実行することは許可されていません。すみません。 </pre> また、以下のようにすることで実行するホストを制限したり、実行権限を指定できる <pre> # visudo (中略) # Allow root to run any commands anywhere root ALL=(ALL) ALL dojo dojo.local=(sfs) /usr/bin/yum,/sbin/shutdown (以下略) </pre> 設定するコマンド、ユーザ、コンピュータの数が多数存在する場合には、エイリアスを用いることで簡潔に記述することができる。 記述方法 <pre> 記述エイリアス名_Alias 名前(大文字アルファベット) = リスト </pre> - 名前を指定する際には大文字のアルファベットを使用する。 以下のように設定することで、「dojo」、「host1」、「host2」ユーザは、「yum」と「shutdown」のみ管理者権限で実行することができる。 <pre> # visudo (中略) ## User Aliases User_Alias DOJO = dojo, host1, host2 (中略) ## Command Aliases Cmnd_Alias YUMSHUT = /usr/bin/yum, /sbin/shutdown (中略) ##Allow root to run any commands anywhere root ALL=(ALL) ALL DOJO ALL=(ALL) YUMSHUT (以下略) </pre> エイリアスを設定することで、下記のような結果を得ることができる。 <pre> # su dojo $ sudo yum install nmap [sudo] password for dojo: (←正しいパスワードの入力) 読み込んだプラグイン:fastestmirror, refresh-packagekit, security インストール処理の設定をしています Loading mirror speeds from cached hostfile * base: centos.usonyx.net * extras: centos.usonyx.net * updates: centos.usonyx.net パッケージ 2:nmap-5.51-4.el6.x86_64 はインストール済みか最新バージョンです 何もしません </pre> NOPASSWDフラグを使用することで、コマンドを実行する際に、パスワード要求がされない。 <pre> # visudo ##Allow root to run any commands anywhere root ALL=(ALL) ALL DOJO ALL=(ALL) NOPASSWD: YUMSHUT (以下略) </pre> NOPASSWDフラグ設定後は、下記のようにパスワード要求がされなくなる。 <pre> # su dojo $ sudo yum install nmap (パスワード要求なしでyumが実行される) 読み込んだプラグイン:fastestmirror, refresh-packagekit, security インストール処理の設定をしています Loading mirror speeds from cached hostfile * base: centos.usonyx.net * extras: centos.usonyx.net * updates: centos.usonyx.net パッケージ 2:nmap-5.51-4.el6.x86_64 はインストール済みか最新バージョンです 何もしません </pre> # HACK#7 暗号シグネチャの自動検証 ## 概要 - ソフトウェアの完全性(データが全て揃っていて欠損や不整合がないこと)を検証してインストールする - トロイが埋め込まれたソフトウェア(マルウェア)が増加しており、インストール前の確認が重要 ## 背景 ### インストールに潜む危険 ソフトウェアをインストールする場合は大抵、他者が作成したソフトウェアをインストールすることが多い。<br> 攻撃者は、ユーザーに疑念を抱かせずに、悪意のあるプログラムをインストールさせることで、PCに侵入することなく、ウィルスをPCに感染させることが可能になる。<br> それを防ぐために、インストールするソフトウェアのデータが全て揃っていて欠損や不整合がないこと(完全性)を**インストール前**に検証する必要がある。 ## 前提知識 ※現在はyumコマンドが自動でインストールするソフトウェアのシグネチャを検証するので導入する必要はありません。 ## 確認方法 yumの設定(/etc/yum.conf)では、本で記載されているgpgでの自動検証を行うものがある ``` # cat /etc/yum.conf [main] cachedir=/var/cache/yum/$basearch/$releasever keepcache=0 debuglevel=2 logfile=/var/log/yum.log exactarch=1 obsoletes=1 gpgcheck=1 ←----------この設定 plugins=1 installonly_limit=5 bugtracker_url=http://bugs.centos.org/set_project.php?project_id=19&ref=http://bugs.centos.org/bug_report_page.php?category=yum distroverpkg=centos-release (中略) # PUT YOUR REPOS HERE OR IN separate files named file.repo # in /etc/yum.repos.d ``` gpgcheck=value <br> value は以下のいずれかで設定を行えます。<br> 0 — インストールされるローカルパッケージなど、全リポジトリ内のパッケージ上での GPG 署名確認を無効にします。<br> 1 — インストールされるローカルパッケージなど、全リポジトリ内の全パッケージ上での GPG 署名確認を有効にします。gpgcheck=1 がデフォルトであるため、すべてのパッケージ署名は確認されます。<br> このオプションが /etc/yum.conf ファイルの [main] セクションで設定されている場合は、全リポジトリに対して GPG 照合規則を設定します。 したがってgpgcheck=1に設定することで、yumでは自動でGPG署名を確認し、パッケージの真正性を検証できた上でインストールを行えます。 # HACK#8 ネットワークサービスチェック ## 概要 - 不要なサービスやバックドア(攻撃者が自分で侵入のために入口として開けるポート)が起動していないか調査する - 不要なポートが開いているとそこから攻撃者が侵入を試みようとしてしまうため ## 背景 不要なサービスが多数存在していたり、使用しないポートを開放していると、セキュリティが弱く、攻撃者からの攻撃により被害を受ける可能性が高くなってしまう。もし攻撃されてバックドア型のウイルスに侵入された場合には、常に無防備になってしまい、知らない内に攻撃を受け続けることになってしまう。未然に防ぐためにも、サービスのチェックや不要なサービスの停止を行う必要がある。 ### バックドア コンピュータに設けられた通信経路のうち、正規の経路や手段を経ずにシステムへ侵入するために設けられる接続経路のこと。 バックドア型マルウェアの例として、「トロイの木馬」がある。もし侵入に成功した場合、所有者に気付かれないようにネットワークのポートを開いてアクセス可能に設定する。バックドアを作られると、ログイン認証で防ぐことが不可能になったり、分散DoS攻撃を行うゾンビマシンとして利用される可能性がある。 ### 対策 OSのインストール時など、動作しているサービスを確認し、不要なサービスを停止、自動で起動を行わないようにする設定も併せて行う。「Nmap」や「Netstat」などのコマンドを使用して稼働中のサービスやポートの使用状況を知り、ネットワークサービスの稼働状況を確認する。このようなチェックを定期的に行うことで、バックドアの疑いがあるサービスや不要なサービスを発見し、サービスを停止させることができる。 ## 前提知識 & 確認方法 ### リスン状態のポートとそれを利用しているプロセスの一覧を表示 ``` # netstat -luntp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1141/rpcbind tcp 0 0 0.0.0.0:59763 0.0.0.0:* LISTEN 1163/rpc.statd tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1315/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1415/master tcp 0 0 :::59429 :::* LISTEN 1163/rpc.statd tcp 0 0 :::111 :::* LISTEN 1141/rpcbind tcp 0 0 :::22 :::* LISTEN 1315/sshd tcp 0 0 ::1:25 :::* LISTEN 1415/master udp 0 0 0.0.0.0:36836 0.0.0.0:* 1163/rpc.statd udp 0 0 0.0.0.0:111 0.0.0.0:* 1141/rpcbind udp 0 0 0.0.0.0:892 0.0.0.0:* 1141/rpcbind udp 0 0 127.0.0.1:915 0.0.0.0:* 1163/rpc.statd udp 0 0 0.0.0.0:68 0.0.0.0:* 2560/dhclient udp 0 0 :::111 :::* 1141/rpcbind udp 0 0 :::892 :::* 1141/rpcbind udp 0 0 :::60430 :::* 1163/rpc.statd ``` | オプション | 説明 | |---|---| | -l | リスン状態のソケットのみを表示 | | -u | UDPソケットを表示 | | -n | ホストやユーザーの名前解決を行わない(IPアドレスを表示) | | -t | TCPソケットを表示 | | -p | PIDとプロセス名を表示 | - 「Local Address」のカラムに「0.0.0.0:22」と数字が表示されています。 これの行はローカルアドレスで使用しているポート番号の一つであり、末尾の22はプログラム名のsshdという表示からsshのデーモンが使用していることがわかります。 - デフォルトで設定されている一般的なポート番号の一覧などは[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7#.E3.83.9D.E3.83.BC.E3.83.88.E7.95.AA.E5.8F.B7.E4.B8.80.E8.A6.A7)で確認できます。 ### 上記で使用されているプログラムを検索・確認 - プログラム名のカラムに表示されている内容は `/etc/services` で一覧が確認できます。 よって、 `grep` というコマンドを使って、ポート番号から検索をかけることができます. ※かならずしも `/etc/services` の中に `netstat` コマンドで表示されているプログラムが出てくるとは限りません。あくまでも参考として確認してください。 ``` # grep -w 22 /etc/services ssh 22/tcp # The Secure Shell (SSH) Protocol ssh 22/udp # The Secure Shell (SSH) Protocol ssh 22/sctp # SSH c1222-acse 1153/tcp # ANSI C12.22 Port c1222-acse 1153/udp # ANSI C12.22 Port ``` ### lsofで使用中プロセスの確認 lsofはlist of open filesの略であり、その名の通り、現在開いているプロセスとそれにまつわる情報をリストアップする | オプション | 説明 | |---|---| | -i | ソケットリストの表示 | | -n | ホストやユーザーの名前解決を行わない(IPアドレスを表示) | リスン状態のポートとそれを利用しているプロセスの一覧を表示 - 'COMMAND|LISTEN':TCPソケットを表示するパターン ``` # lsof -i -n | egrep 'COMMAND|LISTEN' COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME rpcbind 1141 rpc 8u IPv4 10844 0t0 TCP *:sunrpc (LISTEN) rpcbind 1141 rpc 11u IPv6 10849 0t0 TCP *:sunrpc (LISTEN) rpc.statd 1163 rpcuser 9u IPv4 10946 0t0 TCP *:59763 (LISTEN) rpc.statd 1163 rpcuser 11u IPv6 10954 0t0 TCP *:59429 (LISTEN) sshd 1315 root 3u IPv4 11254 0t0 TCP *:ssh (LISTEN) sshd 1315 root 4u IPv6 11256 0t0 TCP *:ssh (LISTEN) master 1415 root 12u IPv4 11615 0t0 TCP 127.0.0.1:smtp (LISTEN) master 1415 root 13u IPv6 11617 0t0 TCP [::1]:smtp (LISTEN) ``` - 'COMMAND|LISTEN|UDP':TCPソケットとUDPソケットを表示するパターン ``` # lsof -i -n | egrep 'COMMAND|LISTEN|UDP' COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME dhclient 1328 root 5u IPv4 9629 0t0 UDP *:bootpc portreser 1485 root 6u IPv4 9957 0t0 UDP *:783 portreser 1485 root 10u IPv4 9967 0t0 UDP *:imap portreser 1485 root 12u IPv4 9969 0t0 UDP *:imaps portreser 1485 root 14u IPv4 9971 0t0 UDP *:pop3 portreser 1485 root 16u IPv4 9973 0t0 UDP *:pop3s rpcbind 1553 rpc 6u IPv4 10131 0t0 UDP *:sunrpc rpcbind 1553 rpc 7u IPv4 10133 0t0 UDP *:880 ~~(中略)~~ sshd 1894 root 3u IPv4 11020 0t0 TCP *:ssh (LISTEN) sshd 1894 root 4u IPv6 11024 0t0 TCP *:ssh (LISTEN) sendmail 1922 root 4u IPv4 11104 0t0 TCP 127.0.0.1:smtp (LISTEN) dnsmasq 2214 nobody 5u IPv4 11977 0t0 UDP *:bootps dnsmasq 2214 nobody 6u IPv4 11984 0t0 TCP 192.168.122.1:domain (LISTEN) dnsmasq 2214 nobody 7u IPv4 11985 0t0 UDP 192.168.122.1:domain ``` 上記の方法では動作中のプロセスが全て表示されるため、特定のポートで使用されているプロセスを確認するのには不向きである。 そこであらかじめ表示させたいポートが決まっている場合には、lsofコマンドにオプション(i)を用いてポート番号を指定することで、指定したポートを使用しているプロセスのみ表示させることができる。 <pre> lsof -i:ポート番号 </pre> 下記のように番号を指定することで、22番ポートを使用しているプロセスを表示させることができる。 <pre> # lsof -i:22 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1928 root 3u IPv4 10936 0t0 TCP *:ssh (LISTEN) sshd 1928 root 4u IPv6 10938 0t0 TCP *:ssh (LISTEN) </pre> # HACK#9 サービスのネットワーク利用を制御 ## 概要 - あるサービスに特定のネットワークインタフェースだけをリスンさせる - 必要以上のポートが開いていると攻撃対象領域を広げてしまう ## 背景 ### ポート - ネットワークでデータを通信するための扉のようなもの - ポート番号はポートごとに割り振られた番号 - ポート番号は0から65535まで存在しており、用途ごとに使用する番号が異なる |ポート番号|名称|特徴| |---|---|---| |0~1023|ウェルノウンポート|メジャーなプロトコルが利用するポート| |1024~49151|レジスタードポート|特定のアプリケーションが使用するポート| |49152~65535|その他|ユーザが自由に使用できるポート| ポート番号の一覧は[こちら](https://ja.wikipedia.org/wiki/TCP%E3%82%84UDP%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7%E3%81%AE%E4%B8%80%E8%A6%A7)を参照 ### ポートを開放する理由 2つのPC同士で特定のアプリケーションが通信するときにポートが解放されていないとその通信がブロックされる。そのためポート開放していないポートを使用するアプリケーションは外部から通信することはできない。 以上よりポート解放する必要がある。 ### ポート解放は危険!? では、通信を行いやすいようにすべてのポートを開放するとどうなるだろう? この場合、攻撃者が開放されたポートに対して不正な通信を行うことで、踏み台となったポートで使用しているアプリケーションの脆弱性をつかれる可能性がある。 不特定多数のポートを開放することは良くないが、ポートを開放しなければ、必要な通信すら行うことができない。そのため対策を行ってポート開放をする必要がある。 対策の一つとしてアプリケーションごとに開放するポートを設定することが挙げられる。 ちなみに今回以外の対策として、ポート開放後のウイルス検索やセキュリティー対策ソフトの常駐が挙げられる。 ## 前提知識 ### Apacheで特定のインタフェースのみをリスンさせる場合 /etc/httpd/conf/httpd.confに下記のようなListenディレクティブを記述する ここでディレクティブは命令やコマンドを意味する <pre> Listen IPアドレス:ポート番号 </pre> 上記のように記述することで、指定したIPアドレスのインタフェースの該当ポートをリスンさせる また、バーチャルホストを利用する場合は下記のように記述する ``` <VirtualHost IPアドレス> … </VirtualHost> ``` ### MySQLでTCPソケットをリスンさせない場合 MySQLとApacheが連携したシステムの場合、MySQLとApacheはネットワークを介さずに通信を行うためTCPソケットをリスンする必要がない そこで、/etc/my.cnfの[mysqld]に下記のような記述を追加してドメインソケットを使用した通信を禁止する <pre> [mysqld] skip-networking </pre> ### XサーバがデフォルトでリスンしているTCPの6000番ポートを閉鎖する X Window Systemは使用者が直接操作するサーバ(Xサーバ)とリモートで動作するクライアント(Xクライアント)で構成される XサーバがイベントをXクライアントに伝えて、Xクライアントはディスプレイへの描画命令をXサーバに伝える 上記のやりとりをTCPの6000番ポートを使用して行うが、SSHのXフォワーディング機能によりSSHトンネルを使用して通信ができる SSHトンネルを使用した通信だとTCPの6000番ポートが必要なくなるため、下記コマンドでXを起動する際にポートを開かないように設定できる <pre> startx -- -nolisten tcp </pre> ## 確認方法 この項目を実践するには、サーバーとクライアント計2つの仮想環境が必要になります。 <pre> server# vim /etc/httpd/conf/httpd.conf (中略) Listen 192.168.1.100(サーバ側のIPアドレス):8080 (以下略) server# service httpd restart httpd を停止中: [OK] httpd を起動中: [OK] (ここで警告が出るかもしれませんがhttpdが起動できていれば成功です。) </pre> 上記のようにhttpd.confを記載することで、HTTPでサーバ側に接続要求があった場合、8080番ポートで接続されるように設定されます。 サーバー側のhttpdの起動後にクライアント側のFirefoxから"サーバー側のIPアドレス:8080を検索してください。 Apacheのテストページが表示されれば、成功です。 # HACK#10 サンドボックスによる実行環境の制限 ## 概要 - サービスをサンドボックス環境上で動作させることで、そのサービスが侵入を受けた場合にシステム全体へ影響が及ぶことを防ぐ - 最新のパッチが適用されていてもコンピュータへの侵入は完全に防げない(新しい攻撃手法は対策前に流通する) ## 背景 ### サイバー攻撃の変遷 かつては、パソコンにウイルスを感染させて、ユーザーを驚かせるようなイタズラや技術自慢などの愉快犯が主流だった 近年は、狙いを定めて必要な情報(クレジットカード番号など)を盗み、利益を得ようとする攻撃に変わってきた その中で特に狭い範囲に絞って、あらゆる手段を用いて情報を盗み出そうとする攻撃を「標的型攻撃」という ### サンドボックスを用いないサイバー攻撃への対策 - 脅威への対策は過去に認識された攻撃のパターンに基づいて行われる - 未知の攻撃パターンが用いられた場合、過去に認識されていないため対応のしようがない<br> → 標的型攻撃は手段を選ばないため、認識済みの攻撃パターンと合致しにくい ### サンドボックスを用いたサーバー攻撃への対策 #### サンドボックスとは - 直訳すると、子どもの遊び場としての「砂場」を意味する - 「攻撃されてもよい環境」として構築する仮想環境<br> ※「攻撃されてもよい環境」=「隔離された環境」 - サンドボックスの中で未確認ファイルや疑わしいファイルを動作させて(遊ばせて)、それらの振る舞いを詳細に分析する 元々あるディレクトリ構造とは隔離された環境で各種プログラムを実行することで、標的型攻撃などによる未知の脅威の影響 がサンドボックスの外の環境に及ぶことを防ぐ ## 前提知識 CentOSではchrootを使うことでサンドボックス環境が構築できる chrootはあるプロセスとその子プロセスのルートディレクトリを変更してコンピュータとサンドボックス環境を隔離する chrootによるサンドボックス環境の構築 サンドボックスのルートディレクトリ及びサブディレクトリ(binなど)を作成する 実環境からサブディレクトリへ必要なディレクトリ及びファイルをコピーする サンドボックス環境下でコマンドを実行するには下記のようにchrootコマンドを実行する(ルートディレクトリの変更) chroot サンドボックス環境のルートディレクトリ コマンドへのパス コマンドが実行できなかった場合は、lddコマンドで必要なライブラリを確認してサンドボックス環境にコピーする ## 確認方法(サンドボック環境でbashを使えるようにする) - サンドボックスとするディレクトリ「chroot_test」を作成 ``` # mkdir -p /chroot_test/bin ``` - サンドボックス上で実行したいコマンドを同じ構成でサンドボックスにコピー - 今回はbashを使用したいため、rootにあるbashを新しいサンドボックスにコピーする ``` # cp /bin/bash /chroot_test/bin ``` - サンドボックス環境でbashを動かしてみる ``` # chroot /chroot_test /bin/bash chroot: failed to run command `/bin/bash': No such file or directory ``` ※エラーが出ると思います - 「bash」コマンドを実行する上で、ライブラリが足りてません。 - 必要なライブラリを調べるために `ldd` というコマンドを使います。 ``` # ldd /bin/bash linux-vdso.so.1 => (0x00007ffddfdd8000) libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007ff5b79f4000) libdl.so.2 => /lib64/libdl.so.2 (0x00007ff5b77f0000) libc.so.6 => /lib64/libc.so.6 (0x00007ff5b745b000) /lib64/ld-linux-x86-64.so.2 (0x00007ff5b7c1d000) ``` - ここで、本とファイル構成が違うことがわかります。(僕の場合はlibではなくlib64、そしてtlsがない) - 本通りにやってしまうと、コマンド実行時に以下のようなエラーが出ると思います ``` cp: cannot stat `libtinfo.so.5': No such file or directory cp: cannot stat `libdl.so.2': No such file or directory cp: cannot stat `libc.so.6': No such file or directory cp: cannot stat `ld-linux-x86-64.so.2': No such file or directory ``` - よく見ると本と僕の `/bin/bash` の出力結果が違うことがわかります。 - サンドボックスを設定する時には自分のマシンの/bin/bashと同じ構成でサンドボックスにコピーする必要があります。 - 以下のように変更してみましょう。 ``` # mkdir -p /chroot_test/lib64 && \ (cd /lib64; \ cp libtinfo.so.5 libdl.so.2 libc.so.6 ld-linux-x86-64.so.2 /chroot_test/lib64) ``` これは、以下を行っているのと、同じことです。 ``` # mkdir -p /chroot_test/lib64 # cd /lib64; # cp libtinfo.so.5 /chroot_test/lib64 # cp libdl.so.2 /chroot_test/lib64 # cp libc.so.6 /chroot_test/lib64 # cp ld-linux-x86-64.so.2 /chroot_test/lib64 ``` ※ コピーしているファイルが上記で `ldd` した時のファイルと同じだということがわかります これでもう一度実行してみましょう ``` # chroot /chroot_test /bin/bash bash-4.1# ``` これでサンドボックス環境でbashが使えることを確認できます。 # HACK#11 ProFTPDの認証にMySQLを利用 ## 概要 - ProFTPDの認証情報をデータベース上に記録して、それを用いてProFTPDの認証を行う - 通常のUnix認証だとユーザーにとって不要な機能まで提供されてしまう ## 背景 ### OS上にいないユーザー(バーチャルユーザー)でFTP接続をする OSユーザーにFTP権限を与えたりすることでアカウントの管理面やセキュリティ面で不安な要素が生じてしまう。 + FTP接続したいユーザーが増えた場合、OS上のユーザーを増やす必要がある + OS上のユーザーは、FTP以外の用途(SSHとか)でも使われる可能性があるため、そのための別途対策が必要となる 純粋にFTPだけができ、わざわざOS上にユーザーを作らなくても良い方法をHACK#11で実践する。 ## 前提知識 ProFTPDはモジュールに対応しているので機能の追加が容易である mod_sqlというモジュールはProFTPDの認証にSQLデータベースを使えるようにする ### 手順の概要 1. ProFTPDのビルド時にmod_sqlを一緒にビルドしてインストールする(DB認証の有効化) 1. FTP専用のLinuxアカウントを作成する(このアカウントをMySQLに登録したユーザーと結びつける) 1. ProFTPD用データベースとそこへのアクセスに用いるdbユーザを作成する 1. 先ほど作成したデータベースにユーザー管理用とグループ管理用のテーブルを作成する 1. /usr/local/etc/proftpd.confに認証にMySQLを利用するための設定を記述する 1. 先ほど作成したテーブルにユーザーデータとグループデータをそれぞれ登録する(ここでFTP専用のLinuxアカウントのUID、GIDを指定することでMySQLに登録したユーザーが実ユーザーと結びつけられる) 1. 最後にFTPユーザー用のホームディレクトリ(所有者、グループはFTP専用のLinuxアカウントのもの)を作成してProFTPDを起動するとデータベースに登録したユーザーでログインができる 現在のところ、テキストのようにデータベースに暗号化したパスワードを登録して、ProFTPDの設定で暗号したパスワード認証を用いるようにしても正常に認証されない(2/21) そのため上記は暗号していないパスワード認証の手順になっている ## 確認方法 1. "https://centossrv.com/mysql.shtml"を参考にMySQLをインストールする(下記ステップができればオッケー) - MySQLインストール - MySQL設定 - MySQL起動 - MySQL初期設定 1. proftpdのソースアーカイブをダウンロードする ``` $ wget ftp://ftp.proftpd.org/distrib/source/proftpd-1.3.6rc4.tar.gz ``` 1. proftpdのソースアーカイブを展開する ``` $ tar xvzf proftpd-1.3.6rc4.tar.gz ``` 1. proftpdをビルドする ``` $ cd proftpd-1.3.6rc4 $ ./configure --with-modules=mod_sql:mod_sql_mysql --with-includes=/usr/include/mysql/ \ --with-libraries=/usr/lib64/mysql/ ``` - mod_sqlはproftpdの認証機構のバックエンドとしてSQLデータベースを利用するためのモジュール - 今回はMySQLをproftpdの認証機構のバックエンドとして利用する 1. proftpdをインストールする ``` $ make && make install ``` ※ proftpd-1.3.6rc4/配下で行う 1. FTP用UNIXアカウントを作成する ``` # groupadd -g 111 ftpgroup # useradd -u 111 -s /bin/false -d /bin/null -c "proftpd user" -g ftpgroup ftpuser ``` * このアカウントをMySQLで管理するバーチャルユーザとマッピングする 1. proftpd用データベースとdbユーザを作成する - 以前のチュートリアルで設定したパスワードでログイン ``` $ mysql -uroot -p ``` - proftpd用データベースを読み出し専用とし、ユーザ名を「proftpd」、パスワードを「secret」としてdbユーザを作成 ``` mysql> create database proftpd; mysql> GRANT SELECT ON proftpd.* TO proftpd@localhost IDENTIFIED BY 'secret'; ``` 1. FTPグループの管理テーブル(ftpgroup)を作成する ``` mysql> CREATE TABLE ftpgroup ( groupname varchar(30) NOT NULL default '', gid int(11) NOT NULL default '0', members varchar(255) default NULL ) TYPE=MyISAM; ``` 1. FTPユーザの管理テーブル(ftpuser)を作成する ``` mysql> CREATE TABLE ftpuser ( userid varchar(30) NOT NULL default '', passwd varchar(30) NOT NULL default '', uid int(11) default NULL, gid int(11) default NULL, homedir varchar(255) default NULL, shell varchar(255) default NULL, UNIQUE KEY uid (uid), UNIQUE KEY userid (userid) ) TYPE=MyISAM; ``` bashに戻る ``` mysql> exit; ``` 1. /usr/local/etc/proftpd.confを編集する ``` $ vi /usr/local/etc/proftpd.conf ``` - 以下の内容を追加 ``` SQLConnectInfo proftpd proftpd secret #データベースの接続情報 SQLAuthTypes Plaintext Crypt #認証方式 SQLAuthenticate users groups SQLUserInfo ftpuser userid passwd uid gid homedir shell SQLGroupInfo ftpgroup groupname gid members SQLMinUserGID 111 #ログインを許可するグループIDの最小値 SQLMinUserUID 111 #ログインを許可するユーザIDの最小値 ``` - 以下の内容を編集(30行目付近) ``` #Group nogroup Group nobody ``` 1. FTPグループの管理テーブル(ftpgroup)に実UID、実GIDをマッピングするデータを投入する ``` $ mysql -uroot-p mysql> INSERT INTO `ftpgroup` (`groupname`, `gid`, `members`) VALUES ('ftpgroup', 111, 'ftpuser'); ``` 1. FTPユーザの管理テーブル(ftpuser)にユーザーデータを投入する ``` mysql> INSERT INTO `ftpuser` (`userid`, `passwd`, `uid`, `gid`, `homedir`, `shell`) VALUES ('user1', 'secret', 111, 111, '/home/user1', '/sbin/nologin'); ``` 1. FTPユーザのホームディレクトリを作成する ``` # mkdir -p /home/user1 # chown 111:111 /home/user1 ``` * 所有者をMySQLのユーザとマッピングしているUNIXユーザの所有者とグループに変更する 1. proftpdを起動する ``` $ /usr/local/sbin/proftpd ``` 1. ユーザ名「user1」、パスワード「secret」でftpクライアントからログインする # HACK#12 スタックへの攻撃防止 ## 概要 - ProPoliceやLibSafeを用いてバッファオーバーフロー攻撃を防ぐ - バッファオーバーフロー攻撃が行われると、スタックが上書きされてプログラムが誤動作したりする ## 背景 概要にも記載してある、バッファオーバーフロー攻撃とはどういったものか。 #### バッファ コンピュータプログラムは何らかの情報を格納するための領域をメモリ上に確保する。 この、情報を格納するための領域のことを **バッファ領域** と呼ぶ。 バッファ領域は「スタック」と「ヒープ」領域の2種類に分類される。 スタックは主に関数内で一時的に利用するデータを格納するために利用される。 また、関数を呼び出す際は、その呼びだした関数を実行した後に呼ばれる関数のアドレス(**リターンアドレス**)が格納されている。 ヒープ領域は、動的に確保されたり、プログラムの開始から終了まで参照される情報を格納しておく領域を指す。 ### バッファオーバーフローはなぜ発生するのか バッファ領域はもちろん無限に確保できるわけではない。 この **領域の上限はプログラムが規定する** のだが、このプログラムを実行する **CPUはバッファ領域の上限を知らない** のである。 CPUはプログラムの通りに処理を動かしているだけであるため、プログラムがバッファ領域を超過する入力データを格納した場合、バッファオーバーフローが発生する。 ### バッファオーバーフロー攻撃の脅威 スタック領域には一時的なデータを格納する領域とリターンアドレスが格納されていると上述しました。 バッファオーバーフロー攻撃では下記画像のように一時的なデータを格納する領域の上限を超えた領域の入力データが格納されるときに発生します。 ![](http://image.itmedia.co.jp/ait/articles/0803/21/r20_5min_baf-01.gif) 1. 上限を超えて入力データをバッファにコピーする 1. リターンアドレスまでもが入力データに上書きされる 1. プログラムが本来実行するべき関数へ戻ることができなくなる この手順を悪用した実際のバッファオーバーフロー攻撃の手順が、上記画像の下段である。 1. 上限を超えて入力データをバッファにコピーする このとき、バッファ内に悪意のあるコードを埋め込む 1. リターンアドレスを悪意のあるコードのアドレスで上書きする 1. 悪意のあるコードが実行される。 それまで実行していたプログラムにroot権限のSUIDがセットされていた場合、 root権限で実行していたはずのプログラムの制御が悪意のあるコードへ渡ってしまう。 つまり、悪意のあるコードをroot権限で実行できてしまうのである。 ### C / C++ の脆弱性 書籍に問題として挙げられている「**C**」「**C++**」はもう使わない情報が格納されたメモリを解放して、再使用可能な状態にするのもユーザーが制御しなければならない等、メモリ管理のほとんどをユーザーに委ねているため、 単純なミスでバッファオーバーフローが発生してしまう。 ※Javaの実行環境には「ガーベジ・コレクション」と呼ばれるメモリ管理機能があり、使用していないメモリ領域(ゴミとも呼ばれる)を発見すると、 再び使用できるようにする仕組みがある。 この章では、バッファオーバーフローが発生しやすい「**C**」と「**C++**」で、 バッファオーバーフローを防ぐための技術が紹介されています。 ## 前提知識 ### 「バッファーオーバーフロー攻撃」とは? - 攻撃者が故意にプログラムが確保したメモリ領域(バッファ)よりも大きなデータを読み込ませることで、メモリ領域からあふれた部分に不正なデータを書き込ませ、システムへの侵入や管理者権限の取得を試みる攻撃。 - CやC++といったプログラム言語がもつ入力データ処理の脆弱性が悪用されることが多い。 - [バッファオーバーフロー攻撃の手口](http://www.geocities.jp/sugachan1973/doc/funto44.html) - 参考サイト:デジタルみかん~とある愛媛のセキュリティーチームブログ~ - [nkozzl](http://digital-mikan.herokuapp.com/2017/01/23/%E8%84%86%E5%BC%B1%E6%80%A7%E5%8F%8A%E3%81%B3%E3%80%81%E6%94%BB%E6%92%83%E6%89%8B%E6%B3%95%E3%81%AE%E3%81%BE%E3%81%A8%E3%82%81/) - [mikyanman](http://digital-mikan.herokuapp.com/2017/01/23/%E8%84%86%E5%BC%B1%E6%80%A7%E5%8F%8A%E3%81%B3%E3%80%81%E6%94%BB%E6%92%83%E6%89%8B%E6%B3%95%E3%81%AE%E3%81%BE%E3%81%A8%E3%82%81/) ### 「ProPolice」とは? - IBM社が開発したバッファーオーバーフロー攻撃に対策するため、コンパイラに適用するパッチのこと - それが適用されコンパイラでコンパイルすることでバッファーオーバーフロー攻撃に強いコードが生成される ### 「LibSafe」とは? - 基本的なライブラリに,バッファーオーバーフローを抑制する機能を加える共有ライブラリのこと - 実行時にバッファーオーバーフロー攻撃の可能性がある関数を安全なものに置き換える ## 確認方法 ### 「ProPolice」でバッファオーバーフローを検出する 1. gccにProPoliceのパッチを適用する 1. コンパイルする <pre> ex)gcc -fstack-ptotector -o sample sample.c </pre> * ProPoliceが適用されている場合 * バッファオーバーフローが検出されるとsyslogに以下のように記録される <pre> ex) sample: stack overflow in function main /kernel: pid xxxxx (sample), uid xxxx: exited on signal 6 (core dumped) </pre> * ProPoliceが適用されていない場合、下記のようなエラーが表示される <pre> cc1: error: unrecognized command line option "-fstack-ptotector" </pre> ※ProPoliceのパッチを提供しているサイトが見つかっていない(2017/02/20現在) ### 「LibSafe」でバッファーオーバーフローを防止する 1. libsafeのソースアーカイブをダウンロードする ``` $ wget http://pkgs.fedoraproject.org/repo/pkgs/libsafe/libsafe-2.0-16.tgz/6b7b6e6df84d4afb469ccc66d04fc24d/libsafe-2.0-16.tgz ``` 1. libsafeのソースアーカイブを展開してインストールする ``` $ tar xvzf libsafe-2.0-16.tgz $ cd libsafe-2.0-16 $ make install ``` 1. 下記のサンプルプログラムを「sample.c」という名前で作成し、コンパイルする ``` # [サンプルプログラム] int main(int argc, char *argv[]) { char buffer[512]; gets(buffer); return 0; } ``` 1. libsafeをロードする ``` # export LD_PRELOAD=libsafe.so.2 ``` * これで「ldd sample」で必要な共有ライブラリを表示すると、libsafeがロードされていることが分かる * libsafeを利用すると、gets()やstrcpy()などの危険性の高い関数を安全なものに置き換えてくれる # HACK#13 コマンドバイナリの改ざんに備える ## 概要 - BusyBoxを利用して汚染されたコマンドバイナリの利用を防ぐ - コマンドバイナリは悪意を持ったユーザーによって改ざんされる可能性がある ## 背景 コンピュータ上のファイルは常に改ざんされる可能性がある。例としては、「touch」コマンドによるファイルのアクセス日時の改ざんのような簡単な方法から、「setuid」コマンドによるroot権限を使用してのpasswdファイルの改ざんといった複雑な方法がある。そこで改ざんされるファイルには、カーネルイメージやライブラリ、コマンドバイナリファイルといった直接使用しないファイルも含まれる。 例えば、「ls」コマンドが改ざんされていた場合を想定する。もしも特定のディレクトリを表示しないように細工されていたとしても管理者は偽物だと気付かなければそのディレクトリの存在を見つけられない。 このように、もし改ざんされた場合に何も対処できず、その後も改ざんされたコマンドを使用し続けなければならなくなってしまう。あらかじめ必要なコマンドバイナリをCD-ROMなどのメディアに保存しておくなどの処置を行っておく必要がある。 ## 前提知識 ## 確認方法 1. busyboxをダウンロード 2. 「busybox-1.4.1.tar.bz2」を解凍 3. 「busybox-1.4.1.tar」を展開 4. 「busybox-1.4.1」のフォルダーに移動 ``` # cd ~ # wget https://busybox.net/downloads/busybox-1.4.1.tar.bz2 # bunzip2 busybox-1.4.1.tar.bz2 # tar xvf busybox-1.4.1.tar # cd busybox-1.4.1 ``` 5. make menuconfigでメニュー画面からBusyBoxの設定を行える > デフォルトで良い場合はしなくてよい > デフォルトのコマンドはhalt, mesg, poweroff, reboot, start-top-deamon, tr, watchdogの7つ > 今回は > 「Coreutils」からls,cat > 「Process Utilities」からps,top を選択 6. コンパイルする ``` $ make ``` 7. 指定したディレクトリにBusyBoxをインストールする ``` $ make CONFIG_PREFIX=ディレクトリ install ``` 8. カレントディレクトリ上の「_install」ディレクトリにBusyBoxをインストールする ``` $ make install ``` 9. busyboxのlsコマンドを実行する ``` $ busybox ls ``` 10. 「/bin/ls」を削除し、コマンドを使えないようにする ``` $ rm /bin/ls ``` 11. lsコマンドが削除されても「busybox」のlsコマンドが実行できることを確認 ``` $ busybox ls ``` # HACK#14 Systraceによるシステムコールの制限 ## 概要 ### Systrace - BSD系のOS上でプログラムごとにシステムコールの発行を管理する機能である<br> ※システムコール:OSのカーネルの機能にアクセスするための関数 - システムコールが返すエラーも定義可能である ### SELinux(Security Enhanced Linux) - Linux系のOS上において、LSMインタフェース上に設けられた強制アクセス制御システムである<br> ※LSM(Linux Security Modules):カーネルが様々なコンピュータ・セキュリティ・モデルをサポートできるようにする フレームワーク - カーネルは各システムコールの前にシステムコールを発行したプロセスが指定された操作に対する 権限の有無をSELinuxに問い合わせる - プロセスに必要最低限の権限(最小特権)を与える - リソースのアクセス制御を強化して統一管理する(MAC:強制アクセス制御) - CentOSではデフォルトで有効になっている ### SystraceとSELinuxの違い - Systraceは直接システムコールに介入して制限をかける - 直接システムコールに介入すると、マルチプロセッサ・カーネルに対応できず、TOCTTOU(競合)攻撃を受けやすくなる<br> ※TOCTTOU(競合)攻撃:TOC(Time Of Check)とTOU(Time Of Use)の差を利用して不整合を発生させる - SELinuxは直接システムコールに介入せず、プロセスやユーザの権限を最小化することで制限をかけている ## 背景 ### システムコールとは - プログラムがカーネルにアクセスしてタスクを実行する方法である - プログラムはシステムコールを使ってプロセスの作成、ネットワーク操作、ファイル入出力などを実行する ### システムコールが無制限に実行された場合 例えば、Webサーバー+データベースで認証機構を構築してアクセス先を制限していても、execve()システムコールで シェルを起動して、他に起動している様々なサービスへ攻撃できてしまう<br> ※参考サイト:http://www.asahi-net.or.jp/~jg3h-snj/documents/20090516_OSC2009Shimane_Shinji.pdf 上記のような呼び出してほしくないシステムコールを呼び出しを禁止するために、SystraceやSELinuxのポリシーを 設定する ### ポリシーの役割 - 「しても良いこと」や「使える特権」などを定義する - 書かれていないことを「禁止」する このポリシーによってシステムコールを管理することで、プログラムから他のサービスへ悪影響を及ぼすような 不正な動作を未然に防ぐ 逆に、ポリシーに定義ミスや定義漏れがあると不正な動作を防ぐことができない ポリシーの定義ミスや定義漏れを防ぐためには、ポリシーの定義を支援するツールを活用すると良い # HACK#15 Systraceポリシーの自動生成 ## 概要 ### Systraceのポリシーファイル - ポリシーファイルはアプリケーションごとに生成する理想だが、各アプリケーションのソースコード理解しなければ ならないので現実的でない - Systraceではポリシー生成ツールを利用してアプリケーションごとに簡単に生成できる ### SELinuxのポリシーファイル - SELinuxのポリシー設定ファイルには下記の3種類がある - Systraceより細分化されていて、柔軟に設定ができる | ポリシーファイル | 概要 | | --- | --- | | ポリシーモジュール(システム) | ディストリビューションの開発者によって作成されたポリシー<br>共通ルール | | ポリシーモジュール(ローカル) | システム管理者によって作成されるポリシー<br>システムの実状に合わせてカスタマイズできる | | メタファイル | ポリシーモジュールに手を加えずに変更可能なSELinux設定を収めたファイル | # HACK#16 PAMによるログイン制御 ## 概要 - PAM(Pluggable Authentication Modules)を用いて特定条件の元でログイン制限を行う - 通常のUNIX認証ではログインユーザーの権限を制限する方法が限られており、柔軟に設定できない ## 背景 ### PAMの必要性 Linuxでは、メールサーバーやDNSサーバーなど多くのアプリケーションでユーザー認証を行う その際、ユーザー認証が必要なすべてのアプリケーションに別々の認証機構やユーザーデータが 登録されたデーターベースを追加するのは無駄が多くなる そこで、各アプリケーション共通で利用できる認証システムであるPAMを利用して認証を行う また、PAMを用いることで、認証方式に変更があってもPAMの設定変更のみで良い<br> (個々のアプリケーションは設定変更しなくて良い) ### PAMの概要 PAMに使用されている認証機構は、シャドウパスワードを用いるUnixのユーザー認証である Unixのユーザー認証では、特定のコンピュータの一部のユーザーだけログインを許可したり、 メンテナンス時間中だけ管理者以外のユーザーをログイン禁止にしたりする設定ができない それらのような柔軟な設定をPAMが可能にしている [PAM認証の構成例] <pre> passwd              SMTPサーバー      ⇔  PAM認証  ⇔ shadow  確認       認証  DNSサーバー </pre> ## 前提知識 PAMでは各種ログイン制限の方法をモジュールで提供している PAMの設定は/etc/pam.d/下の設定ファイルに記述して行う ### PAMのタイプ PAMにはモジュールの利用方法を指定するいくつかのタイプがある | タイプ名 | 説明 | | --- | --- | | auth | 認証の許可、認証の方法などに関するモジュール | | account | アカウントの有効期間や有効性などに関するモジュール | | password | パスワードの設定、確認などに関するモジュール | | session | ユーザーセッションの設定、管理などに関するモジュール | auth → account → password → session の順でユーザー認証を行う ### PAMの制御フラグ 各モジュールが「失敗」「成功」した場合の処理の指定を行う | 制御フラグ | 説明 | | --- | --- | | required | このモジュールが成功しないと全体は失敗<br>失敗しても後の参照は行う | | requisite | このモジュールが成功しないと全体は失敗<br>失敗したときは後の参照を行わない | | sufficient | 他のモジュールが成功してこのモジュールも成功すると、以降のモジュールは参照せず認証される | | optional | 他に参照すべきモジュールがない場合だけ、成功すると認証される<br>その他のモジュールがある場合は無視される | ### PAMの設定 /etc/pam.d下の該当するサービス設定ファイルに、「PAMのタイプ」と「制御フラグ」を用いて下記のように記述する <pre> タイプ 制御フラグ モジュール </pre> タイプや制御フラグの特徴によって正しい順番で記述しないと、意図したログイン制限ができないので注意が必要 ## 確認方法 まずはPAMを使うための準備をします。 以下コマンドでPAMをインストールできます。(「CentOS 6.8」の場合はデフォルトでインストールされているので必要ありません) <pre> # yum -y install pam </pre> 次に、PAMを適用するサービスの設定をします。「/etc/pam.d/」の配下に各サービスのファイルが存在するので、今回はsshにアクセス制限を掛けてみます。 <pre> # vi /etc/pam.d/sshd #%PAM-1.0 auth required pam_sepermit.so auth include password-auth account required pam_access.so (←追記) account required pam_nologin.so account include password-auth password include password-auth session required pam_selinux.so close session required pam_loginuid.so # pam_selinux.so open should only be followed by sessions to be executed in the user context session required pam_selinux.so open env_params session required pam_namespace.so session optional pam_keyinit.so force revoke session include password-auth </pre> これでsshにアクセス制御を適用することができました。 あとは、どう制御するのかを以下で設定します。 <pre> # vi /etc/security/access.conf (前略) # User "john" should get access from ipv6 net/mask #+ : john : 2001:4ca0:0:101::/64 # # All other users should be denied to get access from all sources. #- : ALL : ALL - : vagrant : 192.168.1.XXX (←追記) </pre> これでアクセス元が「192.168.1.XXX」でユーザーが「vagrant」の場合は拒否する、という設定ができました。 実際にアクセスが拒否されるか試してみましょう <pre> # ssh vagrant@192.168.1.XXX vagrant@192.168.11.18's password: (←正しいパスワード) Connection closed by 192.168.11.18 </pre> このようにsshでのログインが拒否されればOKです。 あとは、アクセス時間でも制御できるので、試してみましょう。それには、アクセス時間で制御する用の設定があるので、そちらもsshに適用させてあげましょう。 <pre> # vi /etc/pam.d/sshd #%PAM-1.0 auth required pam_sepermit.so auth include password-auth account required pam_time.so (←追記) account required pam_nologin.so account include password-auth password include password-auth # pam_selinux.so close should be the first session rule session required pam_selinux.so close session required pam_loginuid.so # pam_selinux.so open should only be followed by sessions to be executed in the user context session required pam_selinux.so open env_params session required pam_namespace.so session optional pam_keyinit.so force revoke session include password-auth </pre> これで適用されます。次の、どの時間はアクセスを制限するのかを設定しましょう。 <pre> # vi /etc/security/time.conf (前略) # Another silly example, user 'root' is denied xsh access # from pseudo terminals at the weekend and on mondays. #xsh;ttyp*;root;!WdMo0000-2400 # # End of example file. # sshd;*;*;AL2200-2300 (←追記) </pre> この設定は「22:00 ~ 23;00」の間のみ「全ての」ユーザーは「全ての」ターミナルコンソールからsshができるという設定になっています。 つまり、22:00 - 23:00以外はsshができないという設定です。 実際にアクセス制御できるか設定を書き換えて試してみましょう。 <pre> # vi /etc/security/time.conf sshd;*;*;AL0000-0600 (0時 ~ 6時の間ログインできる) # ssh 192.168.1.XXX root@192.168.1.XXX's password: Connection closed by 192.168.1.XXX </pre> このようにsshが拒否されればOKです。 # HACK#17 SCPとSFTPのユーザーを制限する ## 概要 ### ファイル転送 - ファイル転送を行いたい時には、FTPを使うと良いと言われます。ただし、FTPはセキュリティー上脆弱性だらけで、転送するファイルの内容、ユーザー名、パスワード等、暗号化されずに転送されています。ファイル転送を行なう上で、様々な手段がありますが、主に使われているものを下記のテーブルで比較しました。 | プロトコール名 | 説明 | |---|---| | FTP | - 転送されるデータを一切暗号化しない | | SCP | - インタラクティブ性のないコマンドラインのツールで</br>-(FTPのようなGUIもなく、コマンドを叩いて実行、ファイル転送するという機能しかない)<br>- スクリプトやcronなど、属人的ではないファイル転送を行なう時に有効 | | SFTP | - FTP/Sとは異なる。FTP/SはFTPをセキュアなチャンネルを通して転送する手段 <br>- SFTPはSSHの拡張機能として、転送する前に全てのデータが暗号化されているのが特徴 <br>- 一般的なネットワークセキュリティーリスクから効率的に制御する役割を果たす<br>- GUIも存在する | | FTPS | FTPS (FTP-SSL) は暗号化に TSL/SSL を使用している <br> コントロールセッションんはかならず暗号化されているが、データセッションはそうとも限らない。なぜなら、普段の操作中(ログイン情報など)は常に暗号化されている必要がある <br> が、データ転送を行なう際に、事前に暗号化されているファイルを転送する場合もある。その場合、転送時に再度暗号化すると不要なオーバーヘッド(負荷)がかかる | ### rssh - rsshはOpenSSHを用いった、機能をscpとsftpに限定したシェルです。 - 現在はrdist, rsync, と cvsも利用可能です。 - シェル権限を付与せず、scpのみを利用可能にし、ファイルのコピー等を行わせたい場合、rsshが便利です。 ## 背景 ### なぜFTPでファイル転送しないのか - FTPはクライアントとサーバーが通信する際、ユーザー名やパスワード、転送するファイルの内容が 暗号化されない - クライアントとサーバー間の通信を盗聴されると、通信路を流れている情報が盗まれる - ユーザー名やパスワードが盗まれると、FTPバウンス攻撃に用いられる可能性もある #### FTPバウンス攻撃 - FTPサーバーを中継点にして別のホストを攻撃するもの - ネットワークアドレスや攻撃対象のホスト、ポート番号を含んだPORTコマンドをFTPサーバーに送信して行われる<br> ※PORTコマンドは任意のユーザーに対して送信できるので、あらゆるコンピュータに悪意のあるファイルが転送される 可能性がある ### SCPやSFTPを用いたファイル転送 - SSHによってユーザー名やパスワード、転送するファイルの内容が暗号化される - パスワード認証だけでなく、秘密鍵による認証も可能である しかし、システムにログインしてシェルであらゆるコマンドが実行できてしまう<br> → 悪意あるユーザーにコマンドを実行されて、システムに悪影響が及ぶ可能性がある そこで、rsshを用いる ### rssh - あるホストへのsshを使ったアクセス制限を提供する制限付きシェル(HACK #19参照) - シェルがrsshに設定されたユーザーは下記コマンドのうち許可されたものしか実行できない <pre> scp, sftp, cvs, rdist, rsync </pre> - コマンドが制限されることで必要最低限以上の機能をユーザーに提供しなくて済む ## 前提知識 ## 確認方法 1. rsshをインストール ``` # yum -y install rssh ... No package rssh available. ``` ※上記エラーが出た場合は[EPELリポジトリを追加](http://qiita.com/muniere/items/6c4923a070cbbd824f39)を試してから再度実行してみてください ``` # yum -y install yum-priorities # vi /etc/yum.repos.d/CentOS-Base.repo ``` - サイトの通りに `CentOS-Base.repo` を編集 - サイトの続きを実行・・・ ``` # cd ~ # wget http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm # rpm -ivh epel-release-6-8.noarch.rpm # vi /etc/yum.repos.d/epel.repo ``` - サイト通りに `epel.repo` を編集 - rsshを再インストール ``` # yum install rssh --enablerepo=epel ``` #### rsshの設定 - 参考URL: http://qiita.com/bsdhack/items/8459b4a5b8aebdb95d5b 1. rssh.confを以下のように編集する ``` # vi /etc/rssh.conf ``` ``` allowscp (←コメントアウト scpを許可) allowsftp (←コメントアウト sftpを許可) chrootpath = /path/to/chroot (←修正 chrootの設定) ``` 2. chrootの構築 ``` # sh /usr/share/doc/rssh-2.3.4/mkchroot.sh /path/to/chroot ``` 3.以下コマンドでchroot環境に「/dev/null」を作る ``` # mknod /path/to/chroot/dev/null c 1 3 # chmod 666 /path/to/chroot/dev/null ``` 上のchroot環境を構築するコマンドでコピーしきれなかったライブラリをコピー ``` # cp /lib64/ld-linux-x86-64.so.2 /path/to/chroot/lib64 # cp -p /lib64/libnss_files.so.2 /path/to/chroot/lib64 ``` ログインシェルを変更して、試してみる ``` # chsh -s /usr/bin/rssh root # sftp root@localhost Connecting to localhost... root@localhost's password: sftp> ls dev etc lib64 usr ``` このように、chroot環境下でログインされている # HACK#18 ワンタイムパスワードによる認証を行う ## 概要 - サーバへの信用できないコンピュータからのアクセスのリスクをワンタイムパスワードを用いた認証で軽減する - サーバーへのアクセスに信用できないコンピュータからのアクセスを全て遮断するのは不可能 ## 前提知識 テキストでは、FreeBSDでOPIEを用いる方法及びOpenBSDでS/Keyを用いる方法が記載されているが、ここではCentOS上で利用可能なGoogle Authenticatorを用いる方法を紹介する ### Google Authenticatorとは - OATH(Initiative for Open Authentication)に対応している<br>※OATHはオープンソースの認証技術である - LinuxのPAMに対応しており、HACK#16のように設定ができる ## 確認方法 「Google Authenticator」を使うための準備を行います。 <pre> # yum -y install mercurial pam-devel (必要なパッケージのインストール) # yum -y groupinstall "Development Tools" (開発ツールのインストール) # cd /usr/local/src (Google Authenticatorのgitレポジトリの置き場所) # git clone https://github.com/google/google-authenticator-libpam.git (Google Authenticatorのgitのクローン) # cd google-authenticator-libpam (クローンしたディレクトリへ移動) # ./bootstrap.sh (環境設定) # ./configure (環境設定) # make dist (Google Authenticatorのrpmパッケージを生成) # mkdir -p ~/rpmbuild/SOURCES/ (rpmbuildを実行するためのディレクトリを作成) # cp google-authenticator-1.03.tar.gz ~/rpmbuild/SOURCES/ (rpmパッケージを作成したディレクトリにコピー) # rpmbuild -ba contrib/rpm.spec (rpmファイルの作成) # rpm -Uvh ~/rpmbuild/RPMS/x86_64/google-authenticator-X.XX-1.el7.centos.x86_64.rpm (作成したrpmファイルをインストール) # rpm -ql google-authenticator (インストールした内容の確認) /lib64/security/pam_google_authenticator.so /usr/bin/google-authenticator /usr/share/doc/google-authenticator/FILEFORMAT /usr/share/doc/google-authenticator/README.md /usr/share/doc/google-authenticator/totp.html </pre> これで「Google Authenticator」を実行するための準備が整いました。 実行をする前に、ワンタイムパスワードを受信するためのアプリ「Google Autenticator」をスマホにインストールしておきましょう。 そして、以下のコマンドを実行すると「Google Authenticator」のセットアップが行われます。 途中、何度か聞かれる(y/n)については全て(y)でOKです。 <pre> # google-authenticator Do you want authentication tokens to be time-based (y/n) y Warning: pasting the following URL into your browser exposes the OTP secret to Google: https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/root@localhost.localdomain%3Fsecret%3D5VAAPZ7SEA4WIXTC5RAA3PKXHA%26issuer%3Dlocalhost.localdomain Failed to use libqrencode to show QR code visually for scanning. Consider typing the OTP secret into your app manually. Your new secret key is: 5VAAPZ7SEA4WIXTC5RAA3PKXHA Your verification code is 286963 Your emergency scratch codes are: 22921581 21238297 30949500 83210465 34601615 Do you want me to update your "/root/.google_authenticator" file? (y/n) y Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y By default, a new token is generated every 30 seconds by the mobile app. In order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. This allows for a time skew of up to 30 seconds between authentication server and client. If you experience problems with poor time synchronization, you can increase the window from its default size of 3 permitted codes (one previous code, the current code, the next code) to 17 permitted codes (the 8 previous codes, the current code, and the 8 next codes). This will permit for a time skew of up to 4 minutes between client and server. Do you want to do so? (y/n) y If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attempts every 30s. Do you want to enable rate-limiting? (y/n) y </pre> これでワンタイムパスワードが生成されるようになりました。これを閲覧するには一番最初の(y/n)に答えたあとに標準出力されるURLにアクセスするとQRコードが表示されるので、アプリで読み取ります。 それにより、アプリの方でワンタイムパスワードを確認することができるようになります。 あとは、この「Google Authenticator」を適用させる必要があります。 今回はsshで試してみましょう。 <pre> # vi /etc/ssh/sshd_config ChallengeResponseAuthentication yes (ワンタイムパスワード認証を有効にする) # vi /etc/pam.d/sshd #%PAM-1.0 auth required pam_sepermit.so auth required pam_google_authenticator.so (←追加) auth include password-auth account required pam_nologin.so (以下略) # /etc/init.d/sshd restart </pre> これにより、sshをするときにワンタイムパスワードを求められるようになります。 <pre> # ssh localhost Verification code: (←ワンタイムパスワードを入力) Password: (←Unixのパスワードを入力) Last login: Wed Feb 22 18:04:02 2017 from localhost </pre> 上記のようになれば設定は完了です。 これを活用して、公開鍵暗号方式を適用できていないコンピュータとの通信をより安全なものになるようにしましょう。 # HACK#19 制限シェルの利用 ## 概要 - 制限シェルを用いてユーザーがアクセスできるディレクトリを制限する - 無制限のシェルだとユーザー自身に悪意がなくとも誤ったコマンド実行でシステム全体に悪影響が及ぶ可能性がある - サンドボックス環境でもユーザーの権限を制限できるが、ユーザごとにサンドボックス環境を構築しなければならない ## 背景 ### シェルに制限がかかっていない場合 - ユーザーは自由にコマンドを実行することができる - しかし、Linux初心者や悪意あるユーザーに(システム上のユーザー全員に影響が及ぶような)想定外の使い方をされると、システムに重大な被害が及ぶ可能性がある そこで、システムを守るため、他のユーザーの安全を保証するために上記で示したような一部のユーザーに機能を制限したシェルを利用させるべきである ### シェルに制限がかかっている場合 - 制限シェルを使うように設定されたユーザーの利便性は低くなる - 想定外の使い方が未然に防がれるため、システムの堅牢性が高くなる<br> ※堅牢性:ソフトウェアやシステムなどが、予期しないエラーや障害やセキュリティ上のリスクなどに柔軟に対応できること #### シェルによる機能制限の具体例(bashの制限シェル) - cdできない(カレント・ディレクトリを変更できない) - 環境変数SHELL(ログインシェル)、PATH(コマンドの実体などへのパス)、ENVなどを変更できない - / を含むコマンドを実行できない(コマンドを絶対パスで実行できない) - リダイレクトできない - execできない - . で / を含むシェル・スクリプトを実行できない etc... ## 前提知識 ### bashの制限シェル - 「bash -r」コマンドで制限シェルに切り替えることができる(CentOS6.8ではbashの-rオプションがなくなっているもよう) - アクセスできるディレクトリが制限されることで、安易にコマンドを実行できなくできる - コマンドを実行するためにはコマンド実体へのパスのシンボリックリンクを作成しておかなければならない ### kshの制限シェル - 「ksh -r」コマンドで制限シェルに切り替えることができる - 環境変数PATHにコマンド実体へのパスが登録されているとコマンドの実行が可能である - bashの制限シェルと同じく、コマンド実体へのパスのシンボリックリンクを作成することでも実行可能になる 上記2例のような制限シェルをログインシェルとして指定しておくことで、ユーザーに対して強力な制限をかけることができる ## 確認方法 [bashの制限シェル] 「bash -r」コマンドは使えなかったので、bashへのシンボリックリンクを作成して制限シェルを実現する <pre> # ln -s /bin/bash /opt/rbash </pre> bashのシンボリックリンク名を[rbash]とすることで、[bash -r]と同様の制限シェルとして扱える。 その制限シェル「rbash」をログインシェルとして適用するユーザーを作成する <pre> # useradd user1 -s /opt/rbash(-sオプションはログインシェルの指定) # passwd user1 # mkdir /home/user1/bin(実行を許すコマンドの実体へのシンボリックリンクの格納場所) </pre> また、以下で既存のユーザーのログインシェルを制限シェルに変更できる <pre> # chsh -s /opt/rbash dojo # mkdir /home/dojo/bin(実行を許すコマンドの実体へのシンボリックリンクの格納場所) </pre> コマンドの環境変数PATHを変更して通常のコマンドが実行できないようにする <pre> # vi /home/user1/.bash_profile PATH=$HOME/bin </pre> 制限シェルを適用したユーザーにbash_profileの編集をさせないようにする <pre> # chown root. /home/user1/.bash_profile (←ファイルの所有者とグループをrootにする) # chmod 755 /home/user1/.bash_profile </pre> 上記の設定後、user1としてログインしてコマンドを実行すると下記のようになる <pre> [user1@dojo ~]$ cd .. -rbash: cd: restricted (コマンド実行の拒否) [user1@dojo ~]$ ls -rbash: ls: コマンドが見つかりません (コマンドが見つからない) </pre> 許可したいコマンドの実体へのシンボリックリンクを作成する(今回は例でlsコマンド) <pre> # ln -s /bin/ls /home/user1/bin/ls </pre> もう一度user1としてログインしてコマンドを実行すると下記のようになる <pre> [user1@dojo ~]$ ls bin (コマンドを実行した結果が表示される) </pre> [kshの制限シェル] まず、CentOSにはデフォルトでkshがインストールされていないのでインストールする <pre> # yum install -y ksh </pre> 「ksh -r」コマンドでkshの制限シェルに切り替えてコマンドを実行すると上で示したbashの制限シェルと同じ結果になる - 環境変数PATHにコマンドの実体へのPATHが登録されていない場合は実行できない - コマンドの実体へのシンボリックリンクを作成するとコマンドがじっこうできるようになる ここで示した方法ではbashの制限シェルもkshの制限シェルの仕組みと同じになる # HACK#20 ユーザーやグループへのリソース制限 ## 概要 - ユーザーやグループへのリソース割り当てを適切に行って、システムの性能が過度に低下するのを防ぐ - 悪意の有無に関わらず、メモリやCPU時間などのリソースをまったく気にせずに使っていると、リソースが専有されてシステムの性能が過度に低下することがある ## 背景 ### リソース割り当ての重要性 まず、リソースとは、コンピュータの動作の実行に必要なCPUの処理速度やメモリ容量、HDD容量などのことを表す コンピュータ上に複数のユーザーがいる場合、各ユーザーがリソースを無制限に使用できる状態になっていると、1ユーザーが大量のアプリケーションを実行してCPUの処理速度やメモリ容量を占有してしまい、他のユーザーがアプリケーションを実行できないなどといった現象が発生してしまう そこで、ユーザーに割り当てるリソースに上限値を設定して、リソースの占有が起こらないようにする必要がある ### リソース割り当ての具体的方法 例えば… - 1ユーザーあたりの同時に生成できる最大プロセス数や同時にオープンできる最大ファイル数などを設定することで、CPUの処理速度やメモリの残り容量の低下を抑えることができる - 1ユーザーあたりの最大データサイズや最大ファイルサイズを設定することで、HDDの残り容量の低下を抑えることができる ## 前提知識 リソース制限は、PAMモジュールの1つであるpam_limitsを利用する pam_limitsはPAMシステムがインストール済みだと初期設定がほぼ完了している なので/etc/security/limits.confに下記の形式でユーザーやグループごとの設定を記述していけば良い <pre> ユーザー名orグループ名 制限の方式 リソース 値 </pre> | 制限の方式 | 説明 | | --- | --- | | soft | 制限の上限値を一般ユーザーが変更できる | | hard | 制限の上限値はrootユーザーしか変更できない | | - | softとhardの設定値が同じ(制限の上限値はrootユーザーしか変更できない) | | リソース | 説明 | | --- | --- | | nofile | オープンできる最大ファイル数 | | noproc | 最大プロセス数 | | fsize | 最大ファイルサイズ | | as | 最大メモリ空間サイズ | | maxlogins | このユーザーに許される最大ログイン数、ただしuid=0を除く | ※一部 上限値が変更可能な場合、下記コマンドで上限値を変更できる <pre> ulimit -n 上限値 </pre> また、設定中の上限値は「ulimit -a」コマンドで確認できる ## 確認方法 まず試しに開けるファイル数を0にしてみましょう。 <pre> # vi /etc/security/limits.conf dojo soft nofile 0 </pre> そして、dojoにログインしてみます <pre> # su dojo could not open session </pre> 上記のようなメッセージが表示され、ログインできなくなっています。 これは単純にログインするためのファイルを開くことができなくなっていることが原因です。これで開けるファイル数の制限がけられていることが確認できました。 あとは、制限の方式について確認してみましょう。 <pre> # vi /etc/security/limits.conf dojo hard nofile 1000 # su dojo # ulimit -n 1001 bash: ulimit: open files: cannot modify limit: 許可されていない操作です # ulimit -n 800 # ulimit -n 800 </pre> このように、制限の方式を「hard」にすると1000を超えた数値には設定できず、それ未満の場合は設定可能となっています。softにすると設定した上限値を超えて変更できるようになります。 ここで注意するべきは一度上限値を下げた場合、元には戻せなくなっているということです。 <pre> # ulimit -n 801 bash: ulimit: open files: cannot modify limit: 許可されていない操作です </pre> あまりに下げすぎると、操作不能になる場合もあるので、注意しながら上限値を設定しましょう。 上記と同様に、最大ログイン数の制御も行ってみましょう。 「dojo」ユーザと「limit」グループの最大ログイン数を1に設定します。 グループ名を指定する場合は、先頭に「@」記号を記述します。 <pre> # vi /etc/security/limits.conf dojo - maxlogins 1 @limit - maxlogins 1 # cat /etc/group | grep limit ←「limit」グループに所属しているユーザ確認 limit:x:501:test1,test2 </pre> 別端末でコンソールを2つ起動し、1つ目のコンソールでログインを行います。 <pre> # ssh dojo@192.168.1.xxx dojo@192.168.1.xxx's password: $ (ログイン成功) </pre> 1つ目のコンソールでログインしたまま、2つ目のコンソールでログインを行います。 <pre> # ssh dojo@192.168.1.xxx dojo@192.168.1.xxx's password: Too many logins for 'dojo'. Last login: 曜日 月 日 時刻 年 from ログイン元IP Connection to 192.168.1.xxx closed (ログイン失敗) </pre> 最大ログイン数を1に設定しているため、2つ目のコンソールでログインに失敗することが確認できます。 また「dojo」ユーザだけでなく「test1」、「test2」ユーザでも同様の結果が得られ、制御対象にグループを指定できることが確認できました。 # HACK#21 システムのアップデートの自動化 ## 概要 - ソフトウェアのアップデートやパッチ適用を自動化して常にシステムを最新の状態に保つ - 攻撃者は脆弱性を発見してそこを狙って攻撃してくる - 脆弱性が発見されるたびにソフトウェアは修正されているので、ユーザーはそれを随時適用しなければならない ## 背景 ### システムのアップデートの重要性 ソフトウェアは一度リリースしたらそれで終わりではない 必ずと言っていいほど把握できなかった脆弱性が存在している 脆弱性が存在していると、攻撃者はそれを発見してそこを狙って攻撃してくる その脆弱性を無くすために、ソフトウェアの開発者は日々新バージョンやセキュリティパッチの開発を行っている なので、我々利用するユーザーは新バージョンやセキュリティパッチを適用してソフトウェアを最新の状態に保っておかないと脆弱性を無くせない ### システムアップデートを自動化したほうが良い理由 ソフトウェアの新バージョンやセキュリティパッチが公開されたかどうかはたいていの場合自ら調べないと分からない また、ソフトウェアごとに上記の作業を行っていると非常に手間がかかり、漏れが発生するかもしれない そこで、システムアップデートの自動化を行って、定期的に漏れなくアップデートが適用されるようにする ## 前提知識 手動でアップデートしていくこともできるが、膨大な数なので現実的でない テキストでは、最新のパッケージをダウンロード・インストールしてくれるPerlスクリプト「AutoRPM」を用いる方法とyumコマンドを用いる方法が記載されている。 「AutoRPM」は配布が終了しているので、ここではyumコマンドを用いる方法を紹介する ※テキストの訳注にRedHat系はup2dateコマンドを利用すると良いと記載されているが、CentOS5以降はup2dateコマンドが廃止されている ### yumコマンドを用いたアップデートの自動化 yumコマンドはデフォルトでアップデートとダウンロードとインストールを同時に行うことしかできない これだと所定のメンテナンス時間内でアップデートしか終わらなかったりする事象も発生する そこで、yumコマンドにdownloadonlyというプラグインを適用することで下記コマンドでダウンロードのみが行えるようになる <pre> yum --downloadonly -y update </pre> このコマンドをcrontabに登録しておくと、メンテナンス時間外でも自動でアップデートのダウンロードが行われる あとは「yum update」コマンドを実行するとアップデートをインストールできる ## 確認方法 「crontab」を編集して、定期的にアップデートパッケージのダウンロードが自動で実行されるようにします。 <pre> # crontab -e */1 * * * * /usr/bin/yum --downloadonly -y update </pre> 上記の設定は1分毎に「yum --downloadonly -y update」を実行するという設定になっています。 本来はこんな短い間隔ではしないのですが、きちんとcrontabが動作しているかチェックするためにこの間隔で設定しました。 動作しているかどうかは「/var/log/cron」のログファイルを見ることで確認ができます。 <pre> # tail /var/log/cron Feb 22 16:18:25 localhost crontab[3250]: (root) REPLACE (root) Feb 22 16:18:25 localhost crontab[3250]: (root) END EDIT (root) Feb 22 16:19:01 localhost crond[2285]: (root) RELOAD (/var/spool/cron/root) Feb 22 16:20:01 localhost CROND[3264]: (root) CMD (/usr/lib64/sa/sa1 1 1) Feb 22 16:20:01 localhost CROND[3265]: (root) CMD (/usr/bin/yum --downloadonly -y update) Feb 22 16:22:01 localhost CROND[3289]: (root) CMD (/usr/bin/yum --downloadonly -y update) Feb 22 16:22:13 localhost crontab[3298]: (root) BEGIN EDIT (root) Feb 22 16:22:16 localhost crontab[3298]: (root) REPLACE (root) Feb 22 16:22:16 localhost crontab[3298]: (root) END EDIT (root) Feb 22 16:23:01 localhost crond[2285]: (root) RELOAD (/var/spool/cron/root) </pre> これでcrontabの設定は確認できたので、crontab適切に設定しましょう。 そして、更新されているパッケージがあれば、確認してインストールを行うようにしましょう。

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully