Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Monitor outgoing traffic of UDP and TCP protocols to monitor if all connections are monitored and inform about it in logs #51

Open
marwin1991 opened this issue Nov 18, 2024 · 8 comments

Comments

@marwin1991
Copy link
Collaborator

@witx98 what do you think about something like this?

@witx98
Copy link
Member

witx98 commented Nov 21, 2024

I found some relevant information regarding TCP and UDP support in Spring Integration that might be useful for this issue https://docs.spring.io/spring-integration/reference/ip.html
Could you please clarify what exactly we want to know about these connections?
@marwin1991

@marwin1991
Copy link
Collaborator Author

@witx98 I was thinking about something more like this https://stackoverflow.com/a/63197003

The idea is that, application can do some connections, but we don't know about it and this should capture it and print to logs (if it's not monitored by hofund)

@witx98
Copy link
Member

witx98 commented Nov 21, 2024

The approach mentioned in the Stack Overflow is based on SecurityManager which is deprecated and planned for removal in future Java versions. @marwin1991

@marwin1991
Copy link
Collaborator Author

@witx98 yes, but maybe we can find something inside JVM or lib that will allow us to do it :)

@Athi
Copy link
Collaborator

Athi commented Nov 21, 2024

@marwin1991
Copy link
Collaborator Author

marwin1991 commented Nov 24, 2024

@Athi @witx98

I have made some simple research and jnetpcap-wrapper but it requires Java23.

package abc;

import org.jnetpcap.Pcap;
import org.jnetpcap.PcapException;
import org.jnetpcap.PcapHeader;
import org.jnetpcap.PcapIf;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;

public class Test {

    void main() throws PcapException {
        List<PcapIf> devices = Pcap.findAllDevs();
        for(PcapIf device: devices) {
            try (Pcap pcap = Pcap.create(device)) {
                pcap.activate();
                pcap.loop(0, (String msg, PcapHeader header, byte[] packet) -> {
                    System.out.println(msg + " " + header.toString() + " " + new String(packet));
                }, "[" + device.name() + " - Capture Example]");
            }
        }
    }

    public static void main(String[] args) throws PcapException {
        System.out.println("Przed inicjalizacji");
        new Thread(() -> {
            try {
                new Test().main();
            } catch (PcapException e) {
                throw new RuntimeException(e);
            }
        }).start();
        System.out.println("Po inicjalizacji");

        try {
            // Create HttpClient
            HttpClient client = HttpClient.newHttpClient();

            // Create HttpRequest
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(new URI("https://www.google.com"))
                    .GET() // Optional, as GET is the default method
                    .build();

            // Send request and receive HttpResponse
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

            // Print the response
            System.out.println("Status Code: " + response.statusCode());
//            System.out.println("Response Body: ");
//            System.out.println(response.body());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

I don't now yet how to properly capture traffic, because it looks like it capute with delay (i dont see this call, but I see traffic I made from browser).

The second thing to do is to verify how to get url from raw network package

@marwin1991
Copy link
Collaborator Author

marwin1991 commented Nov 24, 2024

this looks nice and simple:

package pl.com.softnet.jbramka;

import java.net.*;
import java.io.*;
import java.util.*;

public class MonitorOutgoingTraffic {

    public static void main(String[] args) {
        ProxySelector.setDefault(new LoggingProxySelector(ProxySelector.getDefault()));

        // Example outgoing request
        try {
            URL url = new URL("https://example.com");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            System.out.println("Response Code: " + connection.getResponseCode());
            connection.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class LoggingProxySelector extends ProxySelector {
    private final ProxySelector defaultProxySelector;

    public LoggingProxySelector(ProxySelector defaultProxySelector) {
        this.defaultProxySelector = defaultProxySelector;
    }

    @Override
    public List<Proxy> select(URI uri) {
        System.out.println("Outgoing connection detected: " + uri);
        return defaultProxySelector.select(uri);
    }

    @Override
    public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
        System.err.println("Connection failed to URI: " + uri);
        ioe.printStackTrace();
    }
}

output:

Outgoing connection detected: socket://127.0.0.1:40563
Outgoing connection detected: https://example.com/
Outgoing connection detected: socket://example.com:443
Response Code: 200

Process finished with exit code 0

@marwin1991
Copy link
Collaborator Author

Other option is to use AgentBuddy

package abc;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;


import static net.bytebuddy.matcher.ElementMatchers.named;

public class MonitorSocketTraffic {


    public static void main(String[] args) {
        // Install ByteBuddyAgent dynamically
        ByteBuddyAgent.install();

        // Redefine the Socket class using ByteBuddy with reloading strategy
        new ByteBuddy()
                .redefine(Socket.class)
                .visit(Advice.to(SocketAdvice.class).on(named("connect")))
                .make()
                .load(Socket.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());


        // Example outgoing request
        try {
            URL url = new URL("https://example.com");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            System.out.println("Response Code: " + connection.getResponseCode());
            connection.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static class SocketAdvice {
        @Advice.OnMethodEnter
        public static void onEnter(@Advice.Argument(0) Object address) {
            System.out.println("Outgoing connection: " + address);
        }
    }
}

output:

WARNING: A Java agent has been loaded dynamically (/home/pz2/.m2/repository/net/bytebuddy/byte-buddy-agent/1.15.10/byte-buddy-agent-1.15.10.jar)
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
WARNING: Dynamic loading of agents will be disallowed by default in a future release
Outgoing connection: example.com/93.184.215.14:443
Response Code: 200

Process finished with exit code 0
		<dependency>
			<groupId>net.bytebuddy</groupId>
			<artifactId>byte-buddy</artifactId>
			<version>1.15.10</version>
		</dependency>
		<dependency>
			<groupId>net.bytebuddy</groupId>
			<artifactId>byte-buddy-agent</artifactId>
			<version>1.15.10</version>
		</dependency>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants