-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
93c3427
commit 4556fe4
Showing
62 changed files
with
5,281,813 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
*.iml | ||
.gradle | ||
/local.properties | ||
.idea | ||
build | ||
captures |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
68
app-test/app/src/main/java/com/example/aes/MainActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
Oops, something went wrong.