测试环境
NoSQL 注入漏洞
以 JavaScript 注入为例
JavaScript 注入是由允许执行数据内容中 JavaScript 的 NoSQL 数据库所引起的。JavaScript 使得在数据引擎进行复杂事务和查询成为可能。传递 “不干净的用户输入” 到这些查询中,便可以注入任意 JavaScript 代码,这将导致非法的数据获取或篡改。
在测试前,我们先了解一下 $where 操作符。在 MongoDB 中,$where 操作符可以用来执行 JavaScript 代码,将 JavaScript 表达式的字符串或 JavaScript 函数作为查询语句的一部分。
以下为靶场代码,漏洞位于第七行的 where 位置:
(此处有空行)
# mongo sql find
def mongo_find():
ser = request.args
if ser:
# ' || '' == '
sql_query = {"$where": "this.name == '%s'" % (ser.get('name', ''),)}
else:
return SerializerJsonResponse(None, 202, "params error")
client = dt_get_value("mongo_client")
db = client.test
db.drop_collection('user')
collection = db.user
user = {
"id": "10001",
"name": "Jordan",
"age": "20",
"gender": "male"
}
collection.insert_one(user)
u = collection.find_one(sql_query)
if u:
return SerializerJsonResponse(json.loads(json_util.dumps(u)))
else:
return SerializerJsonResponse(status=201, msg="no data")
复制代码
JavaScript 函数并不是编写 MongoDB 查询的可靠方法,除非绝对需要,否则强烈建议不要使用。eg:
db.users.find({ $where: "function(){return(this.username == 'a'; sleep(5000))}" })
复制代码
但在 IAST 检测中,无需构造特殊的 payload,只需正常访问 API,便可检测出漏洞。
直接进行 API 请求测试
检测结果显示,存在 NoSQL 注入漏洞:
修复建议
切勿在用户输入中使用 where,mapReduce 或 group 运算符,因为这些运算符使攻击者能够注入 JavaScript,因此比其他运算符相比危险性更高。为了加强安全性,可在 mongod.conf 设置 javascriptEnabled 为 false 。
LDAP 注入漏洞
LDAP 注入是在利用用户引入的参数生成恶意 LDAP 查询后,通过构造 LDAP 过滤器来绕过访问控制,提升用户权限。在维持正常过滤器的情况下构造出 AND、OR 操作注入来获取敏感信息。
常用应用场景
洞态 IAST hook 了 Python-ldap 和 ldap3 两个库中搜索的方法,以下为靶场的 ldap3 代码:
def ldap3_search():
username = request.args.get('username', '')
password = request.args.get('password', '')
ldap_srv = ldap3.Server("ldap://ldap:10389")
ldap_conn = ldap3.Connection(ldap_srv, user="cn=admin,dc=planetexpress,dc=com", password="GoodNewsEveryone",auto_bind=True)
search_filter = "(&(cn=%s)(userPassword=%s))" % (username, password)
exists = ldap_conn.search("dc=planetexpress,dc=com", search_filter)
if not exists:
return "403"
return "200"
复制代码
在 username 和 password 的位置增加特殊字符过滤:
from ldap3.utils.conv import escape_filter_chars as ldap3_escape_filter_chars
username = ldap3_escape_filter_chars(username)
password = ldap3_escape_filter_chars(password)
复制代码
使用 postman 进行测试:
返回 200 表示可以正常查出数据, 说明可以被注入。
Python-ldap 的使用方法:
def ldap_search():
username = request.args.get('username', '')
password = request.args.get('password', '')
ldap_srv = ldap.initialize("ldap://ldap:10389")
ldap_srv.simple_bind_s("cn=admin,dc=planetexpress,dc=com", "GoodNewsEveryone")
search_filter = "(&(cn=%s)(userPassword=%s))" % (username, password)
exists = ldap_srv.search_s("dc=planetexpress,dc=com", ldap.SCOPE_SUBTREE, search_filter)
if not exists:
return "403"
return "200"
复制代码
在 username 和 password 的位置增加特殊字符过滤:
from ldap.filter import escape_filter_chars as ldap_escape_filter_chars
username = ldap_escape_filter_chars(username)
password = ldap_escape_filter_chars(password)
复制代码
当前接口的测试方式和结果与 ldap3 一致,这里不做详细说明,可参考以上截图。
漏洞危害
修复建议
针对从外部获取的参数,增加特殊字符过滤,使用对应库的 escape_filter_chars 方法。
关于洞态 IAST
洞态 IAST 是全球首个开源 IAST,于 2021 年 9 月 1 日正式开源发布。洞态 IAST 专注于 DevSecOps,具备高检出率、低误报率、无脏数据的特点,帮助企业在应用上线前发现并解决安全风险。自开源发布以来,洞态 IAST 备受开源社区人员和企业的关注,包括工商银行、去哪儿、知乎、同程旅行、轻松筹等在内的近二百家企业均已成为洞态用户。
官网地址:http://dongtai.io
评论