授权与合规声明本文全部操作对象均为自建隔离靶场本机容器或隔离虚拟机涉及安全测试的环节必须以取得合法授权为前提。未经授权的渗透测试违反《中华人民共和国网络安全法》与《刑法》相关条款须承担相应法律责任。本文只讲环境配置、版本对照与靶场隔离不含任何攻击步骤、利用载荷与绕过手法请勿将文中环境指向任何非自有系统。一、普通用户凭什么能改自己的密码一个刚接触 Linux 权限的人很容易被这样一件事绊住改密码用的那个程序普通用户敲得动而它最终要改写的那份账目文件普通用户按九位权限去推本来是没有写权限的。两边一对照结论似乎是这件事不该发生。可它每天都在发生。先把这个现象放一放问一个更靠前的问题一个程序在跑起来的那一刻用的是什么身份多数情况下这个问题的答案很平淡——谁启动它它就用谁的身份。你敲一条命令跑起来的进程就是你你够得着什么它就近乎够得着什么。这是所有人的默认预期也正是为什么有人看到普通用户能改密码时会觉得哪里不对。但有另外一类程序不是这样。它在被执行的那一刻把身份换掉换成一个不是启动者的身份。于是你会看到一种奇怪的分裂启动它的是你跑起来的它却不完全是你。你在终端里的身份没变而进程那一侧已经换了一个人。那九个普通的权限位管的是谁能读这份文件、谁能写这份文件、谁能执行这份文件。它回答得很清楚但它回答不了执行之后进程变成了谁。这个之后的问题由另外三个位回答。三位不在那九位里却和那九位躺在同一串模式位上本文讲的就是它们。1.1 本文讲什么不讲什么把边界一次说清后面就不用来回交代本文讲这三位叫什么、在输出里长什么样、谁改得动、系统层面怎么让它不起作用。本文不讲任何拿到这个身份之后做什么。这个位之所以与安全相关恰恰因为它是一枚执行时换身份的开关而怎么利用它属于另一类内容本文一个字都不写。本文也不做某个具体行为合不合法的判断只讲机制与读法具体情形需要专业判断。1.2 与基础读法的分工九位怎么分成三组、三类用户各读哪三位、目录上的那一位和文件上的那一位有什么差别——这一整套基础读法本文不重复只在这里给一句那部分写在讲权限基础的另一篇里。本文从九位之外这一处往下走。你已经在基础读法里学过的本文接着往下讲的九个字符怎么分组、每组属于谁九位之外的三个位叫什么、由谁管辖目录上的位与文件上的位有什么不同输出里s为什么有时是大写S改完不生效怎么分层定位谁改得动这三个位、系统怎么让它失效这张表列出来是为了让你知道本文的起点在哪不是让你把九位重学一遍。本章可以带走的一句判断程序跑起来之后是谁看的不是那九位而是另外三个位。二、九个位之外还有三个位2.1 官方逐字这三位和九位由同一处管辖先说最要紧的一句。截至 2026-10-13POSIX.1-2024 的chmod()在描述段开头写的是这句逐字不改Thechmod()function shall changeS_ISUID,S_ISGID, [XSI]S_ISVTX, and the file permission bits of the file named by the pathname pointed to by the path argument to the corresponding bits in the mode argument.这句话把三件事一次交代完了。第一改变权限这件事一次改的就是一整组S_ISUID、S_ISGID、S_ISVTX三位加上九个普通权限位。第二它们由同一个函数管辖不是外挂上去的。第三这三位的名字早就写进规范里了S_ISUID、S_ISGID、S_ISVTX。换句人话说你平时看的那九位只是这串模式位的后九位前面还有三位一直都在。它们不是高级权限或隐藏权限只是平时用不到显示出来时你又只看那九位所以很容易当它不存在。2.2 三个位的正式名字把三位排成一张表放在管辖它们的接口这一列里好记位八进制值正式名字本文S_ISUID4000set-user-ID / setuid bit本文主线之一S_ISGID2000set-group-ID / setgid bit本文主线之一S_ISVTX1000sticky bit也叫 restricted deletion flag只提一句不展开这张表里第一列是规范给出的名字第二列的八进制值来自本机man 1 chmodmacOS / CommandLineTools——手册把它写成「4000 (the setuid bit)」「2000 (the setgid bit)」「1000 (the sticky bit)」三行。这三个数字有用因为你在命令行里写权限时这三个位就落在第一个数字上而九位落在后面两位上。理解了这一点看到chmod后面跟四个数字就不奇怪了。2.3t位只提一句第三位S_ISVTX官方名是 sticky bitPOSIX 的ls里还给过它另一个名字叫restricted deletion flag。它有自己的一摊用途本文不展开——原因很实在它在不同对象上管的事和本文讲的执行时换身份没有关系混在一起讲只会把这条主线搅乱。你只要记住三位里有一位叫S_ISVTX另有用途就够了。本章可以带走的一句权限不是九个位是三个特殊位 九个普通位而且它们由同一个接口一起改。三、怎么在输出里认出这两个位3.1 先看chmod手册怎么说s你敲权限时用的那个字母s官方是怎么定义的本机man 1 chmodmacOS在perm符号那一节写得很短s— 「The set-user-ID-on-execution and set-group-ID-on-execution bits.」t— 「The sticky bit.」请注意s这句定义里的一个细节它是两个位共用一个小写字母。“set-user-ID-on-execution” 和 “set-group-ID-on-execution” 写在同一条定义里靠你在前面写u还是g来区分——写us动的是属主那一位写gs动的是属组那一位。这就是为什么两个 s 位这个说法是成立的它们是两个位共用一个显示字符。还有一点值得留意官方给这几个位起的名字里都带着-on-execution。这不是修饰词而是这个位的全部含义所在——它只在被执行这件事上起作用。这一层第四章要单独讲。3.2 再看ls手册怎么说s和S执行ls -l之后权限字段的第一个位置有时是一个小写s有时是一个大写S。很多人在这里卡住明明都是设了那个位为什么涨出来两个不同的字母截至 2026-10-13POSIX.1-2024 的ls对长格式输出字符的逐字定义是这两句s「If inowner permissions, the fileis executable and set-user-ID mode is set. If ingroup permissions, the file is executable and set-group-ID mode is set.」S「If inowner permissions, the fileis not executable and set-user-ID mode is set. If ingroup permissions, the file is not executable and set-group-ID mode is set.」两句只差一个词is executable与is not executable。也就是说s与S的分工由属主的那一位执行权限到底有没有决定位设了执行位也在 → 显示小写s这个位真的会在执行时生效位设了执行位不在 → 显示大写S这个位设了也白设因为执行这件事不会发生。同一个第三位位置上也有一对小写/大写规范里写作t与T它管的是S_ISVTX与另一个权限位的组合按本章的分工点到即止。把第一个位置可能出现的字符放在一张表里一次看清出现在权限字段第一个位置的字符POSIXls的逐字依据一眼读法-None of the attributes of ‘S’, ‘s’, ‘T’, ‘t’, or ‘x’ applies.属主没有执行位也没有设这个位xThe file is executable or the directory is searchable.只有执行位没设特殊位sthe file is executable and set-user-ID mode is set位设了执行位也在Sthe file is not executable and set-user-ID mode is set位设了执行位不在t/T管S_ISVTX本文不展开本文只要求你认得出来读懂这张表之后动作其实很窄只看权限字段最左边那一个字符。下面这条也是只读的放在这里是为了让你把注意力收窄到一个位置上⚠️代码待验证# 只看权限字段最左边的第一位示意写法ls-ldemo.txt读的时候眼睛只停在最左一位它是-、x还是s/S。这一个位置同时背着两件事——属主那三格里的执行位和 setuid 位两个信息挤在同一格上所以它也是最容易看错的一位。3.3 本机实测同一个文件三种样子规范怎么说不算数得自己在机器上看一眼。下面这块是在同一台机器、同一个普通文件上依次做的三次改动每次都只看不改别的然后在ls -l里读权限字段2026-10-13 本机实测chmod755demo.txtls-ldemo.txt# 权限字段-rwxr-xr-xchmodus demo.txtls-ldemo.txt# 权限字段-rwsr-xr-xchmodu-x demo.txtls-ldemo.txt# 权限字段-rwSr-xr-x三行并排看正好把 3.2 的规范口径演了一遍命令ls -l的权限字段对上了哪一句规范chmod 755-rwxr-xr-x属主位是x还没有设特殊位chmod us-rwsr-xr-x属主位是x位也设了 → 小写schmod u-x-rwSr-xr-x属主位不再是x位还在 → 大写S注意第三行chmod u-x动的是执行位没有动那个特殊位可是它把显示从s变成了S。这一个细节把 3.2 的判据说透了——显示是小写还是大写看的从来不是特殊位本身而是它旁边那位执行权限到底在不在。本章可以带走的一句权限字段第一个位置的小写s和大写S说的都是位设了区别只在执行位在不在。四、「执行时换身份」这件事本身4.1 换身份发生在哪一刻第三章一直在说这个名字里带着 -on-execution现在把它拆开。本机man 1 chmodmacOS对八进制 4000 这一条写的是4000 (the setuid bit). Executable files with this bit set will run with effective uid set to the uid of the file owner.一句话讲完了整件事带上这个位的可执行文件跑起来的时候会以一个取自文件属主的有效身份运行。三个要素都在里面可执行文件——这个位只对被执行这件事有意义will run with——它作用在跑起来的那一刻effective uid set to the uid of the file owner——换上去的那个身份是文件属主不是启动者。对照着看更清楚一次执行进程跑起来时的身份取自哪普通程序启动它的那个人的身份带这个位的程序文件属主的身份effective uid set to the uid of the file owner所以那个开头想不通的现象机制上其实是这样的改密码的程序属于第二行。启动它的是普通用户跑起来的那一段却不是普通用户而是文件属主——于是它能碰的文件也就跟着变了。普通用户能改密码不是因为他忽然有了权限而是因为那一刻在跑的不是他。4.2 为什么这套机制是安全相关的到这里为什么它和安全有关这个问题也就有答案了而且答案不在任何用法里因为这是一枚执行即换身份的开关。一次普通的执行身份是延续的一次带位的执行身份是被替换的。身份一旦被替换能碰什么就整体跟着变了——这不是多了某一项权限而是换了一整套账。正因为它换的是整套账系统才不会让它随便设、随便生效。后面两章讲的正是这三道约束谁能改它第五章、系统怎么让它不起作用第六章。本文到此为止只回答身份从哪来。换上去之后能做哪些事不在本文范围之内这一点第一章已经声明过这里再重申一次读到换身份三个字就往下想那我能拿它做什么正是本文不打算接的那条线。本章可以带走的一句这个位不是多给了一项权限而是执行那一刻换了一整套身份。五、谁能改这个位改得动还是改不动5.1 官方逐字给的两条限定能不能设这件事规范里写得很具体。截至 2026-10-13POSIX.1-2024 的chmod()有两条限定逐字如下。第一条关于你有没有资格改If the effective user ID of the process does not match the owner of the file and the process does not have appropriate privileges, thechmod()function shall fail.翻成人话你不是这份文件的属主又没有相应特权这次改动会失败。这条把改动权限收在了属主或有特权者这一处和chmod手册里那句「Only the owner of a file or the super-user is permitted to change the mode of a file.」是同一件事的两种说法。第二条更值得留意关于你改得动但系统会替你改回去If the calling process does not have appropriate privileges, and if the group ID of the file does not match the effective group ID or one of the supplementary group IDs and if the file is a regular file, bitS_ISGID(set-group-ID on execution) in the file’s mode shall be cleared upon successful return fromchmod().这条长句里的关键动作是最后四个词shall be cleared。它说的是调用者没有特权、文件的属组又和调用者的组对不上、而且对象是普通文件时这个位会在chmod()成功返回的那一刻被清掉。这条限定解释了一类很容易困惑的现象命令明明成功了位却不在。因为你有没有权限敲这条命令和这个位留不留得住是两件事——前者管你能不能发起这次改动后者管内核会不会在此基础上再动手。第五章讲的谁能改其实是这两层叠在一起的。本章所有观察都是只读的先给最省事的一组⚠️代码待验证ls-ldemo.txt# 文件那一侧位在不在、它旁边的执行位在不在stat-f%Sp %Sudemo.txt# 同一条记录的另一半模式与属主一次读出两行都只是问不是改。先把位在不在、属主是谁问清楚再谈它为什么改不动——顺序反过来会在是没权限和是被清掉之间来回猜。5.2 本机实测一次没给出结论的尝试规范说归规范机器上跑出来什么样是另一回事。这里做了一次对本机目录的观察把命令和看到的东西如实放在下面2026-10-13 本机实测mkdirdemo_dirchmodgs demo_dirls-lddemo_dir# 权限字段drwxr-xr-xstat-f%Spdemo_dir# 模式40755chmod2755demo_dirls-lddemo_dirstat-f%Spdemo_dir# 模式仍是40755如实说这次观察到的结果你做的事命令结果你在输出里看到的chmod gs一个目录返回码 0没报错ls -ld的权限字段里没有schmod 2755同一个目录同上stat -f %Sp的模式仍是40755两条路都试过了一条用符号写法gs一条用八进制写法2755第一个数字 2 就是S_ISGID。两种写法返回都没报错但权限字段里都没有出现那个位。这里必须把话说死因为它比看到了什么更重要本次实测环境是 macOS APFS 工作沙箱只能说明在这台机器、这个文件系统、这个目录上我没观察到 SGID 位生效。它不足以支撑任何平台结论——不能说 macOS 一律如此更不能反过来说别的平台如何。一次实测能给的是这一次看到了什么要说这个平台如何需要的是在不同对象、不同文件系统上的交叉验证本文没有做因此也不写。如果把它当成一次示范它能示范的恰恰是实测也可能给不出结论命令跑完了、返回是 0、看起来一切正常可你要的那个位就是没出现在输出里。这时候正确的动作不是替它编一个解释而是把观察原样记下来标明它管不到哪里。5.3 把未取到一手依据的那半句也标出来顺带交代一个常见的说法。你可能在别处读到过对目录设上S_ISGID目录里新建的文件会继承这个目录的组。对这句话本文的处理是很多发行版与手册把目录上的这一位描述成组继承但本文未取到一手规范原文因此不把它写成结论只作为一个常说但未核的说法标在这里。这句话到底在你的平台上成不成立需要按 5.2 的办法自己看一次输出——而不是背下来。本章可以带走的一句改权限要过两道门——先看你是不是属主或有特权再看内核会不会在你成功之后把位清掉。配套资料获取第五章这张改得动 / 改不动 / 观察到什么的对照我连同本文用到的手册原文逐字摘录做成了一份权限特殊位速查页放在资料包里扫码即可获取六、两个让它不起作用的开关6.1 官方逐字nosuid到底是什么第五章讲的是位留不留得住这一章讲另一种情形位好好地留在那里可它不生效。这两种情形经常被混为一谈而弄混的代价是你会对着一串明明带着s的权限字段得出错误结论。先把官方的原话拿出来。本机man 8 mountmacOS对nosuid这个挂载选项给的逐字定义是Do not allow set-user-identifier or set-group-identifier bits to take effect.一个词一个词读过去重点落在take effect上——“生效”。它说的是不让这两个位起作用而不是把它们清掉。这个选项写起来是什么样用一段示意看就够了这里只是写法示意不是要你去挂载任何东西⚠️代码待验证# 挂载时带的选项里可以有这么一个开关示意不是完整命令# -o nosuid# 它的效果逐字就是上面那句# Do not allow set-user-identifier or set-group-identifier bits to take effect.6.2 为什么这一字之差值得单独说这句话极其容易被写错、读错。把它和第五章那条shall be cleared摆在一起对比差别就清楚了层面官方原话对位做了什么你还能在ls -l里看到s吗第五章的内核清理bitS_ISGID… shall be cleared把位清掉位不在了看不到第六章的挂载选项nosuidDo not allow … bits to take effect位还在只是不生效看得到第二行是这篇里最值得带走的一处区分你执行ls -l权限字段上的s照常显示但这个位在这次挂载下不产生任何作用。如果你把nosuid理解成会把位清掉那么下一次你在一个ls -l里看到s、却怎么也想不通它为什么不生效时就会绕很大的弯。正确的读法是位是是什么挂载选项是允不允许它起作用。前者写在文件的模式里后者写在文件系统怎么被挂上这一层。两处是两本账。6.3 还有一层开关本文未核除了挂载选项这一处容器那一侧还有它自己的一套默认策略会影响到这个位在容器内起不起作用。这一层本文未核到官方原文所以只把位置指出来不给任何默认值也不作结论如果你在容器里做这类观察先把宿主机上看到的和容器里看到的分开记。顺着这个思路第六章其实给的是同一条方法论看到s先别急着下结论——先问它在哪一层被允许生效。是文件的模式位写的还是挂载选项拦的还是别的层另有取舍一层一层问下去比背一条结论可靠。本章可以带走的一句nosuid是让位不生效不是把位清掉——位还在ls -l照样看得见。七、总结三张账放在一起读7.1 一页总结把全文三个位、三层约束并成一张表看什么在哪看由谁定什么会让它不起作用位设了没有ls -l权限字段的第一个位置文件的模式位本身第五章的内核清理位被清掉位会不会生效同一个位置看它是s还是S属主那一格的执行位在不在执行位不在显示成S位形同虚设这次挂载允不允许它生效挂载选项文件系统怎么被挂上nosuid位在但不生效三行是三层从上到下越来越往外第一行在文件自己身上第二行在同一份文件的另一个位上第三行已经出了文件、到了它挂在哪儿这一层。这正是本文从第一章就选定的读法——同一个s问它的层次不同结论可能完全不同。7.2 一份只读自查单下面这组动作全部是只读的不改变任何环境状态。你不是在改权限只是在问这台机器上现在是什么样⚠️代码待验证ls-ldemo.txt# 读权限字段第一个位置是 s、S 还是别的statdemo.txt# 读模式看三个特殊位在不在ls-lddemo_dir# 对象的位看目录自己那一行三条命令各管一件事。顺手把这是不是一个我自己建的靶场文件也问一遍——本文讲的所有观察都应该发生在自建隔离靶场里这句话在开头声明过这里再落一次地。7.3 收口回到标题那个问题普通用户为什么能改密码。现在你手上的答案不该是一句口诀而是一条链权限不是九个位是三个特殊位加九个普通位其中执行时换身份这一位不落在九位里它能生效与否还取决于文件自己另一位、以及它挂在哪儿。一层一层看下去那个不该发生的现象就站得住了。最后收一句边界。这一层之所以值得学是因为它是一枚能力开关——理解它才知道系统为什么要给它配nosuid这样的选项、为什么改它要受属主与特权的约束。而拿这个开关做什么本文全程没有写也不打算写。把机制读懂边界守住这本身就是这一层最该带走的东西。本章可以带走的一句看到s先别下结论先问它在哪一层被允许生效。配套资料获取第七章这张三层对照表做成了可以打印的一页纸连同一份只读自查命令清单和本文引用的手册原文出处放在资料包里扫码即可获取附表 A本文引用事实与官方出处对照表核验日期一律为2026-10-13标本机实测的两行命令与输出已留存于本批执行记录。手册原文逐字引用未作任何改写。#本文写出的事实一句官方一手出处核验日期本文位置1chmod()一次改的是S_ISUID、S_ISGID、[XSI]S_ISVTX三位加九个普通权限位由同一个函数管辖POSIX.1-2024chmod()DESCRIPTION 首句2026-10-13二、2.12s的符号定义the set-user-ID-on-execution and set-group-ID-on-execution bitst的定义the sticky bit本机man 1 chmodmacOS / CommandLineToolsperm符号节2026-10-13三、3.13八进制4000/2000/1000分别为 setuid / setgid / sticky 三位本机man 1 chmodmacOSMODES 节2026-10-13二、2.24带 setuid 位的可执行文件跑起来时 effective uid 取自文件属主本机man 1 chmodmacOSMODES 节 4000 一行2026-10-13四、4.15ls长格式s executable and set-user-ID mode is setS not executable and set-user-ID mode is setPOSIX.1-2024ls长格式输出字段定义2026-10-13三、3.26ls长格式-表示 ‘S’、‘s’、‘T’、‘t’、‘x’ 都不适用x表示文件可执行或目录可搜索同第 5 条2026-10-13三、3.27ls长格式的t与T管的是 restricted deletion flag本文只要求认得出、不展开同第 5 条[XSI] 部分2026-10-13三、3.28不是文件属主且无相应特权时chmod()会失败POSIX.1-2024chmod()DESCRIPTION2026-10-13五、5.19调用者无特权、文件属组对不上、且为普通文件时S_ISGID位会在chmod()成功返回时被清掉POSIX.1-2024chmod()DESCRIPTIONshall be cleared 句2026-10-13五、5.110nosuid挂载选项的定义Do not allow set-user-identifier or set-group-identifier bits to take effect本机man 8 mountmacOS2026-10-13六、6.111同一普通文件依次chmod 755/us/u-xls -l权限字段为-rwxr-xr-x/-rwsr-xr-x/-rwSr-xr-x本机实测macOS沙箱内2026-10-13 本机实测三、3.312目录执行chmod gs返回 0与chmod 2755后ls -ld与stat -f %Sp均未显示 SGID 位模式仍40755本机实测macOS APFS 工作沙箱2026-10-13 本机实测五、5.2本篇仍标待验证的条目Linux 上目录S_ISGID使新建文件继承目录的组的一手规范原文本批只取到 macOSchmod(1)对s位的定义与 POSIXchmod()的位管辖未取到该行为语义的一手规范原文因此本文只写很多发行版与手册这样描述不作结论五、5.3。macOS APFS 下特殊位到底会怎样本批只观察到文件上的 setuid 位可以设置并显示第 11 条、目录上的 setgid 位未观察到生效第 12 条。两者是不同对象不能互相外推也不足以支撑平台结论五、5.2。容器默认是否保留 setuid 位、相关选项的默认值本文未核到官方原文只指出这一层另有默认策略不给任何默认值六、6.3。附表 B术语速查表术语一句话解释易混点特殊位九位普通权限位之外的三位S_ISUID、S_ISGID、S_ISVTX不是额外权限是同一串模式位的前三位S_ISUIDsetuid可执行文件带上它执行时 effective uid 取自文件属主名字里的 -on-execution 不是修饰词是它的全部含义S_ISGIDsetgid同一位用于属组那一格对普通文件还有会被清除的限定同一个文件上还可能被内核清掉与你设没设是两回事S_ISVTXsticky官方名 sticky bitls里另叫 restricted deletion flag用途与执行时换身份无关本文不展开权限字段第一个位置ls -l输出里属主那三格的第一格它同时承担执行位和setuid 位两件事的显示s与S小写表示位设了且执行位在大写表示位设了但执行位不在显示大小写由执行位决定不由特殊位决定effective uid进程实际以谁的身份运行的那个用户 ID与谁启动了这个进程不是同一件事us/gs符号写法给属主那格 / 属组那格设这个位一个字母s管两个位靠前面的u/g区分八进制写法四位数字第一位是特殊位后三位是九位权限看到四个数字不必惊讶第一个数字就是特殊位nosuid挂载选项让这两个位不生效是不生效不是清掉位还在ls -l照样显示写在最后这篇用到的资料写这篇文章时我把 POSIX.1-2024 对chmod()与ls的逐字定义、本机man 1 chmod与man 8 mount里的原话一条条翻出来核过又对着自己在沙箱里跑出来的三行权限字段比对了一遍顺手也整理了几份配套的东西靶场环境对照表DVWA、upload-labs 在 Windows / macOS / Linux 三平台的可行性与推荐路径Web 安全学习路线图从基础打牢到安全管理四个阶段各学什么常用靶场清单每个靶场练什么、适合哪个阶段资料是我自己整理的放在下面这个码上扫码即可获取添加时备注「靶场」优先通过。拿到之后建议先看环境对照表那一份——先把你手上这套环境里位设了没有、它在哪一层被允许生效这两件事分开记清楚比背一条结论要省下不少时间。