油炸小可爱|黑客大神谈一谈Linux与suid提权

前几天我在代码审计知识星球里发表了一个介绍nmap利用interactive模式提权的帖子:
# 进入nmap的交互模式nmap --interactive# 执行sh , 提权成功!sh
但具体实施的时候会遇到很多有趣的问题 , 我们来详细研究一下 。
suid提权说到这个话题 , 我们不得不先介绍一下两个东西:
? suid提权是什么
? nmap为什么可以使用suid提权
通常来说 , Linux运行一个程序 , 是使用当前运行这个程序的用户权限 , 这当然是合理的 。 但是有一些程序比较特殊 , 比如我们常用的ping命令 。
ping需要发送ICMP报文 , 而这个操作需要发送Raw Socket 。 在Linux 2.2引入CAPABILITIES前 , 使用Raw Socket是需要root权限的(当然不是说引入CAPABILITIES就不需要权限了 , 而是可以通过其他方法解决 , 这个后说) , 所以你如果在一些老的系统里ls -al $(which ping) , 可以发现其权限是-rwsr-xr-x , 其中有个s位 , 这就是suid:
root@linux:~# ls -al /bin/ping-rwsr-xr-x 1 root root 44168 May 7 2014 /bin/ping
suid全称是Set owner User ID up on execution 。 这是Linux给可执行文件的一个属性 , 上述情况下 , 普通用户之所以也可以使用ping命令 , 原因就在我们给ping这个可执行文件设置了suid权限 。
设置了s位的程序在运行时 , 其Effective UID将会设置为这个程序的所有者 。 比如 , /bin/ping这个程序的所有者是0(root) , 它设置了s位 , 那么普通用户在运行ping时其Effective UID就是0 , 等同于拥有了root权限 。
这里引入了一个新的概念Effective UID 。 Linux进程在运行时有三个UID:
? Real UID 执行该进程的用户实际的UID
? Effective UID 程序实际操作时生效的UID(比如写入文件时 , 系统会检查这个UID是否有权限)
? Saved UID 在高权限用户降权后 , 保留的其原本UID(本文中不对这个UID进行深入探讨)
通常情况下Effective UID和Real UID相等 , 所以普通用户不能写入只有UID=0号才可写的/etc/passwd;在suid的程序启动时 , Effective UID就等于二进制文件的所有者 , 此时Real UID就可能和Effective UID不相等了 。
有的同学说某某程序只要有suid权限 , 就可以提权 , 这个说法其实是不准确的 。 只有这个程序的所有者是0号或其他super user , 同时拥有suid权限 , 才可以提权 。
nmap为什么可以用suid提权常用nmap的同学就知道 , 如果你要进行UDP或TCP SYN扫描 , 需要有root权限:
$ nmap -sU targetYou requested a scan type which requires root privileges.QUITTING!$ nmap -sS 127.0.0.1You requested a scan type which requires root privileges.QUITTING!
原因就是这些操作会用到Raw Socket 。
有时候你不得不使用sudo来执行nmap , 但在脚本调用nmap时sudo又需要tty , 有可能还要输入密码 , 这个限制在很多情况下会造成一些不必要的麻烦 。
所以 , 有一些管理员会给nmap加上suid权限 , 这样普通用户就可以随便运行nmap了 。
当然 , 增加了s位的nmap是不安全的 , 我们可以利用nmap提权 。 在nmap 5.20以前存在interactive交互模式 , 我们可以通过这个模式来提权:
油炸小可爱|黑客大神谈一谈Linux与suid提权星球里@A11risefor*师傅提到 , nmap 5.20以后可以通过加载自定义script的方式来执行命令:
补充一个 , --interactive应该是比较老版本的nmap提供的选项 , 最近的nmap上都没有这个选项了 , 不过可以写一个nse脚本 , 内容为os.execute('/bin/sh') , 然后nmap --script=shell.nse来提权
的确是一个非常及时的补充 , 因为现在大部分的nmap都是没有interactive交互模式了 。


推荐阅读