Created
April 27, 2014 04:12
-
-
Save t-j-h/11337380 to your computer and use it in GitHub Desktop.
block the heartbeat usage in application code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* heartbeat_block.c - block the heartbeat usage in application code if | |
* unsure if you are working with a patched or non-patched | |
* library or if you want to log the exploit attempts | |
*/ | |
/* include defines to make code more readable without pulling in | |
* any "internal" OpenSSL header files | |
*/ | |
#ifndef TLS1_RT_HEARTBEAT | |
#define TLS1_RT_HEARTBEAT 24 | |
#endif /* TLS1_RT_HEARTBEAT */ | |
#ifndef TLS1_HB_REQUEST | |
#define TLS1_HB_REQUEST 1 | |
#endif /* TLS1_HB_REQUEST */ | |
#ifndef TLS1_HB_RESPONSE | |
#define TLS1_HB_RESPONSE 2 | |
#endif /* TLS1_HB_RESPONSE */ | |
#ifndef n2s | |
#define n2s(c,s) ((s=(((unsigned int)(c[0]))<< 8)| \ | |
(((unsigned int)(c[1])) )),c+=2) | |
#endif /* n2s */ | |
#ifndef s2n | |
#define s2n(s,c) ((c[0]=(unsigned char)(((s)>> 8)&0xff), \ | |
c[1]=(unsigned char)(((s) )&0xff)),c+=2) | |
#endif /* s2n */ | |
static void msg_cb_hb_block(int write_p, int version, | |
int content_type, const void *buf, size_t len, SSL *ssl, void *arg) | |
{ | |
unsigned char *p=(unsigned char *)buf; | |
unsigned short hbtype=0; | |
unsigned int payload=0; | |
BIO *null_bio=NULL; | |
if (content_type==TLS1_RT_HEARTBEAT) { | |
if (len>=3) { | |
hbtype = *p++; | |
n2s(p,payload); | |
/* if a heartbeat request is requesting a payload larger than the | |
* record size it is an attempt to expolit CVE-2014-0160 and we | |
* force-drop the connection | |
*/ | |
if (3+payload+16>len) { | |
/* remove the I/O layer out from underneath the SSL layer so we | |
* can be sure no processing makes it out | |
*/ | |
/* it would be great if we could just set the BIOs to null as | |
* but unfortunately some OpenSSL internal code assumes the BIO | |
* is always there ... | |
*/ | |
/* | |
(void)SSL_set_bio(ssl,NULL,NULL); | |
*/ | |
null_bio=BIO_new(BIO_f_null()); | |
(void)SSL_set_bio(ssl,null_bio,null_bio); | |
(void)SSL_set_quiet_shutdown(ssl,1); | |
(void)SSL_shutdown(ssl); | |
/* do whatever you want to indicate to the caller the reason | |
* why the connection has been blocked ... can use the 'arg' | |
* value to reach back to whatever was set against the SSL_CTX | |
* or the SSL as the msg_callback_arg - in this simple example | |
* just print out a notice - applications will do something more | |
* interesting to report to the user | |
*/ | |
fprintf(stderr,"msg_cb_hb_block: blocked heartbeat attempt\n"); | |
} | |
} | |
} | |
done: ; | |
} | |
#ifdef PUT_THIS_IN_THE_APPLICATION | |
/* note: change user_context to NULL if you do not have one to use */ | |
/* if using an SSL_CTX level interface to hook this in */ | |
(void)SSL_CTX_set_msg_callback(sctx,msg_cb_hb_block); | |
(void)SSL_CTX_set_msg_callback_arg(sctx,(void *)user_context); | |
/* if using an SSL level hook ... at which point you can track per | |
* connection information | |
*/ | |
(void)SSL_set_msg_callback(ssl,msg_cb_hb_block); | |
(void)SSL_set_msg_callback_arg(ssl,(void *)user_context); | |
#endif /* PUT_THIS_IN_THE_APPLICATION */ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment