Masterarbeit abgeschlossen

Viel Mühe und Fleiß finden ihr Ende, die Masterarbeit ist abgegeben und wurde bewertet. Im Rückblick musste während der Arbeit festgestellt werden, dass der Ansatz leider nicht so geklappt hat, wie er sollte – auch eine Erkenntnis. Dies hat zum Glück keinen Einfluss auf die Abschlussnote :).

Masterthesis
Masterthesis
Masterthesis.pdf
3.2 MiB
836 Downloads
Details

Projektarbeit: Erkennung von Schadsoftware auf Androidgeräten

Während der Vorbereitung auf meine Masterarbeit habe ich diese Projektarbeit verfasst, dessen Schwerpunkt letztendlich die Erstellung des „App-Checkers“ war. Ein weiterer Schwerpunkt der Arbeit ist der Versuch aus Apps zur ihrer Laufzeit Informationen zu ihrem Verhalten zu entlocken.

In der Arbeit wird von einem Modell gesprochen, welches mit einer Support-Vektor-Maschine erstellt wurde. Dieses Modell enthält die Intelligenz vom App-Checker, also die Informationen welche Merkmale eine App enthalten muss damit sie als böse bzw. gut klassifiziert wird. Inzwischen gibt es eine Veröffentlichung zu dem Modell:

Drebin: Efficient and Explainable Detection of Android Malware in Your Pocket. (Daniel Arp, Michael Spreitzenbarth, Malte Hübner, Hugo Gascon, and Konrad Rieck.) In: Proc. of Network and Distributed System Security Symposium (NDSS), to appear 2014.

Drebin-Paper

 

Detecting Code Reflection in Android Apps

While looking for more features to detect Android malware (what is basically part of my master thesis) I visited https://www.virustotal.com, which is by the way, a very nice service for analyzing suspicious files. After uploading an arbitrary Andorid-App I found under the section „Code-related observations“ four points. From those one was new: „code reflection“ and I asked myself how to detect this.

After a little bit of googling and reading the API I remembered that there is the method-invocation stuff form JavaSE. So I tried, to find the feature

Ljava/lang/reflect/Method;.invoke:

from the „dexdump -d“ dump and was lucky. This seems to be a very good feature to detect method invocation and is furthermore explainable because the class „Method“ in the Java-API has only the method „invoke(…)“ and no other ways to use method reflection. For detecting invocation of objects  one could also use the „newInstance(…)“-method in the class „Constructor“.

Additionally the use of „Method.invoke(…)“ is often together with the „getMethod“-method in the class „Class“ and therefore

Ljava/lang/Class;.getMethod:

is a good feature too.

 

App-Checker Desktop: A Java Static Feature Generator for APK-Files

Dieses Tool mit dem Namen „App-Checker Desktop“ ist in der Lage aus einer *.apk-Datei – also einer Android-App – die unten genannten Merkmale zu extrahieren.

Hintergrund: Dieses Tool, was kurzfristig den Namen „App-Checker Desktop“ erhalten hat, entstand während der Projektphase zu meiner Masterarbeit und ist die Desktop-Version der im Rahmen dieses Projektes entwickelten App (dem App-Checker).

Motivation: Damit der App-Checker mittels der Methode  „Drebin“ Vorhersagen über die Bös- oder Gutartigkeit dritter Apps – auf dem Android-Gerät – machen kann, muss er in der Lage sein aus einer *.apk-Datei die gleichen Merkmale zu extrahieren, wie es der Webservice Mobile Sandbox tut. Mit der hier vorgestellten Desktop-Version kann man nun unabhängig von Android-Gerät oder der Mobile Sandbox die folgenden Merkmale auf dem Rechner generieren:

Aus dem Android-Manifest:

1. Angeforderte Rechte der App
2. Angeforderte Hard- und Software
3. Intents
4. Activities
5. Services
6. ContentProvider
7. Broadcast Reciever

Aus dem dexdump -d – Auszug (Assambler der App):
1. Benutzte Rechte
2. Benutzte API-Aufrufe, die Rechte benötigen
3. Benutzte gefährliche API-Aufrufe (können selbst festgelegt werden)
4. Benutzte „Networks“
5. Gefundene URLs und IPs

Ist man nicht wie ich an Java als Programmiersprache gebunden empfehle ich für diesen Anwendungsfall androguard.

 

AppChecker Desktop
AppChecker Desktop
AppChecker Desktop.zip
Version: 1.0
3.8 MiB
115 Downloads
Details

Java LibSVMFormatReader

„svm-predict“ gibt für die one-class-SVM scheinbar nur die vorhergesagten Labels zurück, nicht aber die Vorhersagewerte für die Daten. Da das auch für die Java-libsvm-Varriante gilt – die ich in der Android-App zu meiner Masterarbeit benutze – hier eine Klasse, die aus einer Datei im libsvm-Format die Daten in der internen libsvm-Datenstruktur zurückgibt (d. h. als svm_node[][]). Damit kann man dann nach Belieben eine der „predict“-Funktionen von libsvm aufrufen und somit auch die Vorhersagewerte erhalten.

