KoreanHackerTeam
Moderator
0x00 漏洞描述
1.5.2 이전에 Apache Shiro에 보안 취약점이 있습니다. 공격자는 특별히 제작 된 요청을 사용하여 인증을 우회 할 수 있습니다. Shiro Framework는 Anon, AuthC 및 기타 인터셉터와 같은 인터셉터 기능을 통해 사용자 액세스 권한을 제어합니다. Anon은 익명의 인터셉터이며 로그인에 액세스 할 필요가 없습니다. AuthC는 로그인 인터셉터이며 액세스에 로그인해야합니다. Shiro의 URL 경로 표현식은 개미 형식입니다. 경로 와일드 카드 *는 0 이상의 문자열과 일치하는 것을 의미합니다./*와 일치 할 수 있지만 * 와일드 카드가 경로와 일치 할 수 없기 때문에 일치 할 수는 없습니다. /hello 인터페이스에 AuthC 인터셉터가 설정되어 있다고 가정하면 액세스 /hell Spring의 양식 /hello 및 /hello//hello//hello /hello의 URL에서 액세스하는 리소스는 동일하므로 권한 우회를 달성합니다.0x01 漏洞影响
Apache Shiro 1.5.20x02 Shiro拦截器
Shiro 프레임 워크는 인터셉터 기능을 사용하여 사용자 액세스 권한을 제어하고 가로 채립니다. Shiro의 일반적인 인터셉터에는 ANON, AUTC 및 기타 인터셉터가 포함됩니다. 1. ANON은 익명의 인터셉터이며 로그인하지 않고 액세스 할 수 있습니다. 일반적으로 정적 리소스 또는 모바일 인터페이스에 사용됩니다.2. AUTHC는 액세스에 로그인 인증이 필요한 리소스입니다. 사용자는 Shiro.ini에 일치하는 URL 구성을 작성할 수 있으며, 이는 일치하는 URL을 가로 채고 응답 인터셉터를 실행합니다. 이것은 URL의 액세스 제어를 실현하고 URL 경로 표현식은 일반적으로 개미 형식입니다. 다음 구성으로 /index.html 홈페이지에 액세스 할 때 Shiro는 로그인 판단을하지 않으며 Anon 인터셉터는 로그인하지 않고 액세스 할 수 있습니다. /user /xiaoming 등과 같은 인터페이스의 경우 Authc 인터셉터가 판단하기 위해 로그인하면 로그인 인증이있는 경우에만 리소스에 액세스 할 수 있습니다. [URLS]
/index.html=anon
/user/**=authc
Shiro의 URL 경로 표현식은 개미 형식이며, 경로 와일드 카드가 지원 되는가? ***. 캐릭터와 일치합니다
*: 영역 이상을 일치시킵니다
** : 경로에서 0 이상의 경로를 일치시킵니다
여기서 *는 0 이상의 문자열과 일치하는 것을 의미합니다./*는 /hello /hello /hello /와 일치 할 수 있습니다. * 와일드 카드는 경로와 일치 할 수 없기 때문입니다. /hello 인터페이스에 AuthC 인터셉터가 있다고 가정하면 액세스 /hello는 허가를받을 것입니다. 요청 된 URI가 /hello /인 경우 /*URL 경로 표현식은 올바르게 일치하고 해제되지 않습니다. 그런 다음 스프링 (서블릿) 인터셉터로 들어가면 /hello 양식 및 /Hello /Form의 URL에서 액세스하는 리소스가 동일합니다.
0x03 环境搭建
다운로드 데모 코드 :3https://github.com/lenve/javaboy-code-samples/tree/mas GroupIdorg.apache.shiro/groupId artifactidshiro-spring/artifactid version1.4.2/version/eppendency modify shiroconfig 구성 파일 및 authc interceptor @bean shirofilterctorybean shirofilterfactorybean () {shirofilterfactorybean bean (shirofilterfactorybean); //map.put('/* ','Authc '); map.put ( '/hello/*', 'authc'); bean.setfilterchainDefinitionMap (map); 귀환 콩; } 라우팅 컨트롤러 메소드 @GetMapping ( '/hello/{currentPage}') public String Hello (@PathVariable Integer CurrentPage) {return 'Hello';} 아이디어를 통해 컴파일하면 전쟁 패키지를 얻을 수 있습니다. 여기에서 Docker : Docker Pull Vulfocus/Shiro -CVE_2020_1957



0x04 漏洞复现
1. Shiro1.4.2 버전을 이용하십시오. AuthC 인터셉터가 가로 채고 로그인을 위해 로그인 인터페이스로 점프 할 수 있습니다.


보호 된 부울 경로 관리 (문자열 패턴, 문자열 경로) {
PatternMatcher PathMatcher=this.getPathMatcher ();
return pathmatcher.matches (패턴, 경로);
}
Domatch:109, antpathmatcher (org.apache.shiro.util), Shiro의 개미 형식 경로 패턴의 와일드 카드가 일치하는 경로를 지원하지 않으므로/hello/*는 성공적으로 일치 할 수 없습니다. 이것은 Shiro 인터셉터를 성공적으로 우회 한 다음 스프링 인터셉터에 들어갔다. /hello/1/및/hello/1은 동일한 리소스를 얻을 수 있습니다.





문자열 uri=(문자열) request.getAttribute ( 'javax.servlet.include.request_uri');
if (uri==null) {
uri=request.getRequesturi ();
}
Return Normalize (DecodeandCleanUistring (요청, URI));
}
DecodendCleanUistring 함수는 마침내 requesturi 함수에서 URI를 청소하기 위해 호출됩니다.
개인 정적 문자열 decodeandcleanUristring (httpservletrequest request, string uri) {
uri=decoderequestString (요청, uri);
int semicolonindex=uri.indexof (59); //숫자의 위치를 가져옵니다
반환 semicolonindex!=-1? uri.substring (0, semicolonindex) : uri;
}
A가있는 경우; URI의 번호는 삭제 된 후 모든 문자가 삭제됩니다. /fdsf ;/./hello/1/결국/fdsf가되었습니다.

0x05 修复方案
1. Shiro 1.5.2에서 추가 된 버전 1.5.2에 추가 된 필터 규칙을 업그레이드합니다. '/servlet', '/foobar', '/servlet/foobar') dottestgetPathwithInApplicationFromErquest ( '', 'servlet', '/foobar', '/servlet/foobar') dottestgetPathwithInapplicationFromRequest ( '', 'servlet', '/servlet/') dottestgetPathwithInapplicationFromEquest ( '/', 'servlet', '/foobar', '/servlet/foobar') dottestgetPathwithInApplicationFromRomRequest ( '//', 'servlet', '/foobar', '/servlet/foobar') DottestPathipplest (dottestwithinaptrest (//servertget” '/servlet/foobar') dottestgetPathwithInapplicationFromEquest ( '/context-path', '/servlet', '/foobar', '/servlet/foobar') dottestgetPathWithInApplicationFromErquest ( '//context-path', '//servlet', '//foobar', '/foobar'). dottestgetPathwithInApplicationFromEquest ( '//context-path', '/servlet', '/asdf', '/./servlet/other', '/servlet/other') dottestgetPathWithInApplicationFromErquest ( '//context-path', '/asdf', '/aSDF', '/asdf'). DottestGetPathwithInapplicationFromEquest ( '/context%2525Path', '/servlet', '/foobar', '/servlet/foobar') dottestGetPathWithInApplicationFromEquest ( '/c%6fnext%20 patp', '/servlet', '/server/foobar') DottestGetPathWithInApplicationFromEquest ( '/context path', '/servlet', '/foobar', '/servlet/foobar') dottestGetPathWithInApplicationFromRomRequest ( '', null, '/') dottestPathWithInapplicationFromEquest ( '')2. 동적 라우팅 인터셉터를위한 * 와일드 카드를 URL 경로 표현식으로 사용하지 마십시오.