Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

30
The power of development-driven security testing Marat Vyshegorodtsev System Security Office Rakuten, Inc. https://global.rakuten.com

description

Transcript of Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Page 1: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

The power of development-driven security testingMarat Vyshegorodtsev System Security Office Rakuten, Inc. https://global.rakuten.com

Page 2: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

About Rakuten

Page 3: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

World coverageE-commerce in 14 countries and regions All services and businesses in 27 countries

2011200920082005 201320122010

INVESTMENT

2014

Page 4: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Bio & DisclaimerTechnical Program Manager “Group Core Services” at Rakuten

University of Tokyo graduate

Member of the world-famous CTF team “More Smoked Leet Chicken”

The Russian hacker of Japan :-)

!

I’m not a Java developer. In fact, I’m not a developer at all.

Page 5: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Security & Quality Assurance• Regular QA tests cover “intended” functionality

• Security QA tests try to find all other unintended behavior

Page 6: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Security & Quality Assurance• Regular QA tests cover “intended” functionality

• Security QA tests try to find all other unintended behavior

Page 7: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

QA is hard, Security QA is harder

Main reasons why security tests are hard:

1. Big scope: number of methods times number of tests

2. Hard to hook in

3. Halting problem

Page 8: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

QA is hard, Security QA is harder

Main reasons why security tests are hard:

1. Big scope: number of methods times number of tests

2. Hard to hook in

3. Halting problem

Page 9: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

QA is hard, Security QA is harder

Main reasons why security tests are hard:

1. Big scope: number of methods times number of tests

2. Hard to hook in

3. Halting problem

Page 10: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

QA is hard, Security QA is harder

Main reasons why security tests are hard:

1. Big scope: number of methods times number of tests

2. Hard to hook in

3. Halting problem

Page 11: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Halting problem in one slide

It is impossible to determine if program will halt or not on given inputs

Hence, it is impossible to perform all possible security tests

Give it up.

xkcd.com/1266

Page 12: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Problem 1: Traversing the codeGiven:A service that has 70,000+ lines of code, a build system, and some tests

Find:

• All classes and their methods that use unsafe or deprecated calls

• Classes that must implement certain methods, but didn’t

• Classes that call certain dangerous APIs to fuzz them later

Page 13: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Freud — a framework for writing static analysis tests

LMAX-Exchange/freud

Page 14: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Freud

• Enables iteration over source code and byte code files’ contents

• Supports custom hamcrest matchers to write rules

• Implements DSL-like syntax for writing tests with JUnit or Groovy

Page 15: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Unsafe and deprecated callsBan all direct input/output trough files:

@Test!public void noDirectFileInput() throws Exception {!!

Freud.iterateOver(ImportDeclaration.class).!!!assertThat(no(importDeclarationPathAsString(), containsString("java.io.File"))).analyse(listener);!!

}

Page 16: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Mandatory implementation

@RolesAllowed("Administrator")

public void setNewRate(int rate) {

...

}

Page 17: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Mandatory implementation

Freud.iterateOver(CodeBlock.class).          forEach(method(publicMethod())).              assertThat(hasDeclaredAnnotation(“RolesAllowed”))  !

.in(codeBlocksWithin(methodDeclarationsWithin(classDeclarationsWithin(javaSourceOf(asList(  //  list  of  class  files  URLs  here  )))))).analyse(listener);

Page 18: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Finding bad apples

Freud.iterateOver(CodeBlock.class).    forEach(method(hasMethodCall(“Session.createSQLQuery”)))  !

//  find  out  who  calls  unsafe  APIs  and  try  to  fuzz  it

Page 19: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Fuzzing

// this.function is a iterator for forEach!!

public T next(){! for(Fuzzer f = fuzzDB.createFuzzer("031-B16-HEX", 4); f.hasNext();) {! return function(f.next());! }!}

Page 20: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Problem 2. Going deep

Page 21: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Problem 2. Going deep

Page 22: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Problem 2: Going deepGiven

• Big application with full code coverage

• No security checks implemented

Find

• Certain method is called with a certain parameter

• Some parameters should never be passed to a method

Page 23: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Power of mocking with PowerMock

PowerMock is a custom class-loader and byte-code manipulator allowing to mock static methods

Extends Mockito and JUnit perfectly

Page 24: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Deprecating MD5Problem: MessageDigest.getInstance(“MD5”) must not be used

Solution: Let’s just grep for a string getInstance(“MD5”)!

!

But… remember the halting problem?

MessageDigest.getInstance(Config.getConfiguredHashAlgorithm())

↑ is it MD5?

Page 25: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

@RunWith(PowerMockRunner.class)  @PrepareForTest({MyClass.class,  MessageDigest.class})  public  class  md5Test  extends  PowerMockTestCase  {  !

       @Test          public  void  testDoHash()  throws  Exception  {                  PowerMockito.mockStatic(MessageDigest.class);                  when(MessageDigest.getInstance("MD5")).thenReturn(null);                  PowerMockito.verifyStatic();  !

               assertEquals(“acbd18db4cc2f85cedef654fccc4a4d8",  MyClass.doHash("foo"));          }  !

}

Page 26: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

PowerMock + Hamcrest

• Problem: See if Log function never accepts credit card number-looking strings, given that a developer wrote a test that triggers this behavior

• Solution: Mock Log class, when its functions are called, there is no argThat is a 16 digit string (as an easy example)

Page 27: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

@RunWith(PowerMockRunner.class)  @PrepareForTest({MyClass.class,  Log.class})  public  class  logTest  extends  PowerMockTestCase  {  !

       @Test          public  void  testSomeFunction()  throws  Exception  {                  PowerMockito.mockStatic(Log.class);                  when(Log.i(new  IsCreditCard())).thenReturn(null);                  PowerMockito.verifyStatic();  !

             //  continue  test          }  !

}

Page 28: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

class IsCreditCard extends ArgumentMatcher<String> {! public boolean matches(String message) {! return RegExp.matches(message,”[0-9]{16}”);! }! }

Page 29: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

SummaryIn most of the languages running on VMs it is possible to test certain weaknesses using unit tests

Security engineers working together with TDD/BDD dev teams can write many business logic-aware tests easily using the frameworks I have described

BDD is for intended behavior, security-driven development is for unintended one

Page 30: Making Your Own Static Analyzer Using Freud DSL. Marat Vyshegorodtsev

Thank you!

[email protected] !

@MaratVy maratto.blogspot.com