本文是结合参考资料对CVE-2014-3153的分析,当然各位看官可以看最后的资料,他们写的比我好。
在看CVE-2014-3153之前我们用参考资料4中例子来熟悉下这类漏洞是如何产生的:
/** * 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; }