How to make a TCP proxy in Golang for Pentesting
Monero ChanIntroduction
There are many ways to create a TCP proxy, the one I'm going to show is a turn based one, in which each other waits its turn to transmit data. There are some limitations in this method since the Server you with to connect may not send the control byte EOF (represented by NULL BYTE "\x00"). Because of this you are not able to check if the Server finished sending the packets or not, for this reason we are going to use a Timeout of 1 second (or more depending on your network).

Parsing the command line arguments
First we need to know which domain and port the user wants to connect to

The stdlib function "flag" allow us to parse the arguments, unfortunately it returns a pointer for primitive data types so I'm just dereferencing them and returning the function.
After building and running the program it would be used like this:

main function

Firstly we are simply receiving the parameters from the command line and showing them on the screen. After this we start a TCP listener on 0.0.0.0:1337 which means that we want to listen on ALL interfaces at port 1337. Then we check for any errors and we defer conn.Close() to the end of the program (which will never happen since we have an infinite loop).
Inside of our infinite loop we accept a new connection and show it on screen, then we use a goroutine to deal with the connection without blocking new connections.
handleConnection function

Here we have a lot happening under the hood, objectively the following is going on:
- The proxy connects to the server we requested
- User uses netcat to send data to the Proxy
- Proxy sends data to remote server
- Remote server answers the proxy
- Proxy sends data to the client (the user)
- Both the sockets are closed
Firstly we have a variable block with everything we are going to use. Then we use net.Dial so the Proxy can connect to the remote server using TCP. I created only the "read" functions because of how each endpoint works.
Since we are requesting HTTP we have to put in mind that netcat sends TCP packets on each \n and a valid HTTP ends with \r\n\r\n, these problems are solved inside of readFromNetcat.
readFromNetcat funcion

totalBuffer is the variable that will store every single byte that we are receiving from different TCP packets. As you can see from the last if condition, the only thing that breaks this loop is if the received bytes ends with two \n\n. That means that we should press Enter twice on netcat to "confirm" that we have sent everything.
In the start of the loop is created a buffer with 4096 bytes in length which is actually more than needed for the example I'm going to use. But that number is good since it is OK when you are doing real time processing and it is not too small to lose efficiency.
Then we use bytes.Trim to make our lifes easier since we now have a 4096 bytes long buffer full of NULL BYTES. After the trim the last bytes are the \n\n. Then we append \r\n\r\n to our request since the server cannot understand if we finished sending our data or not.
readFromRemote function

This function is very simple, we create a totalBuffer variable to store every single byte and we set a timeout of 1 second so that remote.Read doesn't wait forever. Inside the loop we put all the bytes inside tmpBuffer and then we trim to remove every NULL BYTE since all TCP packets may come with different amount of bytes. Then we finish by appending it to our totalBuffer
Conclusion

There are several ways of creating a proxy, this is one of the most basic kinds so we can put in practice low-level handling of sockets and bytes. Golang offers several tools to ease the use of HTTP but everything is dependent on what you want to add to your proxy.
It is very useful in Pentests where there is no Python installed on the victim's machine or there are just not enough tools installed. It is also useful when you need to be "stealthy" so you don't get caught by Intrusion Detections Systems.