网站个人和企业有什么区别,开元酒店集团品牌建设,龙岗网站设计,腾讯网站谁做的第5关--------------------------------------------
前端直接不会显示账号密码的打印#xff1b;但是在接收前端的数据的那部分后端那里#xff0c;会看前端传递过来的值是否正确#xff0c;如果不正确#xff0c;后端接收值那里就会当MySQL语句执行错误#xff0c;…第5关--------------------------------------------
前端直接不会显示账号密码的打印但是在接收前端的数据的那部分后端那里会看前端传递过来的值是否正确如果不正确后端接收值那里就会当MySQL语句执行错误直接打印MySQL的报错信息 怎样解决第二关通过这一个打印错误信息的漏洞再让updatexml()方法去真正执行MySQL语句肯定会出现报错情况出现了就会打印报错信息 前面的第一关注入是在web页面会打印当前登录的账号最后如果我们知道了表名和对应表的字段名的话我们就可以通过group_concat(username),group_concat(password)这种将所有的username账号和password密码打印出来了 但是要是前端web页面并不会显示你的账号密码前端压根就不会答应你的账号密码怎么办 拓展 1、group_concat()和concat()的区别
---1、group_concat()函数是将同一个组内的所有指定的值拼接起来
如group_concat(id,:,name);
就是将整个表中的所有id和所有name都拼接起来
是一行一行拼接的拼接的内容是将第一行的id值和‘’和name值都拼接起来
然后再将第二行的id值和‘’和name值都拼接起来
...最后整个表中的数据都拼接完成后再一次性打印在一行里面 ---2、concat()
concat就是将每行记录的都分别拼接起来分别打印在每一行
如select concat(id,:,username) from users ; ---所以concat是拼接出来的有多个成员行数或者所成员个数不变但是group_concat()是将所有的成员拼接成一个成员所以成员变成了一个适合有limit(0,1)的场合 注意不管是group_concat()还是concat()都不能直接对 * 进行字符串连接就是不能类似于这样写select group_concat(*) from users / select concat(*) from users ; 报错注入
本篇后端php会打印你的MySQL报错信息
答应代码 这篇文章开头已经说了当你的web前端页面并不会打印你的账号密码那怎么查询你的账号和密码的值呀
---说实话基本上现在的web前端页面都不会打印你的账号密码的你看看有哪个网站会打印这些重要信息
1、利用updatexml()的报错功能
原理updatexml()方法实际上是去更新我们后端的xml文档但是我们在xml文档路径的位置写一个MySQL的查询语句然后我就会报错但是他在报错的时候其实已经执行了这个MySQL的查询语句因为就是执行了才知道这个是错误的
注意执行的代码是mysql_quer()这个函数 updatexml(old_value,xpath,new_value);
1、old_value ---要更新的数据
2、xpath ---这个xml文档的路径
3、new_value ---更新后的数据
当有如下xml数据时 那么我们想要将指定部分修改成新的数据我们就应该 这里的text()是获取student[1]下所有的数据 ----所以说从这里可以看出来我们在xpath位置必须准确的写上xpath路径那么如果我们写上一个特殊字符这系统显然就能看出来这个路径是不符合规定的所以mysql_quer()在执行时就会发现updatexml的路径不对所以就会报错但是mysql_quer()函数是会将其MySQL代码进行执行
至于这个报错有没有被打印出来那就要看这个后端有没有打印MySQL执行错误的相关代码了反正第5关是打印了的 2、直接在updatexml中在xpath部分执行MySQL代码
---显然xpath部分是应该写xml路径的这里我们写了写了一个不符合规定的路径就会报错如在路径里写了特殊符号就显然会在mysql_quer()执行的时候报错
但是报错的同时里面的MySQL代码还是会被执行这个是updatexml的一个特性 你看这里我就通过concat()方法将特殊字符‘~’插入到了xpath路径里面去同时路径里面还包含了一个MySQL代码mysql_quer()在执行的时候就会发现这个updatexml的路径部分有问题自然而然的就会爆报错同时还是会将其中MySQL代码进行执行
最后因为后端的写了--将这个接收的参数值如果运行出问题的话就会将其打印--的这种代码所以最后就会将这个报错信息打印出来 127.0.0.1/sqli-labs-master/Less-5/?id1andupdatexml(1,concat(!,(database())),1)--
注意你要执行的那个嵌入在路径里面的MySQL代码必须要加括号不然updatexml是真的无法识别你的MySQL代码其实updatexml本意是不想识别出你的MySQL代码的但是你加入了()那她就没办法迫不得已识别出来了 ---这样就把当前使用的数据库找到了
---通过这种类似的方法最终像前面一样将你的数据库列成员一个一个搞出来 3、找到数据库找数据表
127.0.0.1/sqli-labs-master/Less-5/?id1and updatexml(1,concat(!,(selectgroup_concat(table_name)frominformation_schema.tableswheretable_schemasecurity)),1)-- 4、通过数据表查找列成员 ---条件禁止了information_schema库
127.0.0.1/sqli-labs-master/Less-5/?id1 and updatexml(1,concat(!,(select * from (select * from users a join users b using(id,username)) c)),1)--
这里就是查找到了password这个成员 5、通过列成员查找列成员的值
这样如果我们直接输入select * from users时
会出现以下字样这种显示的意思是应该只输出一个成员这里显然 * 代表了id,username,password三个成员了 因为updatexml的错误返回只能是一行字符串所以我们需要使用到group_concat()或concat方法将他们合并
---
127.0.0.1/sqli-labs-master/Less-5/?id1andupdatexml(1,concat(!,(selectgroup_concat(concat(id,username,password))fromusers)),1)-- ---但是显然我们可以看出这个账号密码并没有全部显示出来
这是因为我们的updatexml()方法的报错返回最大只能返回32个字节
所以我们接下来就需要对获取到的数据进行分段获取
分段获取有两种方法1、通过concat()和limit 0,1一起搭配使用
---http://127.0.0.1/sqli-labs-master/Less-5/?id1%20and%20updatexml(1,concat(!,(select%20concat(id,username,password)%20from%20users%20limit 0,1)),1)--
因为concats是将多个字段值合并成类似于一个字段值但是行数不变所以我们这里可以通过limit 一行一行的截取下来
2、通过substring(str,起始位置终止位置)来对字符串进行截取
---http://127.0.0.1/sqli-labs-master/Less-5/?id1%20and%20updatexml(1,concat(!,(select%20substring(group_concat(concat(id,username,password)),32,64)%20from%20users)),1)-- ------------------》》extractvalue(1,xpath)这个函数和updatexml函数除开参数个数不一样其余全部一样 6、如果updatexml和extractvalue函数都被拦截禁用了那么我们该怎么办
--------------没办法只能换函数
报错注入的7大函数 floor函数
1、7大函数中很多函数都被禁用了且很多函数因为版本问题都是被淘汰或者还没有开发出来
但是有一个报错注入函数在MySQL5.0到8.x依然还在继续用这个函数就是----floor函数
floor报错注入函数需要搭配rand()随机函数、group by分组count()统计一起搭配使用
----
127.0.0.1/sqli-labs-master/Less-5/?id1 and
select 1 from
(select count(*),concat(version(),floor(rand(0)*2))a from information_schema.tables group by a)x)--
我们一步一步来解释
1、floor(rand(0)*2) ---生成一个0到1的随机数floor是向下取整然后给这个列取别名为a
2、group by是将a进行分组0为一组1为一组
3、count(*)是计算所有组分别有多少个元素
好问题就出现在这了当我们的count(*)计算分组的元素个数时会出现错误
错误我们的MySQL计算分组时是这样的一个步骤
---1、我们的count(*)在计算分组的条数时他会看到分组group by 是根据floor(rand(0)*2)的值来产生数据的
所以我们的count(*)在取记录时首先是先去执行floor(rand(0)*2)执行结果是0
好count(*)发现0这个分组并没有被记录在案好我们就需要把0插入到我的count(*)这个表中
但又来了我们的count(*)在插入时还会执行一次group by的floor(rand(0)*2);
所以我们最终记录进入count(*)中的分组是1且条数是1
---floor(rand(0)*2)的前6条是011011因为rand(0)会变得固定
---2、第二次取数据实际上是第三次计算数据
得出结果是1然后count(*) 发现这个数据我们count(*)表是有的所以我们就直接在有的基础上1取数据和新插入数据才会对group by 的floor(rand(0)*2进行执行) ---3、第三次取数据实际上是第四次计算数据
我们计算出来的结果是0然后count(*)又发现这个0是表中没有的所以就需要进行插入但是在进行插入的时候又会对group by 的floor(rand(0)*2)进行计算一次
这样原本要新插入的0就变成了要新插入的1当这个1插入的时候系统就会报错这个1已经是存在了的 你这里再插入是属于重复插入重复插入1 就是这种就会出现报错
所以最终我们随便去from一个表都可以只要是有6个行数据即可
只要能到达floor(rand(0)*2)0110116个数据即可 2、这里我们的重复插入1变成了重复插入 版本号1因为我们把版本号和1结合起来了
所以最后就是因为出问题了而且MySQL还是将其含有的MySQL代码执行了
因为后端有php对MySQL执行出错误时的报错打印这样版本号就会被连着错误一起打印出来了 3、select 1 from ()
为什么要在最外层加入色了select 1 from ()?
因为不加入的话select count(*),concat(version(),floor(rand(0)*2))a from information_schema.tables group by a 这行代码代表的是有两个输出成员不管最终有没有输出这两个列成员但是这MySQL代码已经真真切切的表示了这里将会有两个列成员所以系统会直接报错
成员多了是在编译时就会被发现编译时的错误
报错注入是在运行时才会被发现才会被报出有错误运行时的错误
但是打印MySQL错误的这行代码的时候 说明floor错误信息的返回只能是一连串的字符串不允许打印多行或多列的这种类似于表的东西
所以我们不能直接打印你说能直接使用concat(count(*),concat(version(),floor(rand(0)*2))a)吗那你里面取的别名还有什么意义你都包起来形成新的列了所以不行
所以你只能在最前加select 1 from
哎这样也只是让列变少了但是行数还是实打实的跟select count(*),concat(version(),floor(rand(0)*2))a from information_schema.tables group by a的行数一样呀就是两行0和1呀
no,我们刚刚已经算过了压根还没有真正新插入0这一行单单就在插入1这里就出现了重复1的情况所以select 1 from(...)实际上是只输出了一行
所以最终是输出的一行一列在满足MySQL错误打印的要求只能打印一连串字符串不能打印多行或多列的类似于表的东西 ---其余查询的用法就是和updatexml/extractvalue一样了
127.0.0.1/sqli-labs-master/Less-5/?id1and(select1from(selectcount(*),concat((select*from(select*fromusersbjoinusers using(id))a),floor(rand(0)*2))afrominformation_schema.tablesgroupbya)b)-- 如查询字段id的值group_concat(id) ---当我们查询字段username/password的值时 值得注意的是
1、我们前面已经说过我们的update错误返回只能是一行的这种连续的字符串
不能是多行或多列的显示而对于floor来说返回的错误信息如果字符串太长floor错误提示也会出问题说你只能显示一行
floor和count(*)组合的错误提示只能是一行的一连串的字符串且这个字符串不能太长比update的错误提示条件又多了一个字符串错误信息返回不能太长
2、我们的MySQL代码都需要用()包裹起来
3、注意这里的重复和自己组合起来的新表确实是有多行但是你注意没有MySQL的执行顺序是先把内层的执行了再执行外层的这里肯定也是一样先执行内层的
而内层是select * from users b join users ;
注意这里也是不会直接进行展示的这里是需要先进行把表连接起来然后才进行展示
最终而在连接表的时候就会出现字段重复的现象最终达到破解字段名的目的
---MySQL的执行顺序从内到外从右到左
---updatexml/extractvalue 他们错误返回的是最多32个字节的字符串
---floor和count()返回的错误信息只能是字符串且长度不能太长
---order by是将字段值进行一个排序
当一个数据表中有idname,passwd时那么order by 3就是将passwd字段的所有值进行一个排序 ---------------------------------我们只讲思路不讲详细过程 过程是背思路是理解 想要走多远10%背90%理解
祝你年薪百万成绩辉煌