tcpdump - Bizarre output over 3G/mobile data on Android - android

I am capturing packets over 3G on Android and I get an output that is bizarre. I see mac addresses instead of IP addresses and have no clue how to decode it. I see the IP addresses when I run the same capture over WIFI. It appears as if the link type needs to be changed for 3G interface.
Currently, I only see "EN10MB (Ethernet)" option under the list of Data link types (tcpdump -L). I see different link types on tcpdump website (http://www.tcpdump.org/linktypes.html) and I think probably I somehow need to recompile the source, so that I get "LINKTYPE_GPRS_LLC" under Data link types to get the right capture.
Does anyone know how to do this? I have the source for libpcap (v0.9.8) and tcpdump (v3.9.8) (one that comes along with AOSP 4.2.1 source).
Thanks and I really look forward to hear from you guys.
Here is a sample output that I get for a capture over 3G interface:
ping google.com
tcpdump -vvvs 0
22:11:51.450906 40:00:40:11:12:18 (oui Unknown) > 45:00:00:38:66:22 (oui Unknown), ethertype Unknown (0x1528), length 56:
0x0000: 4a4b 4201 2107 bad2 0035 0024 5a5e 140c JKB.!.��.5.$Z^..
0x0010: 0100 0001 0000 0000 0000 0667 6f6f 676c ...........googl
0x0020: 6503 636f 6d00 0001 0001 e.com.....
22:11:52.363748 00:00:fd:11:0c:9c (oui Unknown) > 45:00:00:e8:ed:ed (oui Unknown), ethertype Unknown (0x4201), length 232:

So, here's what solved the problem.
Looks like when we explicitly specify the interface name (cdma_rmnet4 in my case) or do not specify any interface (in this case it automatically assumes the interface to be cdma_rmnet4), it gives the same garbled output.
But when we capture it with “-i any” flag, it does capture on some “LINUX_SLL” interface, which gives the correct output. I googled it and found out that LINUX_SLL is Linux cooked mode capture by libpcap to capture from the "any" device and to capture on some devices where the native link layer header isn't available or can't be used, which is the case with 3G/mobile packets.

If by "Currently, I only see "EN10MB (Ethernet)" option under the list of Data link types (tcpdump -L)." you mean that, when you run tcpdump -L, that means that, on the interface on which you're capturing, the only link-layer header type it claims that it can supply are Ethernet headers.
If that's what it's supplying, tcpdump should be reporting the right packet data.
If that's not what it's supplying, then the driver or networking stack on the version of the Linux kernel your mobile phone/tablet is running is broken - it's supplying the wrong ARPHRD_ value to libpcap, which is then passing that lie on to tcpdump or whatever other program is using libpcap.
The best way to fix this would be to fix the driver or whatever is supplying ARPHRD_ETHER. Unfortunately, a quick look at the 3.11 kernel's include/uapi/linux/if_arp.h doesn't show an ARPHRD_ value that appears to be intended for this.
Note, however, that this is NOT necessarily LINKTYPE_GPRS_LLC! That LINKTYPE_ value is for GPRS LLC frames, as described in 3GPP TS 04.64; those can encapsulate Subnetwork Dependent Convergence Protocol frames, which can encapsulate IP frames (at least according to the Wireshark dissector for GPRS LLC frames), but Android might be using some completely different link-layer headers. GPRS is NOT a 3G service; I think 3G data uses a different link layer.
Tcpdump does not know how to dissect GPRS LLC frames, so, IF that's what the driver is supplying, that wouldn't help without changes to tcpdump to understand GPRS LLC and the Subnetwork Dependent Convergence Protocol.
A quick look at tcpdump's output, and at this similar Wireshark question, suggests that the link-layer type might be LINKTYPE_RAW - the first octet of an Ethernet frame is the first octet of the destination address, so it appears that the first octet of those frames is 0x45, which is also the value that the first octet of an IPv4 frame without options would have (IP version 4, header length 5 32-bit words or 20 bytes).
Try, as an experiment, a version of tcpdump that treats DLT_EN10MB as if it were DLT_RAW; if that works with the 3G interface, then either the drivers or networking stack need to be changed to supply ARPHRD_NONE to libpcap or libpcap needs to look at the device name and, for the Android device or devices in question, map ARPHRD_ETHER to DLT_RAW rather than DLT_EN10MB. What's the name of the device on which you're capturing, i.e., the argument to the -i flag? If you didn't pass an argument to -i, what is the output of ifconfig -a on Android?

Related

Android: Is there a way to validate KASLR at runtime

I would like to know if there is a way to check if KASLR is enabled at run time in android target.
I know that ASLR can be validated by checking /proc/sys/kernel/randomize_va_space against value 2(complete randomization for user space apps).
I have configured
CONFIG_RANDOMIZE_BASE=y
in the board defconfig file.
Now I want to validate it at run time.
We are using kernel version 4.14 in Android P.
I have seen this where it checks the same in ubuntu, with respect to kernel command line args.
I don't see this option in the command line args for android in BoardConfig.mk.
The implementation details of KASLR depend on the CPU architecture (x86, ARM, ARM64, PowerPC, etc.), so I can't say whether you've properly configured it, but at runtime I know of two things you can check:
the /proc/kallsyms file to see the symbol addresses in virtual memory address space.
lsmod to see the kernel module addresses in virtual memory address space. Note: On some machines, lsmod may not show the addresses. In that case, try using cat /proc/modules as root. If not using root, the addresses may be all zeros (cleared for security reasons). ~~Thanks to user #crass for the comment!~~
Both 1 & 2 are similar checks, but depending on what's available to you on your system, you might need to use one or the other.
1. /proc/kallsyms
To do so, simply look at the first few lines of /proc/kallsyms:
root#device:~# head -n 3 /proc/kallsyms
ffffff8008080000 t _head
ffffff8008080000 T _text
ffffff8008080800 T do_undefinstr
Note that the address for, e.g., _head is ffff ff80 0808 0000.
Now reboot your machine and check again.
root#device:~# head -n 3 /proc/kallsyms
ffffff9fc8c80000 t _head
ffffff9fc8c80000 T _text
ffffff9fc8c80800 T do_undefinstr
Note that the address for, e.g., _head is now ffff ff9f c8c8 0000.
Compare the high-level bytes and find that ffffff80080 != 0xffffff9fc8c so the addresses are being changed across reboots. --> KASLR is enabled.
2. lsmod
Similar to /proc/kallsyms method above: check lsmod, reboot, check lsmod again, and compare the addresses.
root#device:~# lsmod
iptable_filter 16384 0 - Live 0xffffffa1c49b9000
ip_tables 28672 1 iptable_filter, Live 0xffffffa1c49ad000
Note that the address for, e.g., iptable_filter is ffff ffa1 c49b 9000.
Now reboot your machine and check again.
root#device:~# lsmod
iptable_filter 16384 0 - Live 0xffffff2100716000
ip_tables 28672 1 iptable_filter, Live 0xffffff210070a000
Note that the address for, e.g., iptable_filter is now ffff ff21 0071 6000.
Compare the high-level bytes and find that ffffff2100716 != 0xffffffa1c49b9 so the addresses are being changed across reboots. KASLR is enabled.
You can do these tests iteratively to determine the quality of the randomness. How different are the addresses across reboots? Are there obvious patterns? The security benefit of KASLR is proportional to the quality of randomness, or entropy.
References:
Debugging Linux Kernels with KASLR
Linux Kernel Driver Database for RANDOMIZE_BASE

Android 7 reserved IP ports restriction

In Android 7, there is a range of reserved IP ports.
This is indicated in the file /proc/sys/net/ipv4/ip_local_reserved_ports:
32100-32600
My application uses a port in that range and I get an error "bind : address already used".
So, I wanted to know if there is a way around this restriction?
I thought to modify the file and exclude the port that I use. In fact I have rooted my device, modified the file but changes were not picked up by the kernel.
Even if the file has been modified, if I restart the device the changes are lost.
Is there a way to circumvent this restriction?
Or somehow force the kernel to take into account my changes?
From https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt:
ip_local_reserved_ports - list of comma separated ranges
Specify the ports which are reserved for known third-party
applications. These ports will not be used by automatic port
assignments (e.g. when calling connect() or bind() with port
number 0). Explicit port allocation behavior is unchanged.
The format used for both input and output is a comma separated
list of ranges (e.g. "1,2-4,10-10" for ports 1, 2, 3, 4 and
10). Writing to the file will clear all previously reserved
ports and update the current list with the one given in the
input.
Note that ip_local_port_range and ip_local_reserved_ports
settings are independent and both are considered by the kernel
when determining which ports are available for automatic port
assignments.
You can reserve ports which are not in the current
ip_local_port_range, e.g.:
$ cat /proc/sys/net/ipv4/ip_local_port_range
32000 60999
$ cat /proc/sys/net/ipv4/ip_local_reserved_ports
8080,9148
although this is redundant. However such a setting is useful
if later the port range is changed to a value that will
include the reserved ports.
Default: Empty
So, I wanted to know if there is a way around this restriction?
I suggest you to use a different port, or else your system may become unstable for a system service may be using a port in that reserved range.
Is there a way to circumvent this restriction? Or somehow force the kernel to take into account my changes?
Since you rooted your device you can try sysctl. These links may help: Android Edit Sysctl Settings and https://forum.xda-developers.com/showthread.php?t=1470125.

How to read random data sent from android to Mac OSx?

I developed an android app that sends data (text, binary, hex..etc) using bluetooth communication. I want to test my app, what methods are there?
Is there a method on mac to receive what is sent ?
There is an app called LightBlue on the Mac (and iOS) App Stores which is very useful when developing with BLE. It allows you to scan, see advertisement data (iOS version only), connect, list services and characteristics, subscribe to a notify / indicate characteristic and read or write a characteristic's value.
For classic Bluetooth, if using SPP you will need a serial terminal. First you need to connect to your device from the Bluetooth System Preferences. This will create a device file in /dev, its name follows the pattern /dev/cu.<DEVICE_NAME>-SPPDev where DEVICE_NAME is the advertised Local Name. This is a character device that you can use with any program that can read(2) and write(2) to a file. For instance the simplest way with default tools, if your device file is /dev/cu.XXXX, is to run cat /dev/cu.XXXX in one terminal window (or cat /dev/cu.XXXX | hexdump -C for hex output), then in another terminal window run echo -n "my command" > /dev/cu.XXXX. Then in the first terminal window you will see the response from your device. For hex input you can use the -e switch and backslash escapes, for instance to send 0x01 0x02, you would run echo -ne "\x01\x02" > /dev/cu.XXXX.
There are programs that are specialized in this sort of communication, called serial terminals. These also let you change the serial port configuration, although the one selected by osx is generally good. I personally use cutecom for this. In cutecom, you need to input the device file name (/dev/cu.XXXX) in the "Device" text field, then configure the desired serial port parameters. To use those that osx selected, just uncheck the "Apply settings when opening" checkbox. Then click on "Open device". You can then input text or hex and see output as text or hex also. If you get gibberish on the output that means that the serial port parameters are not good. If you don't know the right parameters for your device you can experiment, but a typical configuration would be Baud rate : 115200; Data bits : 8; Stop bits : 1; Parity : None, and no handshake.

TCPDUMP's Network Packets in IPv6 Format

I am new to tcpdump tool and I am working in the analysis of network packets, I have analysed the IPv4 Ip packtes generated in case of wifi. But Now I am running my android phone in sim's 3g network which is generated the IPv6 packets ,completely different form IPv4 format. I am confused about the IPv6 packets structure,
Again, I have gone through the IPv6 header format, and my phone's packets given below, These two format does not match. I am totally confused about IPv6 header.
My mobiles's local ip is 100.87.163.16 ,my question is how to detect the received packets and sending packets. Also I want to find out the header length , payload length, source and destination ip address in IPv4 format. I am looking for your valuable suggestions.
Thanks.
10:59:06.365651 00:00:32:06:af:56 (oui Unknown) > 45:00:00:a8:35:49 (oui Unknown), ethertype Unknown (0xd83a), length 168:
0x0000: c40e 6457 a310 01bb e6c0 f6b1 b5ed ec6b �.dW�..������k
0x0010: 23f8 8018 015e dfc7 0000 0101 080a 17c2 #�...^��.......�
0x0020: 6af1 0014 f0c3 1703 0300 6f00 0000 0000 j�..��....o.....
0x0030: 0000 0208 7db4 d0c1 846d ca75 323c e6cb ....}���.m�u2<��
0x0040: 1636 be16 942f 51ea 1caf 1c09 c085 3dbc .6�../Q�.�..�.=�
0x0050: 7642 vB
OK, let's reconstruct the full raw packet contents.
The driver supplied an ARPHRD_ value that got mapped to DLT_EN10MB (probably an inappropriate ARPHRD_ value; this is a known botch in some Android mobile phone interfaces, probably done to cope with inadequacies in the DHCP implementation, and later versions of libpcap work around it), so the packet was interpreted as if it were an Ethernet packet, when it probably was, in fact, not an Ethernet packet.
So tcpdump printed the packet as if the first 6 bytes were a destination MAC address, the next 6 bytes were a source MAC address, and the next 2 bytes were the type/length field.
Thus, the packet began with:
45 00 00 a8 35 49 00 00 32 06 af 56 d8 3a
and that really looks like an IPv4 packet with no link-layer header - which is exactly what the mobile phone interfaces in question provide as packets.
libpcap 1.6.2 and later have the libpcap workaround; if you use a version of tcpdump that uses a later libpcap, that will probably show the packets correctly. (If they don't, perhaps the hack libpcap uses to detect the bad ARPHRD_ values need to check for more interface names; please report this to tcpdump-workers#lists.tcpdump.org or on the GitHub issues list for libpcap. (Report this as a libpcap issue, not a tcpdump issue, as that's what it is.))

