Skip to content

自定义规则

Chanzi-keji edited this page Oct 2, 2024 · 20 revisions

概述

  • 自定义规则采用 cyber查询语言,关于cyber语法可以参考neo4j的 cyber 语言官方手册

规则开发方法

  • 铲子SAST的规则主要用于对图数据库进行查询,可以查询单个节点或数据流作为漏洞
  • 在铲子中,变量都会被当作数据流节点,包括局部变量/方法定义的入参/方法调用的入参/类的成员变量,数据会在这些变量之前流动
  • 数据流规则通常是找到数据流的起点,即source点,和 数据流的终点,即sink点,然后查找source流到sink的路径
  • 查询数据流
  • 下面是一条内置数据流规则,用于识别ssrf漏洞
MATCH (sourceNode:DubboServiceArg|ThriftHandlerArg|SpringControllerArg|JspServiceArg|WebServletArg|WebXmlServletArg|WebXmlFilterArg|JaxrsArg|HttpHandlerArg)
MATCH
  (sinkNode)
  WHERE  'url' IN sinkNode.selectors OR
  'URL' IN sinkNode.selectors OR
  sinkNode.AllocationClassName = 'URL' OR
  sinkNode.AllocationClassName = 'GetMethod' OR
  'HttpGet' IN sinkNode.selectors OR
  ('execute' IN sinkNode.selectors AND   'CloseableHttpClient' IN  sinkNode.receiverTypes) OR
  ('execute' IN sinkNode.selectors AND   'CloseableHttpAsyncClient' IN  sinkNode.receiverTypes) OR
  ('connect' IN sinkNode.selectors AND   'Jsoup' IN  sinkNode.receiverTypes) OR
  ('create' IN sinkNode.selectors AND   'URI' IN  sinkNode.receiverTypes) OR
  ('read' IN sinkNode.selectors AND   'ImageIO' IN  sinkNode.receiverTypes) OR
  ('executeMethod' IN sinkNode.selectors AND   'HttpClient' IN  sinkNode.receiverTypes) OR
  ('Get' IN sinkNode.selectors AND   'Request' IN  sinkNode.receiverTypes) OR
  ('Post' IN sinkNode.selectors AND   'Request' IN  sinkNode.receiverTypes) OR
  ('exchange' IN sinkNode.selectors AND   'RestTemplate' IN  sinkNode.receiverTypes) OR
  ('get' IN sinkNode.selectors AND   'HttpUtil' IN  sinkNode.receiverTypes) OR
  ('post' IN sinkNode.selectors AND   'HttpUtil' IN  sinkNode.receiverTypes) OR
  'openConnection' IN sinkNode.receivers
MATCH
  p = (sourceNode)-[ *..30]->(sinkNode)
RETURN
  p AS path
  • 如何查询source点
  • 铲子自动识别了一些常见框架的请求入口,并打上标签,用户可以利用这些标签快速找到source点,比如下列标签:DubboServiceArg|ThriftHandlerArg|SpringControllerArg|JspServiceArg|WebServletArg|WebXmlServletArg|WebXmlFilterArg|JaxrsArg|HttpHandlerArg
  • 用户如果觉得这些标签不满足需求,也可以根据各种条件找到自己关心的source点,比如springmvc可以利用RequestMapping GetMapping等注解查找,比如下边这条规则就是用注解进行识别的source点
MATCH
  (sourceNode:Argument)
  WHERE
  'RequestMapping' IN sourceNode.methodAnnotations OR
  'GetMapping' IN sourceNode.methodAnnotations OR
  'PostMapping' IN sourceNode.methodAnnotations OR
  'DeleteMapping' IN sourceNode.methodAnnotations OR
  'PutMapping' IN sourceNode.methodAnnotations
MATCH
  (sinkNode)
  WHERE
  'queryForMap' IN sinkNode.selectors OR
  'queryForObject' IN sinkNode.selectors OR
  'queryForList' IN sinkNode.selectors OR
  'queryForRowSet' IN sinkNode.selectors OR
  'batchUpdate' IN sinkNode.selectors OR
  ('query' IN sinkNode.selectors AND   'JdbcTemplate' IN  sinkNode.receiverTypes)
MATCH
  p = (sourceNode)-[*..30]->(sinkNode)
RETURN
  p AS path
  • 如何查询sink点
  • 识别sink点通常可以使用方法调用时的方法名,方法所属对象的对象名,方法所属对象的类型名,构造方法的方法名等,也可以多个条件组合使用
  • 比如runtime.exec(cmd),这样一个调用,runtime是receiver exec是selector Runtime是receivertype ,我们就可以根据receiver receivertype selector等信息找到cmd作为sink点,规则如下:
MATCH
  (sourceNode:DubboServiceArg|ThriftHandlerArg|SpringControllerArg|JspServiceArg|WebServletArg|WebXmlServletArg|WebXmlFilterArg|JaxrsArg|HttpHandlerArg)

MATCH
  (sinkNode)
  WHERE
  ('exec' IN  sinkNode.selectors AND 'Runtime' IN  sinkNode.receiverTypes) OR
  sinkNode.AllocationClassName = 'ProcessBuilder' OR
  ('command' IN sinkNode.selectors AND 'ProcessBuilder' IN sinkNode.receiverTypes) OR
  ('eval' IN sinkNode.selectors AND 'ScriptEngine' IN sinkNode.receiverTypes) OR
  ('evaluate' IN sinkNode.selectors AND 'GroovyShell' IN sinkNode.receiverTypes)
MATCH
  p = (sourceNode)-[*..30]->(sinkNode)
RETURN
  p AS path
  • 查询单个节点
  • 单节点查询通常比较简单,直接通过节点的属性匹配即可
  • 下面是一条单节点规则,用于识别actuator配置不当
MATCH
  (sinkNode:YmlKeyValue|PropertiesKeyValue)
WHERE
sinkNode.name = 'management.endpoints.web.exposure.include' AND (sinkNode.value = '*' OR  sinkNode.value  CONTAINS 'heapdump' )
RETURN
  sinkNode AS path
  • 下面是一条单节点规则,用于识别fastjson版本问题
MATCH
  (sinkNode:PomDependency)
  WHERE
  sinkNode.groupId = 'com.alibaba' AND   sinkNode.artifactId = 'fastjson' AND   sinkNode.version < '1.2.83'
RETURN
  sinkNode AS path

Clone this wiki locally