Intrepidus Group
Insight

Author Archives: wuntee

The story of how qemu met MIPS and created netcat

Posted: October 20, 2011 – 10:57 am | Author: wuntee | Filed under: MIPS, Reverse Engineering

Earlier this week I found myself in a predicament when I was reversing a stripped down MIPS embedded device. The device had minimal available memory and the only real executables on it were an even more stripped down busybox executable, tftp, and tcpdump. My goal was to obtain tcpdump logs being captured on device, but due to the lack of NFS support and the minimal available memory, I had very few options.

Initially I attempted to write the tcpdump logs to a file, and tftp them up to my local box. This became an issue when the log file became too large and all of the running processes started crashing. Trying to get my timing correct for the tftp command to execute, before everything went haywire, became a serious frustration. This is when I decided to go down a different route and try using everyone’s friend netcat. Unfortunately, I could not find a working netcat binary for the device, so I had to compile my own…

First, I downloaded every MIPS netcat I could find and tried to run them on the device. None worked – the output when trying to run them looked like:

# ./netcat
./netcat: line 1: syntax error: "(" unexpected

Which is extremely frustrating because that output looks like the shell is trying to run the netcat binary as a shell script. Anyway, after a few hours of failing, this is when I decided that I needed to compile my own netcat. This day long endeavor took much longer than I anticipated. I am writing this up in the hope that I can save someone else this frustration.

I knew I was going to build a Debian based MIPS system using qemu on Ubuntu 11.04. I found this tutorial that helped greatly:

Mistake: I assumed which architecture I needed. Make SURE you know which architecture and endianness you are going to be building against. There is a very easy trick to understand this. Pull a file of of the device, and run the ‘file’ command against it. In my case it looked like this:

$ file some_elf_binary
some_elf_binary: ELF 32-bit LSB executable, MIPS, MIPS-II version 1 (SYSV), dynamically linked (uses shared libs), stripped

The “LSB” in that line stands for Least Significat Bit and means you should be building a MIPSEL virtual machine. If it says “MSB,” or Most Significant Bit you should build a MIPS virtual machine. I did not take the time to understand this, and now have a MIPS and MIPSEL virtual machine.

To reiterate – run ‘file’ on an existing executable
LSB = Create MIPSEL virtual machine
MSB = Create MIPS virtual machine

Creating the virtual machine with qemu is pretty easy, but time consuming.

First you must install the correct packages on Ubuntu (the ‘extra’ package provides the MIPS architecture):

sudo aptitude install qemu qemu-kvm-extras

Now you need to pull the initrd and vmlinux files from Debian for your virtual machine type. The initrd is the initial ramdisk and is used to load a temporary filesystem in memory. The vmlinux is the kernel that will be loaded into memory.

At the time of writing this, these links work for downloading the files for the respective architecture:
http://ftp.de.debian.org/debian/dists/stable/main/installer-mipsel/current/images/malta/netboot/
http://ftp.de.debian.org/debian/dists/stable/main/installer-mips/current/images/malta/netboot/

The next step is creating a file that will be your virtual hard disk.

qemu-img create -f raw hda.img 1G

Simple enough. Now to boot the initrd/vmlinux combination which will get you to the Debian installer.

NOTE: The ‘-M malta’ that relates to the ‘malta’ Debian images I downloaded. The tutorial I mentioned above uses ‘-M mips’ – this was a hanging point for me. When booting with ‘-M mips’ it just hung, no output, nothing.

MIPSEL:

qemu-system-mipsel -M malta -kernel vmlinux-2.6.26-2-4kc-malta -initrd initrd.gz -hda hda.img -append "root=/dev/ram console=ttyS0" -nographic

MISP:
qemu-system-mips -M malta -kernel vmlinux-2.6.26-2-4kc-malta -initrd initrd.gz -hda hda.img -append "root=/dev/ram console=ttyS0" -nographic