Add IMEI and MAC to wlan0 to Genymotion/AndroVM

Is there any way to add IMEI to AndroVM (now Genymotion) or any other Android Emulator. And also I want MAC address for wlan0 port. We already have emulators which contain MAC at lan0 port but not for wlan.
How can we do so?
if someone in your acquaintances has done so please ask them to contribute.
Details:
I am trying to build a cloud based Android App testing center as my pre final year college project for partial fulfillment towards my Bachelor of Technology (Computer Science) degree.
I am wondering how we can get more configurations for Genymotion.
Or if you can provide me with more device configurations and if it is possible to build configurations for genymotion for different devices very quickly.
Secondly, How to add MAC addresses and IMEI number to the builds?
We are trying to emulate a mobile device (non Google nexus) to make a cloud based testing centre.
For this we are trying to use androVM (Genymotion) and we are facing a few problems
What have we done so far
Building the androVm source code in "VBOX86tp-userdebug" mode from the scratch after following the steps given on official Android website.
After building the source code on a virtual ec2 server, typing the emulator command runs but its blank.
And if possible can AndroVm be run in "Fastboot" mode so that we can install it on the device.
We have been working on "building the androVm" from source code and trying to accomplish few tasks like
Running it with the img's available after the building process is complete.
Making it portable ie creating an iso/ova out of all the stuff found in the out directory.
What we have tried till now
Downloading of the AndroVm source code
initializing the repo using repo init
Downloading the source code using repo sync
choosing the lunch menu using lunch
choosing vbox86tp-userdebug
Other menus full-eng didn't work so discontinued
Few errors that came our way
Make errors: they were pretty straightforward so resolved
system.img was not being generated: resolved by making it again
bin/bash jar command error: happened to be the path error resolved by the exporting the path to jar command.
Few Questions
What an OVA file consits of and how can it be created? From what I have seen it contains few VMDK's and few configurations files attached to it,
How to convert the platform specific image files(system.img ramdisk.img userdata.img) into an OVA or ISO file.
If at all we are missing few files to give to the emulator, can you just name them.
Also how to add IMEI number
We already have MAC for eth0/1 port but we want it on wlan port
Now to make things interesting
This is the reply I got from Genymotion Team:
I want my project to cover various configurations but for starters if i can get something like Samsung Galaxy phones and tab or as a
start if I can get Samsung galaxy tab 2.
You can change the screen size and DPI for each virtual device. You
can toggle navigation bar and virtual keyboard. However, we cannot
provide virtual devices that contains proprietary applications like
Samsung.
Now here what we get is the MAC address of eth0/1 port. What if I need wlan MAC.
Unless one of the two network interface have been disabled, there
should be 2 interfaces, 2 IP, and 2 MAC addresses: adb shell ip a. 2:
eth0: mtu 1500 qdisc pfifo_fast
state UP qlen 1000
link/ether 08:00:27:d4:fe:e0 brd ff:ff:ff:ff:ff:ff
inet 192.168.56.101/24 brd 192.168.56.255 scope global eth0
inet6 fe80::a00:27ff:fed4:fee0/64 scope link
valid_lft forever preferred_lft forever 3: eth1: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:c8:37:e7 brd ff:ff:ff:ff:ff:ff
inet 10.0.3.15/24 brd 10.0.3.255 scope global eth1
inet6 fe80::a00:27ff:fec8:37e7/64 scope link .
Sorry, but we do not provide support for specific ROM. However, I
strongly recommend you to visit the community at:
https://groups.google.com/forum/#!forum/genymotion-users
1. What an OVA file consits of and how can it be created ?From what i have seen it contains few VMDK's and few configurations files
attached to it,
"The entire directory can be distributed as an OVA package, which is a
tar archive file with the OVF directory inside."
(http://en.wikipedia.org/wiki/Open_Virtualization_Format)
2. How to convert the platform specific image files(system.img ramdisk.img userdata.img) into an OVA or ISO file.
If at all we are missing few files to give to the emulator, can you just name them.
Please read the community tutorials
3. Also how to add IMEI number
There is currently no way to add IMEI number. This feature will come
in the near future
4. We already have MAC for eth0 port but we want it on wlan port
There is 2 interfaces: eth0 and eth1. Eth0 is used for Genymotion
application widgets. If this network connection is broken, Genymotion
would not be able to start anymore. Eth1 is used for network current
access (fake WiFi connection). You can change this network
configuration as you want.
It is a common practice for mobile applications to identify the user by IMSI number (associated with the SIM card) or IMEI number (unique ID of the device). Of course, it is also possible on Android:
TelehponyManager manager = (TelehponyManager)getSystemService(TELEPHONY_SERVICE);
String imei = manager.getDeviceId();
String imsi = manager.getSubscriberId();
This code works perfectly fine on a real device, however under emulator IMEI is always all-zero and it’s not configurable. It quickly becomes awkward when debugging a network-enabled application which uses IMEI as a user ID.
Trying to resolve the problem I first looked at the TelephonyManager service, just to find the following snippet:
private IPhoneSubInfo getSubscriberInfo() {
// get it each time because that process crashes a lot
return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
}
Fair comment, isn’t it? It really made my day :)
Anyway, code analysis shows that IMEI/IMSI request goes down through all the telephony layers (see the diagram), eventually getting to the baseband device. In case of emulated system, rild daemon is used together with libreference-ril.so – reference Vendor RIL library which talks to the baseband modem device using plain, old AT commands.
The modem device itself is emulated outside the Android system, as part of qemu (which is the heart of the emulator). Details of the communication between the emulator and the Android system running inside the emulator are interesting on its own (all the communication goes through a virtual serial port, Android system’s qemud daemon is used to (de)multiplex the data). I’ll try to post a brief introduction to the topic soon.
Virtual modem implementation can be found in external/qemu/telephony/android_modem.c. The most important part of the file is this function:
const char* amodem_send( AModem modem, const char* cmd );
This function is called for each received AT command. For each command sDefaultResponses array is searched for a given command and either predefined response is sent, or a command handler is executed. The array itself looks like:
static const struct {
const char* cmd; /* command coming from libreference-ril.so, if first
character is '!', then the rest is a prefix only */
const char* answer; /* default answer, NULL if needs specific handling or
if OK is good enough */
ResponseHandler handler; /* specific handler, ignored if 'answer' is not NULL,
NULL if OK is good enough */
} sDefaultResponses[] =
{
/* ... */
{ "+CIMI", OPERATOR_HOME_MCCMNC "000000000", NULL }, /* request internation subscriber identification number */
{ "+CGSN", "000000000000000", NULL }, /* request model version */
/* ... */
};
Two array rows cited above are responsible for IMSI and IMEI retrieval. As you can see, both values are hardcoded and there is no chance to modify them without recompiling the emulator.
However, an old-school hack comes in handy. The emulator binary is not encrypted nor compressed, so the string literals should be visible inside the emulator binary. In fact they are, and IMEI number can be modified in a few simple steps:
** backup the emulator binary
** open the binary with your favourite hex editor
** search for +CGSN string followed by a null byte, it should be followed by 15 digits of the IMEI number
** edit the number, be careful not to change the number of digits
** save the file, that’s all!
Sure, it’s not a perfectly comfortable solution, yet better than nothing. In the next part I’ll explain how to make IMEI number a configurable option. Enjoy!

Categories

Resources