测试环境
NoSQL 注入漏洞
以 JavaScript 注入为例
JavaScript 注入是由允许执行数据内容中 JavaScript 的 NoSQL 数据库所引起的。JavaScript 使得在数据引擎进行复杂事务和查询成为可能。传递 “不干净的用户输入” 到这些查询中,便可以注入任意 JavaScript 代码,这将导致非法的数据获取或篡改。
在测试前,我们先了解一下 $where 操作符。在 MongoDB 中,$where 操作符可以用来执行 JavaScript 代码,将 JavaScript 表达式的字符串或 JavaScript 函数作为查询语句的一部分。
以下为靶场代码,漏洞位于第七行的 where 位置:
 (此处有空行)# mongo sql finddef 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
评论