When we send a packet from a udp port we receive an exception if the network returns an ICMP host unreachable. The exception doesn't tell us anything useful (like the contents of the ICMP packet).
No problem, we'll just listen for ICMP and that will give us the info we need, while ignoring the exception on the UDP port. So, open a raw socket, listen for ICMP packets and go from there.
Works fine in development (Win XP) but in production on server 2008 it appears the security context the exe is running in must have admin rights to be able to open a raw socket. This is useless for a service. If I understand what Microsoft are saying then the only way we can do what we want is run our service under an account with admin rights. Feels a bit like sledgehammer for a peanut not to mention a potential security hole that goes with having a network facing service running under an admin account.
I really hope I am wrong here but I can't seem to find anything that contradicts the above.
Anyone got any comments / hints or sympathy?
Rather than listening for ICMP responses to your failed UDP sends, why not send a brand spanking new ICMP echo request?
When you get the exception, you could PInvoke the IcmpSendEcho() function (from Win32 IP Helper API) to generate a new ICMP echo request yourself. The key bit is that the function returns a buffer with the echo reply in it, including status codes e.g. IP_DEST_HOST_UNREACHABLE.
I don't think you need any special privileges to do this, so it should be easier than listening for ICMP replies with raw sockets.
You will need three functions: IcmpCreateFile(), IcmpSendEcho() and IcmpCloseHandle() - PInvoke.net has the necessary interop details:
http://www.pinvoke.net/default.aspx/icmp/IcmpCreateFile.html
http://www.pinvoke.net/default.aspx/icmp/IcmpSendEcho.html
http://www.pinvoke.net/default.aspx/icmp/IcmpCloseHandle.html
Had exactly the same issue myself Listen for ICMP packets in C#. Actually looks like your issue is windows permissions so that post won't help.
One area I was planning on delving into a bit further is to check whether there is anymore information in the SocketException generated by the UdpListener. It just seems unreasonable that as Windows is using the ICMP packet to generate the exception it wouldn't be recording the information in that packet somewhere.
Like you I have not been able to get very far with getting the ICMP info out of the exception information at the .Net level but I want to see if there is anything further that can be obtained with the Win32 API such as GetLastError or some other calls specifically for WinSock32.
From the MSDN website:
To use a socket of type SOCK_RAW
requires administrative privileges.
Users running Winsock applications
that use raw sockets must be a member
of the Administrators group on the
local computer, otherwise raw socket
calls will fail with an error code of
WSAEACCES. On Windows Vista and later,
access for raw sockets is enforced at
socket creation. In earlier versions
of Windows, access for raw sockets is
enforced during other socket
operations.
To get around this problem in my project , I've created a Windows service that serves as a network proxy for our UI application. The Windows serves runs under the local admin account in order to get around the limitations. The application connects to the service using WCF, telling it what kind of socket to open and what filter(s) to apply. The data is then sent back via callback using Protocol Buffers for encoding (at least that's the plan - the callback part is still in progress).
Related
I want to build a program that will run on my Raspberry Pi and starts processes when I connect to it. I want to run a specific processes if there is a connection on a specific port.
So I need to get the port somebody is trying to connect to.
For example:
If I open localhost:4444 in my browser I want to get 4444 as a string or an int.
It doesn’t need to be C#. Would be great, but it can also be in other languages.
Is this possible and how can I achieve that?
Listening for an incoming packet on any port number, rather than on a specific port number, is an unnatural act on Linux (the rPi's OS) and on most operating systems.
You could probably, with a lot of work, figure out how to do it with the tcpdump command line utility and/or its underlying libpcap runtime library. This subsystem intercepts network messages at the driver level and reports them. You could write a hunk of code that notices an incoming connection request and launches a server (written in your language of choice) to listen on that port.
But, the server would not be launched in time to handle the request detected by tcpdump or libpcap. Instead, the OS on the rPi would reject it immediately with the ECONNREFUSED OS error. You would have to rely on the client software retrying the connection after the rPi had a chance to launch the server. But client software like web browsers don't automatically retry those refused connections.
You might be able to make this work, but it will always be a brittle solution and a miserable hack. You will be better off rethinking this system design. You should run servers (listeners) on any ports you think your clients will use.
I must mention the security hazards of the approach you propose. A cybercreep could crash your machine simply by running nmap on it if you started servers upon receiving messages on random ports.
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!
I have a device connected to a host computer through cradle usb. Now, I'm just wondering if I could use C# sockets to communicate with the device (ie device sending data, host computer processing it then replying back to the device). How can I accomplish this? by that, what ip address etc etc.. do I have to change so that it would connect cause I have the sockets working on wireless. If not, then is there a way to connect to the device, open and read a file (a text document to be more specific) from the device to my host application.. any ideas?
Thanks! :)
Depending on your target device, when you connect via ActiveSync it likely makes a local RNDIS network connection between teh two devices. You can resolve "ppp_peer" as the partner's network name instead of trying to use a hard-coded IP address (IIRC the IP is different on XP than on Vista).
Be aware that it's not a full connection. TCP packets gets passed through, but things like ICMP do not.
Of course, this just gives you a socket connection, just like if you were to connect between two PCs. It's not going to allow you to do file system operations unless you have an app on the other side listening for commands. If you want that type of thing, Microsoft provides the Remote API (RAPI) interface (wrapped in managed code here)for a lot of basic commands, and it can be extended (with C) to do anything you'd like.
I am writing you because of a new problem I need to solve, and I have now been banging my head against a wall for too long now.
Basically, I need to create an application that can take care of the following:
A user starts an app, which sends a broadcast to the subnet, and recieves a response of all servers there with their IP (and some additional info). The user can then select what server he wants to connect to.
Making it work is simple enough, with identifying the subnet, and broadcasting with UDP, and then having a different server application recieving it and sending back a response . The problem lies with these restrictions, that I need to take into consideration:
There will most likely also be clients on the server machines in the network, meaning that we can assume that the application is present on all machines. Every machine needs to have the listener running, and every machine can launch the GUI for selecting a server.
I am only allowed to add one exception to the firewall - an exception that handles both sending out the broadcasts, recieving broadcasts, sending answers and recieving answers.
I should also only be adding one Windows Service
on a server machine, the listener should run as a windows service, so the user won't notice it. Nor will the user notice, that the response is sent back to the client.
On the client machine, the user can start an application, which will notify the application to emmit the broadcast, and will get all the server responses, so the user can choose one to connect to.
Besides from the application that the user launches in order to select a server, there should be no interaction with the user whatsoever. Not even a popup, requesting the user to allow traffic trough the firewall - it should all be automatically
It needs to work on and in between Win XP, Win Vista and Win 7.
I don't know if I am putting too many constrains on myself, but I really hope that I can make the application with these requirements.
I have a few ideas - I just need to figure out how to do it:
Should i make everything into one application, that I add to the firewall exception list, so it will take care of the traffic on both the server and the client machines?
Should I add a custom exception to the firewall, allowing UDP traffic on a specific port, and then have all traffic flow trough that?
Is there a third and better option for managing that?
It is OK to have the service running on both client and server machines. But can it take care of everything for me - like it handling both the broadcast send/recieve and answer send/recieve? And is there any way to extract the information about servers on the network from a service?
I know it is a lot, but I really hope that you will be able to help me out.
let me know if I wasn't clear enough, or if you need further explanations.
I am coding in C# .Net, and I can utilize all I want from the .Net framework. As soon as I have this functionality implemented
All the best
/Sagi
The kind of peer-to-peer networking problems become simple to the point of being trivial if you designate one machine as the master server. It should have a well-known name that all sub-servers can connect to so they can publish (and withdraw) their availability. A client can then send a query request to the same server and get a list of known servers in return.
This can also solve your firewall problem, the master server could be listening on port 80.
Look into the System.Net.PeerToPeer namespace for a p2p solution supported by the framework.
Maybe a UPnP server and client may be a solution to your problem?
In my company we use small application called IPMsg, a messenger kind of tool to pass messages and file to other fellows in company, even it allows to multicast the message.
And also it lists the user name, host name and IP addresses of users.
How can it do that? There is no server present for message routing and when checked through netstat command in CMD it does not show any details like what protocol and port it is using to communicate.
There is source code also available on the same site which is in VC++. I didn't understand a line of code... (I'm a C# guy)
Can anyone explain me how it can do that?
One simple way would be to let the application listen on a certain network port, and when you start your instance of it, it tries to connect to that port on each computer on the same network. If that other computer has that port open, and answers correctly, then you have found another instance of the application.
IPMsg probably multicasts a request for all clients to report their user and host details.
A similar mechanism is used when Windows Explorer attempts to find other machines on a network. A good description of this type of multicasting discovery is described here.
IPMsg is a daemon which listens to incoming connections on a specific port which is the connection port. You can find out which port it used by using Wireshark.
Start wireshark, start listening on the interface where you have connected to LAN and then start sending any message, wireshark will show you the message on the screen with the port number also.
The application is a peer-to-peer software and doesn't require a central server software to route messages. it only has a small daemon which accepts incoming connections. This is the way Jabber Instant messaging protocol also works.
As you said it lists username, hostname and ip address of users, do you mean it pings the network and finds it? If yes, then it is actually possible to find the IP addresses of computers on the Local Network which requires you to know the subnet on which you are connected.
You can use ARP/ICMP Ping to know the hosts present on your network provided you enter the correct subnet information
Multicasting a message is also nothing special. It is a feature provided with all Networking Stacks.
If you want mutlicasting in .NET, it is allowed. Check this page on Code Project which gives a nice example