mavris / MMLanScan

An iOS LAN Network Scanner library
MIT License
490 stars 121 forks source link

iOS 10.3 and MAC-address #3

Closed akaDuality closed 5 years ago

akaDuality commented 7 years ago

Is seems that iOS 10.2 has damaged something and MAC-resolving isn't working. Every IP has MAC like "02:00:00:00:00:00"

Do you have any idea how to fix it?

ndenlinger commented 7 years ago

I can agree that in offering a solution to this sort of request could in fact accelerate that process.

ecumedesjours commented 7 years ago

a bit more follow-up from Apple today, where the tech acknowledged an ongoing discussion about the issue:

"It is safe to assume that this has been discussed, and there is always room for further discussion. But the case is, security trumps convenience ... Your best bet would be to file an Enhancement Request (https://bugreports.apple.com) on this, to add to the discussion, and to let the decision making teams to hear about the pain points encountered by developers. It is usually more helpful to word the request in terms of how the end users would benefit from such a change, rather than how you as a developer is inconvenienced"

ndenlinger commented 7 years ago

I submitted a report (Bug Report Number: 29935293) with explaining my necessary use case scenario that would require me to use the MAC Address. I hope that other developers follow suit so that we can help to our cause.

mochasoft commented 7 years ago

Here is my solution, it is only test code, not something, I would use direct in a product .But I am sure Apple will block it in the next release.

` for (int a=0;a<255;a++) { NSString * myhost = [NSString stringWithFormat:@"192.168.1.%d",a]; [self jan_mac_addr_test:[myhost UTF8String]];

}`

` -(void) jan_mac_addr_test:(const char*) host {

define BUFLEN (sizeof(struct rt_msghdr) + 512)

define SEQ 9999

define RTM_VERSION 5 // important, version 2 does not return a mac address!

define RTM_GET 0x4 // Report Metrics

define RTF_LLINFO 0x400 // generated by link layer (e.g. ARP)

define RTF_IFSCOPE 0x1000000 // has valid interface scope

define RTA_DST 0x1 // destination sockaddr present

int     sockfd;
unsigned char   buf[BUFLEN];
unsigned char   buf2[BUFLEN];
ssize_t n;
struct rt_msghdr *rtm;
struct sockaddr_in *sin;
memset(buf,0,sizeof(buf));
memset(buf2,0,sizeof(buf2));

sockfd = socket(AF_ROUTE, SOCK_RAW, 0);
rtm = (struct rt_msghdr *) buf;
rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);
rtm->rtm_version = RTM_VERSION;
rtm->rtm_type = RTM_GET;
rtm->rtm_addrs = RTA_DST;
rtm->rtm_flags = RTF_LLINFO;
rtm->rtm_pid = 1234;
rtm->rtm_seq = SEQ;

sin = (struct sockaddr_in *) (rtm + 1);
sin->sin_len = sizeof(struct sockaddr_in);
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = inet_addr(host);
write(sockfd, rtm, rtm->rtm_msglen);

n = read(sockfd, buf2, BUFLEN);
if (n != 0) {
    int index =  sizeof(struct rt_msghdr) + sizeof(struct sockaddr_inarp) + 8;
    // savedata("test",buf2,n);
    NSLog(@"IP %s :: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",host,buf2[index+0], buf2[index+1], buf2[index+2], buf2[index+3], buf2[index+4], buf2[index+5]);

}

} `

lizimu commented 7 years ago

@mochasoft It works thanks a lot . And Learn a lot from U.

HungChun commented 7 years ago

@mochasoft Cool, thanks a lot!

ndenlinger commented 7 years ago

I just tested your sample code there @mochasoft, the output that I receive is all 00's. That even includes the first octet of the MAC Address. Is your code sample supposed to be for looping through the subnet as a scanner? What about the device that is scanning that network? Please note that I am testing this on iOS 9.3.5, and I also tested with the same results on 10.2.1 Beta 3.

iDevo commented 7 years ago

@mochasoft You are my hero! Thank you very much for sharing!

mochasoft commented 7 years ago

ndenlinger, if the iOS arp table is empty, you get zero values. You could select first in your code to ping the IP address, as to get the iOS to do the arp protocol, before "reading" a mac address using my code example.

