Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Hibernate Blind SQLi MISC 2016

Hibernate Blind SQLi MISC 2016

This is a presentation I presented at the Minnesota Information Security Community (MISC) conference in St. Paul on May 15, 2016.

The demo application is located at https://github.com/caseydunham/hibernate-sandbox

Casey Dunham

May 15, 2016
Tweet

More Decks by Casey Dunham

Other Decks in Programming

Transcript

  1. Agenda • Introduction • Prior Research • Hibernate Overview •

    HQL Queries • Injection / Exploiting • Blind SQLi • Injection /Exploiting • Prevention • Q + A
  2. Introduction • Casey Dunham • Security Consultant for GuidePoint Security

    • Application Security • Code Reviews • Assessments • OWASP Maine • DC207 • TOOOL @CaseyDunham @GuidePointSec
  3. • 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
  4. • Renaud Dubourguais • HQL : Hyperinsane Query Language •

    Safety Symposium on Information and Communication Technologies (SSTIC) 2015
  5. “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
  6. “Hibernate's primary feature is mapping from Java classes to database

    tables; and mapping from Java data types to SQL data types.” - Wikipedia
  7. 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
  8. 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); }
  9. 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); }
  10. 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); }
  11. 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); }
  12. 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); }
  13. 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();
  14. 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();
  15. 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();
  16. 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();
  17. 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();
  18. @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
  19. • Similar to SQL • Fully Object Oriented • Uses

    mapped objects and their properties • More limited than SQL Hibernate Query Language
  20. 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(); }
  21. 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(); }
  22. Let’s Fix Our Injection String hql = "from Customer c

    where c.name like '%" + query + “%'";
  23. Let’s Fix Our Injection String query = "' or 1=1

    or ''='"; String hql = "from Customer c where c.name like '%" + query + “%'";
  24. Let’s Fix Our Injection String hql = "from Customer c

    where c.name like '%" + "' or 1=1 or ''='" + "%'";
  25. 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
  26. Success! • We can now continue along with a normal

    SQL Injection • But… • SQL needs to be Valid • HQL needs to be Valid as well
  27. 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%'
  28. 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();
  29. • Look for calls to • createQuery • createSQLQuery •

    All take HQL strings that could have potential for Injection.