ThomasHabets / arping

ARP Ping
http://www.habets.pp.se/synscan/programs.php
GNU General Public License v2.0
398 stars 62 forks source link

Dropping privileges prevents arping from working on Android #24

Closed zb3 closed 7 years ago

zb3 commented 7 years ago

arping drops all privileges, but since Android uses predefined group ids to allow access to various things (enforced by the kernel), dropping all group ids causes arping to fail even though the user has access to raw sockets (inet(3003)).

Fail message:

arping: libnet_get_hwaddr(): socket: Permission denied

Note that it's not about opening raw sockets, that works fine before dropping privileges. Here's the offending syscall:

setgroups32(0, [])                      = 0
setgid32(65534)                         = 0
setuid32(65534)                         = 0
...
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = -1 EACCES (Permission denied)

Maybe it could be solved by making privilege drop optional?

ThomasHabets commented 7 years ago

You're saying you need to be in a particular set of groups to allow any network access?

Hmm, yes that does sound like it calls for a flag to not drop privileges. Unless: is there a well-known group or user that can be changed to (65534 is "nobody") that still has network access?

zb3 commented 7 years ago

Yes, after calling setuid, group 3003(inet) is required to open sockets, while group 3004(net_raw) is required to open raw sockets. I've tested this on Marshmallow, maybe this isn't universal.

ThomasHabets commented 7 years ago

OK, that's what you meant.

Could you confirm that if you change https://github.com/ThomasHabets/arping/blob/arping-2.x/src/arping.c#L330 to day drop_uid(uid, 3003) that it works?

In that case can add a flag that allows setting group by name.

zb3 commented 7 years ago

Yes, drop_uid(uid, 3003) works in my case (setgid to 3004 works too)

ThomasHabets commented 7 years ago

Could you try building current state and running with -g inet?

Actually, maybe arping should detect that it's running in Android and do this automatically, since extra arg every command would be annoying.

zb3 commented 7 years ago

This works for me, but keep in mind that I am building this in a chrooted Debian environment, where there's no group named inet by default (one has to add it manually, for instance by installing the android-permissions package).

ThomasHabets commented 7 years ago

I know very little of Android development. Do you mean android-permissions needs to be installed on the Android phone, or in the development environment?

Do you think arping -g should accept numeric group as well?

And do you know of a way to find out that the system is an Android one, or would it even be possible at compile time? (I don't know the dev environment either)

zb3 commented 7 years ago

I'm not an expert here either :) But let's make one thing clear - by Android here I mean the kernel, not the OS. android-permissions is a Debian package which simply adds groups with proper ids to the /etc/group file so we can refer to them by name. So in that case, we'd need it installed in the OS. It's Debian specific, but we can always use groupadd or simply edit the file.

If arping -g accepted numeric groups, it could make those things easier.

zb3 commented 7 years ago

As for detecting Android kernels, presence of a /dev/binder file seems Android specific, but maybe there's a better way.

ThomasHabets commented 7 years ago

Filed separate feature request for detecting android: https://github.com/ThomasHabets/arping/issues/25