Nachdem die Klasse fertig war, habe ich doch noch in der Java-libsvm-Implementierung ähnliche Funktionalität entdeckt (svm_predict.java – predict(BufferedReader, DataOutputStream, svm_model, int) und musste feststellen, dass ich mir mehr Gedanken bei der Regex hätte machen sollen ;). Aber nun ist es fertig und dafür wenigstens alleinstehend ohne „predict“-Funktion drum herum – vielleicht hilft es ja noch jemandem.

import java.io.BufferedReader;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import libsvmimpl.libsvm.svm_node;

public class LibSVMFormatReader {

	private BufferedReader libsvmFormatFileReader;
	private svm_node[][] x;
	private double[] y;

	//////////////////
	// Constructors //
	//////////////////
	public LibSVMFormatReader(String libSVMFormatFilename) throws IOException {
		this(new File(libSVMFormatFilename));
	}

	public LibSVMFormatReader(BufferedReader buf) throws IOException {
		this.libsvmFormatFileReader = buf;
		convert();
	}

	public LibSVMFormatReader(File libSVMFormatFile) throws IOException {
		this(new BufferedReader(new InputStreamReader(new FileInputStream(
				libSVMFormatFile))));
	}

	////////////////
	// Converters //
	////////////////
	private void convert() throws IOException {
		ArrayList<svm_node[]> nodeArrayList = new ArrayList<svm_node[]>();
		ArrayList labelsList = new ArrayList();

		String line;
		while ((line = this.libsvmFormatFileReader.readLine()) != null) {
			nodeArrayList.add(devideRow(line));
			labelsList.add(getLabel(line));
		}

		// Copy references 1 by 1:
		svm_node[][] svm_nodeArray = new svm_node[nodeArrayList.size()][];
		double[] labels = new double[labelsList.size()];
		if (labels.length != svm_nodeArray.length) {
			throw new IllegalArgumentException(
					"Converting to Java-libsvm failed: could not find the same number of labels and vectors.");
		}

		for (int i = 0; i < svm_nodeArray.length; i++) {
			svm_nodeArray[i] = nodeArrayList.get(i);
			labels[i] = labelsList.get(i);
		}

		this.x = svm_nodeArray;
		this.y = labels;
	}

	private double getLabel(String line) {
		double ret = Double.NaN;
		try {
			ret = Double.parseDouble(line.split("\\s")[0]);
		} catch (NumberFormatException e) {
			throw new IllegalArgumentException(
					"Could not parse label to double-value.", e);
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new IllegalArgumentException(
					"Could split line into different parts.", e);
		}
		return ret;
	}

	/**
	 * This method takes one row from the libsvm-format and converts it into a
	 * svm_node[]. On error it throws an exception.
	 * 
	 * @param row
	 * @return
	 */
	private svm_node[] devideRow(String row) {
		try {
			svm_node tNode;
			String[] tSplit;
			String tToken;

			ArrayList<svm_node> nodes = new ArrayList<svm_node>();

			// TODO Try out which space or character works finest:
			String[] segs = row.split("\\s");
			for (String string : segs) {
				// Skip first - its the label
				// and make sure there nothing suspicious:
				tToken = string.trim();
				if (tToken.contains(":")) {
					tNode = new svm_node();
					tSplit = tToken.split(":");
					tNode.index = Integer.parseInt(tSplit[0]);
					tNode.value = Double.parseDouble(tSplit[1]);
					nodes.add(tNode);
				}
			}

			// Copy to array 1 by 1:
			svm_node[] svm_nodes = new svm_node[nodes.size()];
			for (int i = 0; i < svm_nodes.length; i++) {
				svm_nodes[i] = nodes.get(i);
			}

			if (svm_nodes.length == 0) {
				throw new IllegalArgumentException(
						"No index-value-pairs found.");
			}

			return svm_nodes;

		} catch (NumberFormatException e) {
			throw new IllegalArgumentException(
					"Could not parse index or value into a number. Please proof your file.",
					e);
		}
	}

	/////////////////
	// getXYZ(...) //
	/////////////////

	public double[] getY() {
		return y;
	}

	public svm_node[][] getX() {
		return x;
	}

	/*
	 * Test-Main ...
	 */
	public static void main(String[] args) {
		try {
			LibSVMFormatReader libSVMFormatReader = new LibSVMFormatReader(
					"/Volumes/Android/BENIGN/LEARNDATA/libsvm/MW/25/BUSINESS_25_MW.libsvmS");
			svm_node[][] nA = libSVMFormatReader.x;
			double[] y = libSVMFormatReader.y;
			for (int i = 0; i < y.length; i++) {
				System.out.print("LABEL: " + y[i] + " ");
				for (svm_node node : nA[i]) {
					System.out.print(node);
				}
				System.out.println();
			}

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
LibSVMFormatReader
LibSVMFormatReader
LibSVMFormatReader.java
4.2 KiB
660 Downloads
Details