当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2014-059139

漏洞标题:小米路由器隐私盘功能可绕过访问控制

相关厂商:小米科技

漏洞作者: New4

提交时间:2014-05-01 22:48

修复时间:2014-07-27 22:50

公开时间:2014-07-27 22:50

漏洞类型:权限控制绕过

危害等级:中

自评Rank:5

漏洞状态:漏洞已经通知厂商但是厂商忽略漏洞

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-05-01: 细节已通知厂商并且等待厂商处理中
2014-05-06: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放
2014-06-30: 细节向核心白帽子及相关领域专家公开
2014-07-10: 细节向普通白帽子公开
2014-07-20: 细节向实习白帽子公开
2014-07-27: 细节向公众公开

简要描述:

小米隐私盘功能是基于MAC过滤+MD5的吧,MAC地址可以是伪造的吧?

详细说明:

看lua代码,明显访问控制是基于MAC过滤的,MAC不可信吧可以绕过的吧。而且隐私盘和共享盘也就一个目录之隔,如果有办法跨目录是不是很不安全了?
隐私盘都没有访问密码仅仅只是MAC过滤? 木有买路由 开发组自己测试去吧。
如果你们隐私盘设计初衷就这样,最好建议用户不要把太秘密的东西存储在上面要不很不安全。

漏洞证明:

没有路由器没有办法测试证明,你们测测把 MAC伪造应该不会太难。
Arp -a 命令一般就能找到本网段的其他机器的MAC地址,然后伪造下就可以访问了。

function download()
local fs = require("nixio.fs")
local mime = require("luci.http.protocol.mime")
local ltn12 = require("luci.ltn12")
local log = require("xiaoqiang.XQLog")

local path = LuciHttp.formvalue("path")
if XQFunction.isStrNil(path) then
LuciHttp.status(404, _("no Such file"))
return
end
local constPrefix1 = "/userdisk/data/"
local constPrefix2 = "/extdisks/"
local constPrefix3 = "/userdisk/privacyData/"
if (string.sub(path, 1, string.len(constPrefix1)) ~= constPrefix1) and (string.sub(path, 1, string.len(constPrefix2)) ~= constPrefix2) and (string.sub(path, 1, string.len(constPrefix3)) ~= constPrefix3) then
LuciHttp.status(403, _("no permission"))
return
end
-- check privacy disk permission by md5 device mac address
if string.sub(path, 1, string.len(constPrefix3)) == constPrefix3 then
local secret = LuciHttp.formvalue("secret")
if XQFunction.isStrNil(secret) then
LuciHttp.status(403, _("no permission"))
return
end
log.log(3, "=============secret = " .. secret)
local access = false
local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
local XQDeviceUtil = require("xiaoqiang.util.XQDeviceUtil")
local macfilterInfoList = XQDeviceUtil.getMacfilterInfoList()
for _,value in ipairs(macfilterInfoList) do
if XQFunction.isStrNil(value.mac) == false then
log.log(3, "=============mac = " .. value.mac)
if string.lower(XQCryptoUtil.md5Str(string.lower(value.mac))) == string.lower(secret) then
log.log(3, "=============device found")
if value.pridisk then
access = true
end
break
end
end
end
if access == false then
LuciHttp.status(403, _("no permission"))
return
end
end
log.log(3, "=============path = " .. path)
local stat = fs.stat(path)
if not stat then
LuciHttp.status(404, _("no Such file"))
return
end
LuciHttp.header("Accept-Ranges", "bytes")
LuciHttp.header("Content-Type", mime.to_mime(path))
local range = LuciHttp.getenv("HTTP_RANGE")
-- format: bytes=123-
if range then
LuciHttp.status(206)
range = string.gsub(range, "bytes=", "")
range = string.gsub(range, "-", "")
else
range = 0
end
log.log(3, "=============range = " .. range)
-- format: bytes 123-456/457
local contentRange = "bytes " .. range .. "-" .. (stat.size - 1) .. "/" .. stat.size
log.log(3, "=============contentRange = " .. contentRange)
LuciHttp.header("Content-Length", stat.size - range)
LuciHttp.header("Content-Range", contentRange)
LuciHttp.header("Content-Disposition", "attachment; filename=" .. fs.basename(path))
if string.sub(path, 1, string.len(constPrefix1)) == constPrefix1 then
LuciHttp.header("X-Accel-Redirect", string.gsub(path, constPrefix1, "/download-userdisk/"))
elseif string.sub(path, 1, string.len(constPrefix2)) == constPrefix2 then
LuciHttp.header("X-Accel-Redirect", string.gsub(path, constPrefix2, "/download-extdisks/"))
elseif string.sub(path, 1, string.len(constPrefix3)) == constPrefix3 then
LuciHttp.header("X-Accel-Redirect", string.gsub(path, constPrefix3, "/download-pridisk/"))
end
--local file = io.open(path, "r")
--local position = file:seek("set", range)
--log.log(3, "=============position = " .. position)
--ltn12.pump.all(ltn12.source.file(file), LuciHttp.write)
end


function getMacfilterInfoList()
local LuciUtil = require("luci.util")
local macFilterInfo = {}
local metaData = LuciUtil.execi("/usr/sbin/sysapi macfilter get")
for filterInfo in metaData do
filterInfo = filterInfo..";"
local mac = filterInfo:match('mac=(%S-);') or ""
local wan = filterInfo:match('wan=(%S-);') or ""
local lan = filterInfo:match('lan=(%S-);') or ""
local admin = filterInfo:match('admin=(%S-);') or ""
local pridisk = filterInfo:match('pridisk=(%S-);') or ""
local entry = {}
if (not XQFunction.isStrNil(mac)) then
entry["mac"] = XQFunction.macFormat(mac)
entry["wan"] = (string.upper(wan) == "YES" and true or false)
entry["lan"] = (string.upper(lan) == "YES" and true or false)
entry["admin"] = (string.upper(admin) == "YES" and true or false)
entry["pridisk"] = (string.upper(pridisk) == "YES" and true or false)
table.insert(macFilterInfo, entry)
end
end
return macFilterInfo
end

修复方案:

加个访问密码?隐私加密盘是不是也应该真加密?不应该形同虚设吧!

版权声明:转载请注明来源 New4@乌云


漏洞回应

厂商回应:

危害等级:无影响厂商忽略

忽略时间:2014-07-27 22:50

厂商回复:

最新状态:

暂无