Ò»)¸ÅÊö:
1)´Ó2.1°æ¿ªÊ¼,LinuxÄÚºËÓÐÁËÄÜÁ¦(capability)µÄ¸ÅÄî,¼´Ëü´òÆÆÁËUNIX/LINUX²Ù×÷ϵͳÖг¬¼¶Óû§/ÆÕͨÓû§µÄ¸ÅÄî,ÓÉÆÕͨÓû§Ò²¿ÉÒÔ×öÖ»Óг¬¼¶Óû§¿ÉÒÔÍê³ÉµÄ¹¤×÷.
2)capability¿ÉÒÔ×÷ÓÃÔÚ½ø³ÌÉÏ(ÊÜÏÞ),Ò²¿ÉÒÔ×÷ÓÃÔÚ³ÌÐòÎļþÉÏ,ËüÓësudo²»Í¬,sudoÖ»Õë¶ÔÓû§/³ÌÐò/ÎļþµÄ¸ÅÊö,¼´sudo¿ÉÒÔÅäÖÃij¸öÓû§¿ÉÒÔÖ´ÐÐij¸öÃüÁî,¿ÉÒÔ¸ü¸Äij¸öÎļþ,¶øcapabilityÊÇÈÃij¸ö³ÌÐòÓµÓÐijÖÖÄÜÁ¦,ÀýÈç:
capabilityÈÃ/tmp/testkill³ÌÐò¿ÉÒÔkillµôÆäËü½ø³Ì,µ«Ëü²»ÄÜmountÉ豸½Úµãµ½Ä¿Â¼,Ò²²»ÄÜÖØÆôϵͳ,ÒòΪÎÒÃÇÖ»Ö¸¶¨ÁËËükillµÄÄÜÁ¦,¼´Ê¹³ÌÐòÓÐÎÊÌâÒ²²»»á³¬³öÄÜÁ¦·¶Î§.
3)ÿ¸ö½ø³ÌÓÐÈý¸öºÍÄÜÁ¦ÓйصÄλͼ:inheritable(I),permitted(P)ºÍeffective(E),¶ÔÓ¦½ø³ÌÃèÊö·ûtask_struct(include/linux/sched.h)ÀïÃæµÄcap_effective, cap_inheritable, cap_permitted,ËùÒÔÎÒÃÇ¿ÉÒԲ鿴/proc/PID/statusÀ´²é¿´½ø³ÌµÄÄÜÁ¦.
4)cap_effective:µ±Ò»¸ö½ø³ÌÒª½øÐÐij¸öÌØÈ¨²Ù×÷ʱ,²Ù×÷ϵͳ»á¼ì²écap_effectiveµÄ¶ÔӦλÊÇ·ñÓÐЧ,¶ø²»ÔÙÊǼì²é½ø³ÌµÄÓÐЧUIDÊÇ·ñΪ0.
ÀýÈç,Èç¹ûÒ»¸ö½ø³ÌÒªÉèÖÃϵͳµÄʱÖÓ,LinuxµÄÄں˾ͻá¼ì²écap_effectiveµÄCAP_SYS_TIMEλ(µÚ25λ)ÊÇ·ñÓÐЧ.
5)cap_permitted:±íʾ½ø³ÌÄܹ»Ê¹ÓõÄÄÜÁ¦,ÔÚcap_permittedÖпÉÒÔ°üº¬cap_effectiveÖÐûÓеÄÄÜÁ¦£¬ÕâЩÄÜÁ¦ÊDZ»½ø³Ì×Ô¼ºÁÙʱ·ÅÆúµÄ,Ò²¿ÉÒÔ˵cap_effectiveÊÇcap_permittedµÄÒ»¸ö×Ó¼¯.
6)cap_inheritable:±íʾÄܹ»±»µ±Ç°½ø³ÌÖ´ÐеijÌÐò¼Ì³ÐµÄÄÜÁ¦. ¶þ)capabilityµÄÉ趨ÓëÇå³ý
ÎÒÃÇÔÚÏÂÃæµÄ³ÌÐòÖиøµ±Ç°µÄ½ø³ÌÉ趨ÄÜÁ¦,×îºóÎÒÃÇÇå³ýµôËùÉ趨µÄÄÜÁ¦,Ô´³ÌÐòÈçÏÂ:
1 #include
7 #undef _POSIX_SOURCE 8 #include
10 extern int errno; 11
12 void whoami(void) 13 {
14 printf(\ euid=%i gid=%i\\n\15 } 16
17 void listCaps() 18 {
19 cap_t caps = cap_get_proc(); 20 ssize_t y = 0;
21 printf(\22 (int) getpid(), cap_to_text(caps, &y));
23 fflush(0);
24 cap_free(caps); 25 } 26
27 int main(int argc, char **argv) 28 {
29 int stat; 30 whoami();
31 stat = setuid(geteuid()); 32 pid_t parentPid = getpid(); 33
34 if(!parentPid) 35 return 1;
36 cap_t caps = cap_init(); 37 38
39 cap_value_t capList[5] = 40 { CAP_NET_RAW, CAP_NET_BIND_SERVICE , CAP_SETUID, CAP_SETGID,CAP_SETPCAP } ; 41 unsigned num_caps = 5;
42 cap_set_flag(caps, CAP_EFFECTIVE, num_caps, capList, CAP_SET); 43 cap_set_flag(caps, CAP_INHERITABLE, num_caps, capList, CAP_SET); 44 cap_set_flag(caps, CAP_PERMITTED, num_caps, capList, CAP_SET); 45
46 if (cap_set_proc(caps)) { 47 perror(\48
49 return EXIT_FAILURE; 50 }
51 listCaps(); 52
53 printf(\
54 cap_clear(caps); // resetting caps storage 55
56 if (cap_set_proc(caps)) { 57 perror(\
58 return EXIT_FAILURE; 59 }
60 listCaps(); 61
62 cap_free(caps); 63 return 0; 64 65 }
±àÒë:
gcc capsettest.c -o capsettest -lcap ÔËÐÐ:
./capsettest
uid=0 euid=0 gid=0 The process 2383 was give capabilities = cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw+eip dropping caps
The process 2383 was give capabilities = ×¢:
1)ÎÒÃǶԸýø³ÌÔö¼ÓÁË5ÖÖÄÜÁ¦,ËæºóÓÖÇå³ýÁËËùÓÐÄÜÁ¦.
2)Ê×ÏÈͨ¹ýcap_init()³õʼ»¯´æ·ÅcapÄÜÁ¦ÖµµÄ״̬,Ëæºóͨ¹ýcap_set_flagº¯ÊýµÄµ÷ÓÃ,½«ÈýÖÖλͼµÄÄÜÁ¦ÉèÖøøÁ˱äÁ¿caps,ÔÙͨ¹ýcap_set_proc(caps)É趨µ±Ç°½ø³ÌµÄÄÜÁ¦Öµ,ͨ¹ýcap_get_proc()·µ»Øµ±Ç°½ø³ÌµÄÄÜÁ¦Öµ,×îºóͨ¹ýcap_free(caps)ÊÍ·ÅÄÜÁ¦Öµ. 3)cap_set_flagº¯ÊýµÄÔÐÍÊÇ: int cap_set_flag(cap_t cap_p, cap_flag_t flag, int ncap,const cap_value_t *caps, cap_flag_value_t value);
ÎÒÃÇÕâÀïµÄµ÷ÓÃÓï¾äÊÇ:cap_set_flag(caps, CAP_PERMITTED, num_caps, capList, CAP_SET); µÚÒ»¸ö²ÎÊýcap_pÊÇ´æ·ÅÄÜÁ¦ÖµµÄ±äÁ¿,ÊDZ»É趨ֵ.ÕâÀïÊÇcaps. µÚ¶þ¸ö²ÎÊýflagÊÇÊÇÈýÖÖÄÜÁ¦Î»Í¼,ÕâÀïÊÇCAP_PERMITTED. µÚÈý¸ö²ÎÊýncapÊÇÒªÉ趨ÄÜÁ¦µÄ¸öÊý,ÕâÀïÊÇnum_caps,Ò²¾ÍÊÇ5.
µÚËĸö²ÎÊý*capsÊÇÒªÉ趨µÄÄÜÁ¦Öµ,ÕâÀïÊÇcapListÊý×é,Ò²¾ÍÊÇCAP_NET_RAW, CAP_NET_BIND_SERVICE , CAP_SETUID, CAP_SETGID,CAP_SETPCAP. µÚÎå¸ö²ÎÊývalueÊǾö¶¨ÒªÉ趨»¹ÊÇÇå³ý,ÕâÀïÊÇCAP_SET. 4)cap_set_procº¯ÊýµÄÔÐÍÊÇ:int cap_set_proc(cap_t cap_p); cap_set_procº¯Êýͨ¹ýcap_pÖеÄÄÜÁ¦ÖµÉ趨¸øµ±Ç°µÄ½ø³Ì. 5)cap_get_procº¯ÊýµÄÔÐÍÊÇ:cap_t cap_get_proc(void); cap_get_procº¯Êý·µ»Øµ±Ç°½ø³ÌµÄÄÜÁ¦Öµ¸øcap±äÁ¿. 6)cap_freeº¯ÊýµÄÔÐÍÊÇ:cap_free(caps); cap_freeº¯ÊýÇåÀí/ÊÍ·Åcap±äÁ¿.
7)Èç¹ûÎÒÃÇfork()ÁË×Ó½ø³Ì,ÄÇô×Ó½ø³Ì¼Ì³Ð¸¸½ø³ÌµÄËùÓÐÄÜÁ¦.
8)²»Äܵ¥¶ÀÉ趨CAP_EFFECTIVE,CAP_INHERITABLEλͼ,±ØÐëÒªºÍCAP_PERMITTEDÁªÓÃ,ÇÒCAP_PERMITTEDÒ»¶¨ÒªÊÇÆäËüÁ½¸öλͼµÄ³¬¼¯.
9)Èç¹ûÁ½´Îµ÷ÓÃcap_set_procº¯Êý,µÚ¶þ´Îµ÷ÓõÄÖµÁ¦Öµ²»ÄÜÉÙÓÚ»ò¶àÓÚµÚÒ»´Îµ÷ÓÃ.ÈçµÚÒ»´ÎÎÒÃÇÊÚȨchown,setuidÄÜÁ¦,µÚ¶þ´ÎÖ»ÄÜÊÇchown,setuid²»ÄÜÊÇÆäËüµÄÄÜÁ¦Öµ. 10)ÆÕͨÓû§²»Äܸø½ø³ÌÉ趨ÄÜÁ¦. Èý)½ø³ÌµÄÄÜÁ¦ÑÚÂë:
ÎÒÃÇ¿ÉÒÔͨ¹ýÏÂÃæµÄ³ÌÐò»ñÈ¡µ±Ç°½ø³ÌµÄÑÚÂë,ËüÊÇͨ¹ýcapgetº¯ÊýÀ´»ñȡָ¶¨½ø³ÌµÄÄÜÁ¦ÑÚÂë,µ±È»ÎÒÃÇÒ²¿ÉÒÔÓÃcapsetÀ´É趨ÑÚÂë,ÏÂÃæ»ñÈ¡ÑÚÂëµÄÌåÏÖ:
1 #undef _POSIX_SOURCE 2 #include
4 #include
6 #include
9 int main() 10 {
11 struct __user_cap_header_struct cap_header_data; 12 cap_user_header_t cap_header = &cap_header_data; 13
14 struct __user_cap_data_struct cap_data_data; 15 cap_user_data_t cap_data = &cap_data_data; 16
17 cap_header->pid = getpid();
18 cap_header->version = _LINUX_CAPABILITY_VERSION_1; 19
20 if (capget(cap_header, cap_data) < 0) { 21 perror(\22 exit(1); 23 }
24 printf(\25 cap_data->permitted, cap_data->inheritable); 26 }
gcc capget0.c -o capget0 -lcap ÆÕͨÓû§: ./capget0
Cap data 0x0, 0x0, 0x0 ³¬¼¶Óû§:
/home/test/capget0
Cap data 0xffffffff, 0xffffffff, 0x0
ÕâҲ˵Ã÷ÁËĬÈÏÇé¿öÏÂ,rootÔËÐеĽø³ÌÊÇʲôȨÏÞ¶¼ÓÐ,¶øÆÕͨÓû§ÔòʲôȨÏÞ¶¼Ã»ÓÐ. ÎÒÃÇ¿ÉÒÔ½«±¾³ÌÐòÓëÉÏÃæµÄ³ÌÐò½øÐÐÕûºÏ,ÈçÏÂ:
1 #include
7 #undef _POSIX_SOURCE 8 #include
10 extern int errno;
11
12 void whoami(void) 13 {
14 printf(\ euid=%i gid=%i\\n\15 } 16
17 void listCaps() 18 {
19 cap_t caps = cap_get_proc(); 20 ssize_t y = 0;
21 printf(\22 (int) getpid(), cap_to_text(caps, &y)); 23 fflush(0);
24 cap_free(caps); 25 } 26 27
28 int main(int argc, char **argv) 29 {
30 int stat; 31 whoami();
32 stat = setuid(geteuid()); 33 pid_t parentPid = getpid(); 34
35 if(!parentPid) 36 return 1;
37 cap_t caps = cap_init(); 38
39 cap_value_t capList[5] = 40 { CAP_NET_RAW, CAP_NET_BIND_SERVICE , CAP_SETUID, CAP_SETGID,CAP_SETPCAP } ; 41 unsigned num_caps = 5;
42 cap_set_flag(caps, CAP_EFFECTIVE, num_caps, capList, CAP_SET); 43 cap_set_flag(caps, CAP_INHERITABLE, num_caps, capList, CAP_SET); 44 cap_set_flag(caps, CAP_PERMITTED, num_caps, capList, CAP_SET); 45
46 if (cap_set_proc(caps)) { 47 perror(\48
49 return EXIT_FAILURE; 50 }
51 listCaps(); 52
53 cap_free(caps);
54
55 struct __user_cap_header_struct cap_header_data; 56 cap_user_header_t cap_header = &cap_header_data; 57
58 struct __user_cap_data_struct cap_data_data; 59 cap_user_data_t cap_data = &cap_data_data; 60
61 cap_header->pid = getpid();
62 cap_header->version = _LINUX_CAPABILITY_VERSION_1; 63
64 if (capget(cap_header, cap_data) < 0) { 65 perror(\66 exit(1); 67 }
68 printf(\69 cap_data->permitted, cap_data->inheritable); 70
71 sleep(60); 72 return 0; 73 }
±àÒë²¢Ö´ÐÐ:
gcc capsettest.c -o capsettest -lcap ./capsettest
uid=0 euid=0 gid=0 The process 3101 was give capabilities cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw+eip Cap data 0x25c0, 0x25c0, 0x25c0
×¢:0x25c0=10 0101 1100 0000(¶þ½øÖÆ) ¶ÔÓ³µÄÄÜÁ¦ÈçÏÂ: cap_setgid=6(λ) cap_setuid=7(λ) cap_setpcap=8(λ)
cap_net_bind_service=10(λ) cap_net_raw=13(λ)
ÔÚ³ÌÐòsleepµÄʱºò,ÎÒÃDz鿴һϽø³ÌµÄstatus,ÈçÏÂ: cat /proc/`pgrep capsettest`/status ÂÔ
CapInh: 00000000000025c0 CapPrm: 00000000000025c0 CapEff: 00000000000025c0 CapBnd: ffffffffffffffff
=
ÂÔ
ÎÒÃÇ¿´µ½½ø³ÌµÄstatusÒ²·´Ó³ÁËËüµÄÄÜÁ¦×´Ì¬. CapBndÊÇϵͳµÄ±ß½çÄÜÁ¦,ÎÒÃÇÎÞ·¨¸Ä±äËü.
ËÄ)capabilityµÄ¹¤¾ß½éÉÜ
ÔÚÎÒÃǵÄÊÔÑé»·¾³ÊÇRHEL6,libcap-2.16Èí¼þ°üÖаüº¬ÁËÏà¹ØµÄcapabilityÉèÖü°²é¿´¹¤×÷,ÈçÏÂ:
rpm -ql libcap-2.16-5.2.el6.i686 /lib/libcap.so.2 /lib/libcap.so.2.16
/lib/security/pam_cap.so /usr/sbin/capsh /usr/sbin/getcap /usr/sbin/getpcaps /usr/sbin/setcap
/usr/share/doc/libcap-2.16
/usr/share/doc/libcap-2.16/License
/usr/share/doc/libcap-2.16/capability.notes /usr/share/man/man8/getcap.8.gz /usr/share/man/man8/setcap.8.gz
getcap¿ÉÒÔ»ñµÃ³ÌÐòÎļþËù¾ßÓеÄÄÜÁ¦(CAP). getpcaps¿ÉÒÔ»ñµÃ½ø³ÌËù¾ßÓеÄÄÜÁ¦(CAP). setcap¿ÉÒÔÉèÖóÌÐòÎļþµÄÄÜÁ¦(CAP). ÎÒÃÇÏÂÃæÖ÷ÒªÓÃsetcapÀ´½øÐе÷ÊÔ.
Îå)CAP_CHOWN 0(ÔÊÐí¸Ä±äÎļþµÄËùÓÐȨ)
ÊÚȨÆÕͨÓû§¿ÉÒÔÓÃ/bin/chown³ÌÐò¸ü¸ÄÈÎÒâÎļþµÄowner,ÈçÏÂ: setcap cap_chown=eip /bin/chown ²é¿´/bin/chown³ÌÐòµÄÄÜÁ¦Öµ,ÈçÏÂ: getcap /bin/chown /bin/chown = cap_chown+eip
Çл»µ½testÓû§,½«/bin/ls³ÌÐòµÄowner¸ÄΪtest,ÈçÏÂ: su - test
chown test.test /bin/ls ls -l /bin/ls
-rwxr-xr-x. 1 test test 118736 Jun 14 2010 /bin/ls ×¢:
1)cap_chown=eipÊǽ«chownµÄÄÜÁ¦ÒÔcap_effective(e),cap_inheritable(i),cap_permitted(p)ÈýÖÖλͼµÄ·½Ê½ÊÚȨ¸øÏà¹ØµÄ³ÌÐòÎļþ.
2)Èç¹û¸Ä±äÎļþÃû,ÔòÄÜÁ¦±£Áôµ½ÐÂÎļþ.
3)ÓÃsetcap -r /bin/chown¿ÉÒÔɾ³ýµôÎļþµÄÄÜÁ¦. 4)ÖØÐÂÓÃsetcapÊÚȨ½«¸²¸Ç֮ǰµÄÄÜÁ¦.
Áù)CAP_DAC_OVERRIDE 1(ºöÂÔ¶ÔÎļþµÄËùÓÐDAC·ÃÎÊÏÞÖÆ) ÊÚȨÆÕͨÓû§¿ÉÒÔÓÃ/usr/bin/vim³ÌÐòÐÞ¸ÄËùÓÐÎļþµÄÄÚÈÝ,ÈçÏÂ:
setcap cap_dac_override=eip /usr/bin/vim Çл»µ½ÆÕͨÓû§ su - test
ÐÞ¸Ä/etc/shadowÎļþÄÚÈÝ vim /etc/shadow
root:$6$3hJf.BoIVU/cdLKb$JxLXcQScrLS032aFPAQvVc4RzKYNadcIIzxmzAIw.jejrYOHhqdr0oV7sNBL.IhGBo.mMOYEdevlnCp2OGku8.:15094:0:99999:7::: bin:*:14790:0:99999:7::: daemon:*:14790:0:99999:7::: adm:*:14790:0:99999:7::: ×¢:
DAC_OVERRIDEÄÜÁ¦ÊÇDAC_READ_SEARCHÄÜÁ¦µÄ³¬¼¯.
Æß)CAP_DAC_READ_SEARCH 2(ºöÂÔËùÓжԶÁ¡¢ËÑË÷²Ù×÷µÄÏÞÖÆ)
ÊÚȨÆÕͨÓû§¿ÉÒÔÓÃ/bin/cat³ÌÐò²é¿´ËùÓÐÎļþµÄÄÚÈÝ,ÈçÏÂ: setcap cap_dac_read_search=eip /bin/cat Çл»µ½ÆÕͨÓû§ su - test
²é¿´/etc/shadow,ÈçÏÂ: cat /etc/shadow
root:$6$3hJf.BoIVU/cdLKb$JxLXcQScrLS032aFPAQvVc4RzKYNadcIIzxmzAIw.jejrYOHhqdr0oV7sNBL.IhGBo.mMOYEdevlnCp2OGku8.:15094:0:99999:7::: bin:*:14790:0:99999:7::: daemon:*:14790:0:99999:7::: adm:*:14790:0:99999:7:::
°Ë)CAP_FOWNER 3(ÒÔ×îºó²Ù×÷µÄUID,¸²¸ÇÎļþµÄÏÈǰµÄUID) cp /etc/passwd /tmp/ ls -l /tmp/passwd
-rw-r--r-- 1 root root 1171 2011-04-29 19:21 /tmp/passwd ÊÚȨcap_fownerȨÏÞ¸ø/usr/bin/vim setcap cap_fowner=eip /usr/bin/vim Çл»µ½testÓû§ su - test
±à¼/tmp/passwdÎļþ,´æÅÌÍ˳ö. vi /tmp/passwd
ÐÞ¸ÄÎļþ,²¢±£´æÍ˳ö.
²é¿´/tmp/passwd,·¢ÏÖownerÒѾ±ä³Étest
-rw-r--r-- 1 test test 1176 2011-04-29 19:21 /tmp/passwd
¾Å)CAP_FSETID 4(È·±£ÔÚÎļþ±»Ð޸ĺó²»ÐÞ¸Äsetuid/setgidλ)
ÆðÒòÊǵ±Îļþ±»Ð޸ĺó,»áÇå³ýµôÎļþµÄsetuid/setgidλ,¶øÉ趨CAP_FSETIDºó½«±£Ö¤setuid/setgidλ²»±»Çå³ý.µ«Õâ¶Ôchownº¯ÊýÎÞÓÃ. ²âÊÔ³ÌÐòÈçÏÂ:
1 #include
11 int handle; 12 char string[40]; 13 int length, res; 14
15 if ((handle = open(\O_TRUNC,S_IREAD | S_IWRITE)) == -1) 16 {
17 printf(\18 exit(1); 19 }
20 strcpy(string, \21 length = strlen(string);
22 if ((res = write(handle, string, length)) != length) 23 {
24 printf(\25 exit(1); 26 }
27 printf(\28 close(handle); 29 }
gcc fsetid.c -o fsetid
ÏȲâÊÔûÓÐÉèFSETIDµÄÇé¿ö,ÈçÏÂ: chmod 6777 /tmp/passwd ls -l /tmp/passwd
-rwsrwsrwx 1 test test 14 2011-04-30 14:22 /tmp/passwd /tmp/fsetid
Wrote 14 bytes to the file. ls -l /tmp/passwd
-rwxrwxrwx 1 test test 14 2011-04-30 14:25 /tmp/passwd ÎÒÃÇ¿´µ½setuid/setgidλ±»Çå³ýÁË. ÏÂÃæÊÇÉ趨FSETID,ÈçÏÂ:
O_WRONLY | O_CREAT | chmod 6777 /tmp/passwd ls -l /tmp/passwd
-rwsrwsrwx 1 test test 14 2011-04-30 14:25 /tmp/passwd
Çл»µ½rootÓû§,¸ø/tmp/fsetid³ÌÐòÊÚȨCAP_FSETIDÄÜÁ¦,ÈçÏÂ: setcap cap_fsetid=eip /tmp/fsetid Çл»µ½ÆÕͨÓû§ /tmp/fsetid
Wrote 14 bytes to the file. ls -l /tmp/passwd
-rwsrwsrwx 1 test test 14 2011-04-30 14:28 /tmp/passwd Ê®)CAP_KILL 5 (ÔÊÐí¶Ô²»ÊôÓÚ×Ô¼ºµÄ½ø³Ì·¢ËÍÐźÅ) ÎÒÃÇÏÈÄ£ÄâûÓмÓCAP_KILLÄÜÁ¦µÄÇé¿ö,ÈçÏÂ: ÖÕ¶Ë1,ÓÃrootÓû§ÆôÓÃtop³ÌÐò,ÈçÏÂ: su - root top
ÖÕ¶Ë2,ÓÃtestÓû§kill֮ǰµÄtop½ø³Ì,ÈçÏÂ: pgrep top 3114
/bin/kill 3114
kill: Operation not permitted
ÎÒÃÇ·¢ÏÖÎÞ·¨¶Ô²»ÊôÓÚ×Ô¼ºµÄ½ø³Ì·¢ËÍÐźÅ.
ÏÂÃæÎÒÃÇÓÃCAP_KILLÄÜÁ¦µÄ³ÌÐòÏò²»ÊôÓÚ×Ô¼ºµÄ½ø³Ì·¢ËÍÐźÅ,ÈçÏÂ: É趨killÃüÁîµÄkillλ,ÈçÏÂ: setcap cap_kill=eip /bin/kill ɱµô3114½ø³Ì,ûÓÐÎÊÌâ,ÈçÏÂ: /bin/kill 3114 echo $? 0 ×¢Òâ:
ÆÕͨÓû§ÒªÓÃ/bin/killÕâÖÖ¾ø¶Ô·¾¶µÄ·½Ê½,¶ø²»ÄÜÓÃkillÕâÖÖ·½Ê½.
ʮһ)CAP_SETGID 6 (É趨³ÌÐòÔÊÐíÆÕͨÓû§Ê¹ÓÃsetgidº¯Êý,ÕâÓëÎļþµÄsetgidȨÏÞλÎÞ¹Ø) cp /etc/shadow /tmp/
chown root.root /tmp/shadow chmod 640 /tmp/shadow
Çл»µ½ÆÕͨÓû§test,²¢±àдsetgid²âÊÔ³ÌÐò,ÈçÏÂ: su - test
1 #include
5 gid_t gid = 0; 6 setgid(gid);
7 system(\
8 return 0; 9 }
gcc setgid.c -o setgid
¸ü¸Äsetgid³ÌÐòΪCAP_SETGID setcap cap_setgid=eip /tmp/setgid
Çл»µ½ÆÕͨÓû§,ÔËÐÐ/tmp/setgid³ÌÐò,ÈçÏÂ: su - test /tmp/setgid
root:$1$S9AmPHY8$ZIdORp6aLnYleb5EORxw8/:14479:0:99999:7::: daemon:*:14479:0:99999:7::: bin:*:14479:0:99999:7::: sys:*:14479:0:99999:7::: sync:*:14479:0:99999:7::: games:*:14479:0:99999:7::: man:*:14479:0:99999:7::: lp:*:14479:0:99999:7::: mail:*:14479:0:99999:7::: news:*:14479:0:99999:7::: uucp:*:14479:0:99999:7::: proxy:*:14479:0:99999:7::: www-data:*:14479:0:99999:7::: backup:*:14479:0:99999:7::: list:*:14479:0:99999:7:::
ÎÒÃÇ¿´µ½ÆÕͨÓû§¿ÉÒԲ鿴/tmp/shadowÎļþ,¶øÈ¡ÏûCAP_SETGIDÔòʹ³ÌÐò²»ÄÜÓµÓÐsetgidµÄȨÏÞ,ÈçÏÂ:
setcap -r /tmp/setgid su - test /tmp/setgid
/bin/cat: /tmp/shadow: Permission denied
Ê®¶þ)CAP_SETUID 7 (É趨³ÌÐòÔÊÐíÆÕͨÓû§Ê¹ÓÃsetuidº¯Êý,ÕâÒ²ÎļþµÄsetuidȨÏÞλÎÞ¹Ø) cp /etc/shadow /tmp/
chown root.root /tmp/shadow chmod 640 /tmp/shadow
Çл»µ½ÆÕͨÓû§test,²¢±àдsetuid²âÊÔ³ÌÐò,ÈçÏÂ: su - test cd /tmp/ vi setuid.c
1 #include
5 uid_t uid = 0;
6 setuid(uid);
7 system(\8 return 0; 9 }
gcc setuid.c -o setuid
Çл»µ½rootÓû§,¸ü¸Äsetuid³ÌÐòΪCAP_SETUID su - root
setcap cap_setuid=eip /tmp/setuid
Çл»µ½testÓû§,ÔËÐÐ/tmp/setuid³ÌÐò,ÈçÏÂ: su - test /tmp/setuid
root:$1$S9AmPHY8$ZIdORp6aLnYleb5EORxw8/:14479:0:99999:7::: daemon:*:14479:0:99999:7::: bin:*:14479:0:99999:7::: sys:*:14479:0:99999:7::: sync:*:14479:0:99999:7::: games:*:14479:0:99999:7::: man:*:14479:0:99999:7::: lp:*:14479:0:99999:7:::
ÎÒÃÇ¿´µ½ÆÕͨÓû§¿ÉÒԲ鿴/tmp/shadowÎļþ,¶øÈ¡ÏûCAP_SETUIDÔòʹ³ÌÐò²»ÄÜÓµÓÐsetuidµÄȨÏÞ,ÈçÏÂ:
setcap -r /tmp/setuid su - test /tmp/setuid
/bin/cat: /tmp/shadow: Permission denied
Ê®Èý)CAP_SETPCAP 8 (ÔÊÐíÏòÆäËü½ø³Ì×ªÒÆÄÜÁ¦ÒÔ¼°É¾³ýÆäËü½ø³ÌµÄÈÎÒâÄÜÁ¦)
ÊÂʵÉÏÖ»ÓÐinit½ø³Ì¿ÉÒÔÉ趨ÆäËü½ø³ÌµÄÄÜÁ¦,¶øÆäËü³ÌÐòÎÞȨ¶Ô½ø³ÌÊÚȨ,rootÓû§Ò²²»ÄÜ¶ÔÆäËü½ø³ÌµÄÄÜÁ¦½øÐÐÐÞ¸Ä,Ö»ÄܶԵ±Ç°½ø³Ìͨ¹ýcap_set_procµÈº¯Êý½øÐÐÐÞ¸Ä,¶ø×Ó½ø³ÌÒ²»á¼Ì³ÐÕâÖÖÄÜÁ¦.
ËùÒÔ¼´Ê¹Ê¹ÓÃÁËCAP_SETPCAPÄÜÁ¦,Ò²²»»áÆðµ½ÕæÕýµÄ×÷ÓÃ.
Ê®ËÄ)CAP_LINUX_IMMUTABLE 9 (ÔÊÐíÐÞ¸ÄÎļþµÄ²»¿ÉÐÞ¸Ä(IMMUTABLE)ºÍÖ»Ìí¼Ó(APPEND-ONLY)ÊôÐÔ)
ÆÕͨÓû§²»ÄÜͨ¹ýchattr¶ÔÎļþÉèÖÃIMMUTABLE(chattr +i)ºÍAPPEND-ONLY(chattr +a)ȨÏÞ,¶øÍ¨¹ýCAP_LINUX_IMMUTABLE¿ÉÒÔʹÆÕͨÓû§Í¨¹ý×Ô¼ºÔö¼õ(immutable/append-only)ȨÏÞ.
ÆÕͨÓû§Í¨¹ýchattr¸øÎļþÔö¼ÓimmutableȨÏÞ,ÈçÏÂ: touch /tmp/test chattr +i /tmp/test
chattr: Operation not permitted while setting flags on /tmp/test
ÎÒÃÇ¿´µ½ÊÚȨʧ°ÜÁË,¶øÈç¹ûÎÒÃǶÔchattrÔö¼ÓÁËLINUX_IMMUTABLEȨÏÞ,Ôò¿ÉÒԳɹ¦,ÈçÏÂ:
´ËʱÇл»µ½rootÓû§: su -
setcap cap_linux_immutable=eip /usr/bin/chattr Çл»µ½ÆÕͨÓû§: su - test
chattr +i /tmp/test lsattr /tmp/test
----i-------------- /tmp/test
ÎÒÃÇ¿´µ½ÊÚȨ³É¹¦ÁË,×¢Òâ,ÕâÀïÖ»ÄܶÔ×Ô¼ºµÄÎļþÊÚȨ(immutable/append-only)ȨÏÞ,¶ÔÓÚÆäËüÓû§µÄȨÏÞLINUX_IMMUTABLE²»Æð×÷ÓÃ(root³ýÍâ),ÈçÏÂ: su - test
chattr +i /etc/passwd
chattr: Permission denied while setting flags on /etc/passwd
Ê®Îå)CAP_NET_BIND_SERVICE 10(ÔÊÐí°ó¶¨µ½Ð¡ÓÚ1024µÄ¶Ë¿Ú)
ÆÕͨÓû§²»ÄÜͨ¹ýbindº¯Êý°ó¶¨Ð¡ÓÚ1024µÄ¶Ë¿Ú,¶ørootÓû§¿ÉÒÔ×öµ½,CAP_NET_BIND_SERVICEµÄ×÷ÓþÍÊÇÈÃÆÕͨÓû§Ò²¿ÉÒÔ°ó¶Ë¿Úµ½1024ÒÔÏÂ. ÆÕͨÓû§Í¨¹ýnc°ó¶¨¶Ë¿Ú500,ÈçÏÂ: nc -l -p 500
Can't grab 0.0.0.0:500 with bind : Permission denied
Ôö¼ÓCAP_NET_BIND_SERVICEÄÜÁ¦µ½nc³ÌÐò,ÈçÏÂ: setcap cap_net_bind_service=eip /usr/bin/nc
ÔÙÇл»µ½ÆÕͨÓû§,ͨ¹ýnc°ó¶¨¶Ë¿Ú500,ÈçÏÂ: nc -l -p 500 ²é¿´¸Ã¶Ë¿Ú:
netstat -tulnp|grep nc
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN 2523/nc
Ê®Áù)CAP_NET_BROADCAST 11(ÔÊÐíÍøÂç¹ã²¥ºÍ¶à²¥·ÃÎÊ)
ÊÂʵÉÏËü²¢Ã»Óб»Ó¦ÓÃ,ÆÕͨÓû§Ò²¿ÉÒÔʹÓÃping -b 192.168.0.255Ò²·¢Ë͹㲥°ü Ê®Æß)CAP_NET_ADMIN 12(ÔÊÐíÖ´ÐÐÍøÂç¹ÜÀíÈÎÎñ:½Ó¿Ú,·À»ðǽºÍ·ÓɵÈ)
ÆÕͨÓû§²»ÄÜ´´½¨ÐµÄÍøÂç½Ó¿Ú(interface),²»Äܸü¸ÄipµØÖ·,¶øCAP_NET_ADMIN¿ÉÒÔ°ïÖúÆÕͨÓû§Íê³ÉÕâÏ×÷,ÈçÏÂ:
ÓÃÆÕͨÓû§´´½¨ÐµÄÍø¿¨½Ó¿Úeth0:1ʧ°Ü
/sbin/ifconfig eth0:1 172.16.27.133 netmask 255.255.255.0 SIOCSIFADDR: Permission denied SIOCSIFFLAGS: Permission denied SIOCSIFNETMASK: Permission denied
´ËʱÎÒÃǰÑCAP_NET_ADMINÄÜÁ¦ÊÚȨ¸øifconfig³ÌÐò,ÈçÏÂ: setcap cap_net_admin=eip /sbin/ifconfig
ÎÒÃÇÔÙ´ÎÓÃÆÕͨÓû§¼´¿ÉÒÔн¨ÍøÂç½Ó¿Úeth0:1,²¢¿ÉÒÔDOWNµô½Ó¿Ú,ÈçÏÂ: /sbin/ifconfig eth0:1 172.16.27.133 netmask 255.255.255.0 /sbin/ifconfig eth0:1
eth0:1 Link encap:Ethernet HWaddr 00:0c:29:f9:5e:06
inet addr:172.16.27.133 Bcast:172.16.27.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 Interrupt:18 Base address:0x1080
/sbin/ifconfig eth0:1 down
ͬÑùCAP_NET_ADMIN¿ÉÒÔÈÃÆÕͨÓû§Ôö¼Ó/ɾ³ý·ÓÉ,ÈçÏÂ: /sbin/route add -host 192.168.27.139 gw 192.168.27.2 SIOCADDRT: Operation not permitted ÊÚȨNET_ADMIN,ÈçÏÂ:
setcap cap_net_admin=eip /sbin/route ÔÙ´ÎÓÃÆÕͨÓû§Ôö¼Ó·ÓÉ,ÈçÏÂ:
/sbin/route add -host 192.168.27.139 gw 192.168.27.2 /sbin/route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.27.139 192.168.27.2 255.255.255.255 UGH 0 0 0 eth0 192.168.27.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 0.0.0.0 192.168.27.2 0.0.0.0 UG 0 0 0 eth0 /sbin/route del -host 192.168.27.139 gw 192.168.27.2 ÎÒÃÇ¿´µ½ÎÒÃdzýÁË¿ÉÒÔÔö¼Ó·ÓÉÖ®Íâ,Ò²¿ÉÒÔɾ³ý·ÓÉ.
×îºóNET_ADMIN¿ÉÒÔ°ïÖúÎÒÃÇÈÃÆÕͨÓû§À´¹ÜÀí·À»ðǽ. ÆÕͨÓû§²»ÄÜÓÃiptablesÀ´¹ÜÀí·À»ðǽ,ÈçÏÂ: /sbin/iptables -L -n
iptables v1.4.2: can't initialize iptables table `filter': Permission denied (you must be root) Perhaps iptables or your kernel needs to be upgraded.
ÎÒÃǽ«CAP_NET_ADMINÊÚȨ¸øiptables³ÌÐò,×¢ÒâÎÒÃÇÒ²Òª½«CAP_NET_RAWÊÚȨ¸øiptables,CAP_NET_RAWÎÒÃǺóÃæÔÙ½âÊÍ,ÈçÏÂ:
setcap cap_net_admin,cap_net_raw=eip /sbin/iptables-multi ´Ëʱ¾Í¿ÉÒÔÓÃÆÕͨÓû§À´¹ÜÀí·À»ðǽÁË,ÈçÏÂ: /sbin/iptables -A INPUT -p tcp -j ACCEPT /sbin/iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 Chain FORWARD (policy ACCEPT)
target prot opt source destination Chain OUTPUT (policy ACCEPT)
target prot opt source destination ÎÒÃÇÒ²¿ÉÒÔɾ³ý·À»ðǽ²ßÂÔ,²¢Çå¿Õµ±Ç°µÄÊý¾ÝÁ÷Á¿,ÈçÏÂ: /sbin/iptables -F /sbin/iptables -Z /sbin/iptables -X
Ê®°Ë)CAP_NET_RAW 13 (ÔÊÐíʹÓÃÔʼ(raw)Ì×½Ó×Ö)
ÔʼÌ×½Ó×Ö±à³Ì¿ÉÒÔ½ÓÊÕµ½±¾»úÍø¿¨ÉϵÄÊý¾ÝÖ¡»òÕßÊý¾Ý°ü,¶Ô¼à¿ØÍøÂçÁ÷Á¿ºÍ·ÖÎöÊǺÜÓÐ×÷ÓõÄ.
×î³£¼ûµÄ¾ÍÊÇpingµÄʵÏÖ,ÈçÏÂ:
socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = 3 ÎÒÃÇÏȰÑpingµÄsetuidȨÏÞÈ¥µô chmod u-s /bin/ping ls -l /bin/ping
-rwxr-xr-x 1 root root 30788 2007-12-09 23:03 /bin/ping ÓÃÆÕͨÓû§Ê¹ÓÃping ping 192.168.27.2
ping: icmp open socket: Operation not permitted
ÌáʾûÓÐȨÏÞ,ÎÒÃǽ«pingÊÚȨCAP_NET_RAWÄÜÁ¦,ÈçÏÂ: setcap cap_net_raw=eip /bin/ping
Çл»µ½ÆÕͨÓû§ÔÙ´Îping 192.168.27.2,·¢ÏÖ¿ÉÒÔpingͨ,ÈçÏÂ: ping 192.168.27.2
PING 192.168.27.2 (192.168.27.2) 56(84) bytes of data.
64 bytes from 192.168.27.2: icmp_seq=1 ttl=128 time=0.266 ms 64 bytes from 192.168.27.2: icmp_seq=2 ttl=128 time=0.280 ms 64 bytes from 192.168.27.2: icmp_seq=3 ttl=128 time=0.319 ms
NET_RAWҲͬÑùÓÃÓÚtcpdump/iftop,Ò»¸öÆÕͨÓû§ÎÞ·¨Ê¹ÓÃtcpdump/iftop,¶øCAP_NET_RAW¿ÉÒÔ½â¾öÕâ¸öÎÊÌâ,·½Ê½Í¬pingÒ»Ñù,ËùÒÔÎÒÃDz»×öÑÝʾ. Ê®¾Å)CAP_IPC_LOCK 14 (ÔÚÔÊÐíËø¶¨ÄÚ´æÆ¬¶Î)
rootºÍÆÕͨÓû§¶¼¿ÉÒÔÓÃmlockÀ´Ëø¶¨ÄÚ´æ,Çø±ðÊÇroot²»ÊÜulimitϵÄËø¶¨ÄÚ´æ´óСÏÞÖÆ,¶øÆÕͨÓû§»áÊܵ½Ó°Ïì. ²âÊÔ³ÌÐòÈçÏÂ:
1 #include
2 #include
4 int main(int argc, char* argv[]) 5 {
6 int array[2048]; 7
8 if (mlock((const void *)array, sizeof(array)) == -1) { 9 perror(\10 return -1; 11 } 12
13 printf(\14 array, sizeof(array)); 15 16
17 if (munlock((const void *)array, sizeof(array)) == -1) { 18 perror(\19 return -1; 20 } 21
22 printf(\23 array, sizeof(array)); 24
25 return 0; 26 }
gcc mlock.c -o mlock
Çл»µ½ÆÕͨÓû§,ÎÒÃÇ¿´µ½mlockÊDz»ÊÜÏÞÖÆ ulimit -a
max locked memory (kbytes, -l) unlimited ÎÒÃÇÔËÐгÌÐò ./mlock
success to lock stack mem at: 0xbfd94914, len=8192 success to unlock stack mem at: 0xbfd94914, len=8192 ÎÒÃǽ«ÏÞÖÆ¸ÄΪ1KB,ÔÙ´ÎÔËÐгÌÐò,ÈçÏÂ: ulimit -l 1 ./mlock
mlock: : Cannot allocate memory
Çл»µ½rootÓû§,½«CAP_IPC_LOCKÄÜÁ¦ÊÚȨ¸ømlock²âÊÔ³ÌÐò,ÈçÏÂ: setcap cap_ipc_lock=eip /tmp/mlock ÓÃÆÕͨÓû§ÔÙ´ÎÔËÐгÌÐò,Ö´Ðгɹ¦: ./mlock
success to lock stack mem at: 0xbfec1584, len=8192 success to unlock stack mem at: 0xbfec1584, len=8192 ¶þÊ®)CAP_IPC_OWNER 15 (ºöÂÔIPCËùÓÐȨ¼ì²é)
Õâ¸öÄÜÁ¦¶ÔÆÕͨÓû§ÓÐ×÷ÓÃ,Èç¹ûÓÃrootÓû§´´½¨¹²ÏíÄÚ´æ(shmget),ȨÏÞΪ600,¶øÆÕͨÓû§²»ÄܶÁÈ¡¸Ã¶Î¹²ÏíÄÚ´æ.
ͨ¹ýCAP_IPC_OWNER¿ÉÒÔÈÃÆÕͨÓû§µÄ³ÌÐò¿ÉÒÔ¶ÁÈ¡/¸ü¸Ä¹²ÏíÄÚ´æ. ÎÒÃÇÓÃÏÂÃæµÄ³ÌÐò´´½¨¹²ÏíÄÚ´æ¶Î,²¢Ð´Èë0xdeadbeefµ½¹²ÏíÄÚ´æ¶ÎÖÐ.
1 #include
9 void error_out(const char *msg) 10 {
11 perror(msg);
12 exit(EXIT_FAILURE);
13 } 14 15
16 int main (int argc, char *argv[]) 17 {
18 key_t mykey = 12345678; 19
20 const size_t region_size = sysconf(_SC_PAGE_SIZE); 21 int smid = shmget(mykey, region_size, IPC_CREAT|0600); 22 if(smid == -1)
23 error_out(\24
25 void *ptr;
26 ptr = shmat(smid, NULL, 0); 27 if (ptr == (void *) -1)
28 error_out(\29 u_long *d = (u_long *)ptr; 30 *d = 0xdeadbeef;
31 printf(\32
33 return 0; 34 }
gcc test.c -o test -lrt
ÎÒÃÇÓÃrootÓû§À´Ö´Ðб¾³ÌÐò,´´½¨¹²ÏíÄÚ´æ,ÈçÏÂ: /tmp/test
ipc mem 0xdeadbeef ²é¿´µ±Ç°µÄ¹²ÏíÄÚ´æ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch 0x00bc614e 458752 root 600 4096 0 Ð޸ijÌÐò,½«*d = 0xdeadbeef;¸ÄΪ*d = 0xffffffff; ÔÙ±àÒë,ÓÃÆÕͨÓû§ÔËÐгÌÐò,ÈçÏÂ: gcc test.c -o test -lrt su - test /tmp/test
shmget: Permission denied
ÎÒÃÇ¿´µ½Ã»ÓÐȨÏÞ¸ü¸Ä¹²ÏíÄÚ´æ.
ÓÃrootÓû§°ÑCAP_IPC_OWNERÄÜÁ¦ÊÚȨ¸øtest³ÌÐò,ÈçÏÂ: setcap cap_ipc_owner=eip /tmp/test
ÔÙ´ÎÓÃÆÕͨÓû§ÔËÐгÌÐòtest,¸ü¸Ä¹²ÏíÄÚ´æ,ÈçÏÂ: /tmp/test
ipc mem 0xffffffff
status ÎÒÃÇ¿´µ½Ð޸ijɹ¦,µ«ÒªËµÃ÷CAP_IPC_OWNER²»ÄÜÈýø³Ì/³ÌÐòɾ³ý/ÍÑÀë¹²ÏíÄÚ´æ ¶þʮһ)CAP_SYS_MODULE 16 (ÔÊÐíÆÕͨÓû§²åÈëºÍɾ³ýÄÚºËÄ£¿é)
ÓÉÓÚÆÕͨÓû§²»ÄܲåÈë/ɾ³ýÄÚºËÄ£¿é,¶øCAP_SYS_MODULE¿ÉÒÔ°ïÖúÆÕͨÓû§×öµ½Õâµã ÀýÈç,Óû§test²åÈëÄÚºËÄ£¿énvram /sbin/modprobe nvram
FATAL: Error inserting nvram (/lib/modules/2.6.38.4/kernel/drivers/char/nvram.ko): Operation not permitted
ϵͳÌáʾȨÏÞ²»×ã.
ÎÒÃǰÑCAP_SYS_MODULEÄÜÁ¦ÊÚȨ¸ømodprobe³ÌÐò,ÈçÏÂ: setcap cap_sys_module=eip /sbin/modprobe ÔÙÓÃÆÕͨÓû§¼ÓÔØÄÚºËÄ£¿é,ÈçÏÂ: /sbin/modprobe nvram lsmod |grep nvram
nvram 3861 0 ÎÒÃÇ¿´µ½¿ÉÒÔ¼ÓÔØ.
ͬÑùÎÒÃÇ¿ÉÒÔ½«CAP_SYS_MODULEÊÚȨ¸ørmmod³ÌÐò,ÈÃÆä¿ÉÒÔɾ³ýÄ£¿é,ÈçÏÂ: setcap cap_sys_module=eip /sbin/rmmod su - test
/sbin/rmmod nvram lsmod |grep nvram
¶þÊ®¶þ)CAP_SYS_RAWIO 17 (ÔÊÐíÓû§´ò¿ª¶Ë¿Ú,²¢¶ÁÈ¡Ð޸Ķ˿ÚÊý¾Ý,Ò»°ãÓÃioperm/ioplº¯Êý)
iopermÖ»ÓеͶ˵Ä[0-0x3ff] I/O¶Ë¿Ú¿É±»ÉèÖÃ,ÇÒÆÕͨÓû§²»ÄÜʹÓÃ.
iopl¿ÉÒÔÓÃÓÚËùÓеÄ65536¸ö¶Ë¿Ú,Òò´ËiopermÏ൱ÓÚioplµ÷ÓõÄÒ»¸ö×Ó¼¯.
ÏÂÃæµÄ³ÌÐòÊ×ÏÈÉèÖÃ0x3FF¶Ë¿ÚµÄ¶ÁдȨÏÞ,È»ºó¶Á³öÔÏȵÄÖµ,È»ºó½«ÔÖµµÄLSB·×ª²¢Ð´»Ø¶Ë¿Ú,²¢Ôڴ˶ÁÈ¡¶Ë¿ÚÖµ.
1 #include
4 #define PORT_ADDR 0x3FF 5
6 int main(void) 7 {
8 int ret;
9 char port_val; 10
11 /*set r/w permission of all 65536 ports*/ 12 ret = iopl(3); 13 if(ret < 0){
14 perror(\15 return 0; 16 } 17
18 port_val = inb(PORT_ADDR);
19 printf(\20
21 /*reverse the least significant bit */ 22
23 outb(port_val^0x01, PORT_ADDR); 24 port_val = inb(PORT_ADDR);
25 printf(\26
27 /*set r/w permission of all 65536 ports*/ 28
29 ret = iopl(0); 30 if(ret < 0){
31 perror(\32 return 0; 33 }
34 return 0; 35 }
±àÒë:
gcc iopl.c -o iopl
ÆÕͨÓû§ÔËÐÐiopl³ÌÐò,ÌáʾûÓÐȨÏÞ. /tmp/iopl
iopl set error: Operation not permitted
¸ø³ÌÐòioplÊÚȨCAP_SYS_RAWIOÄÜÁ¦,´ËʱÆÕͨÓû§¿ÉÒÔÖ´ÐÐiopl³ÌÐò,ÈçÏÂ: setcap cap_sys_rawio=eip /tmp/iopl su - test /tmp/iopl
Original value of port 0x3ff is : 01 Current value of port 0x3ff is : 00 /tmp/iopl
Original value of port 0x3ff is : 00 Current value of port 0x3ff is : 01
¶þÊ®Èý)CAP_SYS_CHROOT 18 (ÔÊÐíʹÓÃchroot()ϵͳµ÷ÓÃ)
ÆÕͨÓû§²»ÄÜͨ¹ýchrootϵͳµ÷Óøü¸Ä³ÌʽִÐÐʱËù²Î¿¼µÄ¸ùĿ¼λÖÃ,¶øCAP_SYS_CHROOT¿ÉÒÔ°ïÖúÆÕͨÓû§×öµ½ÕâÒ»µã. ÆÕͨÓû§Ê¹ÓÃchroot,ÈçÏÂ: /usr/sbin/chroot / /bin/bash
/usr/sbin/chroot: cannot change root directory to /: Operation not permitted ͨ¹ýrootÊÚȨCAP_SYS_CHROOTÄÜÁ¦¸øchroot³ÌÐò,ÈçÏÂ: capset cap_sys_chroot=eip /usr/sbin/chroot ÆÕͨÓû§ÔÙ´ÎÓÃchrootÇл»¸ùĿ¼,ÈçÏÂ: /usr/sbin/chroot / /bin/sh sh-3.2$
¶þÊ®ËÄ)CAP_SYS_PTRACE 19 (ÔÊÐí¸ú×ÙÈκνø³Ì)
ÆÕͨÓû§²»Äܸú×ÙÈκνø³Ì,²»°üÀ¨Ëü×Ô¼ºµÄ½ø³Ì,¶øCAP_SYS_PTRACE¿ÉÒÔ°ïÖúÆÕͨÓû§¸ú×ÙÈκνø³Ì.
Çл»µ½ÆÕͨÓû§,¸ú×ÙPID1µÄ½ø³Ì. strace -p 1
attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted
Çл»µ½rootÓû§,½«CAP_SYS_PTRACEÄÜÁ¦ÊÚȨ¸østrace³ÌÐò,ÓÃÓÚ¸ú×Ù½ø³Ì,ÈçÏÂ: setcap cap_sys_ptrace=eip /usr/bin/strace Çл»µ½ÆÕͨÓû§,¸ú×ÙPID1µÄ½ø³Ì,ÈçÏÂ: strace -p 1
Process 1 attached - interrupt to quit
select(11, [10], NULL, NULL, {3, 771381}) = 0 (Timeout)
time(NULL) = 1304348451 stat64(\fstat64(10, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
stat64(\select(11, [10], NULL, NULL, {5, 0}) = 0 (Timeout)
time(NULL) = 1304348456
¶þÊ®Îå)CAP_SYS_PACCT 20 (ÔÊÐíÅäÖýø³Ì¼ÇÕÊprocess accounting)
ÒªÍê³É½ø³Ì¼ÇÕÊ,Òª±£Ö¤ÓÐдÈëÎļþµÄȨÏÞ,ÕâÀïÎÒÃǽ«½ø³Ì¼Ç¼дÈëµ½/home/test/log/psacct. mkdir /home/test/log/
touch /home/test/log/psacct
³ÌÐòͨ¹ýacctº¯Êý,½«½ø³ÌµÄ¼ÇÕÊдÈëµ½Ö¸¶¨ÎļþÖÐ,Èç¹ûacctº¯ÊýµÄ²ÎÊýΪNULL,Ôò¹Ø±Õ½ø³Ì¼ÇÕÊ.
1 #include
7 int ret;
8 ret = acct(\ 9 if(ret < 0){
10 perror(\11 return 0; 12 }
13 system(\14 acct(NULL); 15 if(ret < 0){
16 perror(\17 return 0; 18 }
19 return 0;
20 }
gcc psacct.c -o psacct ./psacct
acct on error: Operation not permitted
¸øpsacct³ÌÐòÊÚȨCAP_SYS_PACCTÄÜÁ¦,ÈçÏÂ: setcap cap_sys_psacct /home/test/psacct
×¢ÒâÕâÀïµÄÄÜÁ¦ÊÇsys_psacct,¶ø²»ÊÇsys_pacct »Øµ½ÆÕͨÓû§,Ö´ÐÐpsacct ./psacct total 24
drwxr-xr-x 2 test test 4096 2011-05-02 13:28 log -rw-r--r-- 1 test test 64 2011-05-02 13:25 pacct -rwxr-xr-x 1 test test 6590 2011-05-02 13:31 psacct -rw-r--r-- 1 test test 314 2011-05-02 13:31 psacct.c
ÎÒÃÇ¿´µ½ÒѾִÐгɹ¦,ÏÂÃæÎÒÃÇÔÙ¿´Ï½ø³Ì¼Ç¼,ÈçÏÂ: lastcomm -f /home/test/log/pacct
ls test pts/0 0.03 secs Mon May 2 13:33
¶þÊ®Áù)CAP_SYS_ADMIN 21 (ÔÊÐíÖ´ÐÐϵͳ¹ÜÀíÈÎÎñ,Èç¹ÒÔØ/Ð¶ÔØÎļþϵͳ,ÉèÖôÅÅÌÅä¶î,¿ª/¹Ø½»»»É豸ºÍÎļþµÈ)
ÏÂÃæÊÇÆÕͨÓû§ÓµÓÐÏà¹Ø¹ÜÀíȨÏ޵IJâÊÔ 1)¸ü¸ÄÖ÷»úÃû
setcap cap_sys_admin=eip /bin/hostname su - test
hostname test2 hostname test2
2)¹ÒÔØ/Ð¶ÔØÎļþϵͳ
ÕâÀïÎÒÃÇ×¢Òâ,ϵͳµÄmountÃüÁî²»ÄÜ×öÕâ¸öÊÔÑé,ÒòΪ³ÌÐòÖÐ×öÁËÅжÏ,Èç¹û²»ÊÇrootÓû§ÇëÍ˳ö.ËùÒÔÎÒÃÇÓÃmount()º¯ÊýÀ´Íê³ÉÕâ¸öÊÔÑé,³ÌÐòÈçÏÂ:
1 #include
6 int ret;
7 ret = mount(\AL, NULL); 8 if(ret < 0){
9 perror(\10 return 0; 11 }
12 return 0; 13 }
ÓÃÆÕͨÓû§±àÒëÔËÐÐ:
gcc mounttest.c -o mounttest ./mounttest
mount error: Operation not permitted
ÎÒÃÇ¿´µ½ÆÕͨÓû§²»ÄÜÍê³Émount²Ù×÷,¶øCAP_SYS_ADMIN¿ÉÒÔ°ïÖúÆÕͨÓû§Íê³É¸Ã²Ù×÷,ÈçÏÂ:
setcap cap_sys_admin=eip /home/test/mounttest Çл»µ½ÆÕͨÓû§,Ö´ÐÐmounttest³ÌÐò,ÈçÏÂ: ./mounttest
cat /proc/mounts ÂÔ
/dev/sda1 /mnt ext3 rw,relatime,errors=remount-ro,barrier=0,data=writeback 0 0 umountºÍmountÒ»Ñù,ÎÒÃÇÔÚÕâÀï²»×öÑÝʾ. 3)swapon/swapoff
ÆÕͨÓû§²»ÄܽøÐÐswapon/swapoff²Ù×÷,¶øCAP_SYS_ADMIN¿ÉÒÔ°ïÖúÆÕͨÓû§Íê³Éswapon/swapoff²Ù×÷,ÈçÏÂ:
dd if=/dev/zero of=/tmp/testdb bs=10M count=1 1+0 records in 1+0 records out
10485760 bytes (10 MB) copied, 0.164669 s, 63.7 MB/s /sbin/mkswap /tmp/testdb
Setting up swapspace version 1, size = 10481 kB
no label, UUID=0ff46dc8-781c-4c3f-81b3-fe860f74793e /sbin/swapon /tmp/testdb
swapon: /tmp/testdb: Operation not permitted
ÎÒÃÇ¿´µ½swapon²Ù×÷±»¾Ü¾ø,ÕâÀïÎÒÃǶÔswapon½øÐÐÊÚȨ,ÈçÏÂ: setcap cap_sys_admin /sbin/swapon ÆÕͨÓû§ÔÙ´Îswapon,ÈçÏÂ: /sbin/swapon /tmp/testdb /sbin/swapon /sbin/swapon -s
Filename Type Size Used Priority /dev/sda6 partition 7815584 0 -1 /tmp/testdb file 10236 0 -2
ÎÒÃÇ¿´µ½swapon²Ù×÷³É¹¦.ÒòΪswapoffÊÇswaponµÄÈíÁ´½Ó,ËùÒÔ¿ÉÒÔÖ±½Óswapoffµô½»»»·ÖÇø,ÈçÏÂ:
/sbin/swapoff /tmp/testdb /sbin/swapon -s
Filename Type Size Used Priority
/dev/sda6 partition 7815584 0 -1 ls -l /sbin/swapoff
lrwxrwxrwx 1 root root 6 2009-08-23 07:49 /sbin/swapoff -> swapon ¶þÊ®Æß) CAP_SYS_BOOT 22 (ÔÊÐíÆÕͨÓÃʹÓÃreboot()º¯Êý)
ÕâÀïÎÒÃÇÎÞ·¨ÓÃrebootÃüÁîÀ´×ö²âÊÔ,ÒòΪrebootÃüÁî×öÁËÅжÏ,Ö»ÔÊÐíroot(UID=0)µÄÓû§¿ÉÒÔʹÓÃ.
ÎÒÃÇÓÃÏÂÃæµÄ³ÌÐò½øÐвâÊÔ.
1 #include
5 sync();
6 return reboot(RB_AUTOBOOT); 7 }
±àÒë:
gcc reboot1.c -o reboot1 ./reboot1
ÕâʱϵͳûÓÐÖØÆô.
ÎÒÃDz鿴³ÌÐòµÄ·µ»ØÂë,ÕâÀïÊÇ255,˵Ã÷³ÌÐòûÓÐÔËÐгɹ¦. echo $? 255
ÎÒÃÇÓÃCAP_SYS_BOOTÄÜÁ¦Ê¹reboot1³ÌÐò¿ÉÒÔ±»ÆÕͨÓû§ÖØÆô,ÈçÏÂ: setcap cap_sys_boot=eip /home/test/reboot1 ÓÃÆÕͨÓû§ÔÙÊÔÔËÐÐreboot1,ÈçÏÂ: reboot1
´Ëʱϵͳ±»ÖØÆôÁË.
¶þÊ®°Ë)CAP_SYS_NICE 23(ÔÊÐíÌáÉýÓÅÏȼ¶,ÉèÖÃÆäËü½ø³ÌµÄÓÅÏȼ¶) ¶ÔÓÚÆÕͨÓû§³ÌÐòµÄNICEÓÅÏȼ¶,²»Äܳ¬¹ýulimit¶ÔËüµÄÏÞÖÆ,ÈçÏÂ: nice -n -5 ls
nice: cannot set niceness: Permission denied
¶øCAP_SYS_NICE¿ÉÒÔ°ïÖúÆÕͨÓû§ÉèÖÃÒ»¸öÏëÒªµÄÒ»¸öÈÎÒâÓÅÏȼ¶. setcap cap_sys_nice=eip /usr/bin/nice Çл»µ½ÆÕͨÓû§,Ö¸¶¨ÓÅÏȼ¶,ÈçÏÂ: nice -n -5 ls
log mnt mount.c mounttest pacct psacct psacct.c reboot1 reboot1.c test ÆÕͨÓû§Ò²²»ÄܸøÖ¸¶¨½ø³ÌÖ¸¶¨NICEÓÅÏȼ¶,¶øCAP_SYS_NICEÒ²¿ÉÒÔ×öµÄ,ÈçÏÂ: renice -5 2255
renice: 2255: setpriority: Operation not permitted setcap cap_sys_nice=eip /usr/bin/renice renice -5 2255
2255: old priority 0, new priority -5
ÎÒÃÇÉõÖÁ¿ÉÒÔÓÃCAP_SYS_NICEÀ´Ö¸¶¨ÊµÊ±ÓÅÏȼ¶
chrt -f 50 ls
chrt: failed to set pid 0's policy: Operation not permitted ¸ø/usr/bin/chrtÃüÁîÊÚȨCAP_SYS_NICEÄÜÁ¦,ÈçÏÂ: setcap cap_sys_nice=eip /usr/bin/chrt Çл»µ½ÆÕͨÓû§,ÈçÏÂ: chrt -f 50 ls
log mnt setulimit setulimit.c
ÎÒÃÇÒ²¿ÉÒÔÖ¸¶¨ËüµÄCPUÇ׺ÍÐÔ,ÈçÏÂ: taskset -p 1 2255
pid 2255's current affinity mask: 1
sched_setaffinity: Operation not permitted failed to set pid 2255's affinity.
¸ø/usr/bin/tasksetÃüÁîÊÚȨCAP_SYS_NICEÄÜÁ¦,ÈçÏÂ: setcap cap_sys_nice=eip /usr/bin/taskset
Çл»µ½ÆÕͨÓû§,ÔÙ´ÎÔËÐÐtaskset,¿ÉÒԳɹ¦µÄÉèÖÃCPUÇ׺ÍÐÔ taskset -p 1 2255
pid 2255's current affinity mask: 1 pid 2255's new affinity mask: 1
¶þÊ®¾Å) CAP_SYS_RESOURCE 24 ºöÂÔ×ÊÔ´ÏÞÖÆ ÆÕͨÓû§²»ÄÜÓÃsetrlimit()À´Í»ÆÆulimitµÄÏÞÖÆ
ÎÒÃÇÓÃÏÂÃæµÄ³ÌÐò½øÐвâÊÔ,ÆÕͨÓû§ÊÇÎÞ·¨ÐÞ¸ÄRLIMIT_STACK(¶ÑÕ»´óС)µÄ.ÈçÏÂ:
1 #include
12 main (int argc, char *argv[]) 13 {
14 int r = 0;
15 struct rlimit rl; 16
17 getrlimit (RLIMIT_STACK,&rl); 18
19 printf(\20 (u_long) rl.rlim_max); 21
22 rl.rlim_max = rl.rlim_max+1;
23 r = setrlimit (RLIMIT_STACK, &rl); 24 if (r){
25 perror(\26 return -1; 27 } 28
29 printf(\30 return 0; 31 }
gcc setulimit.c -o setulimit
ÎÒÃÇÏÈÀ´²é¿´µ±Ç°µÄÏÞÖÆ,ÕâÀïÊÇ10MB,ÈçÏÂ: ulimit -H -s 10240
./setulimit
crrent hard limit is 10485760 setrlimit: Operation not permitted
ÎÒÃǸøsetulimit³ÌÐòÒÔCAP_SYS_RESOURCEµÄÄÜÁ¦,ÈçÏÂ: setcap cap_sys_resource=eip /home/test/setulimit
ÓÃÆÕͨÓû§ÔÙ´ÎÔËÐгÌÐò,ÒѾ¿ÉÒÔͨ¹ýsetrlimit()É趨³¬¹ýÏÞ¶îÁË,ÈçÏÂ: ./setulimit
crrent hard limit is 10485760 limit set to 10485762
ͬÑùÎÒÃÇÒ²¿ÉÒÔÓÃCAP_SYS_RESOURCEÄÜÁ¦Ê¹³ÌÐò³¬³ö´ÅÅÌÏÞ¶î,ÈçÏÂ: quotacheck -avug quotaon -avug edquota -u test
Filesystem blocks soft hard inodes hard
/dev/sda7 0 3 5 0 0
mkdir /export/test
chown -R test.test /export/test/
Çл»µ½ÆÕͨÓû§,ÓÃddÃüÁî²úÉú3MBµÄÎļþ,ÕâÃ÷ÏÔ³¬¹ýÁË5kbµÄÏÞÖÆ,ÈçÏÂ: su - test
dd if=/dev/zero of=/export/test/test bs=1M count=3 sda7: warning, user block quota exceeded. sda7: write failed, user block limit reached. dd: writing `test': Disk quota exceeded 1+0 records in 0+0 records out
4096 bytes (4.1 kB) copied, 0.0117371 s, 349 kB/s
soft 0 ÊÚȨCAP_SYS_RESOURCEÄÜÁ¦¸ø/bin/ddÃüÁî,ÈçÏÂ: setcap cap_sys_resource=eip /bin/dd
ÔÙ´ÎÓÃÆÕͨÓû§ÔËÐÐddÃüÁî,¼´¿ÉÒÔ³¬¹ý5kbµÄÏÞ¶îÁË. su - test
dd if=/dev/zero of=test bs=1M count=3 sda7: warning, user block quota exceeded. 3+0 records in 3+0 records out
3145728 bytes (3.1 MB) copied, 0.423662 s, 7.4 MB/s ÈýÊ®)CAP_SYS_TIME 25(ÔÊÐí¸Ä±äϵͳʱÖÓ) ÆÕͨÓû§²»ÄܸıäϵͳʱÖÓ,ÈçÏÂ: date -s 2012-01-01
date: cannot set date: Operation not permitted Sun Jan 1 00:00:00 EST 2012
CAP_SYS_TIME¿ÉÒÔ°ïÖúÆÕͨÓû§¸Ä±äϵͳʱÖÓ,ÈçÏÂ: setcap cap_sys_time=eip /bin/date
Çл»µ½ÆÕͨÓû§Ôٴθıäʱ¼ä,·¢ÏÖÒѾ¿ÉÒԸıäÁË su - test
date -s 2012-01-01
Sun Jan 1 00:00:00 EST 2012 date
Sun Jan 1 00:00:02 EST 2012
Èýʮһ)CAP_SYS_TTY_CONFIG 26(ÔÊÐíÅäÖÃTTYÉ豸) ÎÒÃÇÏÂÃæÓÃvhangup()º¯ÊýÀ´¹ÒÆðµ±Ç°µÄtty ³ÌÐòÈçÏÂ:
1 #include
4 int main () 5 {
6 int r;
7 r=vhangup(); 8 if (r){
9 perror (\10 }
11 return 0; 12 }
gcc vhup.c -o vhup ./vhup
vhanguo: Operation not permitted
ÎÒÃǸøvhup³ÌÐòÉ趨CAP_SYS_TTY_CONFIGÄÜÁ¦,ÈçÏÂ: setcap cap_sys_tty_config=eip /home/test/vhup
ÔÙ´ÎÓÃÆÕͨÓû§Ö´ÐгÌÐòvhup,tty±»¹ÒÆð,ÈçÏÂ: ./vhup
´Ëʱµ±Ç°tty±»¹ÒÆð.
ÈýÊ®¶þ) CAP_MKNOD 27 (ÔÊÐíʹÓÃmknodϵͳµ÷ÓÃ)
ÆÕͨÓû§²»ÄÜÓÃmknod()À´´´½¨É豸Îļþ,¶øCAP_MKNOD¿ÉÒÔ°ïÖúÆÕͨÓû§×öµ½ÕâÒ»µã,ÈçÏÂ:
mknod /tmp/tnod1 c 1 5
mknod: `/tmp/tnod1': Operation not permitted setcap cap_mknod=eip /bin/mknod
Çл»µ½ÆÕͨÓû§,ÔÙ´ÎÓÃmknodÃüÁî´´½¨É豸Îļþ,ÈçÏÂ: mknod /tmp/tnod1 c 1 5 ls -l /tmp/tnod1
crw-r--r-- 1 test test 1, 5 2012-01-01 00:31 /tmp/tnod1 ÈýÊ®Èý) CAP_LEASE 28(ÔÊÐíÔÚÎļþÉϽ¨Á¢×â½èËø)
ϵͳµ÷ÓÃfcntl()¿ÉÒÔÓÃÓÚ×â½èËø£¬´Ëʱ²ÉÓõĺ¯ÊýÔÐÍÈçÏ£º int fcntl(int fd, int cmd, long arg);
Óë×â½èËøÏà¹ØµÄ cmd ²ÎÊýµÄȡֵÓÐÁ½ÖÖ£ºF_SETLEASE ºÍ F_GETLEASE¡£Æäº¬ÒåÈçÏÂËùʾ£º
F_SETLEASE£º¸ù¾ÝÏÂÃæËùÃèÊöµÄ arg ²ÎÊýÖ¸¶¨µÄÖµÀ´½¨Á¢»òÕßɾ³ý×âÔ¼£º
F_RDLCK£ºÉèÖöÁ×âÔ¼¡£µ±Îļþ±»ÁíÒ»¸ö½ø³ÌÒÔдµÄ·½Ê½´ò¿ªÊ±£¬ÓµÓиÃ×âÔ¼µÄµ±Ç°½ø³Ì»áÊÕµ½Í¨Öª
F_WRLCK£ºÉèÖÃд×âÔ¼¡£µ±Îļþ±»ÁíÒ»¸ö½ø³ÌÒÔ¶Á»òÕßдµÄ·½Ê½´ò¿ªÊ±£¬ÓµÓиÃ×âÔ¼µÄµ±Ç°½ø³Ì»áÊÕµ½Í¨Öª
F_UNLCK£ºÉ¾³ýÒÔǰ½¨Á¢µÄ×âÔ¼
F_GETLEASE£º±íÃ÷µ÷Óýø³ÌÓµÓÐÎļþÉÏÄÄÖÖÀàÐ͵ÄËø£¬ÕâÐèҪͨ¹ý·µ»ØÖµÀ´È·¶¨£¬·µ»ØÖµÓÐÈýÖÖ£ºF_RDLCK¡¢F_WRLCKºÍF_UNLCK£¬·Ö±ð±íÃ÷µ÷Óýø³Ì¶ÔÎļþÓµÓжÁ×â½è¡¢Ð´×â½è»òÕ߸ù±¾Ã»ÓÐ×â½è
ij¸ö½ø³Ì¿ÉÄÜ»á¶ÔÎļþÖ´ÐÐÆäËûһЩϵͳµ÷ÓÃ(±ÈÈç OPEN() »òÕß TRUNCATE())£¬Èç¹ûÕâЩϵͳµ÷ÓÃÓë¸ÃÎļþÉÏÓÉ F_SETLEASE ËùÉèÖõÄ×â½èËøÏà³åÍ»£¬Äں˾ͻá×èÈûÕâ¸öϵͳµ÷Óã»
ͬʱ£¬ÄÚºË»á¸øÓµÓÐÕâ¸ö×â½èËøµÄ½ø³Ì·¢Ðźţ¬¸æÖª´ËÊ¡£ÓµÓдË×â½èËøµÄ½ø³Ì»á¶Ô¸ÃÐźŽøÐз´À¡£¬Ëü¿ÉÄÜ»áɾ³ýÕâ¸ö×â½èËø£¬Ò²¿ÉÄÜ»á¼õ¶ÌÕâ¸ö×â½èËøµÄ×âÔ¼£¬´Ó¶ø¿ÉÒÔʹµÃ¸ÃÎļþ¿ÉÒÔ±»ÆäËû½ø³ÌËù·ÃÎÊ¡£
Èç¹ûÓµÓÐ×â½èËøµÄ½ø³Ì²»ÄÜÔÚ¸ø¶¨Ê±¼äÄÚÍê³ÉÉÏÊö²Ù×÷£¬ÄÇôϵͳ»áÇ¿ÖÆ°ïËüÍê³É¡£Í¨¹ý F_SETLEASE ÃüÁ arg ²ÎÊýÖ¸¶¨Îª F_UNLCK ¾Í¿ÉÒÔɾ³ýÕâ¸ö×â½èËø¡£ ²»¹Ü¶Ô¸Ã×â½èËø¼õ¶Ì×âÔ¼»òÕ߸ɴàɾ³ýµÄ²Ù×÷Êǽø³Ì×ÔÔ¸µÄ»¹ÊÇÄÚºËÇ¿ÆÈµÄ£¬Ö»Òª±»×èÈûµÄϵͳµ÷Óû¹Ã»Óб»·¢³ö¸Ãµ÷ÓõĽø³Ì½â³ý×èÈû£¬ÄÇôϵͳ¾Í»áÔÊÐíÕâ¸öϵͳµ÷ÓÃÖ´ÐС£ ¼´Ê¹±»×èÈûµÄϵͳµ÷ÓÃÒòΪijЩÔÒò±»½â³ý×èÈû£¬µ«ÊÇÉÏÃæ¶Ô×â½èËø¼õ¶Ì×âÔ¼»òÕßɾ³ýÕâ¸ö¹ý³Ì»¹ÊÇ»áÖ´Ðеġ£ Ô´³ÌÐòÈçÏÂ:
1 #define _GNU_SOURCE 2
3 #include
4 #include
7 static void show_lease(int fd) 8 {
9 int res; 10
11 res = fcntl(fd, F_GETLEASE); 12 switch (res) {
13 case F_RDLCK:
14 printf(\15 break; 16 case F_WRLCK:
17 printf(\18 break; 19 case F_UNLCK:
20 printf(\21 break; 22 default:
23 printf(\24 break; 25 } 26 } 27
28 int main(int argc, char **argv) 29 {
30 int fd, res; 31
32 fd = open(argv[1], O_RDONLY); 33 if (fd == -1) {
34 perror(\35 return 1; 36 } 37
38 res = fcntl(fd, F_SETLEASE, F_WRLCK); 39 if (res == -1) {
40 perror(\41 return 1; 42 } 43
44 show_lease(fd); 45
46 if (flock(fd, LOCK_SH) == -1) {
47 perror(\
48 return 1; 49 } 50
51 show_lease(fd); 52
53 return 0; 54 }
±àÒë:
gcc fcntl.c -o fcntl
ÎÒÃÇʹÓÃÆÕͨÓû§ÔÚ/etc/passwdÎļþÉϽ¨Á¢×â½èËø,ÓÉÓÚÆÕͨÓû§Ã»ÓÐ/etc/passwdÉϽ¨×â½èËøµÄȨÏÞ,¹Ê¶ø±¨´í,ÈçÏÂ: su - test
/tmp/fcntl /etc/passwd
Can't set lease: Permission denied ×¢:
ÆÕͨÓû§¿ÉÒÔÔÚ×Ô¼ºµÄÎļþÉÏ(owner)½¨Á¢×â½èËø. ÊÚȨlease¸ø/tmp/fcntlÎļþ,ÈçÏÂ: setcap cap_lease=eip /tmp/fcntl
ÔÙ´ÎÔËÐÐ/tmp/fcntl,¿ÉÒÔ½¨Á¢×â½èËøÁË,ÈçÏÂ: /tmp/fcntl /etc/passwd Write lease Write lease
ÈýÊ®ËÄ)CAP_SETFCAP 31 (ÔÊÐíÔÚÖ¸¶¨µÄ³ÌÐòÉÏÊÚȨÄÜÁ¦¸øÆäËü³ÌÐò) ÀýÈçÎÒÃÇÈÃÆÕͨÓû§Ò²ÄÜÓÃsetcap¸øÆäËü³ÌÐòÊÚȨ,ÈçÏÂ: setcap CAP_SETFCAP=eip /usr/sbin/setcap su - test
setcap CAP_SETPCAP=eip /bin/ls getcap /bin/ls /bin/ls = cap_setpcap+eip ÈýÊ®Áù)ÆäËüµÄÄÜÁ¦ CAP_AUDIT_WRITE CAP_AUDIT_CONTROL CAP_MAC_OVERRIDE CAP_MAC_ADMIN CAP_SYSLOG
ÕâÎå×éÖ»ÄÜÉæ¼°µ½syslog,audit,macµÈ°²È«Ä£¿é,ÒÔºóרÃÅ¶ÔÆä½øÐзÖÎö. ÈýÊ®Æß)×ܽá:
CAP_CHOWN 0 ÔÊÐí¸Ä±äÎļþµÄËùÓÐȨ
CAP_DAC_OVERRIDE 1 ºöÂÔ¶ÔÎļþµÄËùÓÐDAC·ÃÎÊÏÞÖÆ CAP_DAC_READ_SEARCH 2 ºöÂÔËùÓжԶÁ¡¢ËÑË÷²Ù×÷µÄÏÞÖÆ CAP_FOWNER 3 ÒÔ×îºó²Ù×÷µÄUID,¸²¸ÇÎļþµÄÏÈǰµÄUID CAP_FSETID 4 È·±£ÔÚÎļþ±»Ð޸ĺó²»ÐÞ¸Äsetuid/setgidλ CAP_KILL 5 ÔÊÐí¶Ô²»ÊôÓÚ×Ô¼ºµÄ½ø³Ì·¢ËÍÐźÅ
CAP_SETGID 6 ÔÊÐí¸Ä±ä×éID CAP_SETUID 7 ÔÊÐí¸Ä±äÓû§ID
CAP_SETPCAP 8 ÔÊÐíÏòÆäËü½ø³Ì×ªÒÆÄÜÁ¦ÒÔ¼°É¾³ýÆäËü½ø³ÌµÄÈÎÒâÄÜÁ¦(Ö»ÏÞinit½ø³Ì) CAP_LINUX_IMMUTABLE 9 ÔÊÐíÐÞ¸ÄÎļþµÄ²»¿ÉÐÞ¸Ä(IMMUTABLE)ºÍÖ»Ìí¼Ó(APPEND-ONLY)ÊôÐÔ
CAP_NET_BIND_SERVICE 10 ÔÊÐí°ó¶¨µ½Ð¡ÓÚ1024µÄ¶Ë¿Ú CAP_NET_BROADCAST 11 ÔÊÐíÍøÂç¹ã²¥ºÍ¶à²¥·ÃÎÊ(δʹÓÃ)
CAP_NET_ADMIN 12 ÔÊÐíÖ´ÐÐÍøÂç¹ÜÀíÈÎÎñ£º½Ó¿Ú¡¢·À»ðǽºÍ·ÓɵÈ. CAP_NET_RAW 13 ÔÊÐíʹÓÃÔʼ(raw)Ì×½Ó×Ö CAP_IPC_LOCK 14 ÔÊÐíËø¶¨¹²ÏíÄÚ´æÆ¬¶Î CAP_IPC_OWNER 15 ºöÂÔIPCËùÓÐȨ¼ì²é CAP_SYS_MODULE 16 ²åÈëºÍɾ³ýÄÚºËÄ£¿é CAP_SYS_RAWIO 17 ÔÊÐí¶Ôioperm/ioplµÄ·ÃÎÊ CAP_SYS_CHROOT 18 ÔÊÐíʹÓÃchroot()ϵͳµ÷Óà CAP_SYS_PTRACE 19 ÔÊÐí¸ú×ÙÈκνø³Ì
CAP_SYS_PACCT 20 ÔÊÐíÅäÖýø³Ì¼ÇÕÊ(process accounting)
CAP_SYS_ADMIN 21 ÔÊÐíÖ´ÐÐϵͳ¹ÜÀíÈÎÎñ£º¼ÓÔØ/Ð¶ÔØÎļþϵͳ¡¢ÉèÖôÅÅÌÅä¶î¡¢¿ª/¹Ø½»»»É豸ºÍÎļþµÈ.
CAP_SYS_BOOT 22 ÔÊÐíÖØÐÂÆô¶¯ÏµÍ³
CAP_SYS_NICE 23 ÔÊÐíÌáÉýÓÅÏȼ¶£¬ÉèÖÃÆäËü½ø³ÌµÄÓÅÏȼ¶ CAP_SYS_RESOURCE 24 ºöÂÔ×ÊÔ´ÏÞÖÆ CAP_SYS_TIME 25 ÔÊÐí¸Ä±äϵͳʱÖÓ
CAP_SYS_TTY_CONFIG 26 ÔÊÐíÅäÖÃTTYÉ豸 CAP_MKNOD 27 ÔÊÐíʹÓÃmknod()ϵͳµ÷Óà CAP_LEASE 28 ÔÊÐíÔÚÎļþÉϽ¨Á¢×â½èËø
CAP_SETFCAP 31 ÔÊÐíÔÚÖ¸¶¨µÄ³ÌÐòÉÏÊÚȨÄÜÁ¦¸øÆäËü³ÌÐò