Skip to content

Commit

Permalink
Initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
lucapiccolboni committed May 26, 2020
1 parent 93c3427 commit 4556fe4
Show file tree
Hide file tree
Showing 62 changed files with 5,281,813 additions and 2 deletions.
107 changes: 107 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/

# dirs
android-emu
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "scripts/random-tests"]
path = scripts/random-tests
url = https://github.com/dj-on-github/sp800_22_tests
114 changes: 112 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,112 @@
# crylogger
CRYLOGGER: Tool to detect cryptographic misuses in Android
## Introduction

*CRYLOGGER* detects cryptographic (crypto) misuses in Android apps. A crypto misuse is an invocation to a crypto API that does not respect common security guidelines, such as those suggested by cryptographers or organizations like [NIST](https://www.nist.gov/) and [IETF](https://www.ietf.org/). For instance, *CRYLOGGER* can tell you if your Android app uses AES in ECB mode to encrypt multiple data blocks, which is bad in cryptography.

*CRYLOGGER* detects crypto misuses for you automatically, without requiring to analyze a single line of your code. First, *CRYLOGGER* runs your Android app on the official Android [Emulator](https://developer.android.com/studio/run/emulator), whose Java libraries have been instrumented to log the parameters passed to the relevant crypto APIs. Then, it analyzes the log file offline and reports all the crypto misuses. Differently from other approaches, it does *not* employ static analysis. *CRYLOGGER* runs your app by using [Monkey](https://developer.android.com/studio/test/monkey) or the user-interface events you send to the emulator.

If you want to know more about *CRYLOGGER*, please contact me at
[email protected] or read our Oakland paper:

```
Luca Piccolboni, Giuseppe Di Guglielmo, Luca P. Carloni and Simha Sethumadhavan, "CRYLOGGER:
Detecting Crypto Misuses Dynamically", in IEEE Symposium on Security and Privacy (SP), 2021.
```

***

## Requirements

There are not a lot of requirements that are specific to *CRYLOGGER*. If you satisfy the requirements of the [AOSP](https://source.android.com/setup/build/requirements) and you install all the Python packages required for `scripts/run.py` and `scripts/check.py` you are good to go! *CRYLOGGER* has been tested on *Android-9.0.0_r36* (this is the default version of the emulator that is installed as explained below). It should be easy to adapt it to other Android builds. For the host machine, we used a machine with a clean installation of *Ubuntu 18.04.1*.

Make sure you install the [Android SDK](https://developer.android.com/studio) if you want to compile the test app included in this repository (directory `test-app`) and set the environment variable `ANDROID_SDK_ROOT` to point to it.

## Emulator Setup

Once you satisfy the requirements of the AOSP, it is sufficient to run the following command to setup the emulator and *CRYLOGGER*:

```bash
cd scripts/setup
./setup_emu.py
```

This scripts downloads the AOSP in a new directory `android-emu` from the official Google repositories, installs *CRYLOGGER* by copying the files from the directory `scripts/deltas`, and builds it. Please refer to the scripts in the directory `scripts/setup` for more information. By default, it uses all the available cores to compile the AOSP.

In addition, if you want to install apps from the Google Play Store, you need to install the [OpenGApps](https://github.com/opengapps/opengapps). You can do so by running the following commands:

```bash
cd scripts/setup
./setup_opengapps.sh
```

The OpenGApps (*x86-9.0-super-20200103*) are downloaded in `script/opengapps` so they can be installed on the emulator.

***

## Verify your App

You are now ready to run your app on the Android emulator and collect the log that contains information about the crypto APIs that are invoked. We call this log *"cryptolog"*. Here, we verify a simple Android app that you can find in the directory `app-test`. If you have your own APK to test, you can skip the compilation of `app-test`, otherwise:

```bash
cd app-test
./gradlew build
```

If the compilation is successfull, you should find a file named `com.example.aes_0.apk` in the folder `test-app` that points to the APK of the test app. If you use your APK, make sure you use the following naming convention: `<package_name>_<version>.apk`, where `<package_name>` is the package name of the Android app and `<version>` is its version number. Copy the APK in the directory `scripts/data/apks`:

```bash
cp app-test/com.example.aes_0.apk scripts/data/apks/
```

You need to start the emulator by passing the option `-writable-system` (this option is only used to install the OpenGApps):

```bash
# Setup the env variables
cd android-emu
source build/envsetup.sh
lunch sdk_phone_x86-userdebug
# Now start the emulator
emulator -writable-system
```

### Collect the logs

The emulator should be now running. Wait for the completion of the boot process, and then run the following script to execute your app:

```bash
cd scripts
python run.py --work_dir data --session emulator-<number>
```

where `<number>` is the emulator session number (you can find it in the title bar of the emulator window). By default the script `run.py` (1) installs the OpenGApps, if they have not been installed in a previous run, (2) configures the emulator, so that your app can be tested with Monkey, (3) installs your app on the emulator, (4) runs your app with Monkey by using a fixed number of user-interface events (default *100*), (5) collects the cryptolog, which contains information about the use of the crypto APIs, and (6) uninstalls the app. You can easily modify the script `run.py` if you want to use your own user-generated events.

### Analyze the logs

After 'run.py' completes, you should find the log in the directory `scripts/data/crypto_logs`. Now you can analyze them by running the following command:

```bash
cd scripts
python check.py --work_dir data/crypto_logs --rule_ID <number>
```

where `<number>` is the number of the crypto rule you want to check. *CRYLOGGER* support *26* rules that are explained in the paper as well as in the script `check.py`. These rules are suggested by cryptographers or organizations like [NIST](https://www.nist.gov/) and [IETF](https://www.ietf.org/). Try for example to check rule *R-03* by using the following command:

```bash
cd scripts
python check.py --work_dir data/crypto_logs --rule_ID 03
```

You should obtain a file with extension `.rules` in the directory `scripts/data/crypto_logs` that tells you if rule *R-03* is violated. For the app included in this repository the rule should be violated because the app performs encryptions and decryptions by using the insecure ECB mode. Note that some rules require two executions of your app, thus you need to run the script `run.py` twice. The second run should look like this:

```bash
cd scripts
python run.py --work_dir data --session emulator-<number> --suffix 2
```

This command runs again your app on the emulator and appends `'2'` to the cryptolog files (extension `.cryptolog2` instead of simply `.cryptolog`). You can check rules that require two executions, for example rule *R-05* with the following command:

```bash
cd scripts
python check.py --work_dir data/crypto_logs --rule_ID 05
```

If you want to check all the rules supported by *CRYLOGGER*, omit the flag `--rule_ID`.
6 changes: 6 additions & 0 deletions app-test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.iml
.gradle
/local.properties
.idea
build
captures
1 change: 1 addition & 0 deletions app-test/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
41 changes: 41 additions & 0 deletions app-test/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Top-level app build

plugins {
id 'com.android.application'
id 'com.github.sherter.google-java-format' version '0.8'
}

googleJavaFormat {
source = sourceSets*.allJava
}

android {

compileSdkVersion 28

defaultConfig {

applicationId "com.example.aes"
minSdkVersion 26
targetSdkVersion 28
versionCode 1
versionName "1.0"
}

buildTypes {

debug {
debuggable true
}

release {
minifyEnabled false
}
}
}

dependencies {
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
}
21 changes: 21 additions & 0 deletions app-test/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
22 changes: 22 additions & 0 deletions app-test/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.aes">

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
68 changes: 68 additions & 0 deletions app-test/app/src/main/java/com/example/aes/MainActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* Author: Luca Piccolboni ([email protected]) */

package com.example.aes;

import java.io.*;

import java.util.*;

import javax.crypto.*;
import java.security.*;

import java.nio.*;
import java.nio.file.*;
import java.nio.channels.*;
import java.nio.charset.*;

import android.content.*;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

private static int KEY_SIZE = 256;
private static String alg = "AES/ECB/PKCS5Padding";

@Override
protected void onCreate(Bundle savedInstanceState)
{
String ciphertext, plaintext;
FileOutputStream stream = null;
String testString = "The quick brown fox jumps over the lazy dog";

try {

stream = openFileOutput("aes.log",
Context.MODE_PRIVATE |
Context.MODE_APPEND);

Cipher cipher = Cipher.getInstance(alg);

KeyGenerator keygen = KeyGenerator.getInstance("AES");
keygen.init(KEY_SIZE); SecretKey key = keygen.generateKey();

// Encryption
cipher.init(Cipher.ENCRYPT_MODE, key);
ciphertext = Base64.getEncoder().encodeToString(cipher.doFinal(
testString.getBytes(StandardCharsets.UTF_8)));

// Decryption
cipher.init(Cipher.DECRYPT_MODE, key);
plaintext = new String(cipher.doFinal(Base64.getDecoder().decode(
ciphertext)));

stream.write(("[decrypted: " + plaintext + "]\n").getBytes());
stream.close();

} catch (Exception e) {

try { stream.write(("Exception:" +
e.getMessage() + "\n").getBytes()); }
catch (Exception e2) {}

}

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Loading

0 comments on commit 4556fe4

Please sign in to comment.