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"};

验证

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

复现

这个功能,查询功能

刷新发现有默认

子页面保存,一次注入

相关推荐
坚持就完事了15 分钟前
Linux中的变量
linux·运维·服务器
handler0125 分钟前
从源码到二进制:深度拆解 Linux 下 C 程序的编译与链接全流程
linux·c语言·开发语言·c++·笔记·学习
Cat_Rocky41 分钟前
利用Packet Tracer网络实验
linux·运维·服务器
嵌入式×边缘AI:打怪升级日志1 小时前
Linux 驱动实战:SR501 人体红外传感器驱动开发与调试全记录
linux·运维·驱动开发
正点原子1 小时前
【正点原子Linux连载】第三章 U-Boot使用 摘自【正点原子】ATK-DLRK3568嵌入式Linux驱动开发指南
linux·运维·驱动开发
Qbw20041 小时前
【Linux】进程地址空间
linux·c++
NoSi EFUL2 小时前
redis存取list集合
windows·redis·list
jamon_tan3 小时前
linux下lvgl8.3动态库编译
linux
子牙老师4 小时前
软件虚拟化 vs 硬件虚拟化
linux·性能优化·云计算
coNh OOSI4 小时前
Redis——Windows安装
数据库·windows·redis