[prev in list] [next in list] [prev in thread] [next in thread] 

List:       full-disclosure
Subject:    [FD] Using the Android USB Driver to Extract Data as USB Mass Storage Device
From:       Roman Fiedler <roman.fiedler () unparalleled ! eu>
Date:       2021-06-26 17:17:33
Message-ID: 3087-1624727853.235241 () KPAx ! FyFw ! qyvh
[Download RAW message or body]

------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

Due to a harware failure I was searching for a conventient
and efficient way to copy all internal storage of a mostly broken,
powered off, hardware locked, encrypted phone. The only things
still working to interact with the phone were the USB connector
and power on/volume keys. It was not possible to use the touch
screen, extract any partition data via fastboot, access the ADB
interface, connect via WIFI or use any other common remote access
methods. As a result of solving this problem a simple program
to inject as initrd into ABOOT to regain full control of the
phone was developed. The main advantage of this solution is to
get a near forensic quality snapshot of the complete storage
including the partition table, boot image, recovery images, all
firmware update slots without running the target system, a replacement
system with ADB or any other generic tools.

exfiltrate-as-mass-storage.c (158 lines) was developed to run
as alternative "/init". The program will make the phone show
up as mass storage device during boot. The complete internal
storage is available for reading including the partition table
and all 42 partitions of the Android system.

Read more at
https://unparalleled.eu/blog/2021/20210626-android-internal-storage-as-mass-storage/
or follow on Twitter @unparalleled_eu
https://twitter.com/unparalleled_eu/status/1408835870485065734

| |  DI Roman Fiedler
| /  roman.fiedler at unparalleled.eu  +43 677 63 29 28 29
/ |  Unparalleled IT Services e.U.     FN: 516074h           VAT: ATU75050524
| |  https://unparalleled.eu/          Felix-Dahn-Platz 4, 8010 Graz, Austria

------- =_aaaaaaaaaa0
Content-Type: text/plain; name="exfiltrate-as-mass-storage.c";
	charset="us-ascii"
Content-Description: exfiltrate-as-mass-storage.c
Content-Disposition: attachment; filename="exfiltrate-as-mass-storage.c"
Content-Transfer-Encoding: quoted-printable

/** This software is provided by the copyright owner "as is"
 *  and WITHOUT ANY EXPRESSED OR IMPLIED WARRANTIES, including,
 *  but not limited to, the implied warranties of merchantability
 *  and fitness for a particular purpose are disclaimed. In no
 *  event shall the copyright owner be liable for any direct,
 *  indirect, incidential, special, exemplary or consequential
 *  damages, including, but not limited to, procurement of substitute
 *  goods or services, loss of use, data or profits or business
 *  interruption, however caused and on any theory of liability,
 *  whether in contract, strict liability, or tort, including
 *  negligence or otherwise, arising in any way out of the use
 *  of this software, even if advised of the possibility of such
 *  damage.
 *
 *  Copyright (c) 2021 Unparalleled IT Services e.U.
 *  https://unparalleled.eu/blog/2021/20210626-android-internal-storage-as-mass-storage/
 *
 *  The permission to use, copy, modify, and distribute this
 *  software according to GNU Lesser General Public License (LGPL-3.0)
 *  is hereby granted, provided that the above copyright notice
 *  appears in all copies.
 *
 *  This program demonstrates how to initialize the USB interface
 *  on Android using the "/sys/class/android_usb/android0" drivers.
 *
 *  Compiling:
 *
 *  /usr/bin/arm-linux-gnueabihf-gcc -march=armv7-a ExfiltrateAsMassStorage.c -static -o ExfiltrateAsMassStorage
 */

#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <unistd.h>


/** Write a string to a given file.
 *  @return 0 on success.
 */
int writeString(char* targetFile, char* valueStr) {
  int targetFd = open(targetFile, O_WRONLY|O_CREAT, 0666);
  if (targetFd < 0) {
    return 1;
  }
  int length = strlen(valueStr);
  int result = write(targetFd, valueStr, length);
  if (result != length) {
    return 1;
  }
  close(targetFd);
  return 0;
}


/** Flash the light briefly a given number of times.
 */
void doBlink(int num) {
  for (int cnt = 0; cnt < num; cnt++) {
    writeString("/sys/class/leds/white/brightness", "100");
    usleep(100000);
    writeString("/sys/class/leds/white/brightness", "0");
    usleep(500000);
  }
  sleep(2);
}


/** Write a list of strings to target files.
 *  @param writeList the list containing pairs of target file
 *  name and value. A NULL target file name ends the list.
 *  return 0 on success.
 */
int writeStringList(char** writeList) {
  int writeCount = 0;
  while ((*writeList) && (!writeString(*writeList, *(writeList + 1)))) {
    writeList += 2;
    writeCount++;
  }

// Blink as often as the number of the failed data element.
  if (*writeList) {
    doBlink(writeCount + 1);
    return 1;
  }
  return 0;
}


/** Initialize the USB device descriptor string values. The values
 *  are usually ignored by drivers so they can be used to report
 *  up to 126 bytes of data for debugging purposes.
 *  @return 0 on success.
 */
int initUsbInfo(char* manufacturer, char* product, char* serial) {
  char* writeList[] = {
      "/sys/class/android_usb/android0/iManufacturer", manufacturer,
      "/sys/class/android_usb/android0/iProduct", product,
      "/sys/class/android_usb/android0/f_mass_storage/vendor", "ShortStr",
      "/sys/class/android_usb/android0/f_mass_storage/product", product,
      "/sys/class/android_usb/android0/iSerial", serial, NULL};
  return (writeStringList(writeList));
}


int main(int argc, const char *argv[]) {
// Create the memory block device in case it did not exist yet.
  mkdir("/dev", 0755);
  mknod("/dev/mmcblk0", S_IFBLK|0666, 0xb300);

// Make sure "sysfs" is mounted.
  mkdir("/sys", 0755);
  if (mount("sysfs", "/sys", "sysfs", MS_NOATIME, NULL)) {
// No sense to indicate the failure via blink code as sys is
// not mounted yet. Just "kill" init.
    return 1;
  }

// Blink three to indicate that the code is really running.
  doBlink(1);

  if (writeString("/sys/class/android_usb/android0/f_rndis/wceis", "1")) {
    doBlink(2);
    goto mainError;
  }

// Set the USB device descriptor strings.
  if (initUsbInfo("Exfiltrate", "AProduct", "BSerial")) {
    doBlink(3);
    goto mainError;
  }

  char* usbMassStorageInitList[] = {
      "/sys/class/android_usb/android0/enable", "0",
      "/sys/class/android_usb/android0/idProduct", "0x05c6",
      "/sys/class/android_usb/android0/idVendor", "0x9026",
      "/sys/class/diag/diag/logging_mode", "internal",
      "/sys/class/android_usb/android0/f_mass_storage/lun/file", "/dev/mmcblk0",
      "/sys/class/android_usb/android0/functions", "mass_storage",
      "/sys/class/android_usb/android0/enable", "1", NULL
  };
  if (writeStringList(usbMassStorageInitList)) {
    goto mainError;
  }

// Sleep forever to use the phone as mass storage device.
  while (1) {
    sleep(1);
  }

mainError:
// Blink 10x before exit. When this program is run as "init",
// exit will trigger a reboot of the device.
  doBlink(10);
  return 1;
}

------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline


_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: http://seclists.org/fulldisclosure/
------- =_aaaaaaaaaa0--

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic