codeql常用类型及函数积累(进阶)| 相关自写案例

2024-09-02 20:28

本文主要是介绍codeql常用类型及函数积累(进阶)| 相关自写案例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 前言
  • 一、函数
    • method.hasName("query")
    • method.getDeclaringType()
    • methodAccess.getQualifier
    • class.hasQualifiedName("com.mytest", "User")
  • 二、类型
    • ParamTag
    • MethodAccess
    • PrimitiveType
    • RefType
    • TopLevelType
    • NestedType
    • Call
  • 例子1
  • 例子2(spring提取注解参数名)
  • 例子3 (某堡垒机练手)

前言

写着写着,感觉这篇文章意义不是很大,更加推荐去看官方文档,例子和习题:
https://codeql.github.com/docs/codeql-language-guides/analyzing-data-flow-in-java/#examples
类型学习:
https://codeql.github.com/docs/codeql-language-guides/codeql-library-for-java/#types
各种类型漏洞使用codeql查询官方案例:
https://codeql.github.com/codeql-query-help/java/


本篇继续积累一些自己觉得重点的codeql用法和例子

一、函数

method.hasName(“query”)

用于判断一个方法的名称

method.hasName("query")

method.getDeclaringType()

表示获取一个方法所在的类或接口

import javapredicate isStudent(Method method) {
exists(|method.hasName("getStudent"))
}from Method method
where isStudent(method)
select method.getName(), method.getDeclaringType()

methodAccess.getQualifier

获取被调用方法,例如a.b(),那么methodAccess.getQualifier()获取的是a对象

methodAccess.getQualifier().getType() instanceof TypeString

class.hasQualifiedName(“com.mytest”, “User”)

检查是否是一个具有完全限定名称 com.mytest.User 的类。

二、类型

部分类型可翻阅如下文档:
https://codeql.github.com/docs/codeql-language-guides/codeql-library-for-java/#types

ParamTag

获取注释中的标签,例如param

import javafrom Callable c, ParamTag pt
where c.getDoc().getJavadoc() = pt.getParent()
select c, pt

MethodAccess

表示被调用的方法,例如:a.b(),那么这个b()就是被调用的方法

import javafrom Method method,MethodAccess call
where
call.getMethod() = method and
//.getCompilationUnit().fromSource()该条件指定了查询结果中的函数或方法必须来自源代码文件,而非库文件等其他来源。
method.getCompilationUnit().fromSource()
select method,call

PrimitiveType

PrimitiveType表示原始类型,PrimitiveType represents a primitive type, that is, one of boolean, byte, char, double, float, int, long, short; QL also classifies void and (the type of the null literal) as primitive types.

RefType

表示引用(其他对象),即非原始类型,例如:

Student stu //非原始类型
String str //原始类型

TopLevelType

TopLevelType表示在编译单元顶层声明的引用类型。

NestedType

NestedType是在另一个类型中声明的类型。

Call

指代被传递进入的参数,例如a(test),a即为call

例子1

查找new URL(param)这种形式的代码

import java
import semmle.code.java.dataflow.DataFlowfrom Constructor fileReader, Call call, Expr src
wherecall.getCallee() = fileReader andDataFlow::localFlow(DataFlow::exprNode(src), DataFlow::exprNode(call.getArgument(0))) andfileReader.getDeclaringType().hasQualifiedName("java.net","URL")
select call.getCallee(),call,src,fileReader

查找new URL(param)中的param参数

import java
import semmle.code.java.dataflow.DataFlowfrom Constructor fileReader, Call call, Parameter p
wherefileReader.getDeclaringType().hasQualifiedName("java.net", "URL") andcall.getCallee() = fileReader andDataFlow::localFlow(DataFlow::parameterNode(p), DataFlow::exprNode(call.getArgument(0)))
select p,call.getArgument(0)

例子2(spring提取注解参数名)

参考连接:https://tttang.com/archive/1512/

有如下例子:

(@RequestParam(required=true,value="id") String id)

