在打靶场的同时,需要想一下如果你是开发人员你会怎样去防御这种漏洞,而作为攻击方你又怎么去绕过开发人员的防御。
GitHub - j3ers3/Hello-Java-Sec: ☕️ Java Security,安全编码和代码审计

SQLI(SQL Injection), SQL注入是因为程序未能正确对用户的输入进行检查,将用户的输入以拼接的方式带入SQL语句,导致了SQL注入的产生。攻击者可通过SQL注入直接获取数据库信息,造成信息泄漏。
JDBC有两个方法执行SQL语句,分别是PrepareStatement和Statement。
漏洞代码:
- // 采用原始的Statement拼接语句,导致漏洞产生
-
- public String jdbcVul(String id) {
- StringBuilder result = new StringBuilder();
- try {
- Class.forName("com.mysql.cj.jdbc.Driver");
- Connection conn = DriverManager.getConnection(db_url, db_user, db_pass);
-
- Statement stmt = conn.createStatement();
- // 拼接语句产生SQL注入
- String sql = "select * from users where id = '" + id + "'";
- ResultSet rs = stmt.executeQuery(sql);
-
- while (rs.next()) {
- String res_name = rs.getString("user");
- String res_pass = rs.getString("pass");
- String info = String.format("查询结果 %s: %s", res_name, res_pass);
- result.append(info);
- }
漏洞代码二:
- // PrepareStatement会对SQL语句进行预编译,但有时开发者为了便利,直接采取拼接的方式构造SQL,此时进行预编译也无用。
-
- Connection conn = DriverManager.getConnection(db_url, db_user, db_pass);
- String sql = "select * from users where id = " + id;
- PreparedStatement st = conn.prepareStatement(sql);
- System.out.println("[*] 执行SQL语句:" + st);
- ResultSet rs = st.executeQuery();
-
-
MyBatis框架底层已经实现了对SQL注入的防御,但存在使用不当的情况下,仍然存在SQL注入的风险。
漏洞代码:
- // 此漏洞出现频率较高并且很严重!
- // 为何产生:由于使用 #{} 会将对象转成字符串,形成 order by "user" desc 造成错误,因此很多研发会采用${}来解决,从而造成SQL注入
- // 点击运行可通过报错语句获取数据库user
-
- @RequestMapping("/mybatis/vul/order")
- public List<User> orderBy(String field, String sort) {
- return userMapper.orderBy(field, sort);
- }
-
- // mapper.xml语句
- <select id="orderBy" resultType="com.best.hello.entity.User">
- select * from users order by ${field} ${sort}
- </select>
漏洞代码二:
- // 模糊搜索时,直接使用'%#{q}%' 会报错,部分研发图方便直接改成'%${q}%'从而造成注入
-
- @Select("select * from users where user like '%${q}%'")
- List<User> search(String q);
-
- // 安全代码,采用concat
- @Select("select * from users where user like concat('%',#{q},'%')")
- List<User> search(String q);
文件上传漏洞,是指用户上传了一个可执行的脚本文件(如jsp\php\asp),并通过此脚本文件获得了执行服务器端命令的能力。常见场景是web服务器允许用户上传图片或者普通文本文件保存,这种漏洞属于低成本高杀伤力
漏洞代码:
- // 允许上传任意文件导致的安全风险
-
- public String singleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) {
- try {
- byte[] bytes = file.getBytes();
- Path dir = Paths.get(UPLOADED_FOLDER);
- Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
-
- Files.write(path, bytes);
- redirectAttributes.addFlashAttribute("message","上传文件成功:" + path + "");
- } catch (Exception e) {
- return e.toString();
- }
- return "redirect:upload_status";
- }
目录遍历, 应用系统在处理下载文件时未对文件进行过滤,系统后台程序程序中如果不能正确地过滤客户端提交的../和./之类的目录跳转符,攻击者可以通过输入../进行目录跳转