360 likes | 529 Views
The Owasp Orizon Project internals. Paolo Perego Owasp Orizon Project Leader Spike Reply thesp0nge@owasp.org. Agenda. some infos before we start... the Owasp Orizon internals so, next?. $ whoami. Senior Security Consultant @ Spike Reply Srl penetration testing
E N D
The Owasp Orizon Projectinternals Paolo Perego Owasp Orizon Project Leader Spike Reply thesp0nge@owasp.org
Agenda • some infos before we start... • the Owasp Orizon internals • so, next?
$ whoami • Senior Security Consultant @ Spike Reply Srl • penetration testing • secure application building • code review & source code assessment • OwaspOrizon Project leader • Active member in • Owasp Italian chapter • Owasp Code Review Project
Kickoff • A lot of commercial solutions are available for code reviewing • good in finding bugs • skilled support • expensive • Few open source solutions are available too • small number of security checks • good support from open source community • open Why do I need Orizon?
Some infos before we start… • In 2007... • more than 27.000 hits to http://orizon.sourceforge.net • more than 700 downloads for Orizon package releases • v 0.50 downloaded 101 times in 3 months • In 2008… • More than 200 downloads in the first 4 month • v0.80 downloaded 63 times in the first month (from 4 April to 5 May)
The Owasp Orizon Internals • Few things to remember • Orizon is a framework, it is not a tool • details are hidden for developers • 1 or 2 public classes for each engine • few public available methods • engines are intended to be used in stock • framework is in development • Most criticisms are related to • lack of documentation • lack of usage examples • missing framework design overview
The Owasp Orizon Internals: the stack Reporting engine Reporting Jericho engine Dawn engine Plugin engine Code reviewing Crawler engine Code crawling XML Translator engine Preprocessing
The Owasp Orizon Internals: XML translation • Independence from programming language • Source file needs to be translated to XML before review • Translator is an abstract class • for every supported language Translator class must be implemented accordingly • protected abstract boolean translate(); • Used by Orizon hackers • AnyLanguage2XML implements Translator class • Used by people writing code review tool • Hide the preprocessing details to users
The Owasp Orizon Internals: XML translation import org.owasp.orizon.java.Java2XML; // java 2 xml translation... Java2XML j2xml = new Java2XML(fileName); if (!j2xml.exists()) { System.err.println("input file does not exist. Giving up."); return ; } if (j2xml.mustTranslate()) { if (!j2xml.translate()) { System.err.println(fileName + ": translation failed"); System.exit(-1); } System.out.println(j2xml.getOutputFilename() + " created"); } else System.out.println("XML file is up to date”);
The Owasp Orizon Internals: XML translation • This class has no modifiers but it has two fields: • a public String variable named a • a private int variable named b public class uno { public String a; private int b; public uno() { a = new String(); b = 2; } public uno(String a, int b) { this(); setA(a); setB(b); } public boolean areEqualBad(String b) { if (a==b) return true; else return false; } public boolean areEqualGood(String b) { if (a.equal(b)) return true; else return false; } public void setA(String a) { this.a = a; } public void setB(int b) { this.b = b; } } <?xml version="1.0" encoding="ISO-8859-1"?> <!-- generated by Orizon v0.63 (VitalogY) [build: 929] (C) 2007, 2008 thesp0nge@owasp.org --> <source name="uno.java"> <stats loC="35" loc="-1" cci="2" /> <class name="uno" scope="public" implements="" extends=""> <variable name="a" type="String" kind="VARIABLE" scope="public" init="" /> <variable name="b" type="int" kind="VARIABLE" scope="private" init="" /> <constructor> <body> { a = new String(); b = 2; } </body> <block> <assignment variable="a" value="new String()" /> <assignment variable="b" value="2" /> </block> </constructor> XML Class preamble with some stats... This method contains a security violation... where? In the body we found two assignments. Uncommented code... mmmh... this is no good! <method name="areEqualBad" returns="boolean" scope="public" throws=""> <params> <param name="b" type="String" /> </params> <variable name="b" type="String" kind="PARAMETER" scope="" init=""/> <body> { if (a == b) return true; else return false; } </body> <block> <if condition="(a == b)"> <parenthesized> <equal> <left reduced="String"/> <right reduced="String"/> </equal> </parenthesized> <then><return>true</return></then> <else><return>false</return></else> </if> </block> </method>
The Owasp Orizon Internals: crawling • Owasp Code Review project introduced source code crawling in its check list • Orizon v0.70 introduced • org.owasp.orizon.crawler package • An abstract source code crawling class • A set of dangerous keywords for Java and C# in default library • Key points • Good: a quick code review can be performed • Bad: results are more prone to false potives
The Owasp Orizon Internals: crawling • AbstractCrawler • read(): reads the XML file containing the desired keyword list • check (): performs a pattern matching search over a specified file • getReport(): returns a report with found keywords if any
The Owasp Orizon Internals: crawling JavaCrawlerclass package org.owasp.orizon.java; import org.owasp.orizon.core.OrizonCons; import org.owasp.orizon.crawler.AbstractCrawler; public class JavaCrawler extends AbstractCrawler { public JavaCrawler(String xmlFile) { super(xmlFile, OrizonCons.O_JAVA); super.read(); } } jC = new JavaCrawler("dangerous_java_keywords.xml"); if (jC.crawl(filename)) { r = jC.getReport(); if (r != null) { PlainFormatter p = new PlainFormatter(); r.report(p); } } else System.out.println("no dangerous keyword found during crawling"); JavaCrawlerclassusage sample. Developers just needtocall crawl() method…
The Owasp Orizon Internals: the plugin engine • An interface is provided and all plugins must implement it • org.owasp.orizon.plugin.Plugin • A loader class • Extract plugin class from a given jar file • Checks if the plugin is intended for this orizon version • Load the class and returns it to Jericho engine
The Owasp Orizon Internals: the plugin engine • Jericho engine will • Instanciate a new object • Run the plugin via start() and stop() methods • The plugin will be called this way <check id="O_EX_1" severity="error" impact="high" description="This check will be handled by an external piece of code" positive_fail="false" external="yes" jar="c:\users\thesp0nge\test.jar" package="" class="Test" > <catch some_code="no" some_code_bogus="foo"/> </check>
The Owasp Orizon Internals: the plugin engine public classPluginDemo { public static void main(String args[]) { Loader l = new Loader("c:\\users\\thesp0nge\\test.jar"); try { // Plugin p = (Plugin)l.load("Test").newInstance(); Class c = l.load("Test"); if (c==null) return ; Plugin p = (Plugin)c.newInstance(); p.start(); p.stop(); System.out.println("here"); } catch (Exception e) { e.printStackTrace(); System.err.println("main: "+ e.getMessage()); return ; } } }
The Owasp Orizon Internals: static review • The translated source code is read • org.owasp.orizon.core.Source.read() • initialize Jericho engine • initialize Dawn engine • adding XML nodes to Jericho engine • The security checks are applied • org.owasp.orizon.core.Source.review() • loop for security checks • add check to Jericho engine • call Jericho check() method
The Owasp Orizon Internals: static review • Jericho engine internally is called • org.owasp.orizon.jericho.Jericho.check() • most important method • return true if a security violation has been found • it must be called from Source class due to read() method interoperability public boolean check() { boolean ret = false; long startScan = 0, endScan = 0; if (!isInitialized()) return false; if (!checkLoaded) { log.error("aiee, load a check before with add() method"); return false; } startScan = Calendar.getInstance().getTimeInMillis(); if (statLoaded) ret ^= s.check(c); if (equals != null) ret ^= equals.check(c); if (imports != null && imports.length != 0) ret ^= loop(c, new Import()); if (classes != null && classes.length != 0) ret ^= loop(c, new Class()); if (methods != null && methods.length != 0) ret ^= loop(c, new Method()); ret ^= overlook(); endScan = Calendar.getInstance().getTimeInMillis(); report.setScanMillis(endScan - startScan); return (!(ret ^ c.getPositiveFail())); }
The Owasp Orizon Internals: library Library (ZIP file) Recipe 1 (XML file) Recipe 2 (XML file) Recipe n (XML file) Securitycheck 1 Security check 2 <checkid="O_UO_6" severity="error" impact="high" description="Creating a custom class loader that is not secure can allow the loading of malicious classes." positive_fail="true"> <class extends="ClassLoader"/> </check>
The Owasp Orizon Internals: library • The security library • is a ZIP file • contains one or more XML files • is used during static code review • A default library is provided • Developers can write their own library as well
The Owasp Orizon Internals: recipes • The recipes • contain security checks • contain a checksum to prevent tampering • can contain encoded attack patterns <recipefamily="Code design" name="Design classes with a safe access control policies over fields and methods" description="Code design issues related to methods and fields access control" applies="java" requires="0.63" dawn="false" jericho="true" crc="4005429572"> ... </recipe>
The Owasp Orizon Internals: security checks • The check • Describes a safe coding rule • Has its own severity and impact levels <checkid="O_AC_1" severity="error" impact="low" description="A class must be defined as private or public" positive_fail="false"> <class name="*" scope="private|public"/> </check> If a class scope isdifferentbothfrom private than public, a security violationoccurs
The Owasp Orizon Internals: security checks <?xml version="1.0" encoding="ISO-8859-1"?><recipe family="Unsafe operations" name="Ensure that logs are correctly written and exception correctly handled" description="Some operations can lead an attacker to change the class behaviour overriding it." applies="java" requires="0.63." dawn="false" jericho="true" crc="494103265">... <checkid="O_UO_3" severity="error" impact="high" description="Use 'java.security.SecureRandom' instead of 'java.util.Random' or 'Math.random()'" positive_fail="true"><variable type="Math.Random"/></check>... <checkid="O_UO_6" severity="error" impact="high" description="Creating a custom class loader that is not secure can allow the loading of malicious classes." positive_fail="true"><class extends="ClassLoader"/></check>... <checkid="O_UO_8" severity="error" impact="medium" description="Do not use arithmetic operator == to compare String objects. Use equal() method instead." positive_fail="true"><equal l="String" r="String"/></check> If a variable is an instance of Math.Random then an high impact error occurs. SecureRandom class has to be used instead If a class extends ClassLoader then an high impact error occurs because malicious classes can be loaded through custom class loaders Two Strings must not be compared using arithmetic operator, a ClassCastException can occur
The Owasp Orizon Internals: review applied <method name="areEqualBad" returns="boolean" scope="public" throws=""> <params> <param name="b" type="String" /> </params> <variable name="b" type="String" kind="PARAMETER" scope="" init=""/> <body> { if (a == b) return true; else return false; } </body> <block> <if condition="(a == b)"> <parenthesized> <equal> <left reduced="String"/> <right reduced="String"/> </equal> </parenthesized> <then><return>true</return></then> <else><return>false</return></else> </if> </block> </method> This method contains a security violation... where? ... a class cast exception can occur comparing two objects with an arithmetical operator. Orizon is able to guess data type of both operands. For a variable is simple, for a method it will be the data type returned by the method itself. <checkid="O_UO_8" severity="error" impact="medium" description="Do not use arithmetic operator == to compare String objects. Use equal() method instead." positive_fail="true"> <equal l="String" r="String"/> </check>
The Owasp Orizon Internals: dynamic review • Developers need only to change a flag when calling Source.review() • Dawn parameters are the recipe to apply and the working directory to create helpers • An helper is created for each method in the source file being checked • The helper is a Java program that invokes the method giving its command line as argument
The Owasp Orizon Internals: dynamic review Static code review Dynamic code review import org.owasp.orizon.core.Source; import org.owasp.orizon.report.*; // xml file reading Source s = new Source(j2xml.getOutputFilename(), "."+File.separator); s.read(); for (int count = 0; count < recipeCount; count++) { String rName = dl.getRecipeName(count); if (!dl.extract(rName)) { System.err.println("can't extract " + rName); System.exit(-1); } r = new Recipe(rName); org.owasp.orizon.report.Report report = s.review(r, true); if (report != null) { PlainFormatter p = new PlainFormatter(); report.report(p); } r.dispose(); } // for (int count = 0; count < recipeCount; count++) • import org.owasp.orizon.core.Source; • import org.owasp.orizon.report.*; • // xml file reading • Source s = new Source(j2xml.getOutputFilename(), "."+File.separator); • s.read(); • for (int count = 0; count < recipeCount; count++) { • String rName = dl.getRecipeName(count); • if (!dl.extract(rName)) { • System.err.println("can't extract " + rName); • System.exit(-1); • } • r = new Recipe(rName); • org.owasp.orizon.report.Report report = s.review(r, false); • if (report != null) { • PlainFormatter p = new PlainFormatter(); • report.report(p); • } • r.dispose(); • } // for (int count = 0; count < recipeCount; count++)
The Owasp Orizon Internals: dynamic review • Helper is executed passing attack patterns as arguments • Helper output is collected and examined to understand how the method reacts to attack pattern • Dynamic code review concerns about: • cross site scripting attacks • sql injection attacks • unexpected inputs • null values • empty strings, negative integers, ...
The Owasp Orizon Internals: dynamic review Attack patterns: “/><script>alert(‘xss here’);</script> ‘ or 1=1; -- ... main() method A method B method A main() Source file Method A helper method A main() Method A helper • Evaluating output: • are input strings filtered? • are unhandled exceptions raised? • ... method B Method B helper
The Owasp Orizon Internals • org.owasp.orizon.report package • Report is returned back to calling program with security checks that failed • Formatters are provided in order to take a Report and printing it out in: • plain text • file • XML + XSL • Next actions are to improve the number of report ouput format
some links before we leave… • Orizon site: http://orizon.sourceforge.net • Orizon blog: http://blogs.owasp.org/orizon • Orizon page @ Owasp: http://www.owasp.org/index.php/Category:OWASP_Orizon_Project • Milk site (for milk and arachne): http://milk.sourceforge.net • Contact me: thesp0nge@owasp.org
The Owasp Orizon Projectinternals Paolo Perego Owasp Orizon Project Leader Spike Reply thesp0nge@owasp.org