Follow the instructions in the installer, and at the end it will tell you everything is completed and to remove the CD rom or boot media. At this point I waited for the VM to reboot into the installer again, and then had to kill the host’s ‘qemu-system’ process.

NOTE: There is a dialog that tells you that there is no boot loader, and you will have to append some arguments to the kernel. Make sure you take note what device it tells you (sometimes it will be /dev/hda1, others /dev/sda1)

If all went well, you should now be able to boot into the MIPS or MIPSEL OS. As explained above, my two installations had different root partitions that I needed to boot into. Another hanging point when creating my second MIPSEL VM.

MIPSEL:qemu-system-mipsel -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda hda.img -append root=/dev/sda1 -nographic
MIPS:qemu-system-mips -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda hda.img -append root=/dev/hda1 -nographic

Finally we have a MIPS VM shell. I will use netcat as an example of how I built a binary that worked on the end MIPS embedded system. First step is to obviously download the source.

Using wget to pull it down on the MIPS VM, I realized I had to install a compiler.

apt-get install gcc

worked just fine.

Mistake: I did not think about how I had to compile these applications. The end device is very stripped down, and who knows what libraries it even has on it. So after some trial and error I realized that I had to compile with static library linking. It has been a while since I have compiled something like this, so I found this that explains that all you need to do is add the ‘-static’ flag to the compiler arguments, prior to finding that link I asked in the IG chat room, and got a similar response:

[10/11/11 5:10:46 PM] wuntee: how do you force automake/autoconf/gcc whatever to do static librarys, vs dynamic?
[10/11/11 5:11:38 PM] Jeremy: -static
[10/11/11 5:11:39 PM] Sid: -static
[10/11/11 5:11:46 PM] Sid: ^ that
[10/11/11 5:11:46 PM] Jeremy: Zach, go on… say it
[10/11/11 5:11:49 PM] Zach twitches
[10/11/11 5:11:52 PM] Jeremy: -static
[10/11/11 5:11:57 PM] Jeremy: -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static -static
[10/11/11 5:11:57 PM] Sid: -static
[10/11/11 5:12:36 PM] Zach: “./configure –help”

RTFM… Thanks guys.

Mistake: There are MANY options you can pass to the compiler when compiling something for MIPS:. The output of the ‘file’ command on a working executable can be helpful here. In my case it says “ELF 32-bit LSB executable, MIPS, MIPS-II” which meant I wanted to also pass ‘-mips2′ to the compiler.

Configuring and making netcat was easy enough after figuring out all of the options:

CPPFLAGS="-mips2 -static" CFLAGS="-mips2 -static" ./configure && make

Running file on this looks close enough to the working executable, and it is statically linked like I wanted:

some_elf_binary: ELF 32-bit LSB executable, MIPS, MIPS-II version 1 (SYSV), dynamically linked (uses shared libs), stripped
netcat: ELF 32-bit LSB executable, MIPS, MIPS-II version 1 (SYSV), statically linked, for GNU/Linux 2.6.18, with unknown capability 0xf41 = 0x756e6700, with unknown capability 0x70100 = 0x1040000, stripped

You can then put the executable on the device, and it hopefully will run. One last thing you can do to the binary in order to conserve space is strip it. This can be done with the strip command.

After about a day of getting this working, the end netcat file was only 750k, and allowed me to obtain tcpdump output. Hope this helps someone.

wuntee

1 comment

Setting up a persistent trusted CA in an Android emulator

Posted: August 24, 2011 – 12:54 pm | Author: wuntee | Filed under: android, Mallory, Reverse Engineering, ssl

Setting up a persistent trusted CA in the Android emulator is a common problem, encountered any time we assess an application within an emulator, that use SSL properly. The goal is to man-in-the-middle (MITM) traffic from an application running in the Android emulator.