ndenlinger commented 7 years ago

Spot on @mochasoft. That worked beautifully. I suppose that in the future Apple will find out about these exploits and close them. But we'll see.

luoshihui commented 7 years ago

@mochasoft I think the sample code should add close(sockfd); in the end of the function.

mochasoft commented 7 years ago

luoshihui, it is just an example, where the goal is to make it easy to read. In a real world application, there should also be checks for different return values for the function calls.

NSGangster commented 7 years ago

@mochasoft Are you sure this works for iOS? I tried something similar before but I was not able to use SOCK_RAW when creating the socket.

NSGangster commented 7 years ago

Nvm. I was using the AF_INET protocol instead of AF_ROUTE. Tried your code and works great! Thank you for this solution. Even if it's only temporary. I had attempted to read the link layer off of the callback on the icmp packet but no luck. So luckily I already had that part in place :) Cheers.

mavris commented 7 years ago

@mochasoft thank you very much for your solution. Also, I would like to thanks anyone here for your contribution and feedback. I will update the project as soon as I have some free time. Pull request are welcome :)

ndenlinger commented 7 years ago

Yes thank you everyone!

Has anyone recompiled this solution with Xcode 8.3 Beta and iOS 10.3 Beta Yet? I'm waiting on my IT Security Team to say it's okay to upgrade OS X to macOS Sierra so as of right now I'm unable to install 8.3.

mavris commented 7 years ago

@mochasoft @luoshihui Guys I have updated MacFinder repo which is used by MMLanScan and I will update MMLanScan soon. Please check if we can optimize it a little bit since I am not fully aware what's the code is doing. Let me know or send me a pull request.

mochasoft commented 7 years ago

ndenlinger; I see no problems with iOS 10.3 beta.

adib commented 7 years ago

How to get the ethernet address from an IPv6 address?

lizimu commented 7 years ago

@mochasoft Hi I have use this block of code in iOS 10.3 beta 3 but it doesn't work.

Is anything wrong with this code? Thank U

arivas87 commented 7 years ago

It is true, this solution are not working with iOS 10.3 betas. Also I have noticed that Fing does not show MAC address with this version...

ndenlinger commented 7 years ago

You might be right @arivas87. This was originally working in a project that I had successfully implemented this method and it's no longer showing the MAC Address. Apple's too quick to patch a function like this.

adib commented 7 years ago

Would directly sending ARP packets work on iOS 10.3?

Andresmtz89 commented 7 years ago

Had anyone tested the Code and got the Mac Address on an actual Iphone 6/7 with 10.2.1 OS?

We used Mavris code and include it on a test app, we run it on an ipad with ios 10.2.1 and it worked.

image

When installed and run on iphone, something is crashing the app, has anyone experienced this?

mavris commented 7 years ago

@Andresmtz89 Put a breakpoint here:

//Getting the available IPs to ping based on our network subnet.
    self.ipsToPing = [LANProperties getAllHostsForIP:self.device.ipAddress andSubnet:self.device.subnetMask];

in MMLANScan.m and let me know the range. Also make sure that iPhone is not using IPV6

Andresmtz89 commented 7 years ago

Many Thanks @mavris

It is working across multiple ios devices!

gregpardo commented 7 years ago

Heres what I'm using based off the above.. Obviously you'd want to replace the delegate calls with some other sort of callback of your own for when


