/** 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 #include #include #include #include #include /** 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; }