转自: http://blog.csdn.net/jackaduma/article/details/7287946
和zergRush的攻击原理是一样的,其实zergRush的code部分源于GingerBreak,都是先使vold进程崩溃,
从logcat拿到调试信息,然后让vold进程以root权限执行恶意的shellcode(boomsh),
利用了android的/system/vold/DirectVolume.cpp中handlePartitionAdded()函数的漏洞
void DirectVolume::handlePartitionAdded(const char *devpath, NetlinkEvent *evt) {
int major = atoi(evt->findParam("MAJOR"));
int minor = atoi(evt->findParam("MINOR"));
int part_num;
const char *tmp = evt->findParam("PARTN");
if (tmp) {
part_num = atoi(tmp);
} else {
SLOGW("Kernel block uevent missing 'PARTN'");
part_num = 1;
}
+
if (part_num > mDiskNumParts) {
mDiskNumParts = part_num;
}
...
if (part_num > MAX_PARTITIONS) { //攻击点,如果part_num小于1
SLOGE("Dv:partAdd: ignoring part_num = %d (max: %d)\n", part_num, MAX_PARTITIONS);
} else {
mPartMinors[part_num -1] = minor;
}
--mPendingPartsCount;
…
}
Android fixed patch and my hook code:
#include <cutils/log.h>
#define LOG_TAG “gingerbreak hooker”
void DirectVolume::handlePartitionAdded(const char *devpath, NetlinkEvent *evt) {
int major = atoi(evt->findParam("MAJOR"));
int minor = atoi(evt->findParam("MINOR"));
int part_num;
const char *tmp = evt->findParam("PARTN");
if (tmp) {
part_num = atoi(tmp);
} else {
SLOGW("Kernel block uevent missing 'PARTN'");
part_num = 1;
}
+ if (part_num > MAX_PARTITIONS || part_num < 1) {
+ SLOGE("Invalid 'PARTN' value");
+ return;
+ }
if (part_num > mDiskNumParts) {
mDiskNumParts = part_num;
}
...
if (part_num >= MAX_PARTITIONS) {
SLOGE("Dv:partAdd: ignoring part_num = %d (max: %d)\n", part_num, MAX_PARTITIONS);
} else {
mPartMinors[part_num -1] = minor;
}
mPendingPartMap &= ~(1 << part_num);
…
}