CVE-2014-3153分析和利用

   本文是結合參考資料對CVE-2014-3153的分析,固然各位看官能夠看最後的資料,他們寫的比我好。php

  在看CVE-2014-3153以前咱們用參考資料4中例子來熟悉下這類漏洞是如何產生的:html

/**
 * An example of bug that can be exploited through stack manipulation
 * Use -m32 to compile as 32 bit app, so that the int size is the same as pointer size
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct node {
       const char *value;
       struct node *next;
       struct node *prev;
};

struct list {
       struct node *head;
       struct node *tail;
};

void list_add(struct list *lst, struct node *newnode)
{
    if (lst->head==NULL) {
        lst->head = newnode;
        lst->tail = newnode;
    } else {
        newnode->prev = lst->tail;
        lst->tail->next = newnode;
        lst->tail = newnode;
    }
}

struct node * list_remove_last(struct list *lst) 
{
    struct node *result;
    result = lst->tail;

    if (lst->head==lst->tail) { /*zero or 1 element*/
        lst->head = lst->tail = NULL;
    } else  {
        lst->tail = lst->tail->prev;
        lst->tail->next = NULL;
    }
    return result;
}

void list_print(struct list *lst)
{
    struct node *tmp;
    tmp = lst->head;
    while (tmp) {
        printf("Value = %s\n", tmp->value);
        tmp = tmp->next;
    }
}

void list_add_new(struct list *lst, const char *val)
{
    struct node *newnode  = (struct node *)malloc(sizeof(struct node));
    newnode->next = NULL;
    newnode->value = strdup(val);
    list_add(lst, newnode);
}    


void print_with_end_of_list(struct list *lst)
{
    struct node instack;
    instack.next = 0;
    instack.value = "--END OF LIST--";

    printf("Not a buggy function\n");

    list_add(lst, &instack);
    list_print(lst);
    /*we ignore the returned node*/
    list_remove_last(lst);
}


void buggy_print_with_end_of_list(struct list *lst)
{
    int dummy_var1; /*see the article to see why i introduced this*/
    int dummy_var2;
    int dummy_var3;

    struct node instack;

    printf("a buggy function, here is the location of value on stack %p\n", &instack.value);

    instack.next = 0;
    instack.value = "--END OF LIST--";


    list_add(lst, &instack);
    list_print(lst);
    /*we 'forgot' to remove the list element*/

}

void a_function_to_exploit(int element_number, void * value)
{
    int i;
    int buf[10];
    if (element_number==-1) { /*print addressed of buf*/
        for (i=0; i < 10; i++) {
            printf("location of buf[%d] is %p\n", i, &buf[i]);
        }
        return;
    }

    buf[element_number] = (int)value;    

}


int main(int argc, char * argv[])
 {
    struct list mylist;
    mylist.head = NULL;
    mylist.tail = NULL;
    int pos;
    char *val;

    /*we have one parameter*/
    pos = -1;
    if (argc==3) {
        pos = atoi(argv[1]);
        val = argv[2];
    }       

    printf("we will use pos: %d\n", pos);

    list_add_new(&mylist, "Alpha");
    list_add_new(&mylist, "Beta");
    print_with_end_of_list(&mylist);
    buggy_print_with_end_of_list(&mylist);

    a_function_to_exploit(pos, val);

    list_print(&mylist);

    /*this is just a demo, i am skipping the cleanup code*/
    return 0;
}
View Code

 

  編譯上面的代碼(假設編譯後的可執行文件名爲mylist)並執行
node

$ ./mylist 
we will use pos: -1
Not a buggy function
Value = Alpha
Value = Beta
Value = --END OF LIST--
a buggy function, here is the location of value on stack 0xffd724a4
Value = Alpha
Value = Beta
Value = --END OF LIST--
location of buf[0] is 0xffd72488
location of buf[1] is 0xffd7248c
location of buf[2] is 0xffd72490
location of buf[3] is 0xffd72494
location of buf[4] is 0xffd72498
location of buf[5] is 0xffd7249c
location of buf[6] is 0xffd724a0
location of buf[7] is 0xffd724a4
location of buf[8] is 0xffd724a8
location of buf[9] is 0xffd724ac
Value = Alpha
Value = Beta
Value = --END OF LIST--

 

  根據上面的執行結果咱們知道buggy_print_with_end_of_list函數新增list的value值的棧地址恰好對應a_function_to_exploit函數中buf[7]的棧地址,故有繼續執行app

$./mylist 7 HACKED
we will use pos: 7
Not a buggy function
Value = Alpha
Value = Beta
Value = --END OF LIST--
a buggy function, here is the location of value on stack 0xffd3bd34
Value = Alpha
Value = Beta
Value = --END OF LIST--
Value = Alpha
Value = Beta
Value = HACKED

 

  執行結果上面符合,buf[7]存儲着「HACKED」字符串的地址,恰好是list.value的地址,因此在最後輸出"HACKER「。固然這個是bug,它引用了函數中的局部變量(函數返回後,局部變量的值會被後續的代碼覆蓋致使,致使重大bug)。這個例子告訴咱們能夠在相似的bug中咱們能夠操控list值,固然咱們並不會知足於此ide

  

 

 

 另:咱們知道TowelRoot root工具就是利用這個CVE,爲了防止他人拷貝和重打包,使用了O-LLVM來混淆ndk代碼(固然這是另外的課題了,這裏是記錄下,你能夠看譯]使用O-LLVM和NDK對Android應用進行混淆 來熟悉概念)。函數

 

 

參考資料:工具

CVE-2014-3153 分析以及利用this

2  cve2014-3153 漏洞之詳細分析與利用spa

CVE-2014-3153筆記.net

Exploiting the Futex Bug and uncovering Towelroot

相關文章
相關標籤/搜索