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

验证

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

复现

这个功能,查询功能

刷新发现有默认

子页面保存,一次注入

相关推荐
皆圥忈2 分钟前
Linux 进程控制(上):创建、终止与等待
linux·运维·服务器
one优雅的猫3 分钟前
Linux 常用命令
linux·运维·服务器
皆圥忈5 分钟前
Linux 进程控制(下):等待与程序替换
linux·运维·服务器
荒--10 分钟前
SQLMAP工具的使用
linux·服务器
不会就选b15 分钟前
Linux之基本操作(上)
linux·运维·服务器
寺中人29 分钟前
Linux系统超详细解析与零基础实战使用教程
linux·服务器·系统架构·linux命令·零基础教程
Android系统攻城狮35 分钟前
Linux Pulseaudio深度解析之pa_stream_set_overflow_callback用流程与实战(三十七)
linux·运维·服务器·音频进阶·pulseaudio进阶
学无止境_永不停歇39 分钟前
从零手写高性能C++ TCP 服务器框架(十一) --- Connection实现
linux·服务器·网络·c++
AOwhisky44 分钟前
MySQL 学习笔记(第二期):SQL 语言之库表操作与数据类型
linux·运维·数据库·笔记·sql·学习·mysql
爱就是恒久忍耐1 小时前
Ubuntu解决pip3安装库提示This environment is externally managed的问题
linux·python·ubuntu