gpt4 book ai didi

c - Semmle QL : TaintTracking hasFlow() Problem with Sources that taint their Arguments

转载 作者:太空狗 更新时间:2023-10-29 15:31:07 26 4
gpt4 key购买 nike

我想对使用用户输入污染其参数的函数进行 TaintTracking。示例:

fgets(buf, sizeof(buf), stdin); // buf is tainted
[...]
n = strlen(buf); // tainted argument to strlen
[...]
memcpy(somewhere, buf, n) // tainted call to memcpy

Semmle 应该能够通过如下所示的查询发现这一点(仅以 fgets->strlen 为例)。我从 SecurityOptions 借用代码:

import cpp
import semmle.code.cpp.dataflow.TaintTracking

class IsTaintedArg extends string {
IsTaintedArg() { this = "IsTaintedArg" }
predicate userInputArgument(FunctionCall functionCall, int arg) {
exists(string fname |
functionCall.getTarget().hasGlobalName(fname) and
exists(functionCall.getArgument(arg)) and (fname = "fgets" and arg = 0) // argument 0 of fgets is tainted
)
}

predicate isUserInput(Expr expr, string cause) {
exists(FunctionCall fc, int i |
this.userInputArgument(fc, i) and
expr = fc.getArgument(i) and
cause = fc.getTarget().getName()
)
}
}

class TaintedFormatConfig extends TaintTracking::Configuration {
TaintedFormatConfig() { this = "TaintedFormatConfig" }
override predicate isSource(DataFlow::Node source) {
exists (IsTaintedArg opts |
opts.isUserInput(source.asExpr(), _)
)
}
override predicate isSink(DataFlow::Node sink) {
exists (FunctionCall fc | sink.asExpr() = fc.getArgument(0) and fc.getTarget().hasName("strlen")) // give me all calls that land in strlen's first argument
}
}

from TaintedFormatConfig cfg, DataFlow::Node source, DataFlow::Node sink
where cfg.hasFlow(source, sink)
select sink, source

但它看起来并不正常。

但是,当我只查询 cfg.isSource()cfg.isSink() 时,source 和 sink 都会被识别。但是 hasFlow() 仍然没有返回任何内容 - 尽管路径肯定存在。

  • 我正在使用 libssh2 来测试我的发现,示例流程存在 here .

  • 我要测试的查询是 here .

有人知道我在上面的查询中可能做错了什么吗?

最佳答案

缺少的位在 isSource 中,其中污点跟踪从 fgets 的第 0 个参数开始。使用 asExpr 将描述从该参数 fgets 的流程。我们想要的是通过该参数的流出 fgets。您可以通过将 asExpr 替换为 asDefiningArgument 来获得它。

Here是指向您的查询结果的链接,我在 isSource 中同时使用了 asExprasDefiningArgument。这意味着如果您将来扩展 isUserInput,它的表达式将被视为来源,既作为它们的值,也作为输出参数。

新版查询有8个结果,有些只看source和sink很难理解,因为它们可以在不同的文件中。我制作了一个清理版本的查询

  • 生成源和汇之间的路径解释(@kind path-problem),
  • 删除辅助谓词的 IsTaintedArg 类包装,
  • 删除一些未使用的参数和检查,以及
  • 将调用添加到 asDefiningArgument

这是完整的查询:

/**
* @kind path-problem
* @id taint-to-strlen
*/
import cpp
import semmle.code.cpp.dataflow.DataFlow
import DataFlow::PathGraph

predicate userInputArgument(FunctionCall functionCall, int arg) {
functionCall.getTarget().hasGlobalName("fgets") and
arg = 0 // argument 0 of fgets is tainted
}

predicate isUserInput(Expr expr) {
exists(FunctionCall fc, int i |
userInputArgument(fc, i) and
expr = fc.getArgument(i)
)
}

class TaintedFormatConfig extends DataFlow::Configuration {
TaintedFormatConfig() { this = "TaintedFormatConfig" }
override predicate isSource(DataFlow::Node source) {
isUserInput(source.asExpr())
or
isUserInput(source.asDefiningArgument())
}
override predicate isSink(DataFlow::Node sink) {
exists (FunctionCall fc | sink.asExpr() = fc.getArgument(0) and fc.getTarget().hasName("strlen"))
}
}

from TaintedFormatConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink, source, sink, "Taint from fgets call in " + source.getNode().getFunction().getFile().getBaseName()

您可以在 https://lgtm.com/query/4800800615370766111/ 查看结果.

关于c - Semmle QL : TaintTracking hasFlow() Problem with Sources that taint their Arguments,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58164464/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com