In order to successfully MITM traffic, the Certificate Authority (CA) of the middle node must be trusted by the device, otherwise the connection will fail with some generic SSL Handshake error. Typically, the middle node can be flagged as trusted on a rooted phone by modifying the cacerts file, and rebooting the device. When attempting to do this in the Android emulator, rebooting the virtual device causes the OS to revert many system files back to their base state – including the cacerts file. The rest of this post describes how to set up an emulator that will retain modifications to the core system files after reboots. This has not been documented in one place (to my knowledge), so hopefully this will save time for those facing this problem.

Set up OS environment:

The Android cacerts file uses a specific keystore type called Bouncycastle KeyStore (BKS). You will need to download the BouncyCastle provider, and place it in your $JAVA_HOME/jre/lib/ext/.

Note: In OSX, that is: /System/Library/Frameworks/JavaVM.framework/Home/lib/ext

Direct link: http://bouncycastle.org/download/bcprov-jdk16-141.jar

Create an Android Virtual Device (AVD):

Run ‘android’ and create an AVD; note what ‘target’ you specify (including any add-ons, like google API).

You can also use the a combination of the ‘android‘ and ‘emulator‘ commands to create and initialize an AVD:

$ android create avd --target "Google Inc.:Google APIs:10" --name IntrepidusGroup
$ emulator -initdata $ANDROID_HOME/platforms/android-10/images/userdata.img -avd IntrepidusGroup

Note: Where the directory /android-10/ is the same as the ‘target’ you selected in the first command. A list of targets can be found by running the command ‘android list targets’

Set up emulator environment:

By default, the emulator uses a base image each time it boots, so you will need to copy all of these base files to the local directory of the AVD. The source directory will depend on the ‘target’ device you selected above; if there are any additional APIs needed, those must be copied as well. The base Android images are located in ‘$ANDROID_HOME/platforms/*/images/’ and the additional libraries are located in ‘$ANDROID_HOME/add-ons/*/images/’. If you did not specify a directory to create your AVD in, it will be located in ‘~/.android/avd/’. The images directories line up with the ‘target’ version selected previously.

$ ls platforms/
total 0
drwxr-x---@ 6 wuntee staff 204 Jul 27 13:51 .
drwxrwx---@ 9 wuntee staff 306 Jul 27 13:50 ..
drwxr-xr-x 11 wuntee staff 374 Apr 18 13:18 android-10
drwxr-xr-x 12 wuntee staff 408 Apr 18 10:12 android-11
drwxr-xr-x 14 wuntee staff 476 Jun 29 11:41 android-4
drwxr-xr-x 13 wuntee staff 442 Jul 27 13:51 android-8

$ ls add-ons/
total 0
drwxr-x---@ 5 wuntee staff 170 Jun 29 11:44 .
drwxrwx---@ 9 wuntee staff 306 Jul 27 13:50 ..
drwxr-xr-x 8 wuntee staff 272 Apr 18 16:19 addon_google_apis_google_inc_10
drwxr-xr-x 8 wuntee staff 272 Apr 18 16:14 addon_google_apis_google_inc_11
drwxr-xr-x 9 wuntee staff 306 Jun 29 11:44 addon_google_apis_google_inc_4

