SQL注入原理小结

今天,一基友问我一个问题说:为什么SQL注入要加单引号,这个当时我一时也回答不上,怪就怪自己理论太菜,不过回去仔细思考了一下,觉得这个问题也是蛮简单的。

首先大家应该明白的一点就是SQL注入的目的:加单引号是为了让后台SQL语句执行的时候报错,这样,我们就可以初步判断单引号被放在SQL语句中执行了,只是执行的语句因为有单引号而出错了,这里我都有点啰嗦了,笑。

要防御这种单引号攻击,服务器有3种办法:

1、  将单引号过滤或者替换 – 一般程序都是这样做的

2、  将单引号转义 – 所谓转义就是让它成为一个普通的字符,而不具备执行功能,php常用addslashes()函数完成这一功能

3、  将服务器设置为不允许爆错或者爆404 not found

下面详细的介绍一下SQL注入的基本原理

SQL注入是什么?

引用老外的话来说,SQL注入是这样描述的:

SQL injection is a code injection technique, used to attack data-driven applications, in which malicious SQL statements are inserted into an entry field for execution (e.g. to dump the database contents to the attacker).SQL injection must exploit a security vulnerability in an application‘s software, for example, when user input is either incorrectly filtered for string literal escape characters embedded in SQL statements or user input is not strongly typed and unexpectedly executed. SQL injection is mostly known as an attack vector for websites but can be used to attack any type of SQL database.

SQL injection (SQLI) is considered one of the top 10 web application vulnerabilities of 2007 and 2010 by the Open Web Application Security Project. In 2013, SQLI was rated the number one attack on the OWASP top ten.

There are five main sub-classes of SQL injection:

1:Classic SQLI

2:Blind or Inference SQL injection

3:Database management system-specific SQLI

4:Compounded SQLI

5:The Storm Worm is one representation of Compounded SQLI

哎,其实这些描述我也看不大懂,怪就只能怪自己英语没认真学啊!

接下来,看看实例代码

1:权限绕过

statement = "SELECT * FROM users WHERE name =‘" + userName + "‘;"

大家觉得这条语句有SQL注入没?

答案是:有SQL注入

如果我们在web中提交:
 
‘ or ‘1‘=‘1
 
‘ or ‘1‘=‘1‘ -- 
 
