上篇文章就丢了几个demo。太不认真了。这次认真讲一下
其实SDL的大部分漏洞在常规的黑白灰扫描器的逼近之下基本灭亡,仅存一个逻辑漏洞。逻辑漏洞里越权是最常见的,大家的常见方法也就是拿到流量去遍历里面可以遍历的一些内容,比如id,这种number是最容修改 然后就查看到别人的信息的。
这里我就拿一个简单的demo来描述下一般以阿里为例的微服务公司如何做到代码上检测越权漏洞:
首先是一个微服务的基本逻辑:
@RequestMapping(value = "/testRequest",method = RequestMethod.GET)
public ModelAndView selectUser(int id) throws IoException(
Long userId = Long.parseLong(string.valueOf(id));
User user = this.userService.selectUser(userId); //漏洞产生
ModelAndView mv = new ModelAndView() ;//返回视图
string name = user.getUsername();
String email = user.getEmail();
mv.addobject("name", name);
mv.addobject("email",email);
return mv;
把这个接口想象成一个微服务接口,已经通过网关暴露出去了。然后我们构造https://xxx.com/soa/appid-1110101/testRequest?id=111111
这个时候如果修改id就会看到别人的name和email返回。越权漏洞的本质还是因为传递过来的参数没有通过“用户中心服务”拿到索引。
一般来说,微服务公司都会有一个"用户微服务",这个微服务主要用来专门做用户体系认证和一些灵活度高的商业对接的鉴权,通常这个部门会有对应的sdk来解析一个request的唯一索引,例如uid。
而一个直接暴露的微服务的正确写法(我们假定这个用户微服务,以下简称serivce,的名字是getUidByRequest)应该是
@RequestMapping(value = "/testRequest",method = RequestMethod.GET)
public ModelAndView selectUser(dto request) throws IoException(
//Long userId = Long.parseLong(string.valueOf(id));
Long userID = this.userService.getUidByRequest(request); //漏洞产生
User user = this.userService.getUserbyUserId(userID);
ModelAndView mv = new ModelAndView() ;//返回视图
string name = user.getUsername();
String email = user.getEmail();
mv.addobject("name", name);
mv.addobject("email",email);
return mv;
对比下2个情况的差异不难看出来第一个没有经过userService.getUidByRequest方法而已。
那么就不难用codeQL写出这样的数据流规则了。
from RequestMapping rmapping, Method m, Parameter p, Call c, UserService us, DataFlow df1, DataFlow df2,cc Configuration
where rmapping.value = "/testRequest" and
rmapping.method = RequestMethod.GET and
rmapping.declaringType = m.declaringType and
m.hasAnnotation(rmapping) and
p.getParameter instance xxbox and //这里的xxbox就是那个remoteflowsource里去掉纯数字类型的那个总d
类
not cc.hasFlowPath(df1.sink = c and c.name.matches("_getUidByRequest_" and //这里用not,表达"不存在一条经过getUidByRequest的数据流"
df1.source = df2.sink) and
cc.hasFlowPath(df2.fromMethod = us.selectUser and
df1.source.kind = "PARAMETER" and
df1.source.name = "id")
select c, "越权查询"
很久没写codeql了,反正差不多这个意思。理解就行了
原文始发于微信公众号(xsser的博客):微服务下用静态代码扫描越权漏洞
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论