CVE-2022-22978 漏洞分析

admin 2023年11月10日21:18:45评论21 views字数 2834阅读9分26秒阅读模式

产生原因:

输入换行符则绕过权限校验的正则匹配。默认的java Pattern模式,不开启DOTALL时候,在默认匹配的时候不会匹配r n 字符。

漏洞代码

org.springframework.security.web.uti.matcher.RegexRequestMatcher#matchers

public final class RegexRequestMatcher implements RequestMatcher {

    private static final int DEFAULT = 0;
    private static final Log logger = LogFactory.getLog(RegexRequestMatcher.class);

    public RegexRequestMatcher(String pattern, String httpMethod, boolean caseInsensitive) {
        this.pattern = Pattern.compile(pattern, caseInsensitive ? Pattern.CASE_INSENSITIVE : DEFAULT);
                this.httpMethod = StringUtils.hasText(httpMethod) ? HttpMethod.valueOf(httpMethod) : null;
    }


public boolean matches(HttpServletRequest request) {
      if (this.httpMethod != null && request.getMethod() != null && this.httpMethod != HttpMethod.resolve(request.getMethod())) {
          return false;
      } else {
          String url = request.getServletPath();
          String pathInfo = request.getPathInfo();
          String query = request.getQueryString();
          if (pathInfo != null || query != null) {
              StringBuilder sb = new StringBuilder(url);
              if (pathInfo != null) {
                  sb.append(pathInfo);
              }

              if (query != null) {
                  sb.append('?').append(query);
              }

              url = sb.toString();
          }

          logger.debug(LogMessage.format("Checking match of request : '%s'; against '%s'", url, this.pattern));
          return this.pattern.matcher(url).matches();  //匹配模式问题
      }
  }

Pattern.compile方法

 public RegexRequestMatcher(String pattern, String httpMethod, boolean caseInsensitive) {
      this.pattern = Pattern.compile(pattern, caseInsensitive ? 2 : 0);
      this.httpMethod = StringUtils.hasText(httpMethod) ? HttpMethod.valueOf(httpMethod) : null;
  }

第一个参数表示要编译的表达式,
第二个参数则是指定表达式的具体匹配模式,具体可选值有

CASE_INSENSITIVE, MULTILINE, DOTALL, UNICODE_CASE, CANON_EQ, UNIX_LINES, LITERAL, UNICODE_CHARACTER_CLASS and COMMENTS
  • DOTALL:表示更改.的含义,使它与每一个字符匹配(包括换行符n),

  • 默认情况下, 正则表达式中点(.)不会匹配换行符,
    设置了DOTALL模式, 才会匹配所有字符包括换行符。

  • CASE_INSENSITIVE:忽略大小写。

在RegexRequestMatcher中由于第一个构造方法caseInsensitive设置为了false,所以此处的值为0 代表使用默认状态。
第一个构造方法

    public RegexRequestMatcher(String pattern, String httpMethod) {
        this(pattern, httpMethod, false);
    }

修复

RegexRequestMatcher.java文件的修复是增加了对换行符的匹配以及忽略大小写

测试代码

/admin/.* 用于匹配以 /admin/ 开头的字符串,并且可以匹配任意字符的组合.
/admin/* 只匹配精确的 /admin/* 字符串

 public static void main(String[] args) {
      int DEFAULT =Pattern.DOTALL;
      String str="/admin/.*";
      Pattern p =Pattern.compile(str);
      String test="/admin/11"+"n";
      System.out.println(p.matcher(test).matches());// outcome:false
      Pattern p1=Pattern.compile(str,DEFAULT);
      System.out.println(p1.matcher(test).matches());// outcome:true

    }

参考:
https://www.cnblogs.com/TT0TT/p/16652577.html


原文始发于微信公众号(天才少女Alpha):CVE-2022-22978 漏洞分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年11月10日21:18:45
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2022-22978 漏洞分析http://cn-sec.com/archives/2195128.html

发表评论

匿名网友 填写信息