I used this MS link to put together a TCP server in C# on a PC. I'm holding the port open and waiting for connections to be established by various PLC clients. The PLCs are in moving autonomous bots, so they move in and out of Wi-Fi range. I'm using this setup to acquire running variables (battery %, etc.) from the bots and display them in a UI for the system administrator to monitor.
I setup the router with port forwarding so that the data arrives on the server PC from the various clients. I'm using Siemens S7-1200 PLCs and I don't believe that they support high end security features like PCs.
So my question is this, if the admin PC is running a Windows service that constantly monitors the open port then is there a security risk? And if there are risks, can you please explain and support with links or resources to help me patch these holes (in C#)?
It seems safe to me because if the PC is off, the port is closed. If the PC is on, the port is open but is bound to the application monitoring it. If the port receives something that it does not deem valid it just dumps that data. I am not incredibly knowledgeable on software and PC security, but this is slightly different because it is a single PC interfacing with less capable hardware.
Having a port open exposes you to anyone connecting to that port and providing bad information, exposing a vulnerability on your message parsing and socket handling implementation (buffer overflow or script injection), or just swamping your application with traffic. The last one is almost impossible to protect against, someone can always DOS you at some level.
None of these are unexpected risks, but you need to be aware of them and ensure that you properly scrub incoming traffic to reject malformed requests and somehow authenticate and drop connections that aren't from the bots you expect.
If you do make an authentication step, you'll want to encrypt the channel before authentication using something like SSL or SSH. Otherwise, someone else could watch your traffic, observe the authentication transaction, and then just copy it.
Best of luck! Security is a deep rabbit hole, but a very valuable skill!
Related
I'd like to know if a connected socket is using telnet or a different protocol.
What is required to know this? Do I need to inspect network traffic?
Also is there a third party library that might help me?
Interesting question. The first hint that a user is connecting to a "Telnet" socket is the port number, the official port is 23, however the server could be listening on any port.
The biggest issue with detecting Telnet is that there isn't always a strict "Telnet" protocol in use (although one exists) because the server can choose not to implement it and simply talk straight vanilla ASCII. You're essentially dealing with plain ASCII characters and (optional) control characters travelling over a plain old TCP connection. There are some big hints that most telnet servers give out that give them away though, but you'll need to inspect the traffic to be sure.
The things to look for in the network traffic are:
The traffic is mostly ASCII characters, usually with English words or linux program names in the mix.
Control characters. These are not guaranteed to be implemented by all Telnet servers (or the terminal sitting behind it), but almost always are. Specifically look for CSI control codes, which do things like change terminal size, colour, and cursor position.
The smoking gun, Telnet Negotiation. Usually the Telnet server sends these commands upon connection, and the client can respond with information as well. It handles some other functions such as terminal resizing and character sets as well, but again, not all servers implement this. From this info, you can usually scrape what client application the client is using (eg Putty).
Detecting any of these things in a TCP connection is a pretty big indication that a Telnet session is taking place.
We are developing a server application which will listen all the connections (TCPListener) from external devices 24/7 and store these messages in our database.
For these connections, we are opening a port (let's say 13002) in our server. We would like to make this port secure which means that someone will not be able to scan ports, and connect and send thousands of requests to this specific port to make our application slow and even out of order.
Any ideas?
Use a firewall.
In computing, a firewall is a network security system that monitors and controls the incoming and outgoing network traffic based on predetermined security rules. A firewall typically establishes a barrier between a trusted, secure internal network and another outside network, such as the Internet, that is assumed to not be secure or trusted.
If given is your definition of "secure":
someone will not be able to scan ports, and connect and send thousands of requests to this specific port
Then a properly configured firewall will do.
That will however not prevent malicious users from doing harm to your software. If someone can figure out the protocol you use through packet inspection, they can fire arbitrary requests to your application.
This means that if your protocol is not well-designed, users can impersonate other users, send messages they're not supposed to and thus perform actions they're not allowed to.
Just putting a firewall in between will not make your protocol more secure.
I'm having difficulty finding help resources on this. I know how to use the TCPClient class to create a connection between one IP/Port/machine and another.
My doubt is how does that work when one machine wants to initiate a TCP connection to another machine where the destination machine is inside a different network. So the destination network may have hundreds of computers each with its own private ip and the network would have one public IP address. This would be using the TCPClient class or any other that is more appropriate.
I know we could use ports and then inside the network the port could be forwarded to the correct machine but I was looking for a solution like the one services like LogMeIn use. Basically I wanted to use port 80 always and then initiate the connection from the server to that particular machine or others on the same network when I needed.
I suppose, theoretically, I could create the connection first from inside that network, then on the server, save the details and close the connection and then in the near future, when I needed, I would re-open the connection.
So in my scenario, I would have many clients across multiple networks, each network might have multiple internal machines with a client installed. Then on the server I would initiate connection to these machines when needed. Within each network I would want to use port 80 for obvious reasons. The reason I want to initiate the connection from the server and not the client machines is simply to save resources, I couldn't cope with having opened connections until eventually I might need to communicate wit them.
Also, I have no control on the client networks besides them having my client installed.
Ideally, I wish to have c# info, possibly code and not network configuration.
I had this requirement at a previous company. We installed our client/server software (C# based) on numerous different networks with a mix of public/private IPs. I found two relatively simple ways to solve it. First, I want to say that without a public IP, its impossible to connect reliably (in my experience).
When I proposed the solution, I explained the problem to other developers/managers this way.
Your server, the machine with the public IP address [public to clients, but may still be an "internal address"], is like a house without any long distance calling. It can receive calls, but it can't make any calls. The clients are like houses with long distance service. Clients must call the server, because they have long distance. Once connected, any party can talk on the line.
From here you have two choices.
Client connects and never disconnects (this is what I implemented). On the server, I had an object that mapped the client object to the client connection so I could communicate any time with a client that was connected.
Server holds a queue of messages for the client. The client automatically connects on a fixed interval to see if there are any messages (maybe 5 minutes). There would be an option from the server to stay connected for a specific interval. Another vendor called this "fast talk".
There's a couple of approaches.
You could setup NAT - probably no good for your scenario.
You could make an outbound connection from your client.
You could "combine the above" by using STUN (see http://en.wikipedia.org/wiki/STUN) this is quite popular in VOIP for peer to peer scenarios.
The Windows Azure servicebus may have a solution for your problem; NetTcpRelayBinding in hybrid mode allows two comuters behind NAT to create a direct connection with each other. This might not solve your problem if you are money constrained as each connection has an associated cost.The simplest solution is probably to have the clients polling your server.
You may use SignalR, which has been developed for this kind of scenarios.
You must have a third party, though (a server which broadcasts messages from sender to other peers).
But the beauty of this technology is that it chooses the most appropriate way to push data to clients: Polling, long connections, sockets... etc.
This provides an abstraction layer which is quite comfortable.
It has been designed to interact with javascript clients, but may be used in full-C# clients as well.
You need a third server that acts as proxy between your machine and target machine that is behind a firewall.
That is how applications like LogMeIn work.
You can do this using SSH tunnels.
Please check https://serverfault.com/questions/285616/how-to-allow-remote-connections-from-non-localhost-clients-with-ssh-remote-port
The topic is about NAT traversal.
STUN is good choice to try to communicate with client behind NAT.
But if STUN don't work,you can use RELAY service to help to pass the message between your server and remote client.RELAY service is a public service that everyone can reach it.
We are planning on implementing our new software application as shown below.
Does this architecture look fit for purpose?
Items to Note:
There are many PC's
The pc has a WCF client as it needs to upload data to the
database periodically.
The PC has a server because the end user on the terminal server needs
to be able to interrogate the pc for information
The terminal server is the GUI for users so they can remotely connect
to a specific PC to interrogate the pc for information
We are using basicHttpBinding below
What else have we considered?
We have tried WCF NetPeerTcpBinding (i.e P2P) but it does not support
request-reply operations.
We have tried WCF Duplex but with the requirements listed above in the items to note section we would end up with a client and server at both ends anyway.
Well I apologize but I basically disagree with your architecture.
WCF is not designed or suited for anything other than a request-response communication.
Its full duplex ability will not enable your server side to issue communication to a specific client unless that client already issued a connection to the server.
That means that in order to achieve a prestigious online full duplex communication with all your clients - all your clients must maintain an open port to the server.
Having a dual client and server per PC in order to achieve an online full duplex is a step forward as it will solve the issue of keeping a port open per client however it has downsides in terms of security as it means that the specific PC is open to receive multiple connection requests. Another issue can occur with deadly reentrancies if you not careful. So, basically you will be saving 'ports' in exchange for architecture
maintainability and fitness to your solution.
So if you are targeting a deployment of around 200-300 PC's your architecture will hold but if you are targeting a larger deployment of thousands of PC's - it will not hold.
What I have read so far, winPcap allows you to bypass OS and bypass application and transport layer processing for TCP and provides direct access to the link layer.
I am planning to use winpcap to do some user application stuff and not just sniffing. I will be receiving and sending critical information using pcap which I am currently doing via sockets.
Does bypassing OS, and according to my understanding application and transport layers on my side, involve any risks?
As a side question the winpcap documentation I have found so far talks about how to programatically implement it but does'nt tell in detail what it is bypassing and how does it do that. Any link to that will be helpful.
Also, I'd like to know if anyone is using winpcap for any purposes other than network sniffing for monitoring reasons and msn.
Sure, there are plenty of risks:
The OS won't know about your privately-managed TCP connections, so it won't know that the port(s) you've chosen is/are in use. This means that it might try to use the same port for another application's connection, leading to chaos.
The OS won't know about your privately-managed TCP connections, so unless you prevent it from seeing those packets, it will send RST packets to reset the apparently bogus connection.
Your application won't automatically be notified of changes to relevant OS-managed data, configured IP addresses and routing tables. You'll likely have to poll for updates.
Properly implementing the TCP protocol is non-trivial. Most implementations, even very well-used ones, had dormant bugs that weren't found for years. Not all the necessary information is in the RFCs, either; there are places where established practice differs from the documented behaviour, usually for good reason. There's also plenty of code in modern TCP stacks specifically to deal with historical buggy behaviour in other stacks, and replicating all that work isn't simple.
There's a substantial risk of bad interactions with third party network security software installed on the host, which will expect all TCP connections to be made via the OS.
It seems like a support nightmare to me.