‘ or ‘1‘=‘1‘ ({ 
 
‘ or ‘1‘=‘1‘ /* 

那么,SQL查询逻辑就变成这样子了:

SELECT * FROM users WHERE name = ‘‘ OR ‘1‘=‘1‘;
SELECT * FROM users WHERE name = ‘‘ OR ‘1‘=‘1‘ -- ‘;

如果这些SQL查询放在权限验证的代码中,那么该代码就会爆权限绕过了。

2:多语句执行

例如:我们在web中,对name这个变量提交SQL查询:

a‘;DROP TABLE users; SELECT * FROM userinfo WHERE ‘t‘ = ‘t

在完整SQL代码中就是这个样子的:

SELECT * FROM users WHERE name = ‘a‘;DROP TABLE users; SELECT * FROM userinfo WHERE ‘t‘ = ‘t‘;
 
这段SQL语句执行的结果是:users表被删除了,userinfo表的内容被完全展示出来!
 



 
Tips:
 
While most SQL server implementations allow multiple statements to be executed with one call in this way, some SQL APIs such as PHP‘s mysql_query() function do not allow this for security reasons. This prevents attackers from injecting entirely separate queries, but doesn‘t stop them from modifying queries.
 
这个意思最完美,我没翻译,怕翻译出错,呵呵!
 
3:数据类型没有验证
 
例如:SQL语句本来是这样:
 
statement := "SELECT * FROM userinfo WHERE id =" + a_var + ";"
 
这个a_var按正常逻辑来说是int型数据 <虽然用户提交的数据都被server识别为字符 or 字符串>
 
但是,如果Hacker提交如下payload,SQL语句执行结果将会怎样呢?
 
1;DROP TABLE users
 
那么,我们的SQL语句就变成这个样子了:
 
SELECT * FROM userinfo WHERE id=1;DROP TABLE users;

SQL执行的结果是:users表被删除了!

其实,仔细想来,这个地方还是多语句执行造成的,但问题的关键还是programmer没有对用户提交的数据类型做严格检查。

4:SQL盲注

下面科普一下SQL盲注:

Blind SQL Injection is used when a web application is vulnerable to an SQL injection but the results of the injection are not visible to the attacker. The page with the vulnerability may not be one that displays data but will display differently depending on the results of a logical statement injected into the legitimate SQL statement called for that page. This type of attack can become time-intensive because a new statement must be crafted for each bit recovered. There are several tools that can automate these attacks once the location of the vulnerability and the target information has been established.

例如:

Server端SQL查询是这样的:

SELECT * FROM bookreviews WHERE ID = ‘Value(ID)‘;

但是,我们可以将它变成这样:

SELECT * FROM bookreviews WHERE ID = ‘1‘ AND ‘1‘=‘1‘;
 
SELECT * FROM bookreviews WHERE ID = ‘1‘ AND ‘1‘=‘2‘;

如果AND 1=1返回正常页面并且AND 1=2返回错误页面,那么,我们就说这个web页面<当然是后台页面>存在SQL盲注,准确一点是基于布尔型的SQL盲注<Boolean-based SQLBI>。

什么time-based SQLBI、error-based SQLBI,这里就不再细说了。

5:二次注入

二次注入的定义:

Second order SQL injection occurs when submitted values contain malicious commands that are stored rather than executed immediately. In some cases, the application may correctly encode a SQL statement and store it as valid SQL. Then, another part of that application without controls to protect against SQL injection might execute that stored SQL statement. This attack requires more knowledge of how submitted values are later used. Automated web application security scanners would not easily detect this type of SQL injection and may need to be manually instructed where to check for evidence that it is being attempted.

具体实例also see:

http://zone.wooyun.org/content/3565

6:十六进制转换,可以防御SQL注入攻击

这个不怎么好描述,我举几个实例,大家应该就明白了:

具体实例also see:

http://www.cnblogs.com/mincyw/archive/2011/02/10/1950733.html

实例代码:

File: test.php
<?php
 
    include_once( "dosql.php" );
#
#   Put your own database information here.  I‘m using my log file‘s data.
#
    $host = "myhost";
    $usr = "myUser";
    $pwd = "myPassword";
    $db = "myDatabase";
 
    $mysqli = new mysqli( $host, $usr, $pwd, $db );
 
    if( $mysqli->connect_errno ){
        echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
        exit;
        }
    echo "SQL INJECTION - Plain\n";
    $sql = "select * from log where log_id=‘2‘ or 1=1; #‘";
    $res = dosql( $sql );
    foreach( $res[0] as $k=>$v ){
        echo "RES[$k] = $v\n";
        }
 
    echo "\n\nSQL INJECTION = Hexadecimal\n";
    $sql = "select * from log where log_id=unhex(‘" . bin2hex("2‘ or 1=1; #") . "‘)";
    $res = dosql( $sql );
    foreach( $res[0] as $k=>$v ){
        echo "RES[$k] = $v\n";
        }
 
    exit;
?>
 
File: dosql.php
<?php
 
################################################################################
#   dosql(). Do the SQL command.
################################################################################
function dosql( $sql )
{
    global $mysqli;
 
    $cmd = "insert into log (date,entry) values (NOW(),unhex(‘" . bin2hex($sql) . "‘))";
    $res = $mysqli->query( $cmd );
 
    $res = $mysqli->query( $sql );
    if( !$res ){
        $ary = debug_backtrace();
        if( isset($ary[1]) ){ $a = $ary[1][‘line‘]; }
            else if( isset( $ary[0]) ){ $a = $ary[0][‘line‘]; }
            else { $a = "???"; }
 
        echo "ERROR @ " . $a . " : (" .  $mysqli->errno . ")\n" . $mysqli->error . "\n\n";
        echo "SQL = $sql\n";
        exit;
        }
 
    if( preg_match("/insert/i", $sql) ){ return $mysqli->insert_id; }
    if( preg_match("/delete/i", $sql) ){ return null; }
    if( !is_object($res) ){ return null; }
 
    $cnt = -1;
    $ary = array();
    $res->data_seek(0);
    while( $row = $res->fetch_assoc() ){
        $cnt++;
        foreach( $row as $k=>$v ){ $ary[$cnt][$k] = $v; }
        }
 
    return $ary;
}
 
This outputs:
 
SQL INJECTION - PLAIN
RES[log_id] = 1
RES[date] = 2015-03-25 10:40:18
RES[entry] = show full columns from log
 
SQL INJECTION = Hexadecimal
RES[log_id] = 2
RES[date] = 2015-03-25 10:40:18
RES[entry] = select * from log order by title asc

自己好好去琢磨一下!

Tips:

Note that the PLAIN SQL injection actually works - the first record is returned and not the second. But with the hexadecimal put in the correct record is returned. Thus, by using the BIN2HEX and UNHEX commands you no longer have to worry about SQL Injection attacks.

Additionally, overall, the usage of BIN2HEX and UNHEX requires less time to execute than any of the other methods.

This is NOT to say that you shouldn‘t do checks of whatever you get back from the browser before you put it in to the database. This isn‘t a magic wand that will fix everything that has ever been wrong with your database or programs. It does though, make it so you do not have to worry about the kinds of SQL injections presented at the beginning of this webpage. Those it will stop.

时间: 2024-10-21 07:49:54

SQL注入原理小结的相关文章

SQL注入原理讲解,很不错!

SQL注入原理讲解,很不错! 原文地址:http://www.cnblogs.com/rush/archive/2011/12/31/2309203.html 1.1.1 摘要 日前,国内最大的程序员社区CSDN网站的用户数据库被黑客公开发布,600万用户的登录名及密码被公开泄露,随后又有多家网站的用户密码被流传于网络,连日来引发众多网民对自己账号.密码等互联网信息被盗取的普遍担忧. 网络安全成为了现在互联网的焦点,这也恰恰触动了每一位用户的神经,由于设计的漏洞导致了不可收拾的恶果,验证了一句话

SQL注入原理 手工注入access数据库

SQL注入原理 手工注入access数据库 SQL注入是通过将SQL命令插入到web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意SQL指令的目的. 1.判断网站是否有注入点. 在以asp?id=xx(任意数字)结尾的连接依次添加: ' 1=1 1=2 若以上结果显示"数据库出错","正常显示","数据库出错"则该网站存在注入点. 2.猜解表名 在链接末尾添加语句: and exists(select * from admi

SQL注入原理解说,非常不错!

原文地址:http://www.cnblogs.com/rush/archive/2011/12/31/2309203.html 1.1.1 摘要 日前,国内最大的程序猿社区CSDN站点的用户数据库被黑客公开公布,600万用户的登录名及password被公开泄露,随后又有多家站点的用户password被流传于网络,连日来引发众多网民对自己账号.password等互联网信息被盗取的普遍担忧. 网络安全成为了如今互联网的焦点,这也恰恰触动了每一位用户的神经,因为设计的漏洞导致了不可收拾的恶果,验证了

Java程序员从笨鸟到菜鸟之(一百)sql注入攻击详解(一)sql注入原理详解

前段时间,在很多博客和微博中暴漏出了12306铁道部网站的一些漏洞,作为这么大的一个项目,要说有漏洞也不是没可能,但其漏洞确是一些菜鸟级程序员才会犯的错误.其实sql注入漏洞就是一个.作为一个菜鸟小程序员,我对sql注入的东西了解的也不深入,所以抽出时间专门学习了一下.现在把学习成果分享给大家,希望可以帮助大家学习.下面我们就来看一下. 一.什么是sql注入呢?         所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的

SQL注入原理与解决方法代码示例

一.什么是sql注入? 1.什么是sql注入呢? 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击.当应用程序使用输入内容来构造动态sql语句以访问数据库时,会发生sql注入攻击.如果代码使用存储过程,而这些存储过程作为包含未筛选的用户输入的字符串来传递,也会发生sql注入. 黑客通过SQL注入攻击

回头探索JDBC及PreparedStatement防SQL注入原理

概述 JDBC在我们学习J2EE的时候已经接触到了,但是仅是照搬步骤书写,其中的PreparedStatement防sql注入原理也是一知半解,然后就想回头查资料及敲测试代码探索一下.再有就是我们在项目中有一些配置项是有时候要变动的,比如数据库的数据源,为了在修改配置时不改动编译的代码,我们把要变动的属性提取到一个配置文件中,比如properties,因为properties里面都是键值对的形式,所以非常便于阅读和维护. 一.首先说说读取properties文件,这个相对路径和绝对路径的问题:

讲sql注入原理的 这篇不错(有空可以看看)

我们围绕以下几个方面来看这个问题: 1.什么是sql注入? 2.为什么要sql注入? 3.怎样sql注入? 1.什么是sql注入? 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击.当应用程序使用输入内容来构造动态sql语句以访问数据库时,会发生sql注入攻击.如果代码使用存储过程,而这些存储过程作

【转】SQL注入原理和方法

最近在做的项目是网络安全评估的内容,其中包含渗透测试,而SQL注入往往是渗透测试中最为有效的手段之一,本文中将会就SQL注入的原理和方法进行叙述,使普通读者对SQL注入有所了解. SQL注入攻击是黑客对数据库进行攻击的常用手段之一.随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多.但是由于程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患.用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些

报错型sql注入原理分析

0x00:前言 关于sql注入,经久不衰,现在的网站一般对sql注入的防护也相对加强了,2016年的渗透测试报告中,出现最多的是xss(跨站脚本攻击)和明文传输等,但是对sql注入的利用方式,也相对成熟,详细了解sql注入,可以参考之前的文章.http://wt7315.blog.51cto.com/10319657/1828167 今天主要分享下sql注入中的报错型,在大多网上的文章会列出类似于公式的句子,却没解释为什么要使用这样的函数,为什么使用这个函数会出现报错而导致sql注入. 0x01