A large part of modern software engineering consists of standing on the shoulders of other
peoples code, this makes us more productive and lets us focus on the solving our business problems
rather than reinventing wheels all the time.

But sometimes security problems are discovered in those libraries, if the project is well
maintained they request a CVE number, patch the bug and release a new version. CVE numbers
are the canonical identifiers for security problems and they are issued by the
CVE Numbering Authority.

It’s obvious that we don’t want to use libraries in our projects that have known security
holes, but how can we automate this this?

OWASP have solved this problem for us, with
their Dependency Check project.
It can integrate as a step in your build chain and verify your external dependencies.

For java this is done with a maven plugin, you can easily add this to your pom.xml:

When I run mvn verify in one of my projects with the above configuration
it produces this output:

One or more dependencies were identified with known vulnerabilities in ctlog:
httpclient-4.3.3.jar (cpe:/a:apache:httpclient:4.3.3, org.apache.httpcomponents:httpclient:4.3.3) : CVE-2015-5262, CVE-2014-3577
bcprov-jdk15on-1.49.jar (cpe:/a:bouncycastle:bouncy-castle-crypto-package:1.49, cpe:/a:bouncycastle:bouncy_castle_crypto_package:1.49, org.bouncycastle:bcprov-jdk15on:1.49) : CVE-2015-7940
See the dependency-check report for more details.

Wiener attack to solve key 3

Key 3 had a really big e, this was a good hint that we could use the wiener attack.

RSA isn’t an algorithm very well suited to run on constrained systems.
This has led people to try to speed it up, and one thing that they tried was to have
a small d and a large e. Michael J. Wiener was the man who developed an attack against that.

The implementation that we used was this one:

publicclassWienerAttack{//Four ArrayList for finding proper n/d which later on for guessing k/dgprivateList<BigInteger>q=newArrayList<>();privateList<Fraction>r=newArrayList<>();privateList<BigInteger>n=newArrayList<>();privateList<BigInteger>d=newArrayList<>();privateBigIntegere;privateBigIntegerN;privateFractionkDdg=newFraction(BigInteger.ZERO,BigInteger.ONE);// k/dg, D means "divide"//Constructor for the case using files as inputs for generating e and NpublicWienerAttack(BigIntegere,BigIntegerN)throwsIOException{this.e=e;this.N=N;}publicBigIntegerattack(){inti=0;BigIntegertemp1;//This loop keeps going unless the privateKey is calculated or no privateKey is generated//When no privateKey is generated, temp1 == -1while((temp1=step(i))==null){i++;}returntemp1;}//Steps follow the paper called "Cryptanalysis of Short RSA Secret Exponents by Michael J. Wiener"privateBigIntegerstep(intiteration){if(iteration==0){//initialization for iteration 0Fractionini=newFraction(e,N);q.add(ini.floor());r.add(ini.remainder());n.add(q.get(0));d.add(BigInteger.ONE);}elseif(iteration==1){//iteration 1Fractiontemp2=newFraction(r.get(0).denominator,r.get(0).numerator);q.add(temp2.floor());r.add(temp2.remainder());n.add((q.get(0).multiply(q.get(1))).add(BigInteger.ONE));d.add(q.get(1));}else{if(r.get(iteration-1).numerator.equals(BigInteger.ZERO)){returnBigInteger.ONE.negate();//Finite continued fraction. and no proper privateKey could be generated. Return -1}//go on calculating n and d for iteration i by using formulas stating on the paperFractiontemp3=newFraction(r.get(iteration-1).denominator,r.get(iteration-1).numerator);q.add(temp3.floor());r.add(temp3.remainder());n.add((q.get(iteration).multiply(n.get(iteration-1)).add(n.get(iteration-2))));d.add((q.get(iteration).multiply(d.get(iteration-1)).add(d.get(iteration-2))));}//if iteration is even, assign <q0, q1, q2,...,qi+1> to kDdgif(iteration%2==0){if(iteration==0){kDdg=newFraction(q.get(0).add(BigInteger.ONE),BigInteger.ONE);}else{kDdg=newFraction((q.get(iteration).add(BigInteger.ONE)).multiply(n.get(iteration-1)).add(n.get(iteration-2)),(q.get(iteration).add(BigInteger.ONE)).multiply(d.get(iteration-1)).add(d.get(iteration-2)));}}//if iteration is odd, assign <q0, q1, q2,...,qi> to kDdgelse{kDdg=newFraction(n.get(iteration),d.get(iteration));}BigIntegeredg=this.e.multiply(kDdg.denominator);//get edg from e * dg//dividing edg by k yields a quotient of (p-1)(q-1) and a remainder of gBigIntegerfy=(newFraction(this.e,kDdg)).floor();BigIntegerg=edg.mod(kDdg.numerator);//get (p+q)/2 and check whether (p+q)/2 is integer or notBigDecimalpAqD2=(newBigDecimal(this.N.subtract(fy))).add(BigDecimal.ONE).divide(newBigDecimal("2"));if(!pAqD2.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO))returnnull;//get [(p-q)/2]^2 and check [(p-q)/2]^2 is a perfect square or notBigIntegerpMqD2s=pAqD2.toBigInteger().pow(2).subtract(N);BigIntegerpMqD2=BigMath.sqrt(pMqD2s);if(!pMqD2.pow(2).equals(pMqD2s))returnnull;//get private key d from edg/egreturnedg.divide(e.multiply(g));}}publicclassFraction{publicBigIntegernumerator;publicBigIntegerdenominator;//Constructor of the Fraction class which initializes the numerator and denominatorpublicFraction(BigIntegerparamBigInteger1,BigIntegerparamBigInteger2){//find out the gcd of paramBigInteger1 and paramBigInteger2 which is used for ensuring the numerator and denominator are relatively primeBigIntegerlocalBigInteger=paramBigInteger1.gcd(paramBigInteger2);this.numerator=paramBigInteger1.divide(localBigInteger);this.denominator=paramBigInteger2.divide(localBigInteger);}//Constructor for the case when calculating (paramBigInteger1 /(paramFraction.numerator / paramFraction.denominator))publicFraction(BigIntegerparamBigInteger,FractionparamFraction){this.numerator=paramBigInteger.multiply(paramFraction.denominator);this.denominator=paramFraction.numerator;BigIntegerlocalBigInteger=this.numerator.gcd(this.denominator);this.numerator=this.numerator.divide(localBigInteger);this.denominator=this.denominator.divide(localBigInteger);}//Calculate the quotient of this FractionpublicBigIntegerfloor(){BigDecimallocalBigDecimal1=newBigDecimal(this.numerator);BigDecimallocalBigDecimal2=newBigDecimal(this.denominator);returnlocalBigDecimal1.divide(localBigDecimal2,3).toBigInteger();}//Calculate the remainder of this Fraction and assign the result to form a new FractionpublicFractionremainder(){BigIntegerfloor=this.floor();BigIntegernumeratorNew=this.numerator.subtract(floor.multiply(this.denominator));BigIntegerdenominatorNew=this.denominator;returnnewFraction(numeratorNew,denominatorNew);}}

These attacks combined gave us enough plaintext so that we could recover that flag, which was FLAG{ndQzjRpnSP60NgWET6jX}