diff -Nru lime-forensics-1.7.8/debian/changelog lime-forensics-1.8/debian/changelog --- lime-forensics-1.7.8/debian/changelog 2017-06-19 23:39:07.000000000 +0000 +++ lime-forensics-1.8/debian/changelog 2018-09-05 06:17:31.000000000 +0000 @@ -1,3 +1,25 @@ +lime-forensics (1.8-1) unstable; urgency=medium + + * Team upload. + [ Raphaël Hertzog ] + * d/control: + - Update Vcs-Git and Vcs-Browser for the move to salsa.debian.org + - Update team maintainer address to Debian Security Tools + + [ SZ Lin (林上智) ] + * New upstream release + * Add upstream metadata file + * d/control: + - Bump debhelper version to 11 + - Bump Standards-Version to 4.2.1 + * d/copyright: + - Replace "http" with "https" in URL + - Update upstream copyright years + * d/compat: + - Bump compat version to 11 + + -- SZ Lin (林上智) Wed, 05 Sep 2018 14:17:31 +0800 + lime-forensics (1.7.8-1) unstable; urgency=medium * New upstream release. (LP: #1691833) diff -Nru lime-forensics-1.7.8/debian/compat lime-forensics-1.8/debian/compat --- lime-forensics-1.7.8/debian/compat 2017-01-02 03:13:55.000000000 +0000 +++ lime-forensics-1.8/debian/compat 2018-09-05 05:58:11.000000000 +0000 @@ -1 +1 @@ -10 +11 diff -Nru lime-forensics-1.7.8/debian/control lime-forensics-1.8/debian/control --- lime-forensics-1.7.8/debian/control 2017-06-19 23:39:07.000000000 +0000 +++ lime-forensics-1.8/debian/control 2018-09-05 05:58:48.000000000 +0000 @@ -1,13 +1,13 @@ Source: lime-forensics Section: kernel Priority: optional -Maintainer: Debian Forensics +Maintainer: Debian Security Tools Uploaders: Joao Eriberto Mota Filho -Build-Depends: debhelper (>= 10), dkms -Standards-Version: 4.0.0 +Build-Depends: debhelper (>= 11), dkms +Standards-Version: 4.2.1 Homepage: https://github.com/504ensicsLabs/LiME -Vcs-Browser: https://anonscm.debian.org/git/forensics/lime-forensics.git -Vcs-Git: https://anonscm.debian.org/git/forensics/lime-forensics.git +Vcs-Browser: https://salsa.debian.org/pkg-security-team/lime-forensics +Vcs-Git: https://salsa.debian.org/pkg-security-team/lime-forensics.git Package: lime-forensics-dkms Architecture: all diff -Nru lime-forensics-1.7.8/debian/copyright lime-forensics-1.8/debian/copyright --- lime-forensics-1.7.8/debian/copyright 2017-06-19 23:39:07.000000000 +0000 +++ lime-forensics-1.8/debian/copyright 2018-09-05 06:17:08.000000000 +0000 @@ -1,9 +1,9 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: LiME Source: https://github.com/504ensicsLabs/LiME Files: * -Copyright: 2011-2017 Joe Sylve - 504ENSICS Labs +Copyright: 2011-2018 Joe Sylve - 504ENSICS Labs License: GPL-2+ Files: debian/* diff -Nru lime-forensics-1.7.8/debian/upstream/metadata lime-forensics-1.8/debian/upstream/metadata --- lime-forensics-1.7.8/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ lime-forensics-1.8/debian/upstream/metadata 2018-09-05 06:07:59.000000000 +0000 @@ -0,0 +1,5 @@ +Reference: + Author: Joe Sylve + Name: kernel module to memory dump (DKMS) + Year: 2011 + URL: https://github.com/504ensicsLabs/LiME diff -Nru lime-forensics-1.7.8/doc/external_modules.md lime-forensics-1.8/doc/external_modules.md --- lime-forensics-1.7.8/doc/external_modules.md 1970-01-01 00:00:00.000000000 +0000 +++ lime-forensics-1.8/doc/external_modules.md 2018-05-06 17:55:35.000000000 +0000 @@ -0,0 +1,200 @@ +# Building External Modules +## Contents +* [Intro](#intro) ++ [How To](#howto) + + [Required Tools](#tools) + + [Downloading the kernel source](#download) + + [Choosing the correct kernel release](#release) + + [Using an old kernel config](#config) + + [Setting the correct version](#versioncorrect) + + [Prepare the source and compile](#compile) ++ [OS specific resources](#resources) + + [CentOS](#centos) + + [Fedora](#fedora) + + [RHEL](#rhel) + + [Ubuntu](#ubuntu) + +## Introduction +There may come time in life when one would find benefit in compiling kernel modules outside of the running kernel. This is known as compiling **external** or **out of tree** modules. In the case of `LiME`, compiling outside of the running kernel is a more forensically sound and secure method, as the kernel object is not compiled on the target system. Since there is no need to compile on the target systems, Admin's do not have to alter the production systems to include gcc, linux kernel headers, among other development tools. [This link](https://www.kernel.org/doc/Documentation/kbuild/modules.txt) includes the kernel documentation on how to build an external kernel module. + +**NOTE** This guide does not cover `cross compiling` external modules. If your architecture differs from your host machine you will need to cross compile your module. + +## How to +The following is a step-by-step guide, using Ubuntu, in order to compile your own external module. The steps will vary from each distribution. Some distribution specifics will be covered at the end of this document. + +### Required tools +You will need the following tools + +- git +- build-essential package **OS specific** + +### Downloading the kernel source +The first task is to find and download the correct kernel source for your distribution and version. For this I will show you examples with the Ubuntu kernel. You can read Ubuntu's fancy guide for downloading source [here](https://wiki.ubuntu.com/Kernel/Dev/KernelGitGuide). + +But here is the TL;DR version + +In order to determine the correct OS version of your target machine, you can run `cat /etc/os-release`. +``` +$ cat /etc/os-release +NAME="Ubuntu" +VERSION="16.04.2 LTS (Xenial Xerus)" +ID=ubuntu +ID_LIKE=debian +PRETTY_NAME="Ubuntu 16.04.2 LTS" +VERSION_ID="16.04" +HOME_URL="http://www.ubuntu.com/" +SUPPORT_URL="http://help.ubuntu.com/" +BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" +VERSION_CODENAME=xenial +UBUNTU_CODENAME=xenial +``` +From the output above we can see that our release is `Xenial 16.04.2 LTS`. + +Now we must go and clone the source using `git`. For our Ubuntu example the links are in the following format. +``` +kernel.ubuntu.com/ubuntu/ubuntu-< release >.git +``` +Following our Xenial example, we would clone the source by entering this +``` +$git clone git://kernel.ubuntu.com/ubuntu/ubuntu-xenial.git +``` +If you have firewall restrictions or other ridiculousness using the git protocol, you can clone via http. +``` +$git clone http://kernel.ubuntu.com/git-repos/ubuntu/ubuntu-xenial.git +``` +This will be a lot slower and you will not be able to set the history depth, therefore downloading far more data. + +### Choosing the correct kernel release +Once the repository has finished cloning, we will need to checkout the correct kernel release. To complete this task run `uname -r` on the target machine. +``` +$uname -r +4.10.0-38-generic +``` +This most important take-away of the kernel release is the string after the `sublevel` digit. The Linux kernel is versioned in the following format +``` +version.patchlevel.sublevel-localversion +``` +From the example above we can see that our local version needs to be `-38-generic`. Once you have determined the version that you need to build, change directory into your kernel source. From this location run +``` +git tag -l +``` +to list all the tags. Find the tag that matches you kernel version *version.patchlevel.sublevel* and checkout that the point in history. +``` +git checkout < tag > +``` +Following our Ubuntu guide you would run something like the following +``` +git checkout Ubuntu-lts-4.10.0-9.11_16.04.2 +``` + +### Using an old kernel config +In order to build an external modules that will fit target running kernel, we need to know how your kernel was built. The kernel build process stores this information in a config file, storing that in `/boot/config-*`. +Copy the correct config file to your kernel working directory and then rename it to `.config`. In our Ubuntu example the correct config file is located/called +``` +/boot/config-4.10.0-38-generic +``` +Once you have renamed the config file `.config` run the following +``` +$ make olddefconfig + HOSTCC scripts/basic/fixdep + HOSTCC scripts/kconfig/conf.o + SHIPPED scripts/kconfig/zconf.tab.c + SHIPPED scripts/kconfig/zconf.lex.c + SHIPPED scripts/kconfig/zconf.hash.c + HOSTCC scripts/kconfig/zconf.tab.o + HOSTLD scripts/kconfig/conf +scripts/kconfig/conf --olddefconfig Kconfig +# +# configuration written to .config +# +``` +This make function will use the old kernel config and substitute the default values for options that differ in your kernel. + +### Setting the correct version +This is the most important part of the entire process. If the version does not match the running kernel, your module will most likely fail to install. This is due to a kernel safety measure, enabled by default, to prevent incompatible modules from loading. +Once the config completes, we need to make sure that all the versions match before we continue. Run the following make function +``` +$ make kernelrelease +4.10.0+ +``` +Did make complete without error? Does that match the version you want? If so continue; else checkout a different tag with git. + +Did you notice that our kernel release is missing the `localversion` string? Well, let's fix that using your favorite text editor. +Find the lines that say the following +``` +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +``` +Change **both** `CONFIG_LOCALVERSION` and `# CONFIG_COMPILE_TEST is not set` to match the following example +``` +CONFIG_LOCALVERSION="< localversion >" +CONFIG_LOCALVERSION_AUTO=n +``` +In our Ubuntu example add `-38-generic` and don't forget the hyphen. +``` +CONFIG_LOCALVERSION="-38-generic" +CONFIG_LOCALVERSION_AUTO=n +``` + +Now! run `make kernelrelease` again +``` +$ make kernelrelease +4.10.0-38-generic+ +``` +Is your localversion correct? If so, continue +Note the `+` at the end of the localversion string. We need to remove this +``` +touch .scmversion +``` +to create and empty file. Now run `make kernelrelease` once more, this time the version should be an exact match. +``` +$ make kernelrelease +4.10.0-38-generic +``` + +### Prepare the source and compile +Now run +``` +$ make modules_prepare +``` +in order to prepare the kernel source tree for building external modules. We use this function in order to skip compiling an entire kernel, saving you some cycles. If this completes without error, one can proceed with compiling the module. We will use LiME as the example module. Change directory into your LiME source and run +``` +make -C < path-src-tree > KVER=< kernel-version > M=$(pwd) +``` +`path-to-src-tree` is the location where you cloned your kernel source. Again, following our Ubuntu example +``` +make -C /home/kd8bny/ubuntu-xenial KVER=4.10.0-38-generic M=$(pwd) +``` + +And there you have it! A successfully compiled **external** kernel module. Now feel free to load this into the running kernel on your target machine. + +## OS specific resources +### CentOS +CentOS and RHEL package source a little differently. The source is packaged as an RPM. This is a semi-helpful [link](https://wiki.centos.org/HowTos/I_need_the_Kernel_Source). +The source is located [here](http://vault.centos.org). Browse to the following location and download. +``` +http://vault.centos.org/< cent version >/os/Source/SPackages/kernel-3.10.0-123.el7.src.rpm +``` + + Once you have downloaded the RPM extract it using `tar` or some other file archiving tool. Once extracted you will see another archive dubbed `linux-`. This is your source, extract it. You can use the config files already found in this source. Continue as stated in the guide, ignoring the use of `git`. + +### Fedora +Fedora keeps kernel source off the main linux git tree. Clone it here +``` +git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/fedora.git +``` +Follow the same process in the guide. + +### RHEL +Follow the centOS section, as this is where the source is located for non-subscribers. If you are a subscriber, you can download the source from Red Hat. + +### Ubuntu +Follow as shown in guide. +[kernel source](http://kernel.ubuntu.com/git/) diff -Nru lime-forensics-1.7.8/doc/README.md lime-forensics-1.8/doc/README.md --- lime-forensics-1.7.8/doc/README.md 2017-06-15 02:21:29.000000000 +0000 +++ lime-forensics-1.8/doc/README.md 2018-05-06 17:55:35.000000000 +0000 @@ -1,7 +1,8 @@ -#LiME – Linux Memory Extractor -##Contents +# LiME – Linux Memory Extractor +## Contents * [Compiling](#Compile) * [Linux](#Linux) + * [External](#External) * [Debug](#Debug) * [Android](#Android) * [Usage](#Usage) @@ -10,19 +11,22 @@ * [Acquisition of Memory to Disk (SD-Card)](#Disk) * [LiME Memory Range Header Version 1 Specification](#Spec) -##Compiling LiME -###Linux +## Compiling LiME +### Linux LiME is a Loadable Kernel Module (LKM). LiME ships with a default Makefile that should be suitable for compilation on most modern Linux systems. For detailed instructions on using LKM see https://www.kernel.org/doc/Documentation/kbuild/modules.txt. -###Debug +### External +LiME can be compiled externally from the target in order to provide a more forensically sound and secure method. Follow this [guide](./external_modules.md) to learn how. + +### Debug When compiling LiME with the default Makefile, using the command “make debug” will compile a LiME module with extra debug output. The output can be read by using the dmesg command on Linux. -###Android +### Android In order to cross-compile LiME for use on an Android device, additional steps are required. -####PREREQUISITES +#### PREREQUISITES Disclaimer: This list may be incomplete. Please let us know if we've missed anything. * Install the general android prerequisites found at http://source.android.com/source/initializing.html * Download and un(zip|tar) the android NDK found at http://developer.android.com/tools/sdk/ndk/index.html. @@ -31,7 +35,7 @@ * Root your device. In order to run custom kernel modules, you must have a rooted device. * Plug the device into computer via a USB cable. -####SETTING UP THE ENVIORNMENT +#### SETTING UP THE ENVIRONMENT In order to simplify the process, we will first set some environment variables. In a terminal, type the following commands. ``` export SDK_PATH=/path/to/android-sdk-linux/ @@ -41,7 +45,7 @@ export LIME_SRC=/path/to/lime/src ``` -####PREPARING THE KERNEL SOURCE +#### PREPARING THE KERNEL SOURCE We must retrieve and copy the kernel config from our device. ``` cd $SDK_PATH/platform-tools @@ -56,7 +60,7 @@ $ make ARCH=arm CROSS_COMPILE=$CC_PATH/arm-eabi- modules_prepare ``` -####PREPARING THE MODULE FOR COMPILATION +#### PREPARING THE MODULE FOR COMPILATION We need to create a Makefile to cross-compile our kernel module. A sample Makefile for cross-compiling is shipped with the LiME source. The contents of your Makefile should be similar to the following: ``` obj-m := lime.o @@ -68,24 +72,24 @@ $(MAKE) ARCH=arm CROSS_COMPILE=$(CCPATH)/arm-eabi- -C $(KDIR) M=$(PWD) modules ``` -####COMPILING THE MODULE +#### COMPILING THE MODULE ``` cd $LIME_SRC make ``` -##Usage +## Usage To illustrate the use of LiME, we will now walk through two examples of acquiring memory from an Android device. We will first discuss the acquisition of memory over a TCP connection, followed by a discussion of acquiring a memory dump via the device’s SD card. The use of LiME on other Linux devices is similar; however, the use of the Android debug bridge (adb) is not needed. -###Parameters +### Parameters Starting in version 1.1, LiME now supports multiple output formats, including a custom lime format which integrates with Volatility’s new lime address space. This means that additional parameters are needed when installing the LiME kernel module. NOTE: There is a bug in the insmod utility on some Android devices. Multiple kernel module parameters must be wrapped in quotation marks, otherwise only the first parameter will be parsed. See sections 4.2 and 4.3 for examples. ``` path Either a filename to write on the local system (SD Card) or tcp: -format raw: Simply concatenates all System RAM ranges - padded: Pads all non-System RAM ranges with 0s, starting from physical address 0 - lime: Each range is prepended with a fixed-sized header which contains address space information. Volatility address space developed to support this format +format padded: Pads all non-System RAM ranges with 0s, starting from physical address 0. + lime: Each range is prepended with a fixed-sized header which contains address space information. + raw: Simply concatenates all System RAM ranges. Most memory analysis tools do not support this format, as memory position information is lost (unless System RAM is in one continuous range starting from physical address 0) dio Optional. 1 to enable Direct IO attempt, 0 to disable (default) localhostonly Optional. 1 restricts the tcp to only listen on localhost, 0 binds on all interfaces (default) timeout Optional. If it takes longer than the specified timeout (in milliseconds) to read/write a page @@ -93,7 +97,7 @@ The default setting is 1000 (1 second). ``` -###Acquisition of Memory over TCP +### Acquisition of Memory over TCP The first step of the process is to copy the kernel module to the device’s SD card using the Android Debug Bridge (adb), which supports a number of interactions with an Android device tethered via USB. We then use adb to setup a port-forwarding tunnel from a TCP port on the device to a TCP port on the local host. The use of adb for network transfer eliminates the need to modify the networking configuration on the device or introduce a wireless peer—all network data is transferred via USB. For the example below, we have chosen TCP port 4444. We then obtain a root shell on the device by using adb and su. To accomplish this, we run the following commands with the phone plugged into our computer and debugging enabled on the device. ``` adb push lime.ko /sdcard/lime.ko @@ -116,7 +120,7 @@ nc localhost 4444 > ram.lime ``` -###Acquisition of Memory to Disk (SD-Card) +### Acquisition of Memory to Disk (SD-Card) In some cases, such as when the investigator wants to make sure no network buffers are overwritten, disk-based acquisition may be preferred to network acquisition. To accommodate this situation, LiME provides the option to write memory images to the device’s file system. On Android, the logical place to write is the device’s SD card. Since the SD card could potentially contain other relevant evidence to the case, the investigator may wish to image the SD card first in order to save unallocated space. Unfortunately, some Android phones, such as the HTC EVO 4G and the Droid series, place the removable SD card to be either under or obstructed by the phone’s battery, making it impossible to remove the SD card without powering off the phone (these phones will power down if the battery is removed, even if they are plugged into a power source!). For this reason, the investigator needs to first image the SD card, and then subsequently write the memory image to it. While this process violates the typical “order of volatility” rule of thumb in forensic acquisition, namely, obtaining the most volatile information first, it is necessary to properly preserve all evidence. @@ -130,7 +134,7 @@ Once the acquisition process is complete, we can power down the phone, remove the SD card from the phone, and transfer the memory dump to the examination machine. If the phone cannot be powered down, adb can also be used to transfer the memory dump to the investigator's machine. -##LiME Memory Range Header Version 1 Specification +## LiME Memory Range Header Version 1 Specification ``` typedef struct { unsigned int magic; // Always 0x4C694D45 (LiME) diff -Nru lime-forensics-1.7.8/README.md lime-forensics-1.8/README.md --- lime-forensics-1.7.8/README.md 2017-06-15 02:21:29.000000000 +0000 +++ lime-forensics-1.8/README.md 2018-05-06 17:55:35.000000000 +0000 @@ -11,21 +11,26 @@ * Full Android memory acquisition * Acquisition over network interface * Minimal process footprint +* Hash of dumped memory ## Usage Detailed documentation on LiME's usage and internals can be found in the "doc" directory of the project. LiME utilizes the insmod command to load the module, passing required arguments for its execution. ``` -insmod ./lime.ko "path=> format= [dio=<0|1>]" +insmod ./lime.ko "path=> format= [digest=] [dio=<0|1>]" path (required): outfile ~ name of file to write to on local system (SD Card) tcp:port ~ network port to communicate over -format (required): raw ~ concatenates all System RAM ranges - padded ~ pads all non-System RAM ranges with 0s +format (required): padded ~ pads all non-System RAM ranges with 0s lime ~ each range prepended with fixed-size header containing address space info - + raw ~ concatenates all System RAM ranges (warning : original position of dumped memory is likely to be lost) + +digest (optional): Hash the RAM and provide a .digest file with the sum. + Supports kernel version 2.6.11 and up. See below for + available digest options. + dio (optional): 1 ~ attempt to enable Direct IO 0 ~ default, do not attempt Direct IO @@ -60,6 +65,26 @@ # insmod /sdcard/lime.ko "path=/sdcard/ram.lime format=lime" ``` +## Available Digests +Really LiME will support any digest algorithm that the kernel library can. +For a quick reference here is a list of supported digests. +### All kernel versions +``` +crc32c +md4, md5 +sha1, sha224, sha256, sha384, sha512 +wp512, wp384, wp256 +``` +### 4.10 and up +``` +sha3-224, sha3-256, sha3-384, sha3-512 +``` +### 3.0 and up +``` +rmd128, rmd160, rmd256, rmd320 +``` + + ## Presentation LiME was first presented at Shmoocon 2012 by Joe Sylve. Youtube~ Android Mind Reading: Memory Acquisition and Analysis with DMD and Volatility diff -Nru lime-forensics-1.7.8/src/disk.c lime-forensics-1.8/src/disk.c --- lime-forensics-1.7.8/src/disk.c 2017-06-15 02:21:29.000000000 +0000 +++ lime-forensics-1.8/src/disk.c 2018-05-06 17:55:35.000000000 +0000 @@ -95,7 +95,11 @@ pos = f->f_pos; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0) + s = kernel_write(f, v, is, &pos); +#else s = vfs_write(f, v, is, &pos); +#endif if (s == is) { f->f_pos = pos; diff -Nru lime-forensics-1.7.8/src/hash.c lime-forensics-1.8/src/hash.c --- lime-forensics-1.7.8/src/hash.c 1970-01-01 00:00:00.000000000 +0000 +++ lime-forensics-1.8/src/hash.c 2018-05-06 17:55:35.000000000 +0000 @@ -0,0 +1,228 @@ +/* + * LiME - Linux Memory Extractor + * Copyright (c) 2011-2014 Joe Sylve - 504ENSICS Labs + * + * + * Author: + * Joe Sylve - joe.sylve@gmail.com, @jtsylve + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "lime.h" + +// This file +int ldigest_init(void); +int ldigest_update(void *, size_t); +int ldigest_final(void); +static void ldigest_clean(void); +static int ldigest_write(void); + +// External +extern ssize_t write_vaddr(void *, size_t); +extern int setup(void); +extern void cleanup(void); + +static u8 *output; +static int digestsize; +static char *digest_value; + +extern char *digest; +extern char *path; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) +static struct crypto_ahash *tfm; +static struct ahash_request *req; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) +static struct crypto_hash *tfm; +static struct hash_desc desc; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) +struct crypto_tfm *tfm; +#endif + + +int ldigest_init(void) { + DBG("Initializing Digest Transformation."); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) + tfm = crypto_alloc_ahash(digest, 0, CRYPTO_ALG_ASYNC); + if (unlikely(IS_ERR(tfm))) goto init_fail; + + req = ahash_request_alloc(tfm, GFP_ATOMIC); + if (unlikely(!req)) goto init_fail; + + digestsize = crypto_ahash_digestsize(tfm); + + ahash_request_set_callback(req, 0, NULL, NULL); + crypto_ahash_init(req); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) + tfm = crypto_alloc_hash(digest, 0, CRYPTO_ALG_ASYNC); + if (unlikely(IS_ERR(tfm))) + goto init_fail; + + desc.tfm = tfm; + desc.flags = 0; + + digestsize = crypto_hash_digestsize(tfm); + crypto_hash_init(&desc); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) + tfm = crypto_alloc_tfm(digest, 0); + if (unlikely(tfm == NULL)) + goto init_fail; + + crypto_digest_init(tfm); +#else + DBG("Digest not supported for this kernel version."); + goto init_fail; +#endif + + output = kzalloc(sizeof(u8) * digestsize, GFP_ATOMIC); + + return LIME_DIGEST_COMPUTE; + +init_fail: + DBG("Digest Initialization Failed."); + ldigest_clean(); + + return LIME_DIGEST_FAILED; +} + +int ldigest_update(void *v, size_t is) { + int ret; + struct scatterlist sg; + + if (likely(virt_addr_valid((unsigned long) v))) { + sg_init_one(&sg, (u8 *) v, is); + } else { + int nbytes = is; + + DBG("Invalid Virtual Address, Manually Scanning Page."); + while (nbytes > 0) { + int len = nbytes; + int off = offset_in_page(v); + if (off + len > (int)PAGE_SIZE) + len = PAGE_SIZE - off; + sg_init_table(&sg, 1); + sg_set_page(&sg, vmalloc_to_page((u8 *) v), len, off); + + v += len; + nbytes -= len; + } + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) + ahash_request_set_crypt(req, &sg, output, is); + ret = crypto_ahash_update(req); + if (ret < 0) + goto update_fail; + +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) + ret = crypto_hash_update(&desc, &sg, is); + if (ret < 0) + goto update_fail; + +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) + crypto_digest_update(tfm, &sg, is); +#endif + + return LIME_DIGEST_COMPUTE; + +update_fail: + DBG("Digest Update Failed."); + ldigest_clean(); + + return LIME_DIGEST_FAILED; +} + +int ldigest_final(void) { + int ret, i; + + DBG("Finalizing the digest."); + digest_value = kmalloc(digestsize * 2 + 1, GFP_KERNEL); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) + ret = crypto_ahash_final(req); + if (ret < 0) + goto final_fail; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) + ret = crypto_hash_final(&desc, output); + if (ret < 0) + goto final_fail; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) + crypto_digest_final(tfm, output); +#endif + + for (i = 0; i= KERNEL_VERSION(4, 6, 0) + crypto_free_ahash(tfm); + ahash_request_free(req); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) + crypto_free_hash(tfm); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) + crypto_free_tfm(tfm); +#endif + +} diff -Nru lime-forensics-1.7.8/src/lime.h lime-forensics-1.8/src/lime.h --- lime-forensics-1.7.8/src/lime.h 2017-06-15 02:21:29.000000000 +0000 +++ lime-forensics-1.8/src/lime.h 2018-05-06 17:55:35.000000000 +0000 @@ -32,10 +32,18 @@ #include #include #include +#include +#include #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) +#include +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) +#include +#endif + #define LIME_RAMSTR "System RAM" #define LIME_MAX_FILENAME_SIZE 256 #define LIME_MAGIC 0x4C694D45 //LiME @@ -48,6 +56,9 @@ #define LIME_METHOD_TCP 1 #define LIME_METHOD_DISK 2 +#define LIME_DIGEST_FAILED -1 +#define LIME_DIGEST_COMPLETE 0 +#define LIME_DIGEST_COMPUTE 1 #ifdef LIME_DEBUG #define DBG(fmt, args...) do { printk("[LiME] "fmt"\n", ## args); } while (0) diff -Nru lime-forensics-1.7.8/src/main.c lime-forensics-1.8/src/main.c --- lime-forensics-1.7.8/src/main.c 2017-06-15 02:21:29.000000000 +0000 +++ lime-forensics-1.8/src/main.c 2018-05-06 17:55:35.000000000 +0000 @@ -21,16 +21,17 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include "lime.h" // This file static int write_lime_header(struct resource *); static ssize_t write_padding(size_t); static void write_range(struct resource *); -static ssize_t write_vaddr(void *, size_t); -static int setup(void); -static void cleanup(void); static int init(void); +ssize_t write_vaddr(void *, size_t); +int setup(void); +void cleanup(void); // External extern int write_vaddr_tcp(void *, size_t); @@ -41,22 +42,30 @@ extern int setup_disk(void); extern void cleanup_disk(void); +extern int ldigest_init(void); +extern int ldigest_update(void *, size_t); +extern int ldigest_final(void); + static char * format = 0; static int mode = 0; static int method = 0; -static char zero_page[PAGE_SIZE]; +static char * zero_page; char * path = 0; int dio = 0; int port = 0; int localhostonly = 0; +char * digest = 0; +int compute_digest = 0; + extern struct resource iomem_resource; module_param(path, charp, S_IRUGO); module_param(dio, int, S_IRUGO); module_param(format, charp, S_IRUGO); module_param(localhostonly, int, S_IRUGO); +module_param(digest, charp, S_IRUGO); #ifdef LIME_SUPPORTS_TIMING long timeout = 1000; @@ -86,12 +95,13 @@ DBG(" DIO: %u", dio); DBG(" FORMAT: %s", format); DBG(" LOCALHOSTONLY: %u", localhostonly); + DBG(" DIGEST: %s", digest); #ifdef LIME_SUPPORTS_TIMING DBG(" TIMEOUT: %lu", timeout); #endif - memset(zero_page, 0, sizeof(zero_page)); + zero_page = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!strcmp(format, "raw")) mode = LIME_MODE_RAW; else if (!strcmp(format, "lime")) mode = LIME_MODE_LIME; @@ -102,6 +112,7 @@ } method = (sscanf(path, "tcp:%d", &port) == 1) ? LIME_METHOD_TCP : LIME_METHOD_DISK; + if (digest) compute_digest = LIME_DIGEST_COMPUTE; return init(); } @@ -122,16 +133,20 @@ return err; } + if(compute_digest == LIME_DIGEST_COMPUTE) + compute_digest = ldigest_init(); + for (p = iomem_resource.child; p ; p = p->sibling) { + if (strcmp(p->name, LIME_RAMSTR)) continue; if (mode == LIME_MODE_LIME && (err = write_lime_header(p))) { DBG("Error writing header 0x%lx - 0x%lx", (long) p->start, (long) p->end); - break; + break; } else if (mode == LIME_MODE_PADDED && (err = write_padding((size_t) ((p->start - 1) - p_last)))) { DBG("Error writing padding 0x%lx - 0x%lx", (long) p_last, (long) p->start - 1); - break; + break; } write_range(p); @@ -143,6 +158,9 @@ cleanup(); + if(compute_digest == LIME_DIGEST_COMPUTE) + compute_digest = ldigest_final(); + return err; } @@ -206,7 +224,6 @@ #ifdef LIME_SUPPORTS_TIMING start = ktime_get_real(); #endif - p = pfn_to_page((i) >> PAGE_SHIFT); is = min((size_t) PAGE_SIZE, (size_t) (res->end - i + 1)); @@ -218,8 +235,18 @@ write_padding(is); } else { v = kmap(p); - s = write_vaddr(v, is); - kunmap(p); + //If we don't need to compute the digest; lets save some memory + //and cycles + if(compute_digest == LIME_DIGEST_COMPUTE) { + void * lv = kmalloc(is, GFP_ATOMIC); + memcpy(lv, v, is); + s = write_vaddr(lv, is); + kfree(lv); + } else { + s = write_vaddr(v, is); + } + + kunmap(p); if (s < 0) { DBG("Error writing page: vaddr %p ret: %zd. Null padding.", v, s); @@ -239,26 +266,28 @@ break; } #endif - + } } -static ssize_t write_vaddr(void * v, size_t is) { +ssize_t write_vaddr(void * v, size_t is) { + if(compute_digest == LIME_DIGEST_COMPUTE) + compute_digest = ldigest_update(v, is); + return RETRY_IF_INTURRUPTED( (method == LIME_METHOD_TCP) ? write_vaddr_tcp(v, is) : write_vaddr_disk(v, is) ); } -static int setup(void) { +int setup(void) { return (method == LIME_METHOD_TCP) ? setup_tcp() : setup_disk(); } -static void cleanup(void) { +void cleanup(void) { return (method == LIME_METHOD_TCP) ? cleanup_tcp() : cleanup_disk(); } -void cleanup_module(void) -{ +void cleanup_module(void) { } diff -Nru lime-forensics-1.7.8/src/Makefile lime-forensics-1.8/src/Makefile --- lime-forensics-1.7.8/src/Makefile 2017-06-15 02:21:29.000000000 +0000 +++ lime-forensics-1.8/src/Makefile 2018-05-06 17:55:35.000000000 +0000 @@ -21,30 +21,32 @@ obj-m := lime.o -lime-objs := tcp.o disk.o main.o +lime-objs := tcp.o disk.o main.o hash.o KVER ?= $(shell uname -r) +KDIR ?= /lib/modules/$(KVER)/build + PWD := $(shell pwd) .PHONY: modules modules_install clean distclean debug default: - $(MAKE) -C /lib/modules/$(KVER)/build M="$(PWD)" modules + $(MAKE) -C $(KDIR) M="$(PWD)" modules strip --strip-unneeded lime.ko mv lime.ko lime-$(KVER).ko debug: - KCFLAGS="-DLIME_DEBUG" $(MAKE) -C /lib/modules/$(KVER)/build M="$(PWD)" modules + KCFLAGS="-DLIME_DEBUG" $(MAKE) CONFIG_DEBUG_SG=y -C $(KDIR) M="$(PWD)" modules strip --strip-unneeded lime.ko mv lime.ko lime-$(KVER).ko -modules: main.c disk.c tcp.c lime.h +modules: main.c disk.c tcp.c hash.c lime.h $(MAKE) -C /lib/modules/$(KVER)/build M="$(PWD)" $@ strip --strip-unneeded lime.ko modules_install: modules - $(MAKE) -C /lib/modules/$(KVER)/build M="$(PWD)" $@ + $(MAKE) -C $(KDIR) M="$(PWD)" $@ clean: rm -f *.o *.mod.c Module.symvers Module.markers modules.order \.*.o.cmd \.*.ko.cmd \.*.o.d diff -Nru lime-forensics-1.7.8/src/tcp.c lime-forensics-1.8/src/tcp.c --- lime-forensics-1.7.8/src/tcp.c 2017-06-15 02:21:29.000000000 +0000 +++ lime-forensics-1.8/src/tcp.c 2018-05-06 17:55:35.000000000 +0000 @@ -79,7 +79,11 @@ fs = get_fs(); set_fs(KERNEL_DS); - sock_setsockopt(control, SOL_SOCKET, SO_SNDBUF, (void *) &buffsize, sizeof (int)); + r = sock_setsockopt(control, SOL_SOCKET, SO_SNDBUF, (void *) &buffsize, sizeof (int)); + if (r < 0) { + DBG("Error setting socket options"); + return r; + } set_fs(fs);