UPDATE #2:
Apparently Samsung said in their press release that user should try out My Knox, as Knox Personal is deprecated. I just tried to install it but sadly My Knox only works on Samsung Galaxy S5 and Samsung Galaxy Note4.
So Samsung, you're leaving all devices older than the S5 with a vulnerable version of Samsung Knox??
UPDATE:
As Samsung responded with an official press release regarding my blog article (https://www.samsungknox.com/en/blog/response-blog-post-samsung-knox) I also want to response to their press release:
- First of all as I mentioned in the paragraph below, I analysed the pre-installed Knox Container App which is known as Knox Personal and shipped with the Samsung S4 I bought and not Knox EMM. " Knox EMM is a enterprise cloud-based
management solution for mobile devices which was not part of this
analysis."
- I investigated the following version (mentioned in the name of the apk files on the device): KNOX_com.sec.knox.app.container_2.0_2.apk, KNOX_com.sec.knox.containeragent_3.0_30.apk
- A lot of comments and posts claimed that I have just investigated an early developer version. I don't think that version 2.0_2 seems to be an early developer version?!? Also Samsung why are you shipping early developer versions of a product on customer devices?
- I did the analysis about one month ago with a new Samsung S4 and all updates installed. That doesn't seem to be an early developer version, right? Or did I bought a fake one ;)?
- Samsung mentioned the following in their press release: "Concerning the second issue, KNOX does save the encryption key required
to auto-mount the container’s file system in TrustZone. However, unlike
what is implied in the blog, the access to this key is strongly
controlled. Only trusted system processes can retrieve it, and KNOX
Trusted Boot will lock down the container key store in the event of a
system compromise."
- I think Samsung speaks here about their Knox Agent. At the beginning of my analysis I used geohots towelroot to gain root access on the Samsung device. During the analysis the phone wanted to update some "Samsung Security Policies". After the update the Agent blocked the root access to the phone. So this agent seems to be working like a usual Anti-Virus tool. It can only detect attacks if it knows the attack. And as we all know, Anti-Viruses are useless against unknown attacks :). This is the same for their so called "TrustZone".
- All other points the press release mentioned were just about a Knox 1.0 software, which now was replaced by MyKnox. I don't know what Knox 1.0 is and how to get it or on which devices this is installed. All I know is, the version of Knox Container 2.0_2, which was installed on my Samsung S4 is heavily insecure.
- @Samsung: I would really like to investigate your so called MyKnox and check if all your security measurements you mentioned in the press release are true. But please let me know what kind of device I have to buy to get the secure version :).
What is Samsung Knox:
Samsung phones, like the Samsung Galaxy S4, are shipped with
a preinstalled version of Samsung Knox. Samsung advertises Knox with
the following:
"KNOX Workspace container improves the user
experience, providing security for enterprise data by creating a secure
zone in the employee’s device for corporate applications, and encrypting
enterprise data both at rest and in motion. KNOX Workspace container
provides users with an isolated and secure environment within the mobile
device, complete with its own home screen, launcher, applications and
widgets for easier, more intuitive and safe operation. Applications and
data inside the container are separated."
Searching around the internet to find specific
information about Samsung Knox were not satisfying, as Samsung Knox is
not open source. This was the reason to investigate Samsung Knox a
little bit and lead to this analysis. Also today I read an article that the US government certified the use of Samsung Knox for their work and this was the reason to publish my analysis.
Setup:
The Samsung phone comes preinstalled with
two apps: Knox and Knox EMM. Knox EMM is a enterprise cloud-based
management solution for mobile devices which was not part of this
analysis. Focus was set to the Knox app, which provides the Knox
Container and a seperate (secure) home screen with own apps. The setup
for Knox is quite easy, you just have to set a password and a pin for
the Knox App. Looking at the system internals, Knox installs quite a lot
of stuff on your phone. Knox related apps in /data/data/:
com.samsung.klmsagent
com.samsung.knoxemm.mdm
com.sec.knox.app.container
com.sec.knox.containeragent
com.sec.knox.eventsmanager
com.sec.knox.seandroid
com.sec.knox.store
Additionally all apps which are installed in the new Knox home screen
are located in the standard app installation folder /data/data/ and come
with the prefix: com.sec.*. Listing all of them here would be too much.
After a typical Knox installation there are 139 apps and services
installed with the prefix com.sec.*
Looking a bit deeper in the
system, Knox is distributed through the whole system and stores data in a
couple of different locations, for example: the encrypted container
itself will be stored in /data/.container_*
and/data/container/.sdcontainer_1.* Different files and databases for
settings are stored in /data/system/secure_storage and
/data/system/container.
Analysis:
Each analysis of a mobile app starts with a static analysis of the files
the app stored after the setup. A good starting point for Android Apps
is the app folder under /data/data/. These folders typically have the
structure:
com.aPackageName
|- cache
|- databases
|- extracted
|- lib
|- shared_prefs
Especially the folders databases and shared_prefs are the ones that
deserves the first attention. The ContainerAgent app of Knox
(com.sec.knox.containeragent) had some interesting files stored:
Activation.xml
ContainerActivator.xml
ContainerType.xml
CreateSettings.xml
DB_BRIDGE_INIT_SYNC.xml
DB_BRIDGE_ISCHNDUOS.xml
DB_BRIDGE_ONCHANGE_CONTACTS.xml
DB_BRIDGE_ONCHANGE_EVENT.xml
KLMSLicenseStatus.xml
Pref.xml
PrivacyPolicy.xml
bno.xml
com.sec.knox.containeragent_preferences.xml
pin.xml
Yes, guess what is written in the pin.xml file? The pin we had to set during the setup of Knox in cleartext!
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="code">123456789</string>
</map>
The other files didn't reveal other interesting stuff. But back to the
pin.xml file. What is the purpose of the pin in Knox anyway? If you're
going to start Knox you have to provide your password to get access to
the data and the Knox home screen. But there is a small button under the
textfield called "Password forgotten?". By tapping it, you have to
provide your pin. If the PIN is correct the Knox app will show you a
little password hint (the first and the last character of your
password!! + the original length of your password!). So now it is pretty
obvious that Samsung Knox is going to store your password somewhere on
the device! As mentioned above, Knox is not only storing settings in
/data/data/, in the Folder /data/system/container there is a file called
containerpassword_1.key [sic!] stored. The content is a
crypted string: 72C9EE6D56CB15916A4CAB01814F978FA1E2689D (I modified
the string for obvious reasons ;)).
So this looks like an AES encrypted string. No we have to decompile the
apps to have a deeper look how exactly the encryption of the password
works and where the key for the encryption comes from. Samsungs makes
use of dex-preoptimization to strip out all classes.dex files (the java
code is stored in a file called classes.dex and this file is parsed by
the Dalvik JVM) in the Knox apks, thus making reverse engineering a
little bit harder. To get the binaries we have to look at /system/app/
and find .odex files (an odex is basically a pre-processed version of an
application's classes.dex that is execution-ready for Dalvik). odex
files can be converted back into smali code, which then can be converted
back to a dex file. Finally a dex file can be converted into a jar
file, which can be decompiled by any Java Decompiler.
Samsung didn't make any use of code obfuscation but really tried to hide
the password storage code within hundreds of java classes, inheritance
and proxies. Finally in the Knox Store app the proxy IDataService was
implemented which all other apps were constantly calling when handling
something password related. So when saving the password the app is doing
the following:
public boolean setData(String paramAnonymousString) {
this.keyGenInput = DataService.this.mPasswordUtil.getInputForKeyGenerate();
String str = SecureKeyLoader.getKeyForPassword(this.keyGenInput, this.bit_size);
return DataService.this.mEncryptDecrypt.encryptAndSave(paramAnonymousString, str);
}
Let's have a look at each line and the corresponding methods:
public long getInputForKeyGenerate()
{
return Long.parseLong(SecureKeyLoader.getPartialString(getAndroidID()), 16);
}
private String getAndroidID()
{
return Settings.Secure.getString(this.mContext.getContentResolver(), "android_id");
}
So the input for the key is obviously the unique Android ID which every
device has. The 16-Byte ID parsed as Long value is then used as an
argument for the function getKeyForPassword:
public class SecureKeyLoader
{
static
{
System.loadLibrary("mealy");
}
public static native String getKeyForPassword(long paramLong, int paramInt);
public static native String getPartialString(String paramString);
}
Ok, Samsung is obfuscating it more and more to hide the real key
generation. The method getKeyForPassword is placed in a C written shared
library called "mealy". Let's grab the library from the device and put
it into a disassembler like IDA:
The binary has one hardcoded string called "out_char" with the following
value:
eu>q5b0KPlLwyb@*#j9?!*ehjl(LHukkA(di^S4UXAChr3B`_xf+@h*#S&wpfv&#
. By looking at the code the method getKeyForPassword gets as an
argument the long value of getPartialString(getAndroidID()), holding as
variable the out_char String and passes both of them to the subroutine
'mealymachine'. Let's have a look at the function getKeyForPassword and
the subroutine mealymachine in pseudo code:
function Java_com_sec_knox_store_SecurityManager_SecureKeyLoader_getKeyForPassword {
r4 = r0; //partialString androidID as long value
r0 = r2; //integer = 16
r0 = mealymachine(r0, var_8, next, "eu>q5b0KPlLwyb@*#j9?!*ehjl(LHukkA(di^S4UXAChr3B`_xf+@h*#S&wpfv&#", STK29);
r3 = *r4;
r2 = *(r3 + 0x29c);
r0 = (r2)(r4, r0, r2, r3);
return r0;
}
function mealymachine {
r6 = r0; //partialString androidID as long value
r5 = r1; //var_8
r7 = r2; //next
r8 = r3; //eu>q5b0KPlLwyb@*
if (r1 <= 0x64) {
r4 = 0x0;
memset@PLT(0x2144, 0x0, 0x64);
r1 = r4;
do {
if (r4 >= r5) {
break;
}
r0 = r6 & 0x1;
r6 = r6 >> 0x1;
*(int8_t *)(r4 + 0x2144) = *(int8_t *)(r0 + r8 + r1); //AndroidID + eu>q5b0KPlLwyb@*
r4 = r4 + 0x1;
r1 = *(r0 * 0x4 + r7 + r1);
} while (true);
r0 = 0x2144;
*(int8_t *)(r0 + (r5 & !r5)) = 0x0;
return r0;
}
else {
r0 = 0x0;
return r0;
}
return r0;
}
By looking at the subroutine it just adds the long value from the
Android ID and the hardcoded string. The method getPartialString
substractes a part out of the Android ID. Just for the clarification:
every app can ask the system for the Android ID by calling:
Secure.getString(getContext().getContentResolver(),Secure.ANDROID_ID);
Conclusion:
Samsung really tried to hide the
functionality to generate the key, following the security by obscurity
rule. In the end it just uses the Android ID together with a hardcoded
string and mix them for the encryption key. I would have expected from a
product, called Knox, a different approach:
-
The fact that they are persisting the key just for the password hint
functionality is compromising the security of that product completely.
For such a product the password should never be stored on the device.
There is no need for it, only if you forget your password. But then your
data should be lost, otherwise they are not safe if there is some kind
of recovery option.
Recommendation:
Instead of Samsung Knox, use the built-in
Android encrpytion function and encrypt the whole device. Android is
using a PBKDF2 function from the encryption password you choose and
never persists it on the device. Obviously you can never access the data
if you forget your password, but that's the point of a good encryption.