CVE-2022-37202 nday 研究 sql

0x1 SQL 注入 CVE-2022-37202

描述

/admin/advicefeedback/list 参数处理不当,可被利用执行恶意SQL命令。

代码

java 复制代码
 public SQLUtils(String sql) {
        sqlBuffer = new StringBuffer(sql);
    }

tb_advice_feedback表下查询

java 复制代码
@ControllerBind(controllerKey = "/admin/advicefeedback")
public class AdvicefeedbackController extends BaseProjectController {

	private static final String path = "/pages/admin/advicefeedback/advicefeedback_";

	public void list() {
//这里自动获取
		TbAdviceFeedback model = getModelByAttr(TbAdviceFeedback.class);
//查询
		SQLUtils sql = new SQLUtils(" from tb_advice_feedback t where 1=1 ");
//某个条件
		if (model.getAttrValues().length != 0) {
//拼接t,存储进alias
			sql.setAlias("t");
// 查询条件,model.获取,代入
			sql.whereLike("username", model.getStr("username"));
			sql.whereLike("qq", model.getStr("qq"));
			sql.whereLike("email", model.getStr("email"));
			sql.whereLike("telphone", model.getStr("telphone"));
		}

// 排序
//怎么获取
		String orderBy = getBaseForm().getOrderBy();
//sql
		if (StrUtils.isEmpty(orderBy)) {
//尾部添加
			sql.append(" order by t.id desc ");
		} else {
//拼接
			sql.append(" order by ").append(orderBy);
		}

		Page<TbAdviceFeedback> page = TbAdviceFeedback.dao.paginate(getPaginator(), "select t.* ", //
				sql.toString().toString());

		// 下拉框
		setAttr("page", page);
		setAttr("attr", model);
		render(path + "list.html");
	}

String orderBy = getBaseForm().getOrderBy()

java 复制代码
	public BaseForm getBaseForm() {
		BaseForm form = super.getAttr("form");
		return form == null ? new BaseForm() : form;
	}
java 复制代码
public String getOrderBy() {
		if (StrUtils.isEmpty(getOrderColumn())) {
			return "";
		}
//返回字符串
		return " " + getOrderColumn() + " " + getOrderAsc() + " ";
	}

whereLike sql

java 复制代码
 private String alias = "";
public void setAlias(String alias) {
        this.alias = alias;
    }
java 复制代码
//键,值
public void whereLike(String attrName, String value) {
//过滤
        if (checkSQLInject(attrName) || checkSQLInject(value)) {
//返回正常字段
            return;
        }
//代入查询,值
 if (StrUtils.isNotEmpty(value)) {
//t拼接attrName
//append(value)可控
//模糊匹配value
            sqlBuffer.append(" AND " + getAttrName(attrName) + " LIKE '%").append(value).append("%'");
        }
    }
java 复制代码
    private String getAttrName(String attrName) {
        if (StrUtils.isEmpty(alias)) {
//返回attrName
            return attrName;
        }
//拼接
        return alias + "." + attrName;
    }
java 复制代码
//sql.setAlias("t");
private String alias = "";
java 复制代码
//建过滤
public static boolean checkSQLInject(String str) {
        // 如果传入空串则认为不存在非法字符
        if (StrUtils.isEmpty(str)) {
            return false;
        }

// 判断黑名单
        String[] blacks = {"script", "mid", "master", "truncate", "insert", "select", "delete", "update", "declare",
                "iframe", "'", "onreadystatechange", "alert", "atestu", "xss", ";", "'", "<", ">", "(", ")",
                // ",",, "\""
                "\\", "svg", "confirm", "prompt", "onload", "onmouseover", "onfocus", "onerror"};
        // 判断白名单
        String[] whites = {"updatetime", "update_time", "\""};

        // sql不区分大小写
        str = str.toLowerCase();
//2选1
//完整判断
        for (int i = 0; i < whites.length; i++) {
            if (whites[i].equals(str)) {
                return false;
            }
        }
//黑名单
        for (int i = 0; i < blacks.length; i++) {
//字符判断
            if (str.indexOf(blacks[i]) >= 0) {
//日志
                logger.error("SQLInject 原因:特殊字符,传入str=" + str + ",包含特殊字符:" + blacks[i]);
//检查到sql
                return true;
            }
        }
        return false;
    }
}
java 复制代码
//值过滤
public static boolean checkSQLInject(String str) {
        // 如果传入空串则认为不存在非法字符
        if (StrUtils.isEmpty(str)) {
            return false;
        }

        // 判断黑名单
//url绕过(post排除),/**/绕过,不安全过滤
        String[] blacks = {"script", "mid", "master", "truncate", "insert", "select", "delete", "update", "declare",
                "iframe", "'", "onreadystatechange", "alert", "atestu", "xss", ";", "'", "<", ">", "(", ")",
                // ",",, "\""
                "\\", "svg", "confirm", "prompt", "onload", "onmouseover", "onfocus", "onerror"};
        // 判断白名单
        String[] whites = {"updatetime", "update_time", "\""};

        // sql不区分大小写
        str = str.toLowerCase();
//判断是不是白名单,必须有字符
        for (int i = 0; i < whites.length; i++) {
            if (whites[i].equals(str)) {
                return false;
            }
        }
//报错
        for (int i = 0; i < blacks.length; i++) {
            if (str.indexOf(blacks[i]) >= 0) {
                logger.error("SQLInject 原因:特殊字符,传入str=" + str + ",包含特殊字符:" + blacks[i]);
                return true;
            }
        }
        return false;
    }
}
java 复制代码
public String getStr(String attr) {
		// return (String)attrs.get(attr);
		Object s = attrs.get(attr);
		return s != null ? s.toString() : null;
	}
