توی این درس یاد میگیری علاوه بر rwx سه بیت ویژهی دسترسی هم هست: setuid (برنامه با هویت صاحبش اجرا شود)، setgid (فایلهای جدید یک پوشه گروه پوشه را به ارث ببرند) و sticky bit (در پوشهی مشترک فقط صاحب فایل بتواند آن را پاک کند). میبینی چرا passwd با اینکه کاربر عادی اجرایش میکند میتواند /etc/shadow را عوض کند، چرا در /tmp نمیتوانی فایل دیگران را پاک کنی، و آنها را با chmod g+s، chmod +t و حالت چهاررقمی (2775، 1777) تنظیم میکنی. تمرین: یک پوشهی مشترک تیمی میسازی که فایلهایش گروه پوشه را به ارث ببرند.
مسئله: سه معمای دسترسی
Section titled “مسئله: سه معمای دسترسی”۱. فایل /etc/shadow (رمزهای کاربران) را فقط root میتواند بنویسد. ولی هر کاربر عادی با passwd رمز خودش را عوض میکند. چطور؟
۲. در یک پوشهی مشترک تیمی، فایلی که علی میسازد گروه اصلی خودش (ali) را میگیرد، نه گروه تیم؛ پس همکارش رضا (که عضو گروه تیم است) نمیتواند ویرایشش کند.
۳. در /tmp همه فایل میسازند و روی پوشه حق w دارند؛ طبق درس قبل یعنی هر کس میتواند هر فایلی را پاک کند. ولی در واقع نمیتواند. چرا؟
جواب هر سه، سه بیت ویژهاند.
تشبیه: سه برچسب ویژه روی درهای یک ساختمان
Section titled “تشبیه: سه برچسب ویژه روی درهای یک ساختمان”- setuid مثل «نمایندگی رسمی» است: کارمند فقط برای یک کار مشخص، بهجای مدیر امضا میکند؛ نه برای هر کاری.
- setgid مثل «سربرگ تیم» است: هر برگهای که در این اتاق نوشته شود، خودکار سربرگ تیم را میخورد.
- sticky bit مثل «رختکن» است: همه میتوانند کیف بگذارند، ولی فقط صاحب هر کیف میتواند آن را بردارد.
| بیت | عدد | در ls -l |
روی فایل اجرایی | روی پوشه |
|---|---|---|---|---|
| setuid | 4000 | s جای x مالک |
با هویت مالک فایل اجرا میشود | روی لینوکس معنایی ندارد |
| setgid | 2000 | s جای x گروه |
با گروه فایل اجرا میشود | فایلها و پوشههای جدید گروه پوشه را به ارث میبرند |
| sticky | 1000 | t جای x بقیه |
(امروز بیاثر) | فقط مالکِ فایل (یا مالک پوشه، یا root) میتواند آن را پاک یا همنامگذاری کند |
اگر حرف بزرگ (S یا T) ببینی یعنی بیت روشن است ولی x همانجا خاموش است؛ معمولاً نشانهی یک اشتباه است (مثال ۶ و «اشتباهات رایج»).
در drwxrwxrwt کدام حرف نشاندهندهی sticky bit است؟
t در جای x بخش «بقیه» یعنی sticky bit؛ مثل /tmp که با 1777 ساخته شده است.
مثالهای عملی
Section titled “مثالهای عملی”برای آزمایش به چند کاربر لازم داریم: dev1 (برای passwd) و bob، carol و dave. گروه team را برای bob و carol میسازیم (dave عضو نیست). همه در پایان درس پاک میشوند.
مثال ۱: بیتهای ویژه را روی سیستم واقعی ببین
Section titled “مثال ۱: بیتهای ویژه را روی سیستم واقعی ببین”ls -l /usr/bin/passwd /usr/bin/sudo /usr/bin/crontabecho "--- پوشهها:"ls -ld /tmp /var/tmp /var/mailecho "--- عددی (چهار رقم؛ رقم اول بیتهای ویژه):"stat -c '%a %A %n' /usr/bin/passwd /usr/bin/crontab /var/mail /tmp-rwxr-sr-x 1 root crontab 68072 Mar 31 2024 /usr/bin/crontab-rwsr-xr-x 1 root root 72056 May 30 2024 /usr/bin/passwd-rwsr-xr-x 1 root root 335120 Sep 21 18:37 /usr/bin/sudo--- پوشهها:drwxrwxrwt 1 root root 4096 Oct 3 20:51 /tmpdrwxrwsr-x 2 root mail 4096 Sep 11 02:06 /var/maildrwxrwxrwt 1 root root 4096 Oct 3 20:44 /var/tmp--- عددی (چهار رقم؛ رقم اول بیتهای ویژه):4755 -rwsr-xr-x /usr/bin/passwd2755 -rwxr-sr-x /usr/bin/crontab2775 drwxrwsr-x /var/mail1777 drwxrwxrwt /tmppasswdوsudo:-rwsr-xr-x، یعنیsجای x مالک (setuid) و مالکشان root است؛ عددشان4755.crontab:-rwxr-sr-x،sجای x گروه (setgid) با گروهcrontab؛ عدد2755./var/mail: پوشهیdrwxrwsr-xبا گروهmail؛ setgid روی پوشه، برای اینکه صندوقهای ایمیل همه گروهmailبگیرند (2775)./tmpو/var/tmp:drwxrwxrwt،tجای x بقیه (sticky) و عدد1777.
مثال ۲: setuid در عمل، چرا passwd میتواند رمز را عوض کند؟
Section titled “مثال ۲: setuid در عمل، چرا passwd میتواند رمز را عوض کند؟”یک کاربر آزمایشی میسازم و دو تابع کمکی ترمینال مجازی را (مثل درس قبل) تعریف میکنم:
PW=lab-passsudo useradd -m -s /bin/bash dev1echo "dev1:$PW" | sudo chpasswdrun_in_tmux() { tmux -u kill-server 2>/dev/null; tmux -u new-session -d -s t -x 76 -y "${TH:-24}" "$@"; sleep 1; }screen() { tmux capture-pane -t t -p | sed -e :a -e '/^[[:space:]]*$/{$d;N;ba' -e '}'; }fp() { sudo awk -F: '$1=="dev1"{print $2}' /etc/shadow | sha256sum | cut -c1-8; }echo "آماده شد. اثرانگشت (fingerprint) فیلد رمز dev1 در /etc/shadow: $(fp)"آماده شد. اثرانگشت (fingerprint) فیلد رمز dev1 در /etc/shadow: 3e4a92a7fp یک اثرانگشت کوتاه از فیلد رمز او در /etc/shadow میگیرد، تا بدون نمایش چیزی از رمز، تغییرش را ببینیم. حالا بهعنوان dev1 (کاربر عادی، بدون هیچ اجازهای روی /etc/shadow) رمز خودش را عوض میکنم:
echo "اثرانگشت قبل: $(fp)"run_in_tmux "bash --norc"tmux send-keys -t t "sudo -u dev1 -i" Enter; sleep 1tmux send-keys -t t "ls -l /usr/bin/passwd" Enter; sleep 1tmux send-keys -t t "passwd" Enter; sleep 1tmux send-keys -t t "$PW" Enter; sleep 1tmux send-keys -t t "New-Pass-2026x" Enter; sleep 1tmux send-keys -t t "New-Pass-2026x" Enter; sleep 2screenecho "اثرانگشت بعد: $(fp)"اثرانگشت قبل: 3e4a92a7bash-5.2$ sudo -u dev1 -idev1@pc:~$ ls -l /usr/bin/passwd-rwsr-xr-x 1 root root 72056 May 30 2024 /usr/bin/passwddev1@pc:~$ passwdChanging password for dev1.Current password:New password:Retype new password:passwd: password updated successfullydev1@pc:~$اثرانگشت بعد: 54d57b0adev1 رمز را عوض کرد و فیلد او در /etc/shadow واقعاً تغییر کرد، با اینکه خودش اجازهی نوشتن در آن را ندارد. راز: برنامهی /usr/bin/passwd بیت setuid دارد (-rwsr-xr-x) و مالکش root است؛ پس هر کسی اجرایش کند، با هویت root اجرا میشود (فقط همین برنامه، فقط تا پایانش). حالا ثابت میکنم راز همین بیت است: یک کپی از همان برنامه میسازم (کپی بیتهای ویژه را نگه نمیدارد) و با همان کاربر اجرا میکنم:
tmux send-keys -t t "clear" Entertmux send-keys -t t "cp /usr/bin/passwd ~/mypasswd; ls -l ~/mypasswd" Enter; sleep 1tmux send-keys -t t "./mypasswd" Enter; sleep 1tmux send-keys -t t "New-Pass-2026x" Enter; sleep 1tmux send-keys -t t "New2-Pass-2026y" Enter; sleep 1tmux send-keys -t t "New2-Pass-2026y" Enter; sleep 5screendev1@pc:~$ cp /usr/bin/passwd ~/mypasswd; ls -l ~/mypasswd-rwxr-xr-x 1 dev1 dev1 72056 Oct 3 20:51 /home/dev1/mypasswddev1@pc:~$ ./mypasswdChanging password for dev1.Current password:New password:Retype new password:passwd: Authentication token manipulation errorpasswd: password unchangeddev1@pc:~$کپی، همان برنامه با همان کد است، ولی بیت s ندارد (-rwxr-xr-x، مالکش dev1): با هویت خود dev1 اجرا میشود و برای نوشتن در /etc/shadow شکست میخورد (Authentication token manipulation error). حالا کپی را به root میدهم و setuid را روشن میکنم. ترتیب مهم است: chown بیتهای ویژه را پاک میکند، پس اول chown، بعد chmod u+s:
sudo chown root:root /home/dev1/mypasswdsudo chmod u+s /home/dev1/mypasswdsudo ls -l /home/dev1/mypasswdtmux send-keys -t t "clear" Entertmux send-keys -t t "./mypasswd" Enter; sleep 1tmux send-keys -t t "New-Pass-2026x" Enter; sleep 1tmux send-keys -t t "New2-Pass-2026y" Enter; sleep 1tmux send-keys -t t "New2-Pass-2026y" Enter; sleep 2screentmux send-keys -t t "exit" Enter; sleep 1tmux -u kill-server-rwsr-xr-x 1 root root 72056 Oct 3 20:51 /home/dev1/mypasswddev1@pc:~$ ./mypasswdChanging password for dev1.Current password:New password:Retype new password:passwd: password updated successfullydev1@pc:~$با -rwsr-xr-x و مالک root، همان کپی هم کار کرد. (رمز عوضشده در همین آزمایش دور ریخته میشود.)
مثال ۳: فهرست برنامههای setuid و setgid با find
Section titled “مثال ۳: فهرست برنامههای setuid و setgid با find”مدیر سیستم باید بداند کدام برنامهها با قدرت بیشتری اجرا میشوند؛ هر کدام یک راه بالقوه برای حمله است. find -perm -4000 یعنی «همهی بیتهای ۴۰۰۰ روشن باشد»:
echo "--- برنامههای setuid:"find /usr/bin /usr/sbin -perm -4000 -type f 2>/dev/null | sortecho "--- برنامههای setgid:"find /usr/bin /usr/sbin -perm -2000 -type f 2>/dev/null | sortecho "--- شمار setuid در کل این فایلسیستم: $(find / -xdev -perm -4000 -type f 2>/dev/null | wc -l)"--- برنامههای setuid:/usr/bin/chfn/usr/bin/chsh/usr/bin/gpasswd/usr/bin/mount/usr/bin/newgrp/usr/bin/passwd/usr/bin/su/usr/bin/sudo/usr/bin/umount--- برنامههای setgid:/usr/bin/chage/usr/bin/crontab/usr/bin/expiry/usr/bin/plocate/usr/bin/ssh-agent/usr/sbin/pam_extrausers_chkpwd/usr/sbin/unix_chkpwd--- شمار setuid در کل این فایلسیستم: 11هر کدام کاری میکنند که فقط root از پس آن برمیآید: passwd، chsh (تغییر shell) و chfn (تغییر اطلاعات) فایلهای /etc را عوض میکنند؛ mount و umount دیسک وصل میکنند؛ gpasswd و newgrp گروهها را؛ su و sudo هم که هویت را عوض میکنند (درس قبل). فهرست مفصل برای هر سیستم متفاوت است؛ چیز غیرمنتظرهای در آن دیدی، مشکوک شو.
مثال ۴: setgid، پوشهی مشترک تیمی (تمرین اصلی)
Section titled “مثال ۴: setgid، پوشهی مشترک تیمی (تمرین اصلی)”اول کاربرها و گروه را میسازم و پوشهی /srv/project را به گروه team میدهم، با دسترسی 775 (اعضا بنویسند):
sudo groupadd teamfor u in bob carol dave; do sudo useradd -m -s /bin/bash $u; donesudo usermod -aG team bobsudo usermod -aG team carolecho "bob: $(id -Gn bob) | carol: $(id -Gn carol) | dave: $(id -Gn dave)"sudo mkdir /srv/projectsudo chgrp team /srv/projectsudo chmod 775 /srv/projectls -ld /srv/projectbob: bob team | carol: carol team | dave: davedrwxrwxr-x 2 root team 4096 Oct 3 20:51 /srv/projectبدون setgid: bob یک فایل و یک پوشه میسازد (با umask 002 که فایلها برای گروه قابلنوشتن باشند؛ درس دسترسیها) و carol سعی میکند فایل او را ویرایش کند:
echo "--- bob فایل و پوشه میسازد:"sudo -u bob sh -c 'umask 002; echo "از bob" > /srv/project/notes.txt; mkdir /srv/project/docs'ls -l /srv/projectecho "--- carol (همتیمی) میخواهد به فایل bob اضافه کند:"sudo -u carol sh -c 'echo "از carol" >> /srv/project/notes.txt'--- bob فایل و پوشه میسازد:total 8drwxrwxr-x 2 bob bob 4096 Oct 3 20:51 docs-rw-rw-r-- 1 bob bob 9 Oct 3 20:51 notes.txt--- carol (همتیمی) میخواهد به فایل bob اضافه کند:sh: 1: cannot create /srv/project/notes.txt: Permission deniedگروه هر دو آیتم bob است، نه team: گروه فایلهای جدید همیشه گروه اصلی سازنده است. پس با اینکه carol همتیمی است و فایل برای گروه نوشتنی (rw-rw-r--)، چون گروه فایل bob است و نه team، به او «بقیه» میگویند و فقط میخواند. حالا chmod g+s روی خود پوشه:
sudo chmod g+s /srv/projectls -ld /srv/projectecho "--- bob دوباره فایل و پوشه میسازد:"sudo -u bob sh -c 'umask 002; echo "از bob" > /srv/project/plan.txt; mkdir /srv/project/src'ls -l /srv/projectecho "--- carol حالا میتواند:"sudo -u carol sh -c 'echo "از carol" >> /srv/project/plan.txt' && cat /srv/project/plan.txtdrwxrwsr-x 3 root team 4096 Oct 3 20:51 /srv/project--- bob دوباره فایل و پوشه میسازد:total 16drwxrwxr-x 2 bob bob 4096 Oct 3 20:51 docs-rw-rw-r-- 1 bob bob 9 Oct 3 20:51 notes.txt-rw-rw-r-- 1 bob team 9 Oct 3 20:51 plan.txtdrwxrwsr-x 2 bob team 4096 Oct 3 20:51 src--- carol حالا میتواند:از bobاز carolحالا هر چیز جدیدی که در پوشه ساخته میشود گروه team میگیرد (plan.txt و src)، و پوشهی تازه خودش هم بیت setgid را به ارث میبرد (drwxrwsr-x) تا قاعده در همهی زیرپوشهها ادامه پیدا کند. ولی setgid عطف به ماسبق نمیشود: notes.txt و docs که قبلتر ساخته شدند هنوز گروه bob دارند. درستشان میکنیم:
sudo chgrp -R team /srv/projectsudo find /srv/project -type d -exec chmod g+s {} +find /srv/project -printf '%M %u:%g %p\n' | sort -k3drwxrwsr-x root:team /srv/projectdrwxrwsr-x bob:team /srv/project/docs-rw-rw-r-- bob:team /srv/project/notes.txt-rw-rw-r-- bob:team /srv/project/plan.txtdrwxrwsr-x bob:team /srv/project/srcchgrp -R گروه همهی آیتمهای موجود را عوض کرد، و find -type d -exec chmod g+s بیت setgid را فقط به پوشهها داد (چرا فقط پوشهها؟ در «اشتباهات رایج»). برای اینکه بقیهی کاربرها دیگر نبینند، دسترسی را به 2770 میبرم (2 = setgid، 770 = مالک و گروه همهچیز، بقیه هیچ) و با dave که عضو تیم نیست امتحان میکنم:
sudo chmod 2770 /srv/projectstat -c '%a %A %U:%G %n' /srv/projectecho "--- dave (غیر عضو):"sudo -u dave ls /srv/projectecho "--- carol (عضو):"sudo -u carol ls /srv/project2770 drwxrws--- root:team /srv/project--- dave (غیر عضو):ls: cannot open directory '/srv/project': Permission denied--- carol (عضو):docsnotes.txtplan.txtsrcمثال ۵: sticky bit، /tmp و پوشهی تحویل
Section titled “مثال ۵: sticky bit، /tmp و پوشهی تحویل”در یک پوشهی باز برای همه (777) بدون sticky، چون حق w روی پوشه یعنی «اجازهی حذف آیتمهای داخل»، هر کس هر فایلی را پاک میکند:
sudo mkdir /srv/dropsudo chmod 777 /srv/dropecho "--- بدون sticky:"sudo -u bob sh -c 'echo "فایل bob" > /srv/drop/bob.txt'sudo -u carol rm /srv/drop/bob.txt && echo "carol فایل bob را پاک کرد!"echo "--- با chmod +t:"sudo chmod +t /srv/dropls -ld /srv/dropsudo -u bob sh -c 'echo "فایل bob" > /srv/drop/bob.txt'sudo -u carol rm /srv/drop/bob.txtsudo -u bob rm /srv/drop/bob.txt && echo "bob فایل خودش را پاک کرد"--- بدون sticky:carol فایل bob را پاک کرد!--- با chmod +t:drwxrwxrwt 2 root root 4096 Oct 3 20:51 /srv/droprm: cannot remove '/srv/drop/bob.txt': Operation not permittedbob فایل خودش را پاک کردبا chmod +t حرف t آمد (drwxrwxrwt، همان که در /tmp دیدی) و carol دیگر نمیتواند فایل bob را پاک کند (Operation not permitted)، ولی bob فایل خودش را میتواند. فقط مالک فایل، مالک پوشه و root میتوانند حذف یا تغییر نام بدهند. این دقیقاً چیزی است که /tmp را امن میکند: همه در آن مینویسند، ولی کسی فایل دیگران را پاک نمیکند.
مثال ۶: حالت عددی چهاررقمی و نمادین
Section titled “مثال ۶: حالت عددی چهاررقمی و نمادین”بیتهای ویژه همان رقم اول در عدد چهاررقمیاند (۴ = setuid، ۲ = setgid، ۱ = sticky، و جمعشان): 4755 یعنی setuid + 755، و 3770 یعنی setgid + sticky + 770:
mkdir -p ex6 && cd ex6touch f; mkdir d1 d2 d3chmod 4755 fchmod 2775 d1chmod 1777 d2chmod 3770 d3stat -c '%a %A %n' f d1 d2 d3echo "--- برداشتن با حالت نمادین:"chmod u-s fchmod g-s d1chmod -t d2stat -c '%a %A %n' f d1 d24755 -rwsr-xr-x f2775 drwxrwsr-x d11777 drwxrwxrwt d23770 drwxrws--T d3--- برداشتن با حالت نمادین:755 -rwxr-xr-x f775 drwxrwxr-x d1777 drwxrwxrwx d2به d3 نگاه کن: drwxrws--T. مقدار 3770 یعنی sticky روشن ولی «بقیه» اصلاً x ندارند، پس بهجای t یک T بزرگ دیده میشود. (در نمادین: chmod g+s، chmod +t، chmod u+s روشن میکنند و - خاموش.)
پشت پرده: هویت واقعی و مؤثر
Section titled “پشت پرده: هویت واقعی و مؤثر”هر پروسه سه شمارهی کاربری دارد: real UID (چه کسی راهش انداخت)، effective UID (هسته دسترسیها را با این میسنجد) و saved UID (برای برگشتن). بیت setuid فقط در لحظهی اجرا (exec) یک کار میکند: effective UID را برابر مالک فایل میگذارد. با یک نسخهی setuid-root از برنامهی بیخطر sleep ببین:
sudo cp /usr/bin/sleep /usr/local/bin/lx-sleepsudo chmod u+s /usr/local/bin/lx-sleepls -l /usr/local/bin/lx-sleepecho "--- dev1 آن را اجرا میکند و ما از بیرون نگاه میکنیم:"sudo -u dev1 sh -c '/usr/local/bin/lx-sleep 20 & pid=$!; sleep 1; ps -o ruser,euser,comm -p $pid; grep "^Uid" /proc/$pid/status; kill $pid; wait $pid 2>/dev/null'sudo rm /usr/local/bin/lx-sleep-rwsr-xr-x 1 root root 67944 Oct 3 20:51 /usr/local/bin/lx-sleep--- dev1 آن را اجرا میکند و ما از بیرون نگاه میکنیم:RUSER EUSER COMMANDdev1 root lx-sleepUid: 1002 0 0 0RUSER (واقعی) برابر dev1 است ولی EUSER (مؤثر) برابر root. در /proc/.../status هم چهار شمارهی Uid: بهترتیب real، effective، saved و filesystem هستند: 1002 0 0 0. برای همین passwd به /etc/shadow مینویسد، با اینکه dev1 هستی.
نکتهی امنیتی بزرگ: هر باگ در یک برنامهی setuid-root یعنی مهاجمی که آن را اجرا کند root میشود. به همین دلیل:
- برنامههای setuid کوچک و وسواسی نوشته میشوند، و مدیرها فهرستشان را (مثال ۳) میشناسند.
- هرگز
chmod u+sروی ویرایشگر، shell،cp،find، یا هر برنامهای که بشود با آن دستور دلخواه اجرا کرد نزن. - لینوکس setuid را روی اسکریپتها نادیده میگیرد (مشاهده در «اشتباهات رایج»).
- میشود یک پارتیشن را با گزینهی
nosuidوصل کرد تا بیت setuid در آن اثری نداشته باشد (برای/tmpو پوشهی آپلودها معمول است).
جدولهای مرجع
Section titled “جدولهای مرجع”| دستور | کار |
|---|---|
ls -l /usr/bin/passwd |
دیدن بیت setuid (s جای x مالک) |
stat -c '%a %A %n' فایل |
عدد چهاررقمی و حروف |
chmod u+s فایل |
روشنکردن setuid (با احتیاط!) |
chmod g+s پوشه |
setgid: فایلهای جدید گروه پوشه را بگیرند |
chmod +t پوشه |
sticky bit |
chmod 2775 پوشه |
setgid + rwxrwxr-x |
chmod 1777 پوشه |
sticky + rwxrwxrwx (مثل /tmp) |
chmod 2770 پوشه |
تیمی و خصوصی |
find / -xdev -perm -4000 -type f |
همهی برنامههای setuid |
find DIR -type d -exec chmod g+s {} + |
setgid فقط روی پوشهها |
| نماد در ls | معنی |
|---|---|
s (جای x مالک) |
setuid روشن، x هم روشن |
S |
setuid روشن ولی x خاموش (معمولاً اشتباه) |
s (جای x گروه) |
setgid |
t (جای x بقیه) |
sticky |
T |
sticky روشن ولی x بقیه خاموش |
اشتباهات رایج
Section titled “اشتباهات رایج”۱) S یا T بزرگ
Section titled “۱) S یا T بزرگ”mkdir -p m1 && cd m1touch t.sh && chmod 644 t.shchmod u+s t.shls -l t.shecho "--- بعد از اضافهکردن x:"chmod u+x t.shls -l t.sh-rwSr--r-- 1 ali ali 0 Oct 3 20:51 t.sh--- بعد از اضافهکردن x:-rwsr--r-- 1 ali ali 0 Oct 3 20:51 t.sh-rwSr--r-- یعنی setuid روشن است ولی x خاموش، پس بیت بیاثر است. راهحل: یا x را هم بده یا بیت را خاموش کن. (برای T مثال ۶.)
۲) chmod u+s روی اسکریپت
Section titled “۲) chmod u+s روی اسکریپت”printf '#!/bin/sh\nid -un\n' | sudo tee /usr/local/bin/lx-who.sh > /dev/nullsudo chown root:root /usr/local/bin/lx-who.shsudo chmod 4755 /usr/local/bin/lx-who.shls -l /usr/local/bin/lx-who.shecho "--- dev1 اجرا میکند، اسکریپت میگوید چه کسی است:"sudo -u dev1 /usr/local/bin/lx-who.shsudo rm /usr/local/bin/lx-who.sh-rwsr-xr-x 1 root root 17 Oct 3 20:51 /usr/local/bin/lx-who.sh--- dev1 اجرا میکند، اسکریپت میگوید چه کسی است:dev1اسکریپت s دارد و مالکش root است، ولی خروجی dev1 شد، نه root: هسته setuid را روی اسکریپتهای تفسیری عمداً نادیده میگیرد (اجرای اسکریپت دو مرحله دارد و مهاجم میتواند بین آنها فایل را عوض کند). راهحل: برای دادن اجازهی محدود به یک اسکریپت از sudo با قاعدهی دقیق استفاده کن (درس قبل).
۳) chmod -R g+s روی همهچیز
Section titled “۳) chmod -R g+s روی همهچیز”mkdir -p m3/proj/sub && cd m3echo hi > proj/a.txt; echo hi > proj/sub/b.txtchmod -R g+s projls -lR proj | grep -v totalecho "--- راهحل: فقط پوشهها بیت بگیرند:"find proj -type f -exec chmod g-s {} +ls -lR proj | grep -v totalproj:-rw-r-Sr-- 1 ali ali 3 Oct 3 20:51 a.txtdrwxr-sr-x 2 ali ali 4096 Oct 3 20:51 sub
proj/sub:-rw-r-Sr-- 1 ali ali 3 Oct 3 20:51 b.txt--- راهحل: فقط پوشهها بیت بگیرند:proj:-rw-r--r-- 1 ali ali 3 Oct 3 20:51 a.txtdrwxr-sr-x 2 ali ali 4096 Oct 3 20:51 sub
proj/sub:-rw-r--r-- 1 ali ali 3 Oct 3 20:51 b.txt-R بیت را روی فایلها هم گذاشت (-rw-r-Sr--)؛ بیت setgid روی فایل معنی «اجرا با گروه فایل» دارد و در فایلهای متنی بیمعنی و گمراهکننده است. راهحل: با find -type d -exec chmod g+s {} + فقط پوشهها را علامت بزن (مثل مثال ۴).
۴) chown بیت setuid را پاک میکند
Section titled “۴) chown بیت setuid را پاک میکند”mkdir -p m4 && cd m4touch prog && chmod 4755 progls -l progsudo chown root progls -l prog-rwsr-xr-x 1 ali ali 0 Oct 3 20:51 prog-rwxr-xr-x 1 root ali 0 Oct 3 20:51 progبا عوضشدن مالک، s رفت (-rwxr-xr-x)، چون بیتهای ویژه با مالک جدید معنی دیگری پیدا میکنند و لینوکس برای امنیت پاکشان میکند. راهحل: اول chown/chgrp، بعد chmod u+s (همان ترتیبی که در مثال ۲ رفتیم).
۵) فایل با mv گروه پوشه را نمیگیرد
Section titled “۵) فایل با mv گروه پوشه را نمیگیرد”sudo mkdir /srv/project2sudo chgrp team /srv/project2sudo chmod 2775 /srv/project2sudo -u bob sh -c 'cd /home/bob; umask 002; echo moved > moved.txt; echo copied > copied.txt; mv moved.txt /srv/project2/; cp copied.txt /srv/project2/'ls -l /srv/project2sudo rm -rf /srv/project2total 8-rw-rw-r-- 1 bob team 7 Oct 3 20:51 copied.txt-rw-rw-r-- 1 bob bob 6 Oct 3 20:51 moved.txtگروه فقط وقتی از پوشه به ارث میرسد که فایل ساخته شود: cp فایل تازه میسازد (team)، ولی mv فقط همان فایل قبلی را جابهجا میکند و گروه قدیمیاش (bob) میماند. راهحل: بعد از mv با chgrp team گروه را درست کن، یا بهجای mv از cp استفاده کن.
فقط برنامهی setuid ای که اسمش با pass شروع میشود را در /usr/bin پیدا کن و عدد و حروف دسترسیاش را با stat بگیر.
دیدن جواب
find /usr/bin -perm -4000 -name 'pass*'stat -c 'عددی=%a نمادین=%A مالک=%U' /usr/bin/passwd/usr/bin/passwdعددی=4755 نمادین=-rwsr-xr-x مالک=rootتمرین اصلی: یک پوشهی مشترک تیمی بساز که فایلها گروهش را به ارث ببرند. پوشهی /srv/shared-team را برای گروه جدید crew (اعضا: bob و carol) با دسترسی 2770 بساز. ثابت کن فایلی که bob میسازد گروه crew میگیرد، carol میتواند به آن اضافه کند و dave (غیر عضو) هیچ دسترسی ندارد. (از کاربرهای مثالها استفاده کن.)
دیدن جواب
sudo groupadd crewsudo usermod -aG crew bob; sudo usermod -aG crew carolsudo mkdir /srv/shared-teamsudo chgrp crew /srv/shared-teamsudo chmod 2770 /srv/shared-teamstat -c '%a %A %U:%G %n' /srv/shared-teamsudo -u bob sh -c 'umask 002; echo "از bob" > /srv/shared-team/todo.txt'sudo ls -l /srv/shared-teamsudo -u carol sh -c 'echo "از carol" >> /srv/shared-team/todo.txt' && sudo -u carol cat /srv/shared-team/todo.txtecho "--- dave:"sudo -u dave cat /srv/shared-team/todo.txtsudo rm -rf /srv/shared-team; sudo groupdel crew2770 drwxrws--- root:crew /srv/shared-teamtotal 4-rw-rw-r-- 1 bob crew 9 Oct 3 20:51 todo.txtاز bobاز carol--- dave:cat: /srv/shared-team/todo.txt: Permission deniedیک «پوشهی تحویل» بساز: اعضای گروه students (bob و carol) بتوانند فایل بگذارند و فایلها گروه students را بگیرند، ولی هیچکس نتواند فایل دیگری را پاک کند، و dave هیچ دسترسی نداشته باشد. دسترسی پوشه چند میشود؟
دیدن جواب
setgid (۲) و sticky (۱) با هم میشوند ۳، پس 3770:
sudo groupadd studentssudo usermod -aG students bob; sudo usermod -aG students carolsudo mkdir /srv/drop2sudo chgrp students /srv/drop2sudo chmod 3770 /srv/drop2stat -c '%a %A %U:%G %n' /srv/drop2sudo -u bob sh -c 'echo "تکلیف bob" > /srv/drop2/hw-bob.txt'sudo ls -l /srv/drop2echo "--- carol میخواهد فایل bob را پاک کند:"sudo -u carol rm /srv/drop2/hw-bob.txtecho "--- dave:"sudo -u dave ls /srv/drop2sudo -u bob rm /srv/drop2/hw-bob.txt && echo "bob فایل خودش را پاک کرد"sudo rm -rf /srv/drop2; sudo groupdel students3770 drwxrws--T root:students /srv/drop2total 4-rw-rw-r-- 1 bob students 15 Oct 3 20:51 hw-bob.txt--- carol میخواهد فایل bob را پاک کند:rm: cannot remove '/srv/drop2/hw-bob.txt': Operation not permitted--- dave:ls: cannot open directory '/srv/drop2': Permission deniedbob فایل خودش را پاک کردآزمونک
Section titled “آزمونک”در -rwsr-xr-x حرف s چه معنی دارد؟
s در جای x مالک یعنی setuid؛ مثل passwd که مالکش root است.
چرا کاربر عادی با passwd میتواند /etc/shadow را عوض کند؟
برنامهی setuid با هویت مالک (root) اجرا میشود، فقط برای همان برنامه.
setgid روی یک پوشه چه میکند؟
برای پوشهی مشترک تیمی؛ زیرپوشهها هم خود بیت را به ارث میبرند.
چرا در /tmp (با 1777) نمیتوانی فایل دیگران را پاک کنی؟
بدون sticky، حق w روی پوشه یعنی پاککردن هر چیز داخل آن.
chmod 2770 dir چه میکند؟
رقم اول ۲ یعنی setgid؛ ۷۷۰ یعنی مالک و گروه همهچیز و بقیه هیچ.
chmod u+s روی یک اسکریپت bash چه اثری در لینوکس دارد؟
برای امنیت؛ برای اجازهی محدود از sudo با قاعدهی دقیق استفاده کن.
جمعبندی
Section titled “جمعبندی”- سه بیت ویژه: setuid (4000،
sجای x مالک)، setgid (2000،sجای x گروه)، sticky (1000،tجای x بقیه).S/Tبزرگ یعنی x خاموش است. - setuid روی برنامه: با هویت مالک اجرا میشود (
passwd→ root). خطرناک است؛ فقط برای برنامههای کوچک و دقیق، روی اسکریپت اثر ندارد، و باchownپاک میشود (اولchown، بعدchmod u+s). - setgid روی پوشه (
chmod g+s): فایلها و پوشههای جدید گروه پوشه را میگیرند؛ برای پوشهی مشترک تیمی (2775یا2770). عطف به ماسبق نمیشود وmvگروه را عوض نمیکند. - sticky روی پوشه (
chmod +t): فقط مالک فایل، مالک پوشه یا root میتواند پاک کند (/tmpبا1777). - حالت عددی چهاررقمی: رقم اول بیتهای ویژه (۴+۲+۱)؛
3770= setgid + sticky +770. - با
find / -xdev -perm -4000 -type fهمهی برنامههای setuid را فهرست و بازبینی کن.
| دستور | کاری که میکند |
|---|---|
ls -l /usr/bin/passwd | دیدن setuid (s جای x مالک) |
stat -c "%a %A %n" فایل | عدد چهاررقمی و حروف |
chmod u+s فایل / chmod 4755 فایل | setuid (با احتیاط) |
chmod g+s پوشه / chmod 2775 پوشه | setgid برای پوشهی مشترک |
chmod +t پوشه / chmod 1777 پوشه | sticky bit |
chmod 2770 پوشه | تیمی و خصوصی |
chmod 3770 پوشه | setgid + sticky (پوشهی تحویل) |
find / -xdev -perm -4000 -type f | فهرست برنامههای setuid |
find DIR -type d -exec chmod g+s {} + | setgid فقط روی پوشهها |
ps -o ruser,euser,comm -p PID | هویت واقعی و مؤثر یک پروسه |