Example:
$ cd ~/.android/avd/IntrepidusGroup.avd/
$ cp $ANDROID_HOME/platforms/android-10/images/* .
$ cp /Applications/android-sdk-mac_x86/add-ons/addon_google_apis_google_inc_10/images/* .

Run the emulator

When running the AVD, you must specify a ‘partition-size’ argument, which is defined in the emulator help as:
-partition-size system/data partition size in MBs
If you do not include this argument and attempt to push files to the ‘/system’ filesystem, you will get an “INSERT ERROR” error message.

In order to start the emulator, you would run:
$emulator -partition-size 128 @IntrepidusGroup

Install the certificate

Automated:

I have create a set of tools called AndroidAuditTools that will perform all necessary adb actions which can be found on GitHub.  You will want to use the “installcer.rb” command. Here’s the help listing for that:

/androidAuditTools/bin$ ruby installcer.rb --help
Options:
--cerFile, -c <s>: cer file to install
--tmpFile, -t <s>: Temporary cert file (default: /tmp/cacerts)
--storePass, -s <s>: Default Android cacerts store pass (typaicall 'changeit', but sometimes blank '') (default: changeit)
--aliasName, -a <s>: Alias name for the added cert (default: AndroidAuditTools-cert)
--adb, -d <s>: Custom adb command (default: adb)
--debug, -e: Debug
--help, -h: Show this message</s></s></s></s></s>

Manual:

You first must pull the current certfile from the device; it is located: at ‘/system/etc/security/cacerts.bks’
$ adb pull /system/etc/security/cacerts.bks

From here, you can import your certificate file to the ‘cacerts.bks’ file (assuming the CA certificate is called ca.cer)
$ keytool -keystore cacerts.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -storepass changeit -importcert -trustcacerts -alias somealias -file ca.cer -noprompt
Note: There have been devices that use the storepass as nothing, or “”; this must be specified on the command line for the keytool command to execute properly.

Note2: If you are trying to perform MITM using Mallory, the ‘ca.cer’ file is located in ‘mallroy/src/ca/ca.cer’

You must then re-mount the ‘/system’ directory as read-write prior to putting the file back on the device
$ adb shell mount -o remount,rw /dev/block/mtdblock0 /system
Note: This command will always be the same when running it against an emulator, but with a physical device you must run the ‘mount’ command to see where the ‘/system’ directory is mounted and change the ‘/dev/block/mtdblock0 /system’ portion accordingly

Then, the permissions for the current ‘cacerts.bks’ file must be modified in order for it to be overridden:
$ adb shell chmod 777 /system/etc/security/cacerts.bks
You can then override the file on the emulator, and finally change the permissions back:

$ adb push cacerts.bks /system/etc/security/cacerts.bks
$ adb shell chmod 644 /system/etc/security/cacerts.bks

Reboot

Finally, for the device or emulator to use the changes that have been made to the cacerts file, it must be rebooted. Simply close the emulator and re-start it with the command line options described above.

-@wuntee

 

3 comments

Reversing Jailbreakme.com 4.3.3

Posted: July 8, 2011 – 9:36 am | Author: wuntee | Filed under: bugs, iOS, jailbreak, jailbreaking, Mobile Security

UPDATE – July 18 2011

  • There is a good analysis of the exploit here
  • And comex has released the source for this all here

 

Wednesday, @comex came out with a new user-level jailbreak available on jailbreakme.com. I wanted to understand exactly how this exploit is able to get root so easily. Here is my workflow, and preliminary analysis of the exploit.

The first obvious step is to obtain the page that exploits the iPhone:

curl -A "Mozilla/5.0 (iPad; U; CPU OS 4_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F190 Safari/6533.18.5" http://www.jailbreakme.com &gt; exploit.7.6.2011.pdf

After opening up the file, you can see a set of comments which are quite amusing:

Analyzing the page, the bulk of it is in a base64 encoded pdf blob on line 1044:

There are some % notation characters in there that you must convert; specifically %2B=+ and %2F=/. The blob can now be base64 decoded with your favorite method, and you will get a pdf file that is only 16k in size:

$ ls -lah exploit.7.6.2011.pdf
-rw-r--r--@ 1 wuntee staff 16K Jul 6 19:48 exploit.7.6.2011.pdf

$ file exploit.7.6.2011.pdf
exploit.7.6.2011.pdf: PDF document, version 1.3

Examining the PDF file with Didier Stevens pdf-parser tool, there is one object (obj 12 0) that sticks out, consuming most of the file:

Further examining that object, you will see that it is a FlatDecode stream:

After playing around a bit more with the file using Didier Steves tools, and attempting to dump the raw stream, I ended up running the following command that made my terminal freak out.  It minimizes, then restores, over and over again for about 60 seconds (more on this shortly).
NOTE: Do not run this command unless you want your terminal to minimize and restore over and over again.

$ pdf-parser.py --object 12 --raw --filter exploit.7.6.2011.pdf

Finally, I switched over to Sogeti ESEC Lab’s Origami framework, in order to dump the raw stream using the PDF walker GUI:

Looking at the file, you can see it is a PostScript Type 1 font:

$ file raw.stream.12.bin
raw.stream.12.bin: PostScript Type 1 font program data

Examining the contents of file in a text editor, you can see a few interesting things:

First, the header comment, which is explaining that it is “blatantly invalid”, followed by the ‘/TerminalFun’ object, which is what was causing my terminal to freak out when printing the raw contents, as described earlier… Thanks @comex

Now, I am not very familiar with AdobeFont file formats, or font file formats in general, so I started looking at the AdobeFont 1.0 file format spec (Note: The linked PDF is causing my Chrome to crash… Maybe another vuln?) and started stepping through the jailbreakme.com‘s AdobeFont file. I started to compare tis font file to the examples that were given in the AdobeFont document, there are a lot of similarities:

Then I got to the ‘/Private’ portion, and I noticed the ‘/lenIV -1 def’. The AdobeFont spec states:

5.12 lenIV

The lenIV entry is an integer specifying the number of random bytes at the beginning of charstrings for charstring encryption. The default value of lenIV is 4.

Setting an integer (lenIV) to -1 would seem to be a logical place for a vulnerability to trigger. Reading further in the spec document, it also says:

To Decrypt a Sequence of Ciphertext Bytes to Produce the Original Sequence of Plaintext Bytes

1. Initialize an unsigned 16-bit integer variable R to the encryption key (the same key as used to encrypt).

2. For each 8-bit byte, C, of ciphertext the following steps are executed:

a. Assign the high order 8 bits of R to a temporary variable, T.

b. Exclusive-OR C with T, producing a plaintext byte, P.

c. Compute the next value of R by the formula ((C + R) × c1 + c2) mod 65536, where c1 and c2 are the same constants that were used to encrypt.

3. Discard the first n bytes of plaintext; these are the random bytes added during encryption. The remainder of the plaintext bytes are the original sequence.

I think we found our bug… Discard the first -1 bytes of plaintext…

I hosted the pdf file on my local machine, and pointed my 4.3.1 jailbroken iPhone at the PDF while MobileSafari was connected to GDB and see an exception being triggered:

The exception occurred from a ‘KERN_PROTECTION_FAILURE’ which leads me to believe that the exploit may not work with 4.3.1, but it also gives me an insight into where the exception is happening.  Specifically:

__CFPLDataDecodeTable () - t1_decoder_parse_glyph () - t1_decoder_parse_charstrings () - T1_Parse_Glyph_And_Get_Char_String () - T1_Load_Glyph () - FT_Load_Glyph () - FT::font::load_glyph () ...

This makes sense, and confirms my assumption above that the problem is with “decrypting” the /Private blob shown above.

So, this seems to be a single vulnerability/exploit which allows Cydia to be installed (vs a multi-phased exploit that performs a Safari exploit, followed by a privilege escalation).

The next step is to understand how the exploit actually works.

There was some twitter chatter about the exploit having a kernel driver by @saurik:

I have some speculations of my own on how this exploit is actually working. I think the reason this works is because processing/installing fonts happens at an escalated privilege level. Since the exploit is actually happening during the processing of the font, that same security level would have the ability to install an application, such as Cydia, and disabled protections against running un-signed applications.

After examining the AdobeFont file further, it is unclear to me if the ‘/Private’ portion is encrypted/encoded. The /Private section consists of an array of 9 objects, where the 9th one looks like the payload for the exploit:

The endian’ess makes everything backwards, but you can definitely see directories in there:

  • /private/var/mobile
  • /private/var/mobile/Library/preferences/com.apple
  • /private/var/mobile/Library/Preferences/

That is all I have for now. I hope to have an update on how the exploit actually works in the future.

3 comments

androidAuditTools : Dynamic Android analysis tools

Posted: May 18, 2011 – 10:56 am | Author: wuntee | Filed under: android, Reverse Engineering, Tools

Project is hosted on github: https://github.com/wuntee/androidAuditTools

 

When taking the SANS reverse engineering malware class, the two analysis techniques taught are dynamic and static. These concepts/techniques are directly applicable to any sort of reverse engineering. When I am assessing, or pen-testing an application I usually separate my thought process into one of those two buckets.  During dynamic analysis of a mobile device it becomes very difficult to understand whats going on in the operating system due to the lack of automated tools; there are no tools that can easily hook into the kernel processes that tell you key information like network connections, file writes, etc. I also typically don’t enjoy doing work on a physical device – I prefer doing as much analysis on my computer as possible.

One function I find very beneficial in dynamic malware analysis, but is lacking from anything I have seen in the mobile space, is a tool that has the ability to automate and visualize filesystem differences when performing actions like installing or running applications.

This set of points led me to writing a toolset for the Android platform. First, I wrote a tool that recursively lists the directories in an Android filesystem via adb and has the ability to show the differences between two points in time. It can automatically install APK, and pause for you to run them, interact, and then re-scan.  A simple example would be to run google maps, do a search, and close the application.

As you can see, there are many files added ([+]), deleted ([-]) and modified ([c]); that would be almost impossible to determine that from any command line interactions. In fact, I am surprised as to how many files are actually mucked with.

This tool will easily help detect two of the OWASP Top 10 Mobile Security Risks; specifically:

  • 1. Insecure or unnecessary client-side data storage
  • 5. Failure to implement least privilege authorization policy

This tool can also be helpful during mobile malware analysis. For example, when malware starts targeting specific applications (like the Skype issue presented in a previous post), or malware attempts to root a device through an exploit, it will be easy to see if an application creates or modifies files it shouldn’t.

There are two other tools in the androidTools project:

  • findfileswithperms.rb – Find files given a regular expression of the permissions string (ex: find directories – ruby findfileswithperms.rb –perm ‘^d.*’)
  • listallfiles.rb – Lists all files on the device given a base directory

 

Note1: The fsdiff.rb is best used with an emulator because the emulator will automatically drop to a root shell. A (non-rooted) physical devices drops to a a user shell, and does not have access to the entire filesystem; in turn, many changes may be lost.

Note2: This was written in a few hours, there is a lot of functionality that can be added, minimal comments, and potentially many bugs. Please use the github repo for any problems/requests/etc.

Note3: You must run the applications from the bin directory, as it includes the lib directory relative to bin.

2 comments

Apple iOS 4.3 adds additional IPv6 user security

Posted: April 4, 2011 – 4:03 pm | Author: wuntee | Filed under: iOS

A little bit of background on IPv6, NDP, Auto-config, Host Address Randomization, and EUI-64

Note: If you understand IPv6, NDP, Auto-config, Host Address Randomization, and EUI-64, please skip

In IPv4, there is a requirement to have an external entity handle IP address assignments. Typically this is done by a DHCP server where that server keeps track of host state, and assignment.  Although there is DHCPv6, IPv6 has introduced a new means of allowing hosts to auto-assign/negotiate their IPv6 addresses called ‘Stateless Address Autoconfiguration’, defined in RFC4862. Stateless auto-config introduces an entire new concept to the Internet Protocol, and address generation has been moved from a centralized server to each host.  Without taking into account all of the negotiations that need to happen in order to have a stateless, non-colliding, auto address assignment, the host is now the one that has to do the generation of an address.  Since the auto configuration is stateless, there is no starting point like there is in DHCPv4 – for example: there is no 192.168.1.100 that addressing can start from.

Since there is no state, and the address is generated by the host, we would need something that will reliably not collide with other hosts. A way to satisfy the address requirements is to have a unique number for each network device. MAC addresses are unique to each host, which is where EUI-64 was introduced (RFC4291).  EUI-64 is a way of generating an IPv6 host portion of an IPv6 address from a MAC address. This is a working concept, and is implemented in many devices. From a security standpoint you can use this to gain additional information about the specific host.  An attacker can go backwards from IPv6 EUI-encoded address, to get the associated MAC address. They can then go from MAC address to manufacture of the device using IEEE OUI lookup. Although this does not give you much information, it does introduce knowledge to an attacker they they previously had not known.

After EUI-64 was questioned by the security community, Host Address Randomization was introduced. Although I have not read through the entire RFC3014, the concept seems pretty straight forward. You do not want an attacker have any additional information about your host, so randomize each IPv6 address that the host auto-configures.  If the host has multiple IPv6 addresses, one would think the host portion would be re-generated for each one of those addresses. If they aren’t, an attacker would know additional information: given one IPv6 address, an attacker would know the host portion of the rest of the IPv6 addresses. I have seen that most implementations only generate the host portion once, and use that for every provisioned IPv6 address.

 

The actual post

This morning, with the release of the iphone dev team’s un-tethered  iOS 4.3.1 jailbreak, I decided to upgrade my iPhone 4 to the 4.3.1 firmware.

In the midst of creating an IPv6 host randomization testing script, I was happily surprised that the iOS update allows the device to perform full IPv6 host address randomization (as described in: RFC3014).

This is the first implementation I have seen that does host randomization as I would expect it to – a random host address is generated for just about every address that the device provisions. As described above, other implementations generate a single host portion of the address, and will use that host portion of its address for every IPv6 address it auto-configures for itself.  For example, Windows7 was one of the first operating systems that I heard of that supposedly implemented IPv6 host randomization, but when forcing the operating system to generate multiple IPv6 addresses, it doesn’t seem to have any randomization:



As you can see, every “Temporary IPv6 Address” has the same host portion for every address.

Many mobile devices do not have the same capabilities as Windows7 to obtain a full list of current IP addresses, including Apple iOS devices.  In fact,  I have not found any tools that provide any capability to do anything with IPv6 local on Apple’s iOS devices. Now the problem becomes how to test for host address randomization remotely.  The test that I have created to test for IPv6 host address randomisation is as follows:

  1. Obtain the MAC address of the device to test
  2. Start a thread to monitor for all Neighbor Advertisements.  This is sent during neighbor discovery after a host assigns itself with an IPv6 address
  3. Generate an IPv6 Router Advertisement that tell every host on the link-local segment to generate a new public IP address of ’2001:[RANDOM PREFIX]::’ and assign themselves a /64
  4. Send a new random IPv6 Router Advertisement 100 times
  5. Look through the list of Neighbor Advertisements that were observed, and filter out only the ones seen coming from the MAC address of the device to be tested
  6. See how many unique IPv6 host portions were observed during the Router Advertisement flood
  7. If there is greater than one Neighbor Advertisements seen, and multiple unique IPv6 host portions, then their must be some sort of host address randomization
  8. If there is greater than one Neighbor Advertisement seen, and only one unique IPv6 host portion, then host address randomization is not implemented
  9. Otherwise we do not have enough data to make a conclusion

Prior to today, any time I performed this test, there was only observed to be one unique IPv6 host portion on iOS (iPhone 4) 4.2.1, but when doing a test today I noticed:

20 unique host addresses?!

I looked through the debug logs, and confirmed that this was in fact the case.  I have to give Apple props for being the first in my eyes to implement real IPv6 host address randomization.

No comments yet

image

This site is protected with Urban Giraffe's plugin 'HTML Purified' and Edward Z. Yang's Powered by HTML Purifier. 11844 items have been purified.