java 复制代码
public V get(Object key) {
        Node<K,V> e;
        return (e = getNode(hash(key), key)) == null ? null : e.value;
    }

poc

其实思路很明显了,闭合',并且绕过过滤

为什么闭合单引号

sqlBuffer.append(" AND " + getAttrName(attrName) + " LIKE '%").append(value).append("%'")

实际拼接

AND name LIKE '%abc%'

重点

sqlBuffer.append(" AND " + getAttrName(attrName) + " LIKE '%").append(value).append("%'");

绕过

{"script", "mid", "master", "truncate", "insert", "select", "delete", "update", "declare",

"iframe", "'", "onreadystatechange", "alert", "atestu", "xss", ";", "'", "<", ">", "(", ")",

// ",",, "\""

"\\", "svg", "confirm", "prompt", "onload", "onmouseover", "onfocus", "onerror"};

验证

如果拼接过后是%%%,就会全部展现出来。

复现

这个功能,查询功能

刷新发现有默认

子页面保存,一次注入

相关推荐
会编程的土豆1 小时前
Go 模板初识
linux·运维·服务器
aFakeProgramer3 小时前
Linux版本兼容问题及RTA-VRTE环境配置笔记
linux·笔记
Zhu7583 小时前
在Ubuntu24快速配置专用SFTP
linux·sftp
码农客栈4 小时前
Linux 内核顶层 Makefile 详解
linux
Embedded-Xin4 小时前
Rust学习——Cargo工具
linux·学习·架构·rust·嵌入式
weixin_435776114 小时前
2026年长沙托育vi设计从风格定位到元素运用的设计方法
linux·运维·服务器·python
benjiangliu5 小时前
LINUX系统-19-库制作与原理(一)
linux·运维·服务器
趣味科技6 小时前
记录修复EAGET忆捷移动硬盘损坏
windows·数据分析·硬件工程
FriendshipT6 小时前
Ubuntu 20.04 下使用 Ollama 本地部署 AI 大模型
linux·人工智能·python·深度学习·ubuntu
时空节拍AI数字人7 小时前
多模态交互数字人:语音+视觉+触控如何融合
人工智能·microsoft·ai·aigc·交互·语音识别