Share
Embed
Advanced XSS and Injection Attacks
Presentation on XSS in AngularJS and Hibernate SQL Injection given at Security BSides Boston 2016.
Links to the demo application:
https://github.com/caseydunham/angularjs-sandbox
https://github.com/caseydunham/hibernate-sandbox
Casey Dunham
May 21, 2016
Transcript
75 slides
-
Agenda • Introduction • AngularJS Expressions • AngularJS XSS •
HQL SQLi • Prevention • Q + A -
Introduction • Casey Dunham • Security Consultant for GuidePoint Security
• Application Security • Code Reviews • Assessments • OWASP Maine • DC207 • TOOOL @CaseyDunham @GuidePointSec -
<!doctype html> <html lang="en" ng-app="app"> <body> <div ng-repeat="product in vm.featuredProducts">
<h2>{{ product.name }}</h2> <strong class="price">{{ product.price | currency }}</strong> <button type="button" ng-click="vm.addToCart(product.id)">Add to Cart</button> <img ng-src="{{ product.imageUrl }}"/> </div> <script src="/webjars/angularjs/1.4.9/angular.js"></script> <script src="/webjars/angularjs/1.4.9/angular-route.js"></script> ... </body> </html> -
<!doctype html> <html lang="en" ng-app="app"> <body> <div ng-repeat="product in vm.featuredProducts">
<h2>{{ product.name }}</h2> <strong>{{ product.price | currency }}</strong> <button ng-click="vm.addToCart(product.id)">Add to Cart</button> <img ng-src="{{ product.imageUrl }}"/> </div> <script src="/webjars/angularjs/1.4.9/angular.js"></script> <script src="/webjars/angularjs/1.4.9/angular-route.js"></script> ... </body> </html> -
<!doctype html> <html lang="en" ng-app="app"> <body> <div ng-repeat="product in vm.featuredProducts">
<h2>{{ product.name }}</h2> <strong>{{ product.price | currency }}</strong> <button ng-click="vm.addToCart(product.id)">Add to Cart</button> <img ng-src="{{ product.imageUrl }}"/> </div> <script src="/webjars/angularjs/1.4.9/angular.js"></script> <script src="/webjars/angularjs/1.4.9/angular-route.js"></script> ... </body> </html> -
<!doctype html> <html lang="en" ng-app="app"> <body> <div ng-repeat="product in vm.featuredProducts">
<h2>{{ product.name }}</h2> <strong>{{ product.price | currency }}</strong> <button ng-click="vm.addToCart(product.id)">Add to Cart</button> <img ng-src="{{ product.imageUrl }}"/> </div> <script src="/webjars/angularjs/1.4.9/angular.js"></script> <script src="/webjars/angularjs/1.4.9/angular-route.js"></script> ... </body> </html> -
<!doctype html> <html lang="en" ng-app="app"> <body> <div ng-repeat="product in vm.featuredProducts">
<h2>{{ product.name }}</h2> <strong>{{ product.price | currency }}</strong> <button ng-click="vm.addToCart(product.id)">Add to Cart</button> <img ng-src="{{ product.imageUrl }}"/> </div> <script src="/webjars/angularjs/1.4.9/angular.js"></script> <script src="/webjars/angularjs/1.4.9/angular-route.js"></script> ... </body> </html> -
<!doctype html> <html lang="en" ng-app="app"> <body> <div ng-repeat="product in vm.featuredProducts">
<h2>{{ product.name }}</h2> <strong>{{ product.price | currency }}</strong> <button ng-click="vm.addToCart(product.id)">Add to Cart</button> <img ng-src="{{ product.imageUrl }}"/> </div> <script src="/webjars/angularjs/1.4.9/angular.js"></script> <script src="/webjars/angularjs/1.4.9/angular-route.js"></script> ... </body> </html> -
•Evaluated against a scope object •Evaluation is forgiving to undefined
and null •Filters can be used to format data before displaying it •No Control Flow Statements •No Function Declarations •No RegExp Creation With Literal Notation •No Object Creation With New Operator •No Bitwise, Comma, And Void Operators Versus JavaScript Expressions -
• Gareth Heyes (PortSwigger) • XSS without HTML: Client-Side Template
Injection with AngularJS • http://blog.portswigger.net/2016/01/xss-without- html-client-side-template.html Prior Research -
• Mikhail Egorov / Sergey Soldatov • ORM2Pwn: Exploiting Injections
in hibernate ORM • Zeronights 0x05 • New Methods for Exploiting ORM Injections in Java Applications • HITB 2016 (Later this May) Prior Research -
• Renaud Dubourguais • HQL : Hyperinsane Query Language •
Safety Symposium on Information and Communication Technologies (SSTIC) 2015 -
“Hibernate ORM (Hibernate in short) is an object-relational mapping framework
for the Java language. It provides a framework for mapping an object-oriented domain model to a relational database.” - Wikipedia -
“Hibernate's primary feature is mapping from Java classes to database
tables; and mapping from Java data types to SQL data types.” - Wikipedia -
public class Customer { private Long id; private String name;
private String accountId; public Long getId() { return id; } public void setId(Long id) { this.id = id; } … } id name account_id 1 acme acme_123 2 abc abc_789 3 xyz xyz_3843 -
String sql = "SELECT id, name, account_id FROM Customers WHERE
account_id = ?”; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString(1, “acme_123”); ResultSet rs = stmt.executeQuery(); Customer c = new Customer(); if (rs.next()) { long id = rs.getLong("id"); c.setId(id); String name = rs.getString("name"); c.setName(name); String accountId = rs.getString("account_id"); c.setAccountId(accountId); } -
String sql = "SELECT id, name, account_id FROM Customers WHERE
account_id = ?”; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString(1, “acme_123”); ResultSet rs = stmt.executeQuery(); Customer c = new Customer(); if (rs.next()) { long id = rs.getLong("id"); c.setId(id); String name = rs.getString("name"); c.setName(name); String accountId = rs.getString("account_id"); c.setAccountId(accountId); } -
String sql = "SELECT id, name, account_id FROM Customers WHERE
account_id = ?”; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString(1, “acme_123”); ResultSet rs = stmt.executeQuery(); Customer c = new Customer(); if (rs.next()) { long id = rs.getLong("id"); c.setId(id); String name = rs.getString("name"); c.setName(name); String accountId = rs.getString("account_id"); c.setAccountId(accountId); } -
String sql = "SELECT id, name, account_id FROM Customers WHERE
account_id = ?”; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString(1, “acme_123”); ResultSet rs = stmt.executeQuery(); Customer c = new Customer(); if (rs.next()) { long id = rs.getLong("id"); c.setId(id); String name = rs.getString("name"); c.setName(name); String accountId = rs.getString("account_id"); c.setAccountId(accountId); } -
String sql = "SELECT id, name, account_id FROM Customers WHERE
account_id = ?”; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString(1, “acme_123”); ResultSet rs = stmt.executeQuery(); Customer c = new Customer(); if (rs.next()) { long id = rs.getLong("id"); c.setId(id); String name = rs.getString("name"); c.setName(name); String accountId = rs.getString("account_id"); c.setAccountId(accountId); } -
String accountId = request.getParameter(“accountId”); String hql = "from Customer c
where c.accountId = :accountId”; Query query = session.createQuery(hql); query.setString("accountId", accountId); Customer c = (Customer) query.uniqueResult(); -
String accountId = request.getParameter(“accountId”); String hql = "from Customer c
where c.accountId = :accountId”; Query query = session.createQuery(hql); query.setString("accountId", accountId); Customer c = (Customer) query.uniqueResult(); -
String accountId = request.getParameter(“accountId”); String hql = "from Customer c
where c.accountId = :accountId”; Query query = session.createQuery(hql); query.setString("accountId", accountId); Customer c = (Customer) query.uniqueResult(); -
String accountId = request.getParameter(“accountId”); String hql = "from Customer c
where c.accountId = :accountId”; Query query = session.createQuery(hql); query.setString("accountId", accountId); Customer c = (Customer) query.uniqueResult(); -
String accountId = request.getParameter(“accountId”); String hql = "from Customer c
where c.accountId = :accountId”; Query query = session.createQuery(hql); query.setString("accountId", accountId); Customer c = (Customer) query.uniqueResult(); -
@Entity @Table(name=“customer”) public class Customer { @Id @GeneratedValue( strategy=GenerationType.IDENTITY )
private Long id; @Column( name=“name”, nullable=false ) private String name; @Column( name=“account_id”, nullable=false ) private String accountId; … } id name account_id 1 acme acme_123 2 abc abc_789 3 xyz xyz_3843 -
• Similar to SQL • Fully Object Oriented • Uses
mapped objects and their properties • More limited than SQL Hibernate Query Language -
from Customer c where c.accountId = ‘acme_123’ Mapped Object Object
Property Object Alias -
Can Still Be Vulnerable To Injection public List<Customer> findAllCustomersLike(String query)
{ Session session = getSession(); String hql = "from Customer c where c.name like '%" + query + “%'"; Query q = session.createQuery(hql); return (List<Customer>) q.list(); } -
Can Still Be Vulnerable To Injection public List<Customer> findAllCustomersLike(String query)
{ Session session = getSession(); String hql = "from Customer c where c.name like '%" + query + “%'"; Query q = session.createQuery(hql); return (List<Customer>) q.list(); } -
Let’s Fix Our Injection String hql = "from Customer c
where c.name like '%" + query + “%'"; -
Let’s Fix Our Injection String query = "' or 1=1
or ''='"; String hql = "from Customer c where c.name like '%" + query + “%'"; -
Let’s Fix Our Injection String hql = "from Customer c
where c.name like '%" + "' or 1=1 or ''='" + "%'"; -
Escaping HQL • In HQL the \ is a valid
character • In HQL to escape a ' we use ‘' • Can combine these to pass along our SQL Injection through HQL -
Success! • We can now continue along with a normal
SQL Injection • But… • SQL needs to be Valid • HQL needs to be Valid as well -
String hql = "from Customer c where c.name like '%"
+ query + "%'"; Injection Here -
select customer0_.id as id1_0_, customer0_.account_id as account_2_0_, customer0_.name as name3_0_
from customers customer0_ where ( customer0_.name like '%test' ) and '1\''=1 union select 1,database(),version()— '='1%' -
String accountId = request.getParameter(“accountId”); String hql = "from Customer c
where c.accountId = :accountId”; Query query = session.createQuery(hql); query.setString("accountId", accountId); Customer c = (Customer) query.uniqueResult(); -
• Look for calls to • createQuery • createSQLQuery •
All take HQL strings that could have potential for Injection.