How can I detect if another host is using the same MAC address as the current host, e.g. because the other host is spoofing?
I'm working in an embedded environment, so looking for answers on a protocol level, rather than “use such and such a tool”.
Edit: RARP does not solve this problem. For RARP to get any reply at all, there has to be at least one host on the segment which supports RARP. Since RARP is obsolete, modern operating systems don't support it. Furthermore, all RARP can do is tell you your own IP address - the response won't be any different if there’s another host on the segment with the same MAC, unless that host has itself used a different IP address.
This question is too interesting to put down! After several false starts I started thinking about the essential components of the problem and scoured the RFCs for advice. I haven't found a definitive answer, but here's my thought process, in the hope that it helps:
The original question asks how to detect another device with your MAC address. Assuming you're on an IP network, what's required to accomplish this?
The passive method would be simply to listen to traffic and look for any packets that you didn't transmit but have your MAC address. This may or may not occur, so although it can tell you definitively if a duplicate exists, it cannot tell you definitively that it doesn't.
Any active method requires you to transmit a packet that forces an impostor to respond. This immediately eliminates any methods that depend on optional protocols.
If another device is spoofing you, it must (by definition) respond to packets with your MAC address as the destination. Otherwise it's snooping but not spoofing.
The solution should be independent of IP address and involve only the MAC address.
So the answer, it seems, would be to transmit either a broadcast (ethernet) packet or a packet with your MAC address as its destination, that requires a response. The monkeywrench is that an IP address is usually involved, and you don't know it.
What sort of protocol fits this description?
Easy Answer:
If your network supports BOOTP or DHCP, you're done, because this authoritatively binds a MAC address to an IP address. Send a BOOTP request, get an IP address, and try to talk to it. You may need to be creative to force the packet onto the wire and prevent yourself from responding (I'm thinking judicious use of iptables and NAT).
Not-so-easy Answers:
A protocol that's independent of IP: either one that doesn't use the IP layer, or one that allows broadcasts. None comes to mind.
Send any packet that would normally generate a response from you, prevent yourself from responding, and look for a response from another device. It would seem sensible to use your IP address as the destination, but I'm not convinced of that. Unfortunately, the details (and, therefore the answer) are left as an exercise for the OP ... but I hope the discussion was helpful.
I suspect the final solution will involve a combination of techniques, as no single approach seems to guarantee a dependable determination.
Some information is available at http://en.wikipedia.org/wiki/ARP_spoofing#Defenses
If all else fails, you may enjoy this: http://www.rfc-editor.org/rfc/rfc2321.txt
Please post a follow-up with your solution, as I'm sure it will be helpful to others. Good luck!
You could send an ARP request for each possible ip in the subnet.
Of course the source address of the ARP request must be ff:ff:ff:ff:ff:ff, otherwise you might not see the response.
I forged a packet like this with bittwiste and replayed it with PReplay and all the hosts on the network got the response. (I don't know if these forged ARP packets are legal or not... some OSes might ignore them)
Here is what the forged package looked like:
Here is what the reply looked like:
If you watch the responses and see your MAC address in one of the packets (in the red rectangle) , than someone has the same MAC address as you do...
Unfortuantely I couldn't test the theory fully because none of my (Windows) machines care about me trying to set the nic's MAC address...
Two hosts using same MAC address on a single network segment would probably make switches go nuts and you could probably detect it by having an extremely unreliable network connection (as the switches would send some portion of packets that belong to your host to the second one, depending on which one of you sent the last packet in their direction).
This is very late, and a non-answer, but I wanted to follow up with exactly what I did in case anyone else is interested.
I was working with some very weird embedded hardware that doesn’t have a MAC address assigned at manufacture. That means we needed to assign one in software.
The obvious solution is to have the user pick a MAC address that they know is available on their network, preferably from the locally-administered range, and that’s what I did. However, I wanted to pick a reasonably safe default, and also attempt to warn the user if a conflict occurred.
In the end I resorted to picking a random-ish default in the locally-administered range, chosen by making some hardware readings that have moderate entropy. I deliberately excluded the beginning and end of the range on the assumption that those are moderately more likely to be chosen manually. The chances are that there will only be one of these devices on any given network, and certainly less than 20, so the chances of a conflict are very low, albeit not as low as they could be due to the somewhat predictable random numbers.
Given the low chances of there being a problem, and despite the excellent answers above, I decided to dispense with the conflict detection and make do with a warning to the user to look out for MAC conflict problems.
If I did decide to implement conflict detection, then given that I control the whole network stack, I would probably look out for excessive unknown or missing packets, and then trigger a change of MAC address or warn the user when that happens.
Hopefully that will help someone else somewhere – but probably not!
Related
I mean how can a mere website tell my I.P. address and the ports that are available to forward? For example what do I have to do in order to incorporate this kind of facility on my website?
A website must know what your IP address is, otherwise how else would it know where to send the data packets back to?
Also it does not know which ports "are available to forward". It only knows which port your request originates from (this port is random).
Your computer may be making many requests simultaneously from various programs, so knowing the correct IP address makes sure the data gets back to the right computer, and knowing the correct port makes sure it goes to the correct program (or more specifically, the correct process).
I'm experimenting with my Arduino Mega. I also have an Arduino Ethernet Shield.
I need to send emails using them, without the help of a computer (or any other device; like a smartphone, etc.). Though I could find several articles, I couldn't find any acceptable solution...
How can I do it? As I'm not asking this to be used for any special application, you can
make any assumption about missing details.
From the discussion above in comments it sounds like you either need code from someone who has just done it for you or you need to take the time to learn about the components and find or make the components.
They wouldn't make an Ethernet shield for this platform if it was only useful for non-standard packets. So someone somewhere has created some level of an IP stack.
Backing up though, in order to send mail you need to learn the Simple Mail Transfer Protocol (SMTP). Almost all Internet protocol definitions are defined using something called RFCs (Request for Comments). So if you google SMTP RFC you will find RFC 2821.
IETF is Internet engineering task force. There will be many copies of these documents on many websites. And due to the age of the Internet and these protocols in many cases you will find that one RFC has been created to replace a prior one. Version numbers are not used, but it is kind of like HTML 1.0 then HTML 2.0 and so on. I recommend even though the RFC says that it completely replaces RFC xyz, go find RFC xyz and read it. I go back as far as I can find learn that one then work my way forward.
Many/most protocols that ride on top of TCP (TCP is yet another protocol defined in an RFC, more on that later) are ASCII based, makes it very easy to, for example, Telnet to learn/experiment with the protocol, you can probably use Telnet to learn SMTP.
Most protocols are some sort of a half duplex thing, make a connection and often the server sends you a string, you see that string and then you send some sort of hello string, the server responds with some sort of OKAY or fail status. For SMTP, you then do some sort of I am mailing from this email address, server says OKAY, you say I want to mail this person or this list of people, for each email address you get an okay or fail. Eventually, you tell the server you are ready to send the body of the message, you do that, end the message with the defined termination. Then either the server says okay or fail or maybe there is some more handshaking.
The protocols in general though have this back and forth. Usually you are sending strings with commands and usually the server side sends back a short okay or error. Sometimes, if they want, they send back more detail on the error, but always start with the few bytes that indicate okay or error. The protocols generally have a flow, you must do this first then this then that.
You should learn sockets programming, sometimes called Berkeley sockets. You can write programs that are mostly portable across unixes but also across to Windows using Windows sockets if that is your platform of choice. You need to learn the protocol first, and it is better on your desktop/laptop and not embedded, you can get it done faster there. You do NOT have to learn to fork or thread to use sockets. The examples may show that as it is easy to show it that way, but you can write complete applications using polling only, it is half duplex send something, wait, send something, wait. For these simple learning programs, a little time up front to learn sockets, from there, it is all learning the protocols.
Now that was the very easy part, the hard part is the TCP/IP stack. I do not recommend attempting that without gaining a lot more experience taking baby steps on your way there. For example, learn to respond to ARP first (yet another RFC protocol, address resolution protocol) then ping (ICMP echo, one subset of the ICMP protocols) then IP basics (sniffing packets) then receive and generate UDP packets. TCP is a whole other level above that, more handshaking. It is not fixed packet size, it is streaming, do not have your code operate on packets, it is a stream of bytes, like working with a serial port.
Doing your own TCP stack is very much a non-trivial thing, I don't recommend it, you need to find someone that has done a TCP/IP stack for this platform for the Ethernet shield and just use it, whatever RTOS or environment they use, use it. Then take your desktop/laptop based experience with the protocol and apply that.
From the discussion above, if you don't want to learn the protocols, etc., I think you need to google around looking at Arduino Ethernet shield examples and see if anyone has done something that sends emails.
I'm working on a communication protocol that should support self configuration by broadcasting / multicasting the peers' address over the local network. The intuitive way would be to broadcast the address, but as it turns out, it's pretty hard to reliably figure out the local IP address of the current machine (depending on the configuration, you might get "127.0.0.1" or another useless address).
The alternative is to not include the host address in the broadcast message, but to have the receivers call recvfrom on their socket which not only returns the received data, but also the sender's address. As I see it, that call is available on both Unix and Windows (one of my requirements) and probably some more platforms. My question now is, are there situations where this might fail and recvfrom returns an unreachable or otherwise useless address?
If you limit this technique to only broadcast UDP, you should be fine. The only things that tend to mess with this are things like dual NAT or hairpin NAT. That's just not done with broadcasts that are local only anyway.
Any address is subject to becoming unreachable (and therefore useless by your definition) at any time. Your software should be prepared to deal with that.
You can reliably determine the system's IP addresses (note the plural, more on that in a minute) by enumerating the interfaces. How you do this will differ among platforms as there's nothing in a standard (e.g., POSIX) that specifies how it should be done. Many Unixy systems have a getifaddrs() call; Windows does something else. Either way, isolating that code should be easy.
Your software also shouldn't make the assumption that IP it comes across is "the" address. On a system with more than multiple interfaces (which is most of them if you count the loopback), routings may change or someone may want to run your protocol on a segment that isn't on the same interface as the default route.
If you're going to broadcast a message, you need to do it once on every interface which is up, loopbacks included, unless you're configured to do otherwise. The broadcast should also happen from each of those interfaces so it has the proper address. You can't assume that other hosts on the same segment as any interface know about any other interface or have a way to route to their addresses.
If your protocol is intended for use only on connected segments, throwing away data from non-connected subnets would be a reasonable thing to do.
I am trying to write a program that scan an ip range and detect if an ip is address of a router or not.
Currently i used traceroute from my computer to all host in the network. However, i believe there must be some way to directly "ask" a host at an ip if it is a router or not?
by the way, do you know any program/ opensource already does this?
Routers are supposed to talk couple of protocols (actually a neat bunch) that regular IP nodes do not, and then there are some which are more common (i.e. even non-router nodes do).
Router-only protocols:
VRRP
IGRP / EIGRP
OSPF
BGP
RIP
You could do active-probing on those, i.e. send a packet (behaving as if you are another router, or an end-node) and checking to see what kind of response the router (if at all) sends.
Alternatively you could do passive-probing, like 'sniffing', i.e. watching out for the kind of IP packets being sent out by various nodes. There are some which are usually sent out by Routers only (again, mostly from the above list).
Common protocol, but that can actually tell you a lot:
SNMP (esply the unsecure one's like v1/v2, are easy to deal with, without having to establish a secure session)
Other ways:
Portscanning (actually can tell you a real lot), for example all routers have some management ports (although, often they are locked down due to security concerns)
What you want to do is often what many 'Network Management' software do, to "discover" capabilities / functionality of other nodes in the network. And, there isn't a single size-fits all solution. They use bunch of different methods, heuristics to finally figure out what the other node is.
Any node which is hopped to and not just an endpoint is a router. However, this doesn't allow you to detect routers with no reachable devices hooked up. (Any input as to whether my answer has merit would be great!)
I have just started writing socket programs. Came to know that single UDP packet has source port destination port and some MAC address representing router..etc. I wonder why anybody cannot create custom packets with a fake information in and send it over internet. I would like to know how safe are our PCs. What should be done to secure it ?
There are a couple of different aspects to the answer.
One is that the web relies on TCP, not UDP. Which means that it is connection-oriented. Your package will be rejected, unless it appears to be part of an existing connection (which means, among other things, that it has to have the right source IP and port as well. And it has to have the right sequence number to fit into the receive window). This can still be faked without too much trouble, of course. But it does require you to know a bit about the packets being sent on the original connection.
Another part is that whenever we need to be sure that the sender of a packet is who they claim to be, we use encryption. :)
Most packets don't really need this. It's not a huge deal if someone sends a request to Google which appears to come from my IP. But when making credit card transactions, it becomes a bit more important.
Most of the TCP/IP stack "leaks trust", as I once put it -- and there isn't much that you, as a software developer (assuming you're looking for a programming solution, otherwise, stackoverflow's the wrong forum, go to serverfault or superuser;-) can do about it -- beyond choosing and carefully implemented protocols that are reasonable in terms of security expectation.
HTTPS (with strong checks of certificates, etc) is one reasonably strong approach; for stronger security, look into SSH and VPN-based approaches. Of course, nobody should assume privacy or strong authentication is in place unless they've taken specific steps towards it (if they HAVE taken such steps, they may be still subject to successful attacks, which is why using existing, more or less "proven" solutions such as HTTPS, SSH, VPNs, is advisable;-).
Yes, anyone can create packets with whatever data they want and send them out over the internet. Especially with UDP, you can pretend to be anyone you want (unless your ISP does egress filtering). Source addresses for UDP cannot be trusted. Source addresses for TCP can to an extent (you know the data has to be coming from the IP address in question, or someone along the route).
Welcome to the internet :)
Edit: just to clarify egress filtering is something the sending ISP would have to do. As a reciever, there's not really anything you can do to verify the address on a UDP packet without communicating back to the sender. The only reason you can at least partially trust an incoming TCP connection is that TCP requires certain control data flow back to the sender (and hence needs a valid IP address/port to set the connection up and maintain it).
Well, many many people create invalid packets and send them over Internet; for instance, read Ping of death.
A [completly] secure computer is a computer turned off. To make your running PC more secure from this thread kind, you should rely on firewall softwares/hardwares, which can detect that malformed packets.
Custom packets with fake information can easily be created. Therefore you have to make sure you're not vulnerable to them.