1、getAnAnnotation获取注解
2、Annotation注解
3、hasQualifiedName
4、Expr表达式.getValue(“value”)例如:,则getValue(“value”)的值就是id

string getRequestParam(Method m){exists(Parameter p, Expr e, Annotation a | p = m.getAParameter()and a = p.getAnAnnotation()and a.getType().hasQualifiedName("org.springframework.web.bind.annotation", "RequestParam")and e = a.getValue("value")and e.getParent().toString() = "RequestParam"and e.toString() != "\"\""and result = e.toString())
}

例子3 (某堡垒机练手)

这是自己首次尝试构造出的第一个查询,构造过程中学到了很多:
在我参考:https://tttang.com/archive/1512/文章尝试定位注解的名称为RequestParam时,发现返回值居然为空(这可能是我构建数据库代码不全导致)

Annotation a
a.getType().hasQualifiedName("org.springframework.web.bind.annotation", "RequestParam")

解决办法:
通过getAQlClass来获取注解的类,判断其类名为:MetricElement
Annotation:注解

import javafrom Parameter p, Annotation a
wherea = p.getAnAnnotation() anda.getAQlClass().toString() = "MetricElement" 
select a

我主要想实现的功能是查找调用了sendMessageWithResponse的上级方法,全局数据流如下,但由于我分析的是闭源代码,效果不是很理想:

/*** @name Unsafe shiro deserialization* @kind problem* @id java/unsafe-deserialization*/
import java
import semmle.code.java.dataflow.DataFlow// TODO add previous class and predicate definitions hereclass ShiroUnsafeDeserializationConfig extends DataFlow::Configuration {ShiroUnsafeDeserializationConfig() { this = "ShiroUnsafeDeserializationConfig" }override predicate isSource(DataFlow::Node source) {exists(Annotation a,Parameter p |p.getAQlClass().toString().matches("MetricElement") anda = p.getAnAnnotation() andp.getCallable().hasModifier("public")//这里的p.getCallable()就是method)}predicate isDes(Expr arg){exists(MethodAccess des |des.getMethod().hasName("sendMessageWithResponse") andarg = des.getArgument(0))
}override predicate isSink(DataFlow::Node sink) {exists(Expr arg|isDes(arg))}
}from ShiroUnsafeDeserializationConfig config, DataFlow::Node source, DataFlow::Node sink
where config.hasFlow(source, sink)
select source,sink

本地数据流查询实现如下(不完善):

/*** @name Find public callers of sendMessageWithResponse and trace their callers* @description Recursively finds public methods that call sendMessageWithResponse and traces their callers.* @language java*/import javaclass SendMessageWithResponse extends MethodAccess {SendMessageWithResponse() {this.getMethod().hasName("sendMessageWithResponse")}}class PublicCallerOfSendMessage extends Method {PublicCallerOfSendMessage() {this.getDeclaringType().isPublic() andthis.fromSource() andexists(SendMessageWithResponse m |this.calls(m.getMethod()))}}predicate methodRecursivelyCalls(Method caller, Method callee) {caller = callee orexists(Method intermediate |caller.calls(intermediate) andmethodRecursivelyCalls(intermediate, callee))}class TopLevelCaller extends Method {TopLevelCaller() {this.getDeclaringType().isPublic() andthis.fromSource() andexists(Method m |methodRecursivelyCalls(this, m) andm instanceof PublicCallerOfSendMessage)}}from TopLevelCaller topLevelCallerselect topLevelCaller.getDeclaringType(), topLevelCaller

这篇关于codeql常用类型及函数积累(进阶)| 相关自写案例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1130983

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

sqlite3 相关知识

WAL 模式 VS 回滚模式 特性WAL 模式回滚模式(Rollback Journal)定义使用写前日志来记录变更。使用回滚日志来记录事务的所有修改。特点更高的并发性和性能;支持多读者和单写者。支持安全的事务回滚,但并发性较低。性能写入性能更好,尤其是读多写少的场景。写操作会造成较大的性能开销,尤其是在事务开始时。写入流程数据首先写入 WAL 文件,然后才从 WAL 刷新到主数据库。数据在开始

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象