Course Body
Environment Setup/Error Reporting: https://sts.tools/setup
NoSQLi: From Beginner To BSON Injection
Table Of Contents
- NoSQLi: From Beginner To BSON Injection
- Talk Scope
- What is NoSQL Injection (NoSQLi)?
- SQL Injection: Foundational Thinking
- SQL Vs NoSQL Injection (CONT.)
- SQL Vs NoSQL Injection (CONT.)
- Mongos NoSQLi Response
- Mongos NoSQLi Response (CONT)
- Mongos NoSQLi Response (CONT)
- BSON Injection
- BSON-RUBY Injection: Background
- BSON-RUBY Injection (CONT)
- Takeaways
Talk Scope
- What is NoSQL injection (NoSQLi)?
- How does NoSQLi compare to SQLi?
- Evaluate MongoDb's claim that "traditional SQL injection attacks are not a problem" in MongoDb
- Evaluate how MongoDb can be exploited through BSON injection
- Understand the execution contexts that queries are evaluated in (and how they can be exploited)
What is NoSQL Injection (NoSQLi)?
- Introduced when developers create dynamic database queries that include user supplied input
- Untrusted input
- Can contain the typical types: strings (code), ints (numbers), etc.
- NoSQLi can also contain query objects
- noSQLi MongoDB examples
- Focus due to popularity
SQL Injection: Foundational Thinking
Understanding the thought process behind SQLi will help us understand NoSQLi
- When
sqlStatement
is passed toquery()
as a string, what functionality does this inhibit?query()
has no way to scopeusername_value
tousername
- Problems?
- As
username_value
isn't scoped tousername
it can affect the meaning of other items that come after it
- As
SQL Vs NoSQL Injection (CONT.)
Resulting SQL
Typical MongoDb Equivalent
db.accounts.find({username: username_value, password: password_value});
SQL Vs NoSQL Injection (CONT.)
username_value
is scoped tousername
- Is this injectable?
- Mongo has a statement on this
Mongos NoSQLi Response
- MongoDB represents queries as BSON objects (Binary JSON)
"Typically client libraries provide a convenient, injection free, process to build these objects. Consider the following C++ example:"
// db.accounts.find({username: username_value}); BSONObj my_query = BSON( "username" << username_value ); auto_ptr<DBClientCursor> cursor = c.query("accounts", my_query);
- "As a client program assembles a query in MongoDB, it builds a BSON object, not a string. Thus traditional SQL injection attacks are not a problem"
- client program = client library
Mongos NoSQLi Response (CONT)
// db.accounts.find({username: username_value}); BSONObj my_query = BSON( "username" << username_value ); auto_ptr<DBClientCursor> cursor = c.query("accounts", my_query);
- "If
my_query
contained special characters, for example,
,:
, and{
, the query wouldn’t match any documents. For example, users cannot hijack a query and convert it to a delete."let username_value = "admin' -- "
- Special characters were used to alter the meaning of the SQL query
Mongos NoSQLi Response (CONT)
db.accounts.find({username: username_value, password: password_value});
- Mongo's statement about the lack of injection vulnerabilities assumes the input will be passed in a certain way
- What is the input assumption?
- String
- What is the input assumption?
BSON Injection
{"username": "admin"}
..snip..
\x02 // 0x02 = type String
username\x00 // field name
\x06\x00\x00\x00admin\x00 // field value
\x00 // 0x00 = type EOO ('end of object')
- How could a string potentially exploit this BSON object?
- Insert a BSON special character/delimiter:
0x00
- Similar idea to the
'
within'${username_value}'
- Similar idea to the
- Insert BSON directly
- Nested BSON object
- Insert hex/binary directly
- Insert garbage that isn't BSON and cause a DoS
- Insert a BSON special character/delimiter:
BSON-RUBY Injection: Background
- BSON-Ruby Background
- Mongoid is an Ruby ODM (Object-Document-Mapper) for MongoDB
- Leveraged a lower-level adapter called Moped
- Moped leveraged the BSON-Ruby library
- Leveraged a lower-level adapter called Moped
- Mongoid is an Ruby ODM (Object-Document-Mapper) for MongoDB
- Ruby Regex Background
\A
and\z
match the start and end of the string^
and$
match the start/end of a line$
matches a/n
- Other languages this matches the end of a string
- Issue in the wild with bson-ruby
BSON-RUBY Injection (CONT)
# Determine if the provided string is a legal object id (hex string)
def legal?(string)
string.to_s =~ /^[0-9a-f]{24}$/i ? true : false
end
end
How can this hex check be exploited?
Wonderful research from Egor Homakov
Takeaways
- Contrary to what organizations say, injection is always a risk when you take into account all contexts that a query is evaluated in
- Next module: "Hands On" NoSQLi exercise where you inject a query object
0 comments