
不想看你只看过没用过的东西被别人当成实战教程。这篇文章就是把你带到键盘前面一步一步走完从环境搭建到拿到第一管数据的全过程。如果你想学安全不管以后是打CTF、做护网还是搞等保SQL注入尤其是配合自动化工具的攻击方式你是躲不开的。所以今天这篇我用DVWA这个经典靶场手把手带你把sqlmap从入门到能实际打点全部走一遍该踩的坑我提前给你踩你只需要跟着敲命令就行。写这篇的由头很简单我最近在带几个新人入门发现一个特普遍的问题很多人知道sqlmap这个工具也背过不少参数但真正到了自己搭了个本地靶场反而各种连不上、扫不出、跑不完然后就卡在那儿放弃了。问题出在哪多半不是工具不行而是你压根没理解sqlmap的工作方式和它说的“人话”。今天这篇就来解决这个事全程实操你跟着我命令敲完脑子里有整个脉络了以后遇到真实场景套路也是一样的。1. 动手之前先把靶场环境给我搭明白很多人一上来就急着敲sqlmap命令结果连目标都访问不了。咱们干这活儿的铁律先有合法可控的目标再谈测试。DVWADamn Vulnerable Web Application这种自带的“漏洞练习生”就是干这个用的。专门为想学Web安全的兄弟们设计的一台“带病”的Web应用你可以在里面放心大胆地折腾搞坏了也不心疼。1.1 DVWA靶场搭建两种最快、最省心的姿势搭建DVWA我推荐在国内网络环境下优先用Docker方式。别去费劲搞什么PHPStudy加手工配置数据库又慢又容易出幺蛾子。方式一Docker一条龙强烈推荐干净利落我假设你已经装好了Docker和Docker Compose。没装的自己官网下个桌面版就行。然后我们干这几件事# 1. 拉取 DVWA 的官方镜像这个镜像里面环境都给你配好了 docker pull vulnerables/web-dvwa # 2. 启动容器映射端口 80 到本地的 8081方便访问 docker run -d -p 8081:80 --name dvwa vulnerables/web-dvwa # 3. 启动完成后先看一眼容器日志确认 Apache 和 MySQL 都正常运行 docker logs -f dvwa看到日志里出现了Apache started和MySQL started的字样就说明环境起来了。这时候你在浏览器里输入http://127.0.0.1:8081就能看到DVWA的登录界面了。默认账号密码是admin/password。注意我第一次拉这个镜像的时候出现过容器能启动但数据库没初始化好的情况。最直接的办法就是docker restart dvwa重启一下容器多试两次基本能好。如果一直连接不上数据库就docker exec -it dvwa /bin/bash进容器里去手动启一下 MySQL 服务。方式二本地手动搭建有基础的老手专用如果你不想用Docker那就自己装个PHPMySQL环境。Windows上可以考虑用小皮面板Mac上可以用MAMP或者自己配。去 GitHub 把 DVWA 源码下载下来扔到 Web 服务器的根目录。复制config/config.inc.php.dist为config.inc.php改一下数据库密码。然后访问http://127.0.0.1/dvwa/setup.php点一下 “Create / Reset Database” 按钮。手动搭建的问题在于PHP版本和MySQL版本兼容性我遇到过用新版本PHP直接白屏的情况这时候宁可换老一点的PHP版本别在这上面耗时间。1.2 登录和初始化拿到一个能用的“带病”目标无论用哪种方式第一步都是进到DVWA首页。默认账号密码是admin/password。进去之后你会看到左边一排菜单User Registration、Brute Force、SQL Injection……咱们今天的主角是SQL Injection这个页面。划个重点页面最底下有个Security Level安全级别选择器。你刚开始学务必选成 Low。这个选项代表着后端代码过滤的严格程度。Low 级别是最原始的、没有任何防护的代码非常适合先搞清楚sqlmap的攻击流程。等你 Low 玩明白了再调到 Medium 和 High 去看看你就知道为什么真实环境中token、过滤和WAF会让工具寸步难行了。2. 核心武器扒开sqlmap的“胃”看它怎么把注入跑出来的在敲第一条命令之前我强烈建议你先明白sqlmap的内部逻辑。它不是一个只会拿Payload乱怼的“脚本小子工具”它内部是个井井有条的流水线。2.1 从发个包到拿数据sqlmap的工作流水线sqlmap拿到你的目标URL后心里其实有一本账踩点探测先发送一些正常的请求看看目标站点的响应状态、Web容器、数据库指纹等基础信息。检测Detection在一个参数里注入一些能让SQL语句“报错”的特殊字符比如单引号然后观察响应内容有没有变化。如果页面报错信息显露了数据库语法或者返回了和原请求不同结构的数据它就认为这里有戏。确认Confirm通过布尔逻辑盲注?id1 and 11 和 ?id1 and 12或者时间盲注?id1 and sleep(5)来再次确认这个参数确实是SQL注入漏洞。指纹识别DBMS Fingerprinting不同的数据库MySQL、Oracle、SQL Server注入语法和拿数据的姿势是完全不一样的。sqlmap会先判断出当前环境是MySQL还是别的然后决定后续用何种姿势怼。数据榨取Data Extraction确认了漏洞和数据库类型剩下的就是机械化地跑数据了。它会先列出所有的库名--dbs然后再跑表名-D 库名 --tables再跑字段名-D 库名 -T 表名 --columns最后就是把字段的具体值拖出来--dump。所以一条sqlmap命令的本质就是告诉它“你要打哪个靶场”和“你想打到什么程度”。2.2 新手必知的“生活化”参数类比sqlmap的参数很多初学者不要被吓到。我们就拿“点菜吃饭”来打个比方一下就记住了参数/用法吃饭类比作用解释-u或--url告诉服务员你去哪家饭店指定目标URL--batch让服务员全权代理不用每道菜都问你一遍自动回答所有交互式问题用默认选项--dbs服务员把整个菜单所有数据库拿给你枚举出所有数据库-D指定你这顿要去吃川菜选库指定要查的数据库名称--tables把川菜店的所有菜品列表拿上来枚举指定库中的所有数据表-T你看上了“回锅肉”这道菜指定要操作的数据表--columns这盘回锅肉你问老板是用了哪些材料做的枚举指定表的所有字段名--dump别问材料了我直接把菜偷吃掉将指定字段/表的数据全部拖下来--level和--risk你这人能吃辣吗能的话我就上魔鬼辣检测深度和风险等级越高测的点和Payload类型越多--dbms你直接跟老板说“我就信任重庆师傅”指定后端数据库类型加快检测速度有了这个“菜单”你再去看sqlmap命令是不是就觉得顺眼多了它就是个自动化的点菜员。2.3 选好你的第一道菜注入点在哪参数怎么填DVWA的 SQL Injection 页面实际上是一个经典的GET型参数注入。它的请求URL长这样http://127.0.0.1:8081/vulnerabilities/sqlib/?id1SubmitSubmit这里面id1就是我们要下手的“主菜”。所有流程都从搞这个参数开始。注意一点DVWA是需要登录的所以你敲sqlmap命令时必须带上当前浏览器的会话Cookie不然sqlmap发出去请求会被服务器重定向到登录页啥也跑不出来。我会在下面实操命令中把具体做法写出来。3. 实战从“hello world”到“数据在手”全流程详解现在请打开你的终端跟我走一遍完整的实战。这一段就用上面提到的Docker DVWA环境来演示目标URL我换成通用写法你自己敲命令时记得把IP和端口换成你自己的。开局第一步确认靶场可用性这一步可做可不做但我强烈建议先手动在浏览器里访问一下http://你的IP:8081/vulnerabilities/sqlib/?id1SubmitSubmit确认页面能正常显示。如果能出来一个User ID: 1以及First name和Surname那咱们的靶场环境就绪了。3.1 基础探测先让sqlmap“尝一口”判断能否下嘴第一轮探测我们先用最基础的姿势让sqlmap去判断这是不是个注入点。必须带着Cookie。Cookie哪里找用浏览器开发者工具F12网络Network选项卡随便点一个请求在请求头里就能看到Cookie字段。# 这条命令告诉sqlmap # 1. 目标URL是什么--url # 2. 带上登录态的Cookie--cookie # 3. 所有交互问题都自动选默认--batch # 4. 只做检测不进行后续的数据榨取--current-db sqlmap -u http://你的IP:8081/vulnerabilities/sqlib/?id1SubmitSubmit --cookiePHPSESSID你抓到的会话ID; securitylow --batch --current-db跑完这条命令如果一切正常你就会在漫天的日志里看到这么几个关键信息Parameter: id (GET)sqlmap找到了注入参数是id。Type: boolean-based blind这个参数存在布尔型盲注。Type: UNION query这个参数还存在联合查询注入。Type: error-based还有报错注入。current database: dvwa它掏出了当前数据库的名字。看到这些你的眼睛就可以放光了说明第一步成功了。尤其注意current database这个词它意味着sqlmap不仅发现了漏洞而且已经成功连上了数据库服务器别人家的库名都拿到手了。3.2 进阶操作暴力获取整个数据库里的“宝藏”确认有洞之后咱们干点正事把数据都捞出来。刚才那步骤是试探这一步是真的开吃。# 直接把整个 dvwa 库的所有表数据都给拉下来这会需要一点时间 sqlmap -u http://你的IP:8081/vulnerabilities/sqlib/?id1SubmitSubmit --cookiePHPSESSID你抓到的会话ID; securitylow --batch -D dvwa --dump--dump这个参数是集成了前面--tables和--columns的“一条龙服务”它会自动枚举出你指定的库-D dvwa下面所有的表再枚举出每个表的列最后把列里的数据全部导出。跑完之后sqlmap会创建一个结果的本地存储文件路径一般是~/.local/share/sqlmap/output/你的IP地址/dump/dvwa/下面。里面会有各个表名的CSV文件。你打开users.csv就能看到DVWA靶场里所有用户的账号密码了。反正我本地靶场里用户的密码Hash是一堆看不懂的密文因为DVWA默认用了MD5加密。但这不影响我们理解整个流程这时候你就该明白当真实渗透时拿到这个CSV文件就意味着你对这个系统的账户体系已经了如指掌了。3.3 从GET到POST换汤不换药的注入姿势很多新手会卡在POST型注入上。DVWA里有个 “SQL Injection (Blind)” 页面它是POST请求。GET请求是把参数放在URL后面POST请求是把参数放在请求体里面。sqlmap也早就想到了处理方式很简单姿势一手动把报文存成文件你打开Burp Suite手动拦截一下这个POST请求然后把整个原始HTTP报文复制出来存成一个post.txt文件。POST /vulnerabilities/sqli_blind/ HTTP/1.1 Host: 你的IP:8081 Cookie: PHPSESSID你的会话ID; securitylow Content-Type: application/x-www-form-urlencoded id1SubmitSubmit然后sqlmap直接读取这个文件sqlmap -r post.txt --batch --dbs姿势二直接用命令指定数据参数不想用Burp直接用--data参数指定POST数据也行sqlmap -u http://你的IP:8081/vulnerabilities/sqli_blind/ --cookiePHPSESSID你的会话ID; securitylow --dataid1SubmitSubmit --batch --dbs说句实在话在真实的Web渗透中POST型注入比GET型要多得多。因为开发人员大部分情况下会把查询操作留成GET把更新、添加操作留成POST而POST参数又是藏起来的所以很多人会忽略。你用-r读取HTTP报文的方式是我个人最常用的因为它可以最完整地还原现场还能顺便修改报文里的一些请求头信息。3.4 提升伤害力认清瓶颈在哪刚才我们直接--dump很爽但真实环境下没那么简单。如果目标库很大跑起来就很慢很慢。这时候就别傻等着在命令里加个并发# --threads 参数能提升并发数但别打太高太高容易影响目标稳定性惊醒蓝队。 sqlmap -u http://你的IP:8081/vulnerabilities/sqlib/?id1SubmitSubmit --cookiePHPSESSID你的会话ID; securitylow --batch -D dvwa --dump --threads3而且当你明确知道这是一个MySQL数据库时加个--dbmsmysql参数能帮sqlmap省掉很大一部分识别数据库指纹的时间跑起来效率能翻倍提升。4. 工具和人谁才是决定结果的关键聊完怎么跑sqlmap咱们得聊聊比工具更重要的东西。我见过太多人依赖sqlmap跑线上目标结果跑半天什么都跑不出来就开始怀疑工具不行。其实问题不在这。4.1 绕过套路一箩筐别被“秒破”带偏真实生产环境的数据库十有八九不是Low级别的DVWA。开发人员会加各种过滤WAF也有可能拦着你。针对这种情况sqlmap提供了很多“绕WAF”的参数但效果因站而异。我这里可以给一个“组合拳”示例但这是给Medium级别DVWA用的而且不保证在真实场景一定通杀实际上每个目标都不一样没有银弹。把重点放在理解原理不要把“套路”当“公式”。# 这是一个非常基础的绕WAF思路用注释符、大小写和解码组合breaking LCASE等手段 # 真实环境一定要仔细看目标响应的差异再针对性进行设计。 sqlmap -u http://你的IP:8081/vulnerabilities/sqlib/?id1SubmitSubmit --cookiePHPSESSID你的会话ID; securitymedium --batch --tamperspace2comment --level3 --risk2--tamperspace2comment是一个脚本能把Payload里的空格改成/**/去绕过过滤。这属于最常见的绕WAF思路让检测规则认不出你的SQL语句。但各位醒醒。这只是入门玩具。真实的WAF拦截策略比这复杂得多什么二次编码、参数污染、分块传输……水很深。你现在最该信的那些教程应该教会你的是如何分析WAF的拦截日志而不是只会套用--tamper参数。4.2 手动注入的能力才是你的底气sqlmap查不出来或者被封了怎么办这时候你就得回归手动。手测SQL注入的基本功是必须有的因为工具的本质是替代你发送大量请求但确认漏洞存在、判断注入类型这些逻辑你自己心里必须有数。比如拿到一个id1参数你首先会在URL后面加个如果页面报错或显示不正常说明有戏。然后再试id1 and 11和id1 and 12如果前者显示正常后者显示空白或报错那这就是个典型的布尔盲注。接着你再试id1 union select 1,2,3如果页面上显示了2或3那恭喜你联合查询注入也成立。这一套手动流程走下来你对SQL注入的理解绝对比只会敲--dump的人深刻十倍。这个基本功作用很多没跑过测试的人体会不到。我就遇到过用sqlmap怎么都跑不出来手动看了一眼才发现其实是个鉴权缺陷导致的逻辑漏洞根本不是SQL注入的情况。工具再强分析思路才是决定你天花板的那个东西。5. 实战中99%的人都会碰到的报错与问题排查最后把大家私信问得最多的一类问题集中整理一下。这些问题我当年刚学的时候也都遇见过现在给你提前打好预防针。5.1 常见报错速查表这里有一份我自己的排错备忘录你可以保存下来遇到问题先按表排查。报错信息 / 现象根本原因解决办法connection timed out网络不通或目标地址错误ping 一下目标IP确认Docker容器端口映射是否正确invalid URLURL格式不对检查URL末尾是否有空格参数是否写错too many redirects或it is not a valid target报错说目标不是动态页面加上--force-ssl强制SSL或者去掉多余的参数确认URL确实存在动态参数unable to connect to the target URL目标站点拒绝连接可能是需要特殊Header比如Host头、User-Agent用--headers带上跑了几分钟还在testing connection to the target URL网络实在慢或者目标环境有网络波动耐心等或者ctrlc中断后换个--delay参数重新来提示detected the back-end DBMS is MySQL后就没动静了正在跑数据库指纹识别很正常喝口水等它自己跑完。如果很久没反应可以加--dbmsmysql指定数据库类型加快速度中途报错failed to retrieve the data可能是目标数据库有写入保护或临时表被锁换个时间段重试加--no-cast参数去掉强转类型或者--hex强制使用十六进制查询5.2 解决“跑得太慢”的核心思路很多人反馈sqlmap跑数据的时候一条一条滚跟老牛拉车一样特别急人。这其实特别正常。盲注的机制就是一次问数据库一个问题根据是或否来判断数据内容慢是它的天性。遇到这种情况你的第一反应不该是加--threads无限加速而是去想能不能换个注入类型。比如把--techniqueB纯布尔盲注改成--techniqueU联合查询如果目标存在联合查询注入那速度简直就像从走楼梯变成了坐电梯。核心思想是快没快的道理慢有慢的原因先搞清楚目标支持哪种注入技术再去对症下药。5.3 别忘了日志和输出文件是你的救命稻草sqlmap在你运行结束后会自动把结果存在本地的文件里。路径通常是~/.local/share/sqlmap/output/你的目标IP/这个文件夹里的log文件记录了sqlmap运行的全过程dbs、tables、columns等CSV文件就是你要的数据。我强烈建议你每跑完一个目标就去翻一下这个目录里的日志想想为什么sqlmap能成功为什么中间会报错这里面信息量巨大。顺便多说一句不同版本的sqlmap行为差别挺大的。老版本的--batch行为可能和新版本不一致所以我在指导新人时一般会让他们先跑个sqlmap --version确认一下自己的版本再按对应的参数来操作。最后说点实在话搞渗透测试工具可以让你跑得很快但只有思路能让你走得很远。sqlmap是每个Web安全从业者手上一个必备的锤子但你要知道什么时候该用锤子什么时候该换用螺丝刀、换用剪刀。这篇文章带你把sqlmap在DVWA上的流程完整走了一遍你把这个过程摸索透了之后再去看那些精妙的绕过技巧才能入木三分。我这边的经验是学这种攻击工具最好的方式就是把它丢进各种故意的、带漏洞的靶场里去反复蹂躏摸清它每一步做了什么、为什么这么做。等你拿着sqlmap能在一台陌生的靶机上跑出库名和表名的瞬间你才能体会到那种“我把它拿下了”的快感。别急着上真站也别迷信单一工具多练边界多关注防御的思路。这条路很长我还在走希望你也能保持好奇踩坑不回头。