diff options
author | Bas Alberts <anticomputer@github.com> | 2020-04-02 17:14:49 -0400 |
---|---|---|
committer | Bas Alberts <anticomputer@github.com> | 2020-04-02 17:14:49 -0400 |
commit | fb863c6bfba2593c4bb64b94615ac2e15662aa18 (patch) | |
tree | 30d84aaaf452a72f7df2e35ffad039c2e950759d /.lgtm | |
parent | 56ca71bda9870e78ba0ee70fe226c4a4fcc36a04 (diff) |
ql query to identify suspicious use of network sourced integers
Diffstat (limited to '.lgtm')
-rw-r--r-- | .lgtm/cpp-queries/packet-payload-integer-arithmetic.ql | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/.lgtm/cpp-queries/packet-payload-integer-arithmetic.ql b/.lgtm/cpp-queries/packet-payload-integer-arithmetic.ql new file mode 100644 index 000000000..5940f602a --- /dev/null +++ b/.lgtm/cpp-queries/packet-payload-integer-arithmetic.ql @@ -0,0 +1,83 @@ +/** +* @name Suspicious packet->payload based integer arithmetic +* @description An arithmetic operation influenced array access is suspicious +* if it uses an integer value that is likely to be network-controlled, and +* may require a closer manual audit. +* @kind problem +* @problem.severity warning +* @id cpp/packet-payload-integer-arithmetic +* @tags audit security +*/ + +import cpp + +import semmle.code.cpp.dataflow.TaintTracking +import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis + +/** A source of an integer value that is likely to come from the network. + * This is produced by an invocation of a macro of the form `ntoh*` or `get_u_int*_t`, + * called with `packet->payload` as an argument. + */ + +class NetworkMacro extends Macro { + NetworkMacro() { this.getName().regexpMatch("^ntoh(ll|l|s)") } +} + +class NetworkIntegerSource extends Expr { + NetworkIntegerSource() { + exists(MacroInvocation mi | + this = mi.getExpr() and + mi.getUnexpandedArgument(0).regexpMatch(".*packet->payload.*") | + // catch all get_u_int*_t(x) + mi.getMacroName().regexpMatch("^get_u_int(64|32|16|8)_t") and + // dedup ntoh*(get_u_int*_t(x)) since we'll catch those in the next case + not mi.getOutermostMacroAccess().getMacro() instanceof NetworkMacro + or + // catch all ntoh*(x) ... this will also catch the nested cases + mi.getMacro() instanceof NetworkMacro + ) + } +} + +class ArithmeticOperation extends Operation { + ArithmeticOperation() { + this instanceof UnaryArithmeticOperation or this instanceof BinaryArithmeticOperation + } +} + +class NetworkToArrayAccess extends TaintTracking::Configuration { + NetworkToArrayAccess() { this = "NetworkToArrayAccess" } + + override predicate isSource(DataFlow::Node source) { + source.asExpr() instanceof NetworkIntegerSource + } + + override predicate isSink(DataFlow::Node sink) { + exists(ArrayExpr ae | sink.asExpr() = ae.getArrayOffset()) + } +} + +class NetworkToArithmetic extends TaintTracking::Configuration { + NetworkToArithmetic() { this = "NetworkToArithmetic" } + + override predicate isSource(DataFlow::Node source) { + source.asExpr() instanceof NetworkIntegerSource + } + + override predicate isSink(DataFlow::Node sink) { + exists (Assignment assign | + sink.asExpr() = assign.getRValue().(ArithmeticOperation) or + sink.asExpr() = assign.(AssignArithmeticOperation) + ) or + exists(LocalVariable var | + sink.asExpr() = var.getInitializer().getExpr().(ArithmeticOperation) + ) + } +} + +// find audit candidates based on suspicious network integer use +from NetworkIntegerSource source, Expr sink1, Expr sink2, NetworkToArithmetic config1, NetworkToArrayAccess config2 +where config1.hasFlow(DataFlow::exprNode(source), DataFlow::exprNode(sink1)) + // or this if you want integer arithmeric _OR_ array accesses + and config2.hasFlow(DataFlow::exprNode(source), DataFlow::exprNode(sink2)) +select source, "Suspicious use of network integer arithmetic." |