- (void)scan {

    int mib[6];
    size_t needed;
    char *host, *lim, *buf, *next;
    struct rt_msghdr *rtm;
    struct sockaddr_inarp *sin;
    struct sockaddr_dl *sdl;
    struct hostent *hp;
    int _nflag = 0;
    extern int h_errno;

    mib[0] = CTL_NET;
    mib[1] = PF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_INET;
    mib[4] = NET_RT_FLAGS;
    mib[5] = RTF_LLINFO;
    if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
        err(1, "route-sysctl-estimate");
    if ((buf = malloc(needed)) == NULL)
        err(1, "malloc");
    if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
        err(1, "actual retrieval of routing table");
    lim = buf + needed;

    for (next = buf; next < lim; next += rtm->rtm_msglen) {
        rtm = (struct rt_msghdr *)next;
        sin = (struct sockaddr_inarp *)(rtm + 1);
        sdl = (struct sockaddr_dl *)(sin + 1);

        if (_nflag == 0) {
            NSDate *hostStart = [NSDate date];
            hp = gethostbyaddr((caddr_t)&(sin->sin_addr),sizeof sin->sin_addr, AF_INET);
            NSDate *hostEnd = [NSDate date];

            NSTimeInterval executionTime = [hostEnd timeIntervalSinceDate:hostStart];
            //NSLog(@"Execution Time: %f",executionTime);
            if (executionTime > 1) {
                _nflag = 1;
            }

        } else
            hp = 0;
        if (hp)
            host = hp->h_name;
        else {
            host = "";
            if (h_errno == TRY_AGAIN)
                _nflag = 1;
        }

        if (sdl->sdl_alen) {

            NSString* newAddress = [NSString stringWithFormat:@"%s",inet_ntoa(sin->sin_addr)];
            gethostbyaddr((caddr_t)&(sin->sin_addr),sizeof sin->sin_addr, AF_INET);
            NSString* newHost = [NSString stringWithFormat:@"%s", host];

            [self ipToMac:newAddress
                   completion:^(NSString *macAddress) {

                       NSArray *ipSplit = [newAddress componentsSeparatedByString:@"."];
                       if ([ipSplit[0] isEqualToString:@"169"] || [macAddress isEqualToString:@"FF:FF:FF:FF:FF:FF"]) { //Broadcast address and self assigned IP's
                           //skip sending to delegate
                       }  else {
                          // TODO: Replace this code below with a callback of your own
                           if ([self.delegate respondsToSelector:@selector(discoveredGatewaySibling:macAddress:host:)]) {
                               [self.delegate discoveredGatewaySibling:newAddress macAddress:macAddress host:newHost];
                           }
                       }

                   }];

        } else{
            if (rtm->rtm_rmx.rmx_expire == 0)
                printf(" permanent");
            if (sin->sin_other & SIN_PROXY)
                printf(" published (proxy only)");
            if (rtm->rtm_addrs & RTA_NETMASK) {
                sin = (struct sockaddr_inarp *)
                (sdl->sdl_len + (char *)sdl);
                if (sin->sin_addr.s_addr == 0xffffffff)
                    printf(" published");
                if (sin->sin_len != 8)
                    printf("(weird)");
            }

        }
    }
}

- (void)ipToMac:(NSString *)ip
     completion:(void (^)(NSString* macAddress))completion {

#define BUFLEN (sizeof(struct rt_msghdr) + 512)
#define SEQ 9999
#define RTM_VERSION 5   // important, version 2 does not return a mac address!
#define RTM_GET 0x4 // Report Metrics
#define RTF_LLINFO  0x400   // generated by link layer (e.g. ARP)
#define RTF_IFSCOPE 0x1000000 // has valid interface scope
#define RTA_DST 0x1 // destination sockaddr present
    const char* host = [ip UTF8String];
    int sockfd;
    unsigned char buf[BUFLEN];
    unsigned char buf2[BUFLEN];
    ssize_t n;
    struct rt_msghdr *rtm;
    struct sockaddr_in *sin;
    memset(buf,0,sizeof(buf));
    memset(buf2,0,sizeof(buf2));

    sockfd = socket(AF_ROUTE, SOCK_RAW, 0);
    rtm = (struct rt_msghdr *) buf;
    rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);
    rtm->rtm_version = RTM_VERSION;
    rtm->rtm_type = RTM_GET;
    rtm->rtm_addrs = RTA_DST;
    rtm->rtm_flags = RTF_LLINFO;
    rtm->rtm_pid = 1234;
    rtm->rtm_seq = SEQ;

    sin = (struct sockaddr_in *) (rtm + 1);
    sin->sin_len = sizeof(struct sockaddr_in);
    sin->sin_family = AF_INET;
    sin->sin_addr.s_addr = inet_addr(host);
    write(sockfd, rtm, rtm->rtm_msglen);

    n = read(sockfd, buf2, BUFLEN);
    if (n != 0) {
        int index =  sizeof(struct rt_msghdr) + sizeof(struct sockaddr_inarp) + 8;

        NSString* mac = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
                                buf2[index+0], buf2[index+1], buf2[index+2], buf2[index+3], buf2[index+4], buf2[index+5]];
        close(sockfd);
        completion(mac);
    }
}
arivas87 commented 7 years ago

This code does not works on 10.3 iOS version...

mochasoft commented 7 years ago

I have tested my code (mocha ping) and mmlanscandemo with iOS 10.3 beta 5 (14E5296a, mar 8 2017) on an iPad (compiled with 8.3 beta 4 (8w143q) and I can read the mac address with both Apps. Only difference I see is: the IP address for my iPad cannot be listed, it has mac address 02:00...

mavris commented 7 years ago

@mochasoft That makes sense! It seems that Apple will restrict the device's MAC address but they will allow as to use ARP Table for other devices. It's not perfect solution but it's something.

blganesh101 commented 7 years ago

Seems strange but after you run the app several times, the mac address is no more retrieved. Is anyone facing this issue?

mavris commented 7 years ago

Which iOS? 10.3?

blganesh101 commented 7 years ago

It's 10.2.1

mavris commented 7 years ago

I am on 10.2.1 too and I never experienced that issue. I tried it today and seems fine. Can you debug the MacFinder and post your findings? We might be able to reproduce it

blganesh101 commented 7 years ago

I see same behavior on iPhone and iPad. I did debug a little and looked like this is happening after I ran my version of the code which used ipv6 addresses. Now even if I run original code from macfinder it never returns mac

leonfu commented 7 years ago

Fing is updated to say compatible with iOS 10.3. Anyone tried?

mavris commented 7 years ago

Yes. Everything seems fine except when you query for device's MAC Address. Then you will get the 02:00...

adib commented 7 years ago

However the same technique seems to work on tvOS 10.2 (which is about the same generation of updates with iOS 10.3) – able to see other devices’ MAC addresses.

On 7 Apr 2017, at 14:14, Michael Mavris notifications@github.com wrote:

Yes. Everything seems fine except when you query for device's MAC Address. Then you will get the 02:00...

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/mavris/MMLanScan/issues/3#issuecomment-292450672, or mute the thread https://github.com/notifications/unsubscribe-auth/AAKv0dgvbIdXstyh132-uO3zDLJf_0Zlks5rtdRJgaJpZM4K-50O.

gregpardo commented 7 years ago

I'm able to get other devices mac address in 10.3.2 but not the device the code is running on.

Andresmtz89 commented 7 years ago

Hello, Has anyone been able to make it work on IOS 10.3?

Darshanptl7500 commented 7 years ago

We are using this library and we are able to get mac address in 10.2 and 10.3.2. Will the app will be rejected if we are going to upload the app on the appstore? Is anyone using the library in apps on appstore ?

Please let us know Thanks

gregpardo commented 7 years ago

I have had an app accepted recently. It did require IPv6 support but that was a small tweak. You should be fine.

lizimu commented 7 years ago

@gregpardo Yes,You can get other device mac address no matter which version it is. First of all, the one you want to get mac address must in your arp table. That's trick. Now I can only ping all of the device in private network region.

iremkorkmaz commented 7 years ago

@Darshanptl7500 & @gregpardo , have you had it running in 10.3.2? because @Darshanptl7500 told that it works on 10.3.2. If you had it working how? Please help :)

mavris commented 7 years ago

@iremkorkmaz It's working for every other device except yours (It cant' retrieve MAC address from arp table for your device). Other than that the scanning is fine

iremkorkmaz commented 7 years ago

ah ok, I thought it was working also for the running device for them. We had an application that relies on Mac Address, it now worths nothing... :(

jpalten commented 7 years ago

Can you tell us more? How/why did it rely on MacAddress? When they blocked the device macaddress, Apple provided other ways to do a lot of things, depending on your purpose.

iremkorkmaz commented 7 years ago

@jpalten , it was a wi-fi analytic platform supported with an app. so app side is nothing now :)

mavris commented 7 years ago

Why don't you ask the user to enter his mac address manually? He will do that once (Settings-General-About-Wifi Address). (If you just want to display the MAC Address of WiFi, of course, this is not an acceptable solution).

mavris commented 7 years ago

https://github.com/mavris/MMLanScan/issues/23 Any one found something about iOS 11?