1. 整体设计思路与方案选型1.1 为什么还要搭一个WooYun漏洞库环境你要是这两年才入行安全,可能对WooYun这个名字有点陌生,但只要你翻过不少漏洞分析报告,或者在某站看过那种“某某漏洞影响XXX”的历史记录,大概率绕不开这个库。WooYun平台曾经是国内漏洞报告圈子里的一个重要存在,大量白帽子在上面提交过真实漏洞案例。后来平台方向调整,原站点停止服务,但那些漏洞数据并没有消失,很多安全研究者把当时公开的漏洞库内容整理、打包、保留了下来。现在你在一些公开渠道还能找到它的源码包和数据包,用它们搭一套本地环境,纯粹是为了技术研究、漏洞分析和安全教学。有人可能会问,平台都没了,我扒拉一堆旧漏洞出来有什么用?我个人的看法是,漏洞库的价值从来不是“当下是否还通用”,而是“历史漏洞为什么存在、怎么被挖掘、怎么被修复”。尤其对新人来说,WooYun里的很多案例是活生生的从0到1的漏洞发现过程,远比你在靶场里照着答案打一遍要更有代入感。比如某个SQL注入案例,报告里写了参数怎么构造、报错怎么回显、为什么这个过滤能被绕过,这种完整链路在普通漏洞库和CVE描述里是很难看到的。也正是这个原因,我当时给新人做内训时,第一件事就是让他们先把一套WooYun漏洞库环境搭起来,先改代码、再查库、最后复现报告里的某个漏洞,以“倒推”的方式去理解漏洞原理。那为什么还需要“环境搭建”这一步?因为WooYun的数据包不是给你一个现成的Web界面,它就像一堆玩具零件,需要把运行环境、数据库、代码目录全部拼起来。网上虽然流传过一些打包好的虚拟机镜像,但那种镜像一来不敢乱用——你也不知道里面有没有被人塞过别的东西,二来不利于理解系统的依赖关系。自己动手搭一遍,既能获得一套干净可控的漏洞检索系统,又能把LNMP或者LAMP这套经典架构从配置到调优走一遍,训练价值是双份的。1.2 搭建方案选型:从系统到Web架构的取舍搭建WooYun漏洞库环境,本质上就是搭一个“古老的PHP应用”。因为这代码的历史包袱不小,它依赖的PHP版本、数据库版本都比较老,和我们现在新装的PHP 8.x环境兼容性很差,所以我做方案选型时第一件事就是把“现代化环境”从脑海里抹掉,老老实实模拟2012年前后的经典Web环境。先看操作系统。我当时用的是CentOS,但现在说实话CentOS 7已经进入维护尾声了,新装系统我建议直接用Debian或者Ubuntu的LTS版本。数据包本身和操作系统关联不大,PHP版本才是大头。WooYun源码主要依赖PHP 5.x,我在实际测试时发现,放到PHP 5.6环境下最稳,MySQL用5.6或5.7都行。如果你非要挑战一下,把它跑在PHP 7.0以上也不是完全不能跑,但各种通知报错、函数弃用警告会冒出来一堆,有些函数(比如旧版MySQL扩展相关接口)在高版本PHP里直接没了,处理起来很闹心,没必要给自己找不痛快。Web服务器选Nginx还是Apache?我的建议是,能用Apache就别折腾Nginx,原因很简单:WooYun源码里大量使用,开头就带参数的URL跳转和rewrite规则,Apache的mod_rewrite处理起来更省心,而且老PHP和Apache的搭配是“原配”,兼容性问题最少。不过如果你对Nginx更熟,也没问题,多加几行rewrite规则的事。我当时图省事用的Apache,后面讲具体配置时你就能感受到,几乎不用为路径分发操心。数据库方面,我强调一下千万别想着用MariaDB 10.x的高版本直接导入。WooYun的SQL文件里有些字段定义和老语法,在高版本MariaDB的严格模式下可能直接报错中断导入。我实际遇到过一次字段默认值导致的导入错误,后来换了MySQL 5.7才顺利导入。所以你在选型时,要么用MySQL 5.7,要么在导入前把SQL文件里的严格模式限制绕过去——这个后面我细说。整体方案选型结论就是:Debian/Ubuntu + Apache + PHP 5.6 + MySQL 5.7,这套组合最稳,问题最少。如果你想折腾,也可以全容器化,但我个人觉得本地虚拟机或云主机直接装,比Docker更直观,因为之后维护数据、改代码都要方便一些。2. 核心细节解析与实操要点2.1 环境准备:软件版本选择与关键理由我这里直接给出我实测稳定的一套软件版本组合,供你参考:组件推荐版本选择理由操作系统Ubuntu 16.04/18.04或Debian 9/10对PHP 5.6的软件源支持好,依赖安装省心Web服务器Apache 2.4对老PHP兼容性强,rewrite规则无需额外折腾PHP5.6.xWooYun源码依赖的旧函数和语法在5.6中运行最顺MySQL5.7.x对老SQL文件的兼容性比MySQL 8.x好,不会因为默认值报错PHP扩展mysql扩展(非mysqli)、curl、gd源码里部分功能模块需要调用这些扩展你可能会问,PHP 5.6不是早就停止维护了吗?装它会不会有问题?这想法没错,但请你换个角度想:你是在搭一个“历史的漏洞库系统”,不是在给生产环境写新业务。PHP 5.6老归老,在本地或内网环境跑这套检索系统,安全风险是可控的,而且源码本身就是这样设计的。真要让它跑在PHP 7上,你反而要花大量时间改代码,改完还不一定能保证功能完整。做安全研究的人应该明白,工具链的“新”不等于“合适”,稳定与还原才是目标。另外,如果你用的Ubuntu源里默认没有PHP 5.6,可以手动添加一个软件源来装。我用的是某个第三方维护的PHP版本源,里面5.6、7.0这些老版本都有。添加源之后直接apt-get install就能装上,省去自己编译的麻烦。自己编译PHP 5.6也不是不行,但为了搭个漏洞库环境去编译一遍PHP,步骤有点多,而且依赖容易缺,不值得。新手尽量直接用软件源。2.2 配置文件里的几个关键命门WooYun源码解压后,最核心的配置文件主要涉及数据库连接和站点访问路径。先看数据库配置,通常路径是“/includes/config.php”之类,你需要修改其中数据库地址、用户名、密码三个参数,确保和本地建的库对得上。再说说PHP配置,里面有几个开关直接影响系统能不能正常跑。第一个是short_open_tag,老代码经常用“”这类短标签方式写PHP,而新版本PHP默认把short_open_tag关掉了,不打开的话页面内容会直接当成纯文本输出,整个界面就是乱的,看起来像代码没执行一样。第二个是display_errors,建议临时打开,搭环境阶段免不了要调试各种报错,把错误显示出来能省很多排查时间。第三个是allow_url_open的配置,如果你后面要分析WooYun里的历史URL或字段,有些地方需要它,但出于安全考虑搭完建议关掉。Apache那边主要注意DocumentRoot指向源码目录,同时开启mod_rewrite模块。WooYun源码里有些URL路径是动态拼接的,不开rewrite的话,点击某些分类标签会找不到页面。另外还要设置一下AllowOverride All,否则源码里的.htaccess规则不会生效。数据库导入的核心是SQL文件。WooYun数据包里的SQL文件通常很大,几百MB甚至上GB都很正常。刚解压的时候我还愣了一下,以为下载错了,后来才明白这就是完整漏洞库的数据量。用命令行导入比用phpMyAdmin靠谱,phpMyAdmin对超大文件导入容易超时或者内存溢出。命令行一条source命令完事,还能看到导入进度统计——有没有报错一目了然。这里特别提醒:如果你把SQL文件用文本编辑器打开过,建议重新从安装包解压一份出来再导入,否则编辑器可能会偷偷改编码或换行符,导入时冒出莫名其妙的错误。2.3 源码目录结构速览WooYun源码的目录结构不复杂,但搞清楚它能让之后的修改和维护效率提高不少。一般源码解压后主要包含三个部分:前端页面目录、接口目录、后台管理目录。前端页面就是普通用户看漏洞列表、漏洞详情的地方;接口目录处理搜索、筛选、分页这些动态请求;后台管理目录则是管理漏洞提交、审核、用户管理的入口。我在第一次搭建时犯过一个低级错误,以为源码里的所有目录都需要Web访问权限,于是把整个源码目录的权限都放开了。结果安全隐患也来了,后台管理脚本也暴露在Web端,连日志目录都能直接访问。正确做法是:只给Web服务运行所需的目录开放读写权限,其他目录保持默认,尤其是配置文件和包含敏感信息的脚本,绝不能允许Web端直接访问。做安全这一行,搭环境的时候就要有安全意识,不然你搭的是漏洞库,库本身反过来成了你的漏洞。3. 实操过程与核心环节实现3.1 一键准备依赖:源码包下载与目录规划先把依赖环境装好。我现在假设你用的是Ubuntu 16.04这个老版本,因为第三方源对老PHP的适配做得比较完整。如果用的是更新版本,有些源可能不太兼容,需要临时调整一下源地址。装依赖的先手顺序是:先更新软件源索引,然后装Apache和MySQL,最后通过第三方源装PHP 5.6全家桶,具体命令如下:sudo apt update sudo apt install -y apache2 mysql-server mysql-client sudo add-apt-repository ppa:ondrej/php sudo apt update sudo apt install -y php5.6 php5.6-mysql php5.6-gd php5.6-curl这里有个小坑要说明一下:不同环境下PHP 5.6包的名称可能稍有差异。有些源里叫“php5.6”,有些叫“php5”,装之前最好先用“apt-cache search php5”扫一遍看看实际包名。我就是一开始想当然直接安装,结果提示找不到包,后来搜索才发现装的是“php5.6-cli”“php5.6-common”这些带后缀的包。另外Apache的PHP模块也要注意,安装后需要确认“/usr/lib/apache2/modules”下有没有对应的libphp5.6模块文件,没有的话重启Apache时PHP不会生效。源码包下载后先别急着直接扔进网站目录。我习惯的做法是先在“/opt”下建一个目录统一存放原始包,解压一份作为“干净底稿”,再复制一份到网站目录做实际运行环境。这样之后改动出问题,还能从底稿快速还原,不用重新下载。尤其是数据包很大时,重新下载的成本挺高的,留个底稿就等于留了条退路。具体目录规划大概是这样的:/opt/wooyun_source/ # 原始包底稿,只读 /var/www/html/wooyun/ # 实际Web运行目录 /var/lib/mysql/wooyun/ # 数据库数据目录(默认即可)然后下载下来的SQL文件我习惯单独放一个“/opt/wooyun_sql/”目录,和源码解压目录分开,因为它的体积太大,放源码目录里备份时要一起打包,时间浪费不说,压缩包体积也大得离谱。3.2 数据库配置与数据导入全流程数据库的创建和导入这步是整个搭建过程中的核心,也是最容易翻车的地方。先用MySQL的root账号进入命令行,创建数据库和专用账号:CREATE DATABASE wooyun DEFAULT CHARACTER SET utf8; CREATE USER 'wooyun_user'@'localhost' IDENTIFIED BY 'your_password'; GRANT ALL PRIVILEGES ON wooyun.* TO 'wooyun_user'@'localhost'; FLUSH PRIVILEGES;字符集这里我强调一下,一定要显式指定UTF-8。WooYun数据包里虽然有些内容是GBK编码的,但整体框架用的是UTF-8,如果你的数据库默认字符集是latin1或别的,导入过程中会有大量中文乱码,后面改起来非常麻烦。数据导入用命令行执行:mysql -u wooyun_user -p wooyun < /opt/wooyun_sql/wooyun_full.sql执行前建议先看看SQL文件体积。如果超过200MB,导入时间可能长达几分钟到十几分钟,期间终端看起来像是“卡住”了,其实是在跑,不要急。为了观察导入进程,可以先看文件大小,然后用“time”命令包一层,估算执行耗时。我第一导的时候不知道,等了半天没反应,差点以为进程挂了。导入完成后别急着推进度,先检查一下数据的完整性。最简单的验证方法是登录MySQL,统计几张核心表的数据量。如果某张表和预期数量差太多,说明导入过程中有错误被跳过了。遇到这种情况,可以用下面这种方式精确排查:mysql -u wooyun_user -p --default-character-set=utf8 wooyun -e "SELECT COUNT(*) FROM vul_info;"表名不一定固定,你可以列一下所有表看看,再用“DESC表名”查看结构,确认关键字段是否齐全。如果存在半截导入的情况,最稳妥的做法是删库重建再导一次,而不是试图在现有数据基础上做增量修复。别问我怎么知道的,我第一次为了省时间想补数,到最后数据结构一团乱,反而浪费了更多功夫。3.3 Web端配置:让漏洞库跑起来数据库就绪以后,把源码复制到Web目录:sudo cp -r /opt/wooyun_source/. /var/www/html/wooyun/ sudo chown -R www-data:www-data /var/www/html/wooyun/然后修改源码中的数据库连接配置,把刚才建的库名、账号、密码填进去,同时确认连接端口默认是3306。我这里要专门提一个细节:源码里可能有多处数据库配置,不只有一个config文件,有时候是“include”“function”目录下也有,甚至有个别页面单独写了连接逻辑。你可以在源码目录里全局搜一下“mysql_connect”或“mysqli_connect”这样的关键词,把所有连接点都找出来一并改掉。接下来是Apache配置。在站点配置文件里把文档根目录指到“/var/www/html/wooyun”,并设置“AllowOverride All”,然后启用Apache的rewrite模块:sudo a2enmod rewrite sudo systemctl restart apache2访问前先确认PHP已经生效。在Web目录里放一个探针文件,写上“”,然后浏览器访问探针页面确认输出PHP版本信息。探针显示的PHP版本如果还是系统默认的7.x,说明Apache加载的PHP模块指错了,需要手动切换一下Apache可用的PHP模块优先级。这一步如果搞不定,后面的所有页面都会以源代码形式赤裸裸展示在浏览器里,这其实也是一种“漏洞”,但在你搭建漏洞库时,它就纯粹是烦人。如果探针页面正常,可以试着访问“http://你的服务器IP/wooyun/”,看到漏洞首页或搜索页面就算基本跑通了。到这里,一个可用的WooYun漏洞库环境就已经搭建完成,你可以开始检索历史漏洞、阅读报告原文、分析数据字段了。4. 常见问题与排查技巧实录4.1 页面纯文本输出:PHP没生效的经典症状搭建过程中最常见的现象就是打开页面看到一串串PHP源代码,而不是正常的网页。第一反应不用慌,这十有八九是PHP模块没加载成功,或者Apache没重启。排查步骤依次是:先用“php -v”确认命令行PHP版本正常,再用“apachectl -M”查看Apache加载的模块列表里有没有“php5_module”。没有的话,执行“a2dismod php7.x”和“a2enmod php5.6”,切换模块,再重启Apache。如果模块列表里根本没有PHP相关的模块,那说明安装阶段出了问题,用“apt-get install libapache2-mod-php5.6”补装一下。还有一种情况是部分页面有PHP代码输出,部分页面直接空白或显示源码,这多半是源码文件编码或语法错误引起的。可以去Apache错误日志里查一下,“tail -f /var/log/apache2/error.log”看看有没有PHP Parse error,有的话就得定位到对应文件,看是不是压缩包解压不完整导致文件残缺。4.2 数据库导入中断:是先查内存再谈优化几百MB的SQL文件导入到一半连接断开,这种事情我遇到不下三次。很多时候MySQL服务直接被系统OOM杀掉,或者导入过程中出现“Packet too large”这种报错,本质上是内存和包大小限制没调好。解决办法有两个方向。一个是调整MySQL配置,在配置文件里增加一行“max_allowed_packet=256M”,调高单次传输包大小的上限,然后重启MySQL。另一个是导入前把SQL文件拆成多个小文件,分批导入。不推荐一开始就拆,先试直接导入,大部分情况下只要内存够(建议2GB以上),一次导入就能过。内存实在不够的话,可以用“split”命令按行数拆分SQL文件,比如每5万行一个文件,再用循环导完。因为SQL文件里的INSERT语句比较大,按行数拆分基本不会从INSERT语句内部割开,安全系数比较高。导一个文件确认一个表的数量,这样出错也能精确定位是哪个文件的问题。4.3 列表页能看、详情页404:Rewrite规则问题这个问题很有代表性。列表页能打开,点进漏洞详情页却404,这多半是Apache的rewrite规则没生效,或者“.htaccess”文件不可见。先用“ls -la”检查源码目录里有没有“.htaccess”文件。有时候这个文件是隐藏的,直接看目录列表根本发现不了。有的话检查Apache配置里“AllowOverride”是不是“All”,不是的话改成“All”,重启服务。再看一下模块状态,“a2enmod rewrite”执行过没有。还有一个很容易漏的点:如果你的“DocumentRoot”和源码目录之间隔着多层目录,“.htaccess”的规则作用范围可能会被上级目录的配置覆盖,这种情况就要手动在Apache配置里多写一段“RewriteRule”。如果确认配置没问题还是404,直接看Apache错误日志,看请求实际落到哪个文件上。有一回我发现问题是用户访问“/detail/10001”时,Apache把“10001”当成目录路径去解析了,而不是通过“index.php”接收参数,这就是rewrite规则缺失导致的路径解析错误。4.4 内容乱码:编码统一要重视乱码的问题分为两类。一类是页面上的中文全部变成“锟斤拷”或者一堆问号,这种情况通常是页面HTML里的字符集声明和数据库里的字符集不一致。我们要确保数据库、表、连接三者的字符集都是UTF-8,缺一个都不行。另一类是数据库里的某部分内容本身是GBK,比如某些老帖子里嵌套的特殊符号,用UTF-8读取就会变乱。这种情况可以手动针对单条记录做转换,或者在不重要的展示页面里加一层转码输出。乱码问题最难受的点在于不好一次定位,需要排查的链路比较长。我的经验是先用MySQL命令行直接查询某条记录,看原始数据是不是正常的。如果在命令行里看到的都是乱码,那是导入时的编码问题;如果命令行正常但页面乱,那是Web连接层的编码参数问题。两条路径完全不一样,排查方向不能搞反。4.5 快速排查速查表症状优先排查方向常用修复手段页面输出源码,不渲染页面PHP模块未加载 / 未重启Apache检查模块,切换PHP版本,重启服务数据库导入中断MySQL内存不足 / 包大小限制调高max_allowed_packet,分拆SQL文件列表正常,详情404rewrite规则未生效 / 配置文件权限不对检查.htaccess,开启AllowOverride页面中文乱码字符集不统一库、表、连接统一为UTF-8后台无法登录数据库密码错误 / 会话目录权限问题检查配置文件,清空会话缓存目录我个人操作中的体会是,搭这套环境最磨练人的不是某个具体技术难点,而是一遍遍提醒自己“别拿新版本的思维去套老代码”。这种意识在做安全研究时很重要:漏洞库是历史产物,你在里面看到的漏洞手法、修复方式、思路演进,都需要放到对应的时代背景下理解,而不是简单地拿今天的攻击手段去对比判断谁高谁低。最后再分享一个小技巧:搭建完成后,不用急着删除探针文件,但记得把它改名成一个非常隐蔽的名字,或者直接移出Web目录。另外建议每天定时做一次数据库备份,用crontab加一条“mysqldump wooyun > /data/backup/wooyun_$(date).sql”就行。这个习惯能让你后续研究过程中心态稳很多——数据在手,折腾不愁。
1. 整体设计思路与方案选型1.1 为什么还要搭一个WooYun漏洞库环境你要是这两年才入行安全,可能对WooYun这个名字有点陌生,但只要你翻过不少漏洞分析报告,或者在某站看过那种“某某漏洞影响XXX”的历史记录,大概率绕不开这个库。WooYun平台曾经是国内漏洞报告圈子里的一个重要存在,大量白帽子在上面提交过真实漏洞案例。后来平台方向调整,原站点停止服务,但那些漏洞数据并没有消失,很多安全研究者把当时公开的漏洞库内容整理、打包、保留了下来。现在你在一些公开渠道还能找到它的源码包和数据包,用它们搭一套本地环境,纯粹是为了技术研究、漏洞分析和安全教学。有人可能会问,平台都没了,我扒拉一堆旧漏洞出来有什么用?我个人的看法是,漏洞库的价值从来不是“当下是否还通用”,而是“历史漏洞为什么存在、怎么被挖掘、怎么被修复”。尤其对新人来说,WooYun里的很多案例是活生生的从0到1的漏洞发现过程,远比你在靶场里照着答案打一遍要更有代入感。比如某个SQL注入案例,报告里写了参数怎么构造、报错怎么回显、为什么这个过滤能被绕过,这种完整链路在普通漏洞库和CVE描述里是很难看到的。也正是这个原因,我当时给新人做内训时,第一件事就是让他们先把一套WooYun漏洞库环境搭起来,先改代码、再查库、最后复现报告里的某个漏洞,以“倒推”的方式去理解漏洞原理。那为什么还需要“环境搭建”这一步?因为WooYun的数据包不是给你一个现成的Web界面,它就像一堆玩具零件,需要把运行环境、数据库、代码目录全部拼起来。网上虽然流传过一些打包好的虚拟机镜像,但那种镜像一来不敢乱用——你也不知道里面有没有被人塞过别的东西,二来不利于理解系统的依赖关系。自己动手搭一遍,既能获得一套干净可控的漏洞检索系统,又能把LNMP或者LAMP这套经典架构从配置到调优走一遍,训练价值是双份的。1.2 搭建方案选型:从系统到Web架构的取舍搭建WooYun漏洞库环境,本质上就是搭一个“古老的PHP应用”。因为这代码的历史包袱不小,它依赖的PHP版本、数据库版本都比较老,和我们现在新装的PHP 8.x环境兼容性很差,所以我做方案选型时第一件事就是把“现代化环境”从脑海里抹掉,老老实实模拟2012年前后的经典Web环境。先看操作系统。我当时用的是CentOS,但现在说实话CentOS 7已经进入维护尾声了,新装系统我建议直接用Debian或者Ubuntu的LTS版本。数据包本身和操作系统关联不大,PHP版本才是大头。WooYun源码主要依赖PHP 5.x,我在实际测试时发现,放到PHP 5.6环境下最稳,MySQL用5.6或5.7都行。如果你非要挑战一下,把它跑在PHP 7.0以上也不是完全不能跑,但各种通知报错、函数弃用警告会冒出来一堆,有些函数(比如旧版MySQL扩展相关接口)在高版本PHP里直接没了,处理起来很闹心,没必要给自己找不痛快。Web服务器选Nginx还是Apache?我的建议是,能用Apache就别折腾Nginx,原因很简单:WooYun源码里大量使用,开头就带参数的URL跳转和rewrite规则,Apache的mod_rewrite处理起来更省心,而且老PHP和Apache的搭配是“原配”,兼容性问题最少。不过如果你对Nginx更熟,也没问题,多加几行rewrite规则的事。我当时图省事用的Apache,后面讲具体配置时你就能感受到,几乎不用为路径分发操心。数据库方面,我强调一下千万别想着用MariaDB 10.x的高版本直接导入。WooYun的SQL文件里有些字段定义和老语法,在高版本MariaDB的严格模式下可能直接报错中断导入。我实际遇到过一次字段默认值导致的导入错误,后来换了MySQL 5.7才顺利导入。所以你在选型时,要么用MySQL 5.7,要么在导入前把SQL文件里的严格模式限制绕过去——这个后面我细说。整体方案选型结论就是:Debian/Ubuntu + Apache + PHP 5.6 + MySQL 5.7,这套组合最稳,问题最少。如果你想折腾,也可以全容器化,但我个人觉得本地虚拟机或云主机直接装,比Docker更直观,因为之后维护数据、改代码都要方便一些。2. 核心细节解析与实操要点2.1 环境准备:软件版本选择与关键理由我这里直接给出我实测稳定的一套软件版本组合,供你参考:组件推荐版本选择理由操作系统Ubuntu 16.04/18.04或Debian 9/10对PHP 5.6的软件源支持好,依赖安装省心Web服务器Apache 2.4对老PHP兼容性强,rewrite规则无需额外折腾PHP5.6.xWooYun源码依赖的旧函数和语法在5.6中运行最顺MySQL5.7.x对老SQL文件的兼容性比MySQL 8.x好,不会因为默认值报错PHP扩展mysql扩展(非mysqli)、curl、gd源码里部分功能模块需要调用这些扩展你可能会问,PHP 5.6不是早就停止维护了吗?装它会不会有问题?这想法没错,但请你换个角度想:你是在搭一个“历史的漏洞库系统”,不是在给生产环境写新业务。PHP 5.6老归老,在本地或内网环境跑这套检索系统,安全风险是可控的,而且源码本身就是这样设计的。真要让它跑在PHP 7上,你反而要花大量时间改代码,改完还不一定能保证功能完整。做安全研究的人应该明白,工具链的“新”不等于“合适”,稳定与还原才是目标。另外,如果你用的Ubuntu源里默认没有PHP 5.6,可以手动添加一个软件源来装。我用的是某个第三方维护的PHP版本源,里面5.6、7.0这些老版本都有。添加源之后直接apt-get install就能装上,省去自己编译的麻烦。自己编译PHP 5.6也不是不行,但为了搭个漏洞库环境去编译一遍PHP,步骤有点多,而且依赖容易缺,不值得。新手尽量直接用软件源。2.2 配置文件里的几个关键命门WooYun源码解压后,最核心的配置文件主要涉及数据库连接和站点访问路径。先看数据库配置,通常路径是“/includes/config.php”之类,你需要修改其中数据库地址、用户名、密码三个参数,确保和本地建的库对得上。再说说PHP配置,里面有几个开关直接影响系统能不能正常跑。第一个是short_open_tag,老代码经常用“”这类短标签方式写PHP,而新版本PHP默认把short_open_tag关掉了,不打开的话页面内容会直接当成纯文本输出,整个界面就是乱的,看起来像代码没执行一样。第二个是display_errors,建议临时打开,搭环境阶段免不了要调试各种报错,把错误显示出来能省很多排查时间。第三个是allow_url_open的配置,如果你后面要分析WooYun里的历史URL或字段,有些地方需要它,但出于安全考虑搭完建议关掉。Apache那边主要注意DocumentRoot指向源码目录,同时开启mod_rewrite模块。WooYun源码里有些URL路径是动态拼接的,不开rewrite的话,点击某些分类标签会找不到页面。另外还要设置一下AllowOverride All,否则源码里的.htaccess规则不会生效。数据库导入的核心是SQL文件。WooYun数据包里的SQL文件通常很大,几百MB甚至上GB都很正常。刚解压的时候我还愣了一下,以为下载错了,后来才明白这就是完整漏洞库的数据量。用命令行导入比用phpMyAdmin靠谱,phpMyAdmin对超大文件导入容易超时或者内存溢出。命令行一条source命令完事,还能看到导入进度统计——有没有报错一目了然。这里特别提醒:如果你把SQL文件用文本编辑器打开过,建议重新从安装包解压一份出来再导入,否则编辑器可能会偷偷改编码或换行符,导入时冒出莫名其妙的错误。2.3 源码目录结构速览WooYun源码的目录结构不复杂,但搞清楚它能让之后的修改和维护效率提高不少。一般源码解压后主要包含三个部分:前端页面目录、接口目录、后台管理目录。前端页面就是普通用户看漏洞列表、漏洞详情的地方;接口目录处理搜索、筛选、分页这些动态请求;后台管理目录则是管理漏洞提交、审核、用户管理的入口。我在第一次搭建时犯过一个低级错误,以为源码里的所有目录都需要Web访问权限,于是把整个源码目录的权限都放开了。结果安全隐患也来了,后台管理脚本也暴露在Web端,连日志目录都能直接访问。正确做法是:只给Web服务运行所需的目录开放读写权限,其他目录保持默认,尤其是配置文件和包含敏感信息的脚本,绝不能允许Web端直接访问。做安全这一行,搭环境的时候就要有安全意识,不然你搭的是漏洞库,库本身反过来成了你的漏洞。3. 实操过程与核心环节实现3.1 一键准备依赖:源码包下载与目录规划先把依赖环境装好。我现在假设你用的是Ubuntu 16.04这个老版本,因为第三方源对老PHP的适配做得比较完整。如果用的是更新版本,有些源可能不太兼容,需要临时调整一下源地址。装依赖的先手顺序是:先更新软件源索引,然后装Apache和MySQL,最后通过第三方源装PHP 5.6全家桶,具体命令如下:sudo apt update sudo apt install -y apache2 mysql-server mysql-client sudo add-apt-repository ppa:ondrej/php sudo apt update sudo apt install -y php5.6 php5.6-mysql php5.6-gd php5.6-curl这里有个小坑要说明一下:不同环境下PHP 5.6包的名称可能稍有差异。有些源里叫“php5.6”,有些叫“php5”,装之前最好先用“apt-cache search php5”扫一遍看看实际包名。我就是一开始想当然直接安装,结果提示找不到包,后来搜索才发现装的是“php5.6-cli”“php5.6-common”这些带后缀的包。另外Apache的PHP模块也要注意,安装后需要确认“/usr/lib/apache2/modules”下有没有对应的libphp5.6模块文件,没有的话重启Apache时PHP不会生效。源码包下载后先别急着直接扔进网站目录。我习惯的做法是先在“/opt”下建一个目录统一存放原始包,解压一份作为“干净底稿”,再复制一份到网站目录做实际运行环境。这样之后改动出问题,还能从底稿快速还原,不用重新下载。尤其是数据包很大时,重新下载的成本挺高的,留个底稿就等于留了条退路。具体目录规划大概是这样的:/opt/wooyun_source/ # 原始包底稿,只读 /var/www/html/wooyun/ # 实际Web运行目录 /var/lib/mysql/wooyun/ # 数据库数据目录(默认即可)然后下载下来的SQL文件我习惯单独放一个“/opt/wooyun_sql/”目录,和源码解压目录分开,因为它的体积太大,放源码目录里备份时要一起打包,时间浪费不说,压缩包体积也大得离谱。3.2 数据库配置与数据导入全流程数据库的创建和导入这步是整个搭建过程中的核心,也是最容易翻车的地方。先用MySQL的root账号进入命令行,创建数据库和专用账号:CREATE DATABASE wooyun DEFAULT CHARACTER SET utf8; CREATE USER 'wooyun_user'@'localhost' IDENTIFIED BY 'your_password'; GRANT ALL PRIVILEGES ON wooyun.* TO 'wooyun_user'@'localhost'; FLUSH PRIVILEGES;字符集这里我强调一下,一定要显式指定UTF-8。WooYun数据包里虽然有些内容是GBK编码的,但整体框架用的是UTF-8,如果你的数据库默认字符集是latin1或别的,导入过程中会有大量中文乱码,后面改起来非常麻烦。数据导入用命令行执行:mysql -u wooyun_user -p wooyun < /opt/wooyun_sql/wooyun_full.sql执行前建议先看看SQL文件体积。如果超过200MB,导入时间可能长达几分钟到十几分钟,期间终端看起来像是“卡住”了,其实是在跑,不要急。为了观察导入进程,可以先看文件大小,然后用“time”命令包一层,估算执行耗时。我第一导的时候不知道,等了半天没反应,差点以为进程挂了。导入完成后别急着推进度,先检查一下数据的完整性。最简单的验证方法是登录MySQL,统计几张核心表的数据量。如果某张表和预期数量差太多,说明导入过程中有错误被跳过了。遇到这种情况,可以用下面这种方式精确排查:mysql -u wooyun_user -p --default-character-set=utf8 wooyun -e "SELECT COUNT(*) FROM vul_info;"表名不一定固定,你可以列一下所有表看看,再用“DESC表名”查看结构,确认关键字段是否齐全。如果存在半截导入的情况,最稳妥的做法是删库重建再导一次,而不是试图在现有数据基础上做增量修复。别问我怎么知道的,我第一次为了省时间想补数,到最后数据结构一团乱,反而浪费了更多功夫。3.3 Web端配置:让漏洞库跑起来数据库就绪以后,把源码复制到Web目录:sudo cp -r /opt/wooyun_source/. /var/www/html/wooyun/ sudo chown -R www-data:www-data /var/www/html/wooyun/然后修改源码中的数据库连接配置,把刚才建的库名、账号、密码填进去,同时确认连接端口默认是3306。我这里要专门提一个细节:源码里可能有多处数据库配置,不只有一个config文件,有时候是“include”“function”目录下也有,甚至有个别页面单独写了连接逻辑。你可以在源码目录里全局搜一下“mysql_connect”或“mysqli_connect”这样的关键词,把所有连接点都找出来一并改掉。接下来是Apache配置。在站点配置文件里把文档根目录指到“/var/www/html/wooyun”,并设置“AllowOverride All”,然后启用Apache的rewrite模块:sudo a2enmod rewrite sudo systemctl restart apache2访问前先确认PHP已经生效。在Web目录里放一个探针文件,写上“”,然后浏览器访问探针页面确认输出PHP版本信息。探针显示的PHP版本如果还是系统默认的7.x,说明Apache加载的PHP模块指错了,需要手动切换一下Apache可用的PHP模块优先级。这一步如果搞不定,后面的所有页面都会以源代码形式赤裸裸展示在浏览器里,这其实也是一种“漏洞”,但在你搭建漏洞库时,它就纯粹是烦人。如果探针页面正常,可以试着访问“http://你的服务器IP/wooyun/”,看到漏洞首页或搜索页面就算基本跑通了。到这里,一个可用的WooYun漏洞库环境就已经搭建完成,你可以开始检索历史漏洞、阅读报告原文、分析数据字段了。4. 常见问题与排查技巧实录4.1 页面纯文本输出:PHP没生效的经典症状搭建过程中最常见的现象就是打开页面看到一串串PHP源代码,而不是正常的网页。第一反应不用慌,这十有八九是PHP模块没加载成功,或者Apache没重启。排查步骤依次是:先用“php -v”确认命令行PHP版本正常,再用“apachectl -M”查看Apache加载的模块列表里有没有“php5_module”。没有的话,执行“a2dismod php7.x”和“a2enmod php5.6”,切换模块,再重启Apache。如果模块列表里根本没有PHP相关的模块,那说明安装阶段出了问题,用“apt-get install libapache2-mod-php5.6”补装一下。还有一种情况是部分页面有PHP代码输出,部分页面直接空白或显示源码,这多半是源码文件编码或语法错误引起的。可以去Apache错误日志里查一下,“tail -f /var/log/apache2/error.log”看看有没有PHP Parse error,有的话就得定位到对应文件,看是不是压缩包解压不完整导致文件残缺。4.2 数据库导入中断:是先查内存再谈优化几百MB的SQL文件导入到一半连接断开,这种事情我遇到不下三次。很多时候MySQL服务直接被系统OOM杀掉,或者导入过程中出现“Packet too large”这种报错,本质上是内存和包大小限制没调好。解决办法有两个方向。一个是调整MySQL配置,在配置文件里增加一行“max_allowed_packet=256M”,调高单次传输包大小的上限,然后重启MySQL。另一个是导入前把SQL文件拆成多个小文件,分批导入。不推荐一开始就拆,先试直接导入,大部分情况下只要内存够(建议2GB以上),一次导入就能过。内存实在不够的话,可以用“split”命令按行数拆分SQL文件,比如每5万行一个文件,再用循环导完。因为SQL文件里的INSERT语句比较大,按行数拆分基本不会从INSERT语句内部割开,安全系数比较高。导一个文件确认一个表的数量,这样出错也能精确定位是哪个文件的问题。4.3 列表页能看、详情页404:Rewrite规则问题这个问题很有代表性。列表页能打开,点进漏洞详情页却404,这多半是Apache的rewrite规则没生效,或者“.htaccess”文件不可见。先用“ls -la”检查源码目录里有没有“.htaccess”文件。有时候这个文件是隐藏的,直接看目录列表根本发现不了。有的话检查Apache配置里“AllowOverride”是不是“All”,不是的话改成“All”,重启服务。再看一下模块状态,“a2enmod rewrite”执行过没有。还有一个很容易漏的点:如果你的“DocumentRoot”和源码目录之间隔着多层目录,“.htaccess”的规则作用范围可能会被上级目录的配置覆盖,这种情况就要手动在Apache配置里多写一段“RewriteRule”。如果确认配置没问题还是404,直接看Apache错误日志,看请求实际落到哪个文件上。有一回我发现问题是用户访问“/detail/10001”时,Apache把“10001”当成目录路径去解析了,而不是通过“index.php”接收参数,这就是rewrite规则缺失导致的路径解析错误。4.4 内容乱码:编码统一要重视乱码的问题分为两类。一类是页面上的中文全部变成“锟斤拷”或者一堆问号,这种情况通常是页面HTML里的字符集声明和数据库里的字符集不一致。我们要确保数据库、表、连接三者的字符集都是UTF-8,缺一个都不行。另一类是数据库里的某部分内容本身是GBK,比如某些老帖子里嵌套的特殊符号,用UTF-8读取就会变乱。这种情况可以手动针对单条记录做转换,或者在不重要的展示页面里加一层转码输出。乱码问题最难受的点在于不好一次定位,需要排查的链路比较长。我的经验是先用MySQL命令行直接查询某条记录,看原始数据是不是正常的。如果在命令行里看到的都是乱码,那是导入时的编码问题;如果命令行正常但页面乱,那是Web连接层的编码参数问题。两条路径完全不一样,排查方向不能搞反。4.5 快速排查速查表症状优先排查方向常用修复手段页面输出源码,不渲染页面PHP模块未加载 / 未重启Apache检查模块,切换PHP版本,重启服务数据库导入中断MySQL内存不足 / 包大小限制调高max_allowed_packet,分拆SQL文件列表正常,详情404rewrite规则未生效 / 配置文件权限不对检查.htaccess,开启AllowOverride页面中文乱码字符集不统一库、表、连接统一为UTF-8后台无法登录数据库密码错误 / 会话目录权限问题检查配置文件,清空会话缓存目录我个人操作中的体会是,搭这套环境最磨练人的不是某个具体技术难点,而是一遍遍提醒自己“别拿新版本的思维去套老代码”。这种意识在做安全研究时很重要:漏洞库是历史产物,你在里面看到的漏洞手法、修复方式、思路演进,都需要放到对应的时代背景下理解,而不是简单地拿今天的攻击手段去对比判断谁高谁低。最后再分享一个小技巧:搭建完成后,不用急着删除探针文件,但记得把它改名成一个非常隐蔽的名字,或者直接移出Web目录。另外建议每天定时做一次数据库备份,用crontab加一条“mysqldump wooyun > /data/backup/wooyun_$(date).sql”就行。这个习惯能让你后续研究过程中心态稳很多——数据在手,折腾不愁。