What is the best way of reading, changing, and resending tcp communications?
For instance i have a server application that tells a master server it's alive sending a packet over TCP on port 3209. It sends out "I'm alive, my ip is xxx.xxx.xxx.xxx and I have currently 3 clients connected to me." the master server then responds, "Hello xxx.xxx.xxx.xxx i see you there."
Whats the best way of MITM of the server sending its packet to the master server? I would like to be able to change "i'm alive," to something like, "I'm changed," or even "currently 3 clients connected" to "currently 0 clients connected"
Any ideas appreciated, thank you.
There's no need to send out that kind of message.
First of all, TCP is connection oriented, so as long as you have a connection you'll be alive.
You can check if you're still connected by using the TCPClient.Connected property.
Secondly, TCP runs over IP so in the IP header you can find the sender IP (is in the socket properties) so no need to send the IP neither.
You can check the remote IP address by using TCPClient.Socket.RemoteEndPoint property.
Finally, the only thing you might be interested in telling is the "3 clients connected part" wich can be coded as a simple integer transmision. That is, a 4 bytes hearbeat.
Getting in the middle of the connection IS tricky and has nothing to do with communication protocols. And honestly it's a hell of a job, if there's a connection already present you'll have to find a way to make the client or the server drop it and then have the server reestablish it to your MIDM. More though, if the connection is made directly to an IP address you'll have to mess with the router tables somehow for the attact to be succesful, if it's not maybe DNS poisoning will work for you... anyway not an easy task.
Those are only ideas... it depends on the class of network, if you have physical access or not, if the client and the server trust each other (as in if they are your applications) and so on... I assume all this is ethical or educational at least... :)
Have a look at SharpPcap or any other packet capturing/injecting library.
In order to MITM, you'll have to force the client to think you're the server and the server to think you're the client. For that, you'll have to send ICMP packet to both machines as described here. Then, you will capture the packets, modify them and inject them to the network (with the correct MAC address).
Pick a different tool - this is too low level a kind of thing to attempt in C#. This kind of thing is achieved (on Vista and later) using the Windows Filtering Platform
Related
I've developed a basic console application that will work as server-client. My general workflow will be like, Server starts clients connect to server and once a client send something the server will receive it and send it to ALL clients. Currently I can do this with my codes but my question is when I send back I've tested Socket.RemoteEndPoint and I saw ports like 65xxx. Like my first client had 65020, second 65021 and so go on. I wonder why this happen since I connect with using 9001 port and listen to 9001 port on my computer. I've done a little bit research but couldn't find a solution to my question. Why do I get these port numbers when I use Socket.RemoteEndPoint? It's okay for me since I don't use firewall or anything while I'm testing to even if the clients connects from another ports it's fine by me as long as its works but what if I have a firewall and I open ONLY 9001 port? Will my client-server based programs work then?
So far as the server/firewall on that machine is concerned, what normally matters is the server port. You wouldn't normally apply any filtering based on the client's port, which as I said in a comment, will normally be an ephemeral port. Under most circumstances, client code will make no effort to specify the local port or IP address and will let the OS pick appropriate values.
The Socket class's LocalEndPoint and RemoteEndPoint use "local" and "remote" to mean "from the perspective of the machine on which this code is running", not "who initiated the connection vs who was connected to".
So on the server, LocalEndPoint will give you information about the server end of the connection and RemoteEndPoint will give you information about the client end of the connection. Irrespective of who initiated the connection.
I have a server that i use to run game servers on for my friends and me, and some of the servers are "attack-able" (monsters can destroy our base) so i want the server to be shut down when not in use. Then i was wondering if there was a way to detect if there was an incoming signal (trying to connect to the server) on the given port, so the server can be turned on?
Raw question:
Is there a way to detect, if someone is trying to send a message (or connect) through a specific port in c# (or another language better suited for this action)?
Yes, you have to create a server to listen on that port. The problem you will face is that the server you create to detect incoming connections will need to be shut down so the game server can be turned on. They can't listen on the same port unless they're coded to work together and that likely isn't going to be the case with your game server.
If you want to see if there is any connections in use you can try to list all current TCP connections (assuming server using TCP) and find if there is any alive connection to specific port.
Resmon does this in his "Network" tab, so there must be a way to access it programmatically.
Here is answer describing how to get active TCP connections.
How can I get all the the active TCP connections using .NET Framework (no unmanaged PE import!)?
You probably should monitor server with some intervals because player might lose and reestablish connection, so sample it every 10 seconds or so and if there is no connection for more than few samples - shut down the server.
I'm currently trying to make an online video game, which currently uses TCP to send packets. I want to use UDP, but I'm extremely new to UDP and I'm having some issues.
When I test my server/client(s) on the same computer (localhost), the packets seem to be interfering with each other.
For example, if the client sends a packet to the server (UDP, 127.0.0.1:1338), the client ends up receiving the packet, since the client is also listening for packets from 127.0.0.1 on port 1338. Similarly, when I try to test 2 clients and 1 server, the clients may send out packets which are meant for the server, but are picked up by the other client.
How can I test UDP on localhost since all packets are being received from/sent to 127.0.0.1:1338? Do I need to implement some sort of layer in my packets that distinguishes if the packet is meant for the server, or a specific client?
Only your Server should listen on the defined port number (1338). Each client should select a free port number and send the server this port number. The server has to store the client information and send then the packets to the clients in this client list.
The clients should also send a goodby packet when the client is closing to know on the server side which clients are still available and which aren't participating anymore.
You should also implement some kind of housekeeping in this client list. For example store the timestamp of the last received packet from the client and remove clients that haven't sent data for some time (crashed client, lost connection ...) from the list.
An additional layer will not help - because the server may never actually get the packet.
Make the ports on the server and client configurable. That way you could have different ports on the same machine for testing and change it when going to production. Just remember you need to configure both ports in both the client and server. This is a good practice anyway.
You still have another problem - of several clients residing on the same machine and listening to the same port. You can have a random port for each client (the client selects one in random and then notifies the server). Or you can try binding to different IP addresses (one will use 127.0.0.1 an another will use the real IP of the PC), but it's not extensible.
If you are going to use this in a LAN setup, then you can always filter the received packet based on the sender's address -- recvmsg() of UDP allows you to retrieve sender's address and port number. If you are going to use this in a WAN setup, then this likely would not be an issue unless you are trying to do multicast. And, even with multicast, duplciate packets are not send back to the receiver. You can use IP_MULTICAST_LOOP to disable this option.
I was wondering it it was possible to relay a socket object in either C# or Java? (Preferably C#)
I have lots of little programs i make and host them on my home pc, but my pc is behind a router, so i have to forward a port on my router every time i want to make a new application. So is there a way to send a tcp connection to another application on the same computer? for instance i get a connection in with the first line of text being RELAY::21005 which would then forward that port to localhost:21005 ?
Any help, tutorials, code snippets would be much appreciated. Thank you! :)
One problem you might face with your suggested solution (first line identifies target port) is that you'll have to change all of your client programs to send that first line. That's easy for programs you've written yourself but not so convenient if you want to connect to your PC's web server or ssh daemon etc. It's not impossible of course, but does make it hard.
I'd suggest your routing server listens on two ports - a control port and a "normal" port (I can't think of a better name at the moment). You would send control messages to the control port to indicate "until further notice redirect all incoming connections on the normal port to port nnnn". That avoids having to manipulate client protocols.
I don't know enough C# to provide advice about a C# solution, but in Java I'd simply do something like:
while (true) {
acceptConnectionOnNormalPort()
connectToTargetPort()
startThreadCopyingDataFromAcceptedPortToTargetPort()
startThreadCopyingDataFromTargetPortToAcceptedPort()
}
You'd not be able to scale that easily into thousands of connections...
K I take back my comment, check this out:
http://msdn.microsoft.com/en-us/library/aa395195.aspx
Using this requires the port sharing service to be up (it is disabled by default):
The Net.TCP Port Sharing Service is available on all operating systems
that support .NET Framework 3.0, but the service is not enabled by
default.
All of this is only useful to you if you are using WCF services tho.
The easiest approach IMO is to use ssh tunneling. As I wrote in my comment, there are lots of questions on SU that will show you how to do this.
But assuming that you want to program something ...
You'll need to create a client and a server. The client will have threads that call accept on whatever local ports you want to open. When a connection comes to a port, you create another thread that opens a connection to the server and continually sends data over the wire.
The server program listens on a single port, which you open in your firewall. It waits for connections on that port, and when it receives one it opens a connection to the specified local port. Then it shuffles bytes from one to the other.
The only trick is that you have to define a protocol for specifying the destination port in the client-server stream. Simplest approach is to write a two-byte integer at the start of the stream.
Yes, it is possible to relay a socket.
You can use TURN http://en.wikipedia.org/wiki/Traversal_Using_Relay_NAT
Some of TURN library/application:
pjnath
turnserver.sourceforge.net
I am very interested in at least trying to implement NAT break through for my senior project.
(I am doing a networking API).
It's not even a requirement of my project, just a interest of mine.
I know the basics of how it works, correct me if I'm wrong:
Two clients connect to a server that isn't behind a NAT and this server, knowing the IP of these two clients, tell the clients to connect to each other at the same time. Thus the "Breakthrough".
This seems not terribly easy or terribly hard to code.
However, the part I'm stuck at is the testing of this. Is there a reasonable setup I can do with just one router/one NAT and my three available computers?
Thanks for any advice!
In terms of code/theory on NAT breaking, I cannot offer advice, but I can make some suggestions on setting up a test environment.
You can download a copy of m0n0wall and run it inside of a Virtual PC image (both free). This will give you a second router w/out purchasing any additional hardware. With this extra router, you can create a seperate subnet for your two clients.
Another, easier to grasp option is simply to pickup a second router, you can get a good one pretty cheap.
Then setup your existing router and server as they are now, a 192.168.1.x /24 subnet; then setup your second router (m0n0wall/hardware router) as 192.168.2.x /24 subnet, and plug the second router's "internet" port into one of the "PC" ports on your first router. Then plug both clients into the second router.
(I realize thats a bit confusing, comment if you cannot follow what I mean)
Let me see if I have this straight. You have two clients that are both behind NAT and a server that is not. Both clients connect to the server and are informed of the public facing IP address of the other. Since each now has a destination, they disconnect from the server and connect directly through their respective NAT boxes to each other. Is that your thinking? If so, I may have some bad news for you.
In order for this to work at all, you will have to have dedicated ports set up in each NAT configuration to forward at least one external port to a predefined internal IP address/port number. In a generic NAT setup outgoing connection requests will be captured by the NAT which will open a temporary external port. That external port number is used only for communications to that one originating address and port. When the connection is closed, that external port goes away and will be reassigned for another connection later. So if both clients talk to the server and then disconnect, the information the server sent them is now invalid.
Assuming you've worked around this somehow, it should be fairly easy to just connect both clients to the "internal" side of the NAT and the server PC to the "external" side. Then you have to hope that your NAT box is smart enough to loop back packets from one local external port to another. I'm sure that netfiler could be configured this way but I doubt a home internet "router" (e.g., Linksys, NetGear, etc.) would do it of the shelf.