Search code examples
javaproxyman-in-the-middle

Creating Java Proxy MITM


I'm trying to create a Java program as a proxy to view packets from an incoming source to debug. To do this, I have created a simple Java server application and have edited my host file on the device. Everything works fine as of now, (even my Relay class file) but I am trying to make it into a full fledged proxy. How could I incorporate elements to send data to the server, and send the response back to the client? Sort of like a Man-In-The-Middle type of thing.

import java.net.*;
import java.io.*;
import org.ini4j.Ini;

public class RelayMultiClient extends Thread {
    private Socket socket = null;
    Socket relay = null;

    public RelayMultiClient(Socket socket) {
    super("RelayMultiClient");
    this.socket = socket;
    }

    public void run() {

    try {
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                    socket.getInputStream()));
        if(Relay.max_clients == Relay.connected_clients) {
            //There are too many clients on the server.
            System.out.println("Connection refused from " + socket.getRemoteSocketAddress() + ": Too many clients connected!");
            out.close();
            in.close();
            socket.close();
        }
        else {
            Ini ini = new Ini(new File("settings.ini"));
            Relay.connected_clients++;
            System.out.println("Connection from client " + socket.getRemoteSocketAddress() + " established. Clients Connected: " + Relay.connected_clients);
            while (in.readLine() != null) {
                //Send data to the server
                //Receive data from server and send back to client
            }
            System.out.println("Connection from client " + socket.getRemoteSocketAddress() + " lost.");
            Relay.connected_clients--;
            out.close();
            in.close();
            socket.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    }
}

Thanks, Chris

P.S: I'm not attempting to get HTTP data, I am trying to get data from a game I have created. I don't know if this type of data requires any extra handling.


Solution

  • How could I incorporate elements to send data to the server, and send the response back to the client?

    Try the following example as basic proxy:

    public class Proxy {
        public static void main(String[] args) throws IOException {
            ServerSocket serverSocket = new ServerSocket(1230); // proxy port
            Socket socket = serverSocket.accept();
            Socket relay = new Socket("localhost", 1234); // server address
            new ProxyThread(relay.getInputStream(), socket.getOutputStream()).start();
            new ProxyThread(socket.getInputStream(), relay.getOutputStream()).start();
        }
    }
    
    class ProxyThread extends Thread {
        private InputStream inputStream;
        private OutputStream outputStream;
    
        ProxyThread(InputStream inputStream, OutputStream outputStream) {
            this.inputStream = inputStream;
            this.outputStream = outputStream;
        }
    
        public void run() {
            try {
                int i;
                while ((i = inputStream.read()) != -1) {
                    outputStream.write(i);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    It lacks proper exception handling, only demonstrating the basic idea.