Работа над распаковкой TLS

This commit is contained in:
serega6531
2020-05-01 00:00:50 +03:00
parent 1cc9755d21
commit 49dcd974bc
7 changed files with 79 additions and 65 deletions

View File

@@ -39,16 +39,18 @@ public class LivePcapWorker extends AbstractPcapWorker {
applyFilter();
try {
log.info("Intercept started");
pcap.loop(-1, this, loopExecutorService);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
// выходим
} catch (Exception e) {
log.error("Error while capturing packet", e);
stop();
}
loopExecutorService.execute(() -> {
try {
log.info("Intercept started");
pcap.loop(-1, this);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
// выходим
} catch (Exception e) {
log.error("Error while capturing packet", e);
stop();
}
});
}
@SneakyThrows

View File

@@ -33,6 +33,7 @@ public class RsaKeysHolder {
@EventListener(ApplicationReadyEvent.class)
public void afterStartup(ApplicationReadyEvent event) {
log.info("Loading RSA keys...");
File dir = new File("rsa_keys");
if (dir.exists() && dir.isDirectory()) {
for (File keyFile : Objects.requireNonNull(dir.listFiles())) {

View File

@@ -21,27 +21,57 @@ public class StreamOptimizer {
*/
public List<Packet> optimizeStream() {
if (service.isDecryptTls()) {
decryptTls();
try {
decryptTls();
} catch (Exception e) {
log.warn("Error optimizing stream (tls)", e);
return packets;
}
}
if (service.isProcessChunkedEncoding()) {
processChunkedEncoding();
try {
processChunkedEncoding();
} catch (Exception e) {
log.warn("Error optimizing stream (chunks)", e);
return packets;
}
}
if (service.isUngzipHttp()) {
unpackGzip();
try {
unpackGzip();
} catch (Exception e) {
log.warn("Error optimizing stream (gzip)", e);
return packets;
}
}
if (service.isParseWebSockets()) {
parseWebSockets();
try {
parseWebSockets();
} catch (Exception e) {
log.warn("Error optimizing stream (websocketss)", e);
return packets;
}
}
if (service.isUrldecodeHttpRequests()) {
urldecodeRequests();
try {
urldecodeRequests();
} catch (Exception e) {
log.warn("Error optimizing stream (urldecode)", e);
return packets;
}
}
if (service.isMergeAdjacentPackets()) {
mergeAdjacentPackets();
try {
mergeAdjacentPackets();
} catch (Exception e) {
log.warn("Error optimizing stream (adjacent)", e);
return packets;
}
}
return packets;
@@ -51,7 +81,7 @@ public class StreamOptimizer {
final TlsDecryptor tlsDecryptor = new TlsDecryptor(packets, keysHolder);
tlsDecryptor.decryptTls();
if(tlsDecryptor.isParsed()) {
if (tlsDecryptor.isParsed()) {
packets = tlsDecryptor.getParsedPackets();
}
}

View File

@@ -99,6 +99,7 @@ public class TlsDecryptor {
}
}
@SneakyThrows
private void decryptTlsRsa(String blockCipher, String hashAlgo) {
Optional<RSAPublicKey> publicKeyOpt = getRsaPublicKey();
@@ -144,18 +145,8 @@ public class TlsDecryptor {
bb.get(clientIV);
bb.get(serverIV);
Optional<byte[]> clientFinishedOpt = getFinishedData(true);
Optional<byte[]> serverFinishedOpt = getFinishedData(false);
if (clientFinishedOpt.isEmpty() || serverFinishedOpt.isEmpty()) {
return;
}
byte[] clientFinishedEncrypted = clientFinishedOpt.get();
byte[] serverFinishedEncrypted = serverFinishedOpt.get();
Optional<Cipher> clientCipherOpt = createCipher(clientEncryptionKey, clientIV, clientFinishedEncrypted);
Optional<Cipher> serverCipherOpt = createCipher(serverEncryptionKey, serverIV, serverFinishedEncrypted);
Optional<Cipher> clientCipherOpt = createCipher(clientEncryptionKey, clientIV);
Optional<Cipher> serverCipherOpt = createCipher(serverEncryptionKey, serverIV);
if (clientCipherOpt.isEmpty() || serverCipherOpt.isEmpty()) {
return;
@@ -174,13 +165,8 @@ public class TlsDecryptor {
byte[] data = ((ApplicationDataRecord) tlsPacket.getRecord()).getData();
boolean client = packet.isIncoming();
byte[] decoded;
if (client) {
decoded = clientCipher.update(data);
} else {
decoded = serverCipher.update(data);
}
Cipher cipher = client ? clientCipher : serverCipher;
byte[] decoded = cipher.doFinal(data);
decoded = clearDecodedData(decoded);
@@ -246,14 +232,13 @@ public class TlsDecryptor {
}
@SneakyThrows(value = {NoSuchAlgorithmException.class, NoSuchPaddingException.class})
private Optional<Cipher> createCipher(byte[] key, byte[] iv, byte[] initData) {
private Optional<Cipher> createCipher(byte[] key, byte[] iv) {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // TLS_RSA_WITH_AES_256_CBC_SHA
SecretKeySpec serverSkeySpec = new SecretKeySpec(key, "AES");
IvParameterSpec serverIvParameterSpec = new IvParameterSpec(iv);
try {
cipher.init(Cipher.DECRYPT_MODE, serverSkeySpec, serverIvParameterSpec);
cipher.update(initData);
return Optional.of(cipher);
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
@@ -263,26 +248,12 @@ public class TlsDecryptor {
}
private byte[] clearDecodedData(byte[] decoded) {
int start = 32;
int end = decoded.length - 6; //FIXME
int start = 16;
int end = decoded.length - 21; // почему?)
decoded = ByteArrays.getSubArray(decoded, start, end - start);
return decoded;
}
private Optional<byte[]> getFinishedData(boolean incoming) {
var contentOpt = tlsPackets.asMap().entrySet().stream()
.filter(ent -> ent.getKey().isIncoming() == incoming)
.map(Map.Entry::getValue)
.flatMap(Collection::stream)
.filter(p -> p.getContentType() == ContentType.HANDSHAKE)
.map(p -> ((HandshakeRecord) p.getRecord()))
.filter(r -> r.getHandshakeType() == HandshakeType.ENCRYPTED_HANDSHAKE_MESSAGE)
.map(r -> ((BasicHandshakeRecordContent) r.getContent()))
.findFirst();
return contentOpt.map(BasicHandshakeRecordContent::getContent);
}
private Optional<HandshakeRecordContent> getHandshake(HandshakeType handshakeType) {
return tlsPackets.values().stream()
.filter(p -> p.getContentType() == ContentType.HANDSHAKE)