ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SQL注入靶场SqliLabs搭建:PHP版本与数据库连接避坑

SQL注入靶场SqliLabs搭建:PHP版本与数据库连接避坑 搭建 SqliLabs 这件事看起来就是下载—解压—丢进网站根目录—打开浏览器这四步但真正动过手的人都知道能一次跑通的概率大概跟抛硬币差不多。我第一次搭的时候折腾了整整一个下午安装页面要么白屏要么卡在第一步不动要么直接提示数据库连不上。后来带着别人一起搭发现大家踩的坑高度重合基本都集中在 PHP 版本、数据库配置、字符集和安装脚本这几个地方。SqliLabs 说白了就是一套用 PHP 写的、故意留了练习缺口的环境专门给学 Web 安全的人用来在本地模拟各种注入场景不联网、不影响别人、搞坏了删掉重来就行。它适合刚入门安全方向、想找个安全沙箱练手的人也适合需要临时搭一套环境做验证的老手。下面我就把搭建过程中真正会卡住人的点按出现频率从高到低捋一遍尽量让你少走我当年走过的弯路。1. 先把 SqliLabs 的出身弄明白才知道它为什么这么挑环境很多人搭不起来根源其实在一开始就没搞清楚这东西是个什么年代的产物。你把它当成一个普通的现代 Web 应用去部署那自然会处处碰壁。理解它的出身后面所有报错就都能串起来。1.1 它本质上是一套写死在老版本 PHP 上的代码SqliLabs 最早是十多年前的产物那会儿国内用 PHP 5.2、5.3 的还一大堆所以它的源码里大量使用了mysql_connect、mysql_query、mysql_fetch_array这一批函数。这批函数有个特点它们在 PHP 5.x 时代是主力但到了 PHP 7.0 被官方直接删掉了不是废弃而是移除——也就是说只要你用 PHP 7 以上去跑老版本的 SqliLabs连数据库那一步就会直接抛致命错误。这就解释了一个非常典型的现象同一份代码放在同事的电脑上能跑放在你的电脑上就白屏。不是代码有问题也不是你装错了纯粹是两边 PHP 版本不一样。我当年就是被这个坑到怀疑人生的——本地环境装的是最新版集成工具默认 PHP 8 起步结果mysql_*函数一律找不到。1.2 新版环境越先进越跑不动的反直觉结论安全圈里有个挺有意思的现象越是刚装好的新环境越跑不动这些经典靶场。因为 PHP 8 之后不仅移除了mysql_*还收紧了一大堆语法规则比如未定义变量会直接报 Warning、动态属性被弃用、字符串与数字比较规则也变了。SqliLabs 的代码里到处是能跑就行的写法在严格模式下自然一路飘红。所以正确的思路不是想办法让新 PHP 兼容它而是给它配一个它出生的年代的环境。这跟你在老电脑上跑 DOS 游戏是一个道理——你不太可能去改游戏而是搞个模拟器。SqliLabs 的模拟器就是 PHP 5.4 到 5.6 这一段区间绝大多数版本在 5.4/5.6 上都跑得非常稳。理解这一点后面选环境、切版本就有了主心骨不会被各种花里胡哨的报错牵着鼻子走。2. PHP 版本是第一道硬门槛绕不过去如果说搭建 SqliLabs 只有一个必须解决的问题那一定是 PHP 版本。这道坎你迈不过去后面数据库、字符集、权限的事情根本轮不到你操心。下面把报错、原因和两种主流解法讲透。2.1 典型报错长什么样它的真实含义是什么当你用 PHP 7/8 去跑老版 SqliLabs 时浏览器里通常会看到类似这样的字Fatal error: Uncaught Error: Call to undefined function mysql_connect() in ...或者Deprecated: The each() function is deprecated ...再或者干脆一片空白什么都不显示。前两条很直白——它在告诉你我要调用的这个函数在这个 PHP 里不存在。第三条白屏最坑因为默认情况下 PHP 的错误是不显示的你得先把php.ini里的display_errors打开错误才会浮到页面上来。我的习惯是搭这类环境时第一件事就把报错打开display_errors On error_reporting E_ALL改完记得重启 Web 服务不然php.ini不会重新加载。这一步看着简单但能帮你省掉大量盲猜的时间——有报错和没报错排查效率差十倍。2.2 降级 PHP 还是换一套代码我的选择逻辑面对版本不兼容你面前有两条路第一条是降级 PHP 环境装一个 PHP 5.4/5.6 的运行时让原始代码原封不动地跑起来。第二条是换一套已经适配新版 PHP 的代码社区里有不少人在原版基础上把mysql_*改成了mysqli或 PDO 的版本。我个人的选择是优先降级环境而不是换代码。理由很实在——你学这套靶场的目的是理解注入原理而不是给自己新开一个调代码的坑。换来的适配版代码谁改的、改得全不全、有没有顺手把某些行为改掉你都不清楚练到某一关时行为跟教程对不上你反而会怀疑自己学错了。而用 PHP 5.4/5.6 跑原版行为跟绝大多数公开资料完全一致出了问题也容易对上号。当然如果你手上环境受限、实在装不了老 PHP那就退而求其次用适配版但要有个心理准备个别关卡的响应可能和网上描述略有出入遇到时先别怀疑自己先对比代码。2.3 集成环境怎么配几个真正管用的操作大多数人是通过集成环境就是把 Apache、PHP、MySQL 打包在一起的那种工具来搭的这确实是最省事的路子。关键在于选一个支持自由切换 PHP 版本的集成环境。切换的步骤通常是关掉当前服务在版本列表里选到 5.4 或 5.6启动然后把 SqliLabs 的整个文件夹放进网站根目录一般是WWW或www目录。这里有几个我踩过的细节切换 PHP 后一定要重启服务不然 Apache 加载的还是旧的 PHP 模块。确认网站根目录到底是哪个有些集成环境默认站点目录和软件安装目录不是同一个放错地方就是 404。访问地址别写错大小写比如文件夹叫sqli-labs你在浏览器里就老老实实写sqli-labs别写成SqliLabs。Windows 下可能不敏感但一旦你迁到类 Unix 环境大小写就是致命的。把这一层搞定你访问首页就能看到那个经典的欢迎界面和一行行的关卡链接了。看到界面说明最硬的坎已经过了。3. 数据库连接账号、密码、端口三件套对不上就卡死PHP 版本解决之后下一个高频翻车点就是数据库连接。SqliLabs 的安装脚本需要连上 MySQL 去建库建表只要这个连接对不上安装就会卡在第一步反复报错。这块看着简单但细节全在配置文件的默认值上。3.1 默认凭据和你的实际环境对不上SqliLabs 的数据库连接信息集中写在一个配置文件里通常在sql-connections目录下文件名带db-creds字样。里面长这样$dbuser root; $dbpass root; $dbname security;问题就出在这儿它默认用户名和密码都是 root/root。而很多集成环境里MySQL 的 root 密码是空的或者被设成了别的字符串。你的环境是空密码脚本却拿着root当密码去连自然连不上。解决方式很直接——把配置文件里的用户名密码改成你环境里真实的值。如果是空密码就把$dbpass留空$dbuser root; $dbpass ;这一步几乎是人人都要改一次的。我建议你搭之前先确认两件事一是 MySQL 服务确实启动了有些集成环境默认不开二是你的 root 密码到底是什么。拿不准就用命令行工具连一下能连上再回来改配置。3.2 MySQL 端口和连接方式的隐藏坑除了账号密码还有两个不显眼但很要命的地方。第一是端口。默认 MySQL 用 3306但如果你的机器上已经装过一个独立的 MySQL或者之前装过别的数据库占用了 3306集成环境里的 MySQL 可能被自动换到了 3307、3308 之类的端口。这种情况下PHP 脚本仍然去连 3306就连到了错误的实例上要么连不上要么连上了但库不存在。第二是本地连接方式。有些环境下连接本机数据库时用的不是 TCP 端口而是本地套接字文件socket。如果配置里写的是localhost走的可能就是 socket 路径而 socket 文件的路径在不同集成环境里又不一样偶尔会出现明明服务在跑、端口也对就是连不上的情况。遇到这种玄学问题可以试着把连接主机从localhost改成127.0.0.1强制走 TCP很多时候一下就通了。提示改完配置文件后不需要重启数据库但 PHP 是每次请求重新读取脚本的所以直接刷新页面即可生效。4. 卡在安装页面一条可以照着做的完整排查链路前面两步都过了之后你会来到那个安装 / 重置数据库的页面。这页面上通常有几个步骤按钮比如创建数据库创建数据表写入数据。很多人在这里卡住——点一下转半天、点完没反应、或者报一堆红字。下面是我总结的一套排查顺序照着走基本能定位到问题。4.1 第一步永远是看报错而不是反复点新手最容易犯的错就是点了一次没反应再点还不行继续点最后把库搞成了半残状态。正确做法是——先看报错信息。如果页面什么都不显示回到第 2 节说的把 PHP 报错打开。报错里通常已经写清楚了是连接被拒绝表已存在权限不足还是语法错误。我遇到过最常见的三类提示连接类账号密码端口不对、已存在类上次安装残留了同名数据库、权限类当前数据库账号没有建库权限。这三类的处理方式完全不同不看报错根本没法对症下药。所以别急先把报错读懂。4.2 分步验证连接、建库、建表、写数据逐个击破安装脚本干的事其实就是四件连上数据库、建库、建表、写初始数据。任何一步失败整体就卡住。你可以按这个顺序用命令行手动验证比在页面上盲点高效得多验证环节怎么做常见失败原因连接数据库命令行用配置里的账号密码登录密码错、端口错、服务没开建库手动执行一句建库语句账号无建库权限、同名库已存在建表在刚建的库里建一张测试表字符集不支持、权限不足写数据往测试表插一行再查出来权限不足、字符集不匹配这套流程走一遍问题出在哪一环一目了然。我习惯在安装前先手动确认连接能用连接这一关过了后面基本都是小问题。如果之前装失败过建议先把残留的同名数据库删掉再重新跑安装否则脚本很可能因为库已存在而在中途报错留下一个半成品环境。4.3 安装跑完了但页面还是报数据库错误还有一种诡异情况安装页面上所有步骤都显示成功了可你回到关卡列表点进某一关还是提示无法连接数据库或未知数据库。这通常有两个原因。一是你访问的关卡引用的库名和你实际创建的库名对不上——安装脚本会创建几个不同名字的库如果某个库没建成功用到它的关卡就会报错。二是浏览器缓存了旧的页面你看到的是上一轮的残留状态。遇到这种情况先清缓存、换无痕窗口刷新还不行就进数据库命令行show databases;看一眼到底建出来哪几个库跟关卡实际引用的名字对一遍。这个对比动作能立刻帮你判断是库没建全还是页面没刷新比反复重启服务省事多了。5. 字符集、权限和那些容易忽略的小细节主体流程跑通之后还有一类问题不会让你彻底打不开但会在你用的时候冷不丁冒出来比如中文乱码、某些关卡行为异常、文件读写失败等。这些细节不影响能打开但影响好用。5.1 字符集不止影响显示还可能影响行为数据库和表的字符集设置会直接影响数据的存储和取出方式。如果你建库时没指定字符集落到了默认值上而脚本又按另一种字符集去读写就可能出现中文乱码甚至某些关卡的数据对不上号。稳妥的做法是建库时明确指定一个通用的字符集比如CREATE DATABASE security CHARACTER SET utf8 COLLATE utf8_general_ci;这里要强调一点字符集的选择不光关乎显示得好不好看它在你后续研究不同编码相关的注入场景时本身就是关键变量之一。所以别图省事全用默认明确建一个你知道的字符集后面做实验时心里才有底。这一点我在实际操作中体会很深——同一个关卡换个字符集表现可能就不一样提前把环境变量固定下来才谈得上可复现。5.2 目录权限和文件路径类 Unix 环境下的高发区如果你不是用集成环境而是自己在服务器上手动搭那目录权限就是绕不开的坎。Web 服务进程比如 Apache 或 Nginx 的运行用户需要对 SqliLabs 的目录有读取权限对某些需要写文件的子目录还得有写权限。权限没配好表现可能是页面能开但图片、样式加载不出来或者安装脚本无法写入临时文件。另外就是路径问题。SqliLabs 里有不少地方用了相对路径来引用配置文件。如果你把它塞进了一个多层嵌套的子目录或者改了目录名相对路径就可能断掉导致某些页面单独报错、其他页面正常这种迷惑现象。我的建议是把整个文件夹原样丢进网站根目录不改目录名、不加嵌套层级先把最干净的路径跑通再考虑改名的事。5.3 浏览器缓存和假成功的迷惑最后说一个特别容易被忽略的点浏览器缓存。搭建过程中你会反复刷新安装页面和关卡页面浏览器很可能把某一次的报错页缓存下来导致你明明已经改好了配置刷新看到的还是旧报错。这时候你会以为自己没改对来回折腾配置。解决办法很简单——用无痕窗口或者强制刷新CtrlF5。我搭环境的习惯是全程开着无痕窗口省得被缓存牵着走。还有一种假成功配置改完页面看起来正常了但其实是浏览器显示了缓存的正确页实际请求还是失败的。判断方法也简单打开开发者工具看一眼网络请求的状态码200 还是 500 一目了然别只信眼睛看到的页面。6. 反复踩坑之后我攒下的几条省事经验搭了这么多次我现在的流程已经固定下来了基本能一次跑通。这里把经验摊开说你照着做大概率能少折腾。第一动手前先确认三件事PHP 版本是不是 5.4/5.6、MySQL 服务是不是在跑、root 密码到底是什么。这三件事确认完80% 的坑就已经提前避开了。很多人是装到一半才发现版本不对前面做的全白费。第二报错一定要开。display_errors和error_reporting这两项是我搭任何 PHP 环境的第一步。没有报错信息的环境就是在摸黑走路。第三配置文件的账号密码先改再装。别指望默认的 root/root 能对上你的环境先去看一眼自己环境的真实凭据改完再点安装能省下一轮排查。第四失败过的安装一定要清干净再重来。残留的同名库是新安装失败的最常见原因之一删库重来比修修补补快得多。第五环境要固定、要记录。我每次搭完都会在纸上或文档里记一笔PHP 版本、MySQL 端口、库名字符集、配置文件改了哪几处。下次迁移或者帮别人搭直接照抄。别小看这个习惯——靶场这类东西环境和行为是强绑定的你今天调好的一个参数可能就是你明天复现某个现象的关键。还有一个我自己踩过的教训别一边搭环境一边急着做练习。环境没彻底稳定之前就冲进去稍微有点异常你分不清是环境问题还是自己操作问题越练越乱。老老实实把环境跑到首页、点到任意一关都能正常响应确认稳定了再开始用它。这个先后顺序是我花了两个下午才想明白的。如果你搭到一半又遇到没见过的报错先别慌回到连接—建库—建表—写数据这条链路上一段一段验。绝大多数问题都能在这条链路上找到那个断掉的小环节。
返回列表