2011年9月15日星期四

【轉載】結合init源碼剖析android root提權漏洞(CVE-2010-EASY)


作 者: androider
時 間: 2011-09-04,21:41:26
鏈接: http://bbs.pediy.com/showthread.php?t=139738

轉載請註明出處:http://hi.baidu.com/androidhacker/blog/item/59faabfda34b71f57709d707.html

這篇文章是上一篇博客的後續分析,主要介紹向init進程發送熱拔插信息後init進程的處理流程

首先我們來了解一個數據結構,uevent,如下


代碼:
struct uevent {

    const char *action;

    const char *path;

    const char *subsystem;

    const char *firmware;

    int major;

    int minor;

};
 

內核收到的信息如下,ACTION=addDEVPATH=/../data/local/tmpSUBSYSTEM=firmwareFIRMWARE=../../../data/local/tmp/hotplug
通過如下函數parse_event進行解析


代碼:
static void parse_event(const char *msg, struct uevent *uevent)

{

 

    while(*msg) {

        if(!strncmp(msg, "ACTION=", 7)) {

            msg += 7;

            uevent->action = msg;

        } else if(!strncmp(msg, "DEVPATH=", 8)) {

            msg += 8;

            uevent->path = msg;

        } else if(!strncmp(msg, "SUBSYSTEM=", 10)) {

            msg += 10;

            uevent->subsystem = msg;

        } else if(!strncmp(msg, "FIRMWARE=", 9)) {

            msg += 9;

            uevent->firmware = msg;

        } else if(!strncmp(msg, "MAJOR=", 6)) {

            msg += 6;

            uevent->major = atoi(msg);

        } else if(!strncmp(msg, "MINOR=", 6)) {

            msg += 6;

            uevent->minor = atoi(msg);

        }

         while(*msg++);

    }

}
經過解析之後,u​​event的結構為:
action="add"
path="/../data/local/tmp"
subsystem="firmware"
firmware="../../../data/local/tmp/hotplug"


之後來到處理firmware的核心函數


代碼:
static void process_firmware_event(struct uevent *uevent)

{

    l = asprintf(&root, SYSFS_PREFIX"%s/", uevent->path);

    //root為/sys/../data/local/tmp/=/data/local/tmp/

    

    l = asprintf(&loading, "%sloading", root);

    //loading為/data/local/tmp/loading

    

    l = asprintf(&data, "%sdata", root);

    //data為/data/local/tmp/data 其內容為指向/proc/sys/kernel/hotplug的符號鏈接

    

    l = asprintf(&file, FIRMWARE_DIR"/%s", uevent->firmware);

    //file為/etc/firmware/../../../data/local/tmp/hotplug=/data/local/tmp/hotplug

    

    loading_fd = open(loading, O_WRONLY);

    

    data_fd = open(data, O_WRONLY);

    

    fw_fd = open(file, O_RDONLY);

    

    load_firmware(fw_fd, loading_fd, data_fd);

}

 

最後來到load_firmware函數,把hotplug中的數據寫到/proc/sys/kernel/hotplug中
其內容變為/data/local/tmp/exploid


代碼:
static int load_firmware(int fw_fd, int loading_fd, int data_fd)

{

    while (len_to_copy > 0) {

        char buf[PAGE_SIZE];

 

 

        nr = read(fw_fd, buf, sizeof(buf));

                                                                        

        len_to_copy -= nr;

        while (nr > 0) {

                                                                                              

            nw = write(data_fd, buf + nw, nr);

 

            nr -= nw;

        }

    }

}
 

終於/proc/sys/kernel/hotplug中寫入了我們的惡意程序了,只要再次受到如wifi打開、usb插入等熱拔插信息,內核就會以root權限加載我們的程序再一次執行,從而達到提權的目的

没有评论:

发表评论