0

使用 CodeQL 对以下代码执行污点分析。一个有风险的执行路径如下:从网络中读取数据,然后将读取的数据作为系统函数的参数。我的目的是找到所有这样的路径,但我只能找到level1的路径。

struct CliMsg {
    int fd;
    char msg[64];
};

void system_msg(struct CliMsg *cli_msg) {
    system(cli_msg->msg);
}

// level1
void handle_msg_level1(int client, char *buffer) {
    char msg[256];
    strncpy(msg, buffer, sizeof(msg));
    system(msg);
}

// level2
void handle_msg_level3(int client, char *buffer) {
    struct CliMsg *cli_msg = (struct CliMsg*)malloc(sizeof(struct CliMsg));
    cli_msg->fd = client;
    memset(cli_msg, 0, sizeof(cli_msg));
    strncpy(cli_msg->msg, buffer, sizeof(cli_msg->msg) - 1);
    system_msg(cli_msg);
    free(cli_msg);
}

// level3
void handle_msg_level2(int client, char *buffer) {
    struct CliMsg *cli_msg = (struct CliMsg*)malloc(sizeof(struct CliMsg));
    cli_msg->fd = client;
    memset(cli_msg, 0, sizeof(cli_msg));
    strncpy(cli_msg->msg, buffer, sizeof(cli_msg->msg) - 1);
    pthread_t handle_client_t;
    pthread_create(&handle_client_t, NULL, (void *)system_msg, cli_msg);
    pthread_join(handle_client_t, NULL);
    free(cli_msg);
}

void handle_client(int client) {
    char buffer[256];
    memset(buffer, 0, sizeof(buffer));
    recv(client, buffer, sizeof(buffer), 0);
    int level = buffer[0] - '1';
    switch (level) {
        case 1:
            handle_msg_level1(client, buffer + 1);
            break;
        case 2:
            handle_msg_level2(client, buffer + 1);
            break;
        case 3:
            break;
            handle_msg_level3(client, buffer + 1);
    }
}

我的 CodeQL 查询语句如下:

import cpp
import semmle.code.cpp.dataflow.TaintTracking
import DataFlow::PathGraph

class ReceivedBuffer extends Expr {
    ReceivedBuffer() { exists(FunctionCall caller | caller.getTarget().getName() = "recv" | caller.getArgument(1) = this)}
}

class SystemCmd extends Expr {
    SystemCmd() { exists(FunctionCall caller | caller.getTarget().getName() = "system" | caller.getArgument(0) = this)}
}

class Config extends TaintTracking::Configuration {
    Config() { this = "NetworkToSystem" }

    override predicate isSource(DataFlow::Node source) {
        source.asDefiningArgument() instanceof ReceivedBuffer
    }

    override predicate isSink(DataFlow::Node sink) {
        sink.asExpr() instanceof SystemCmd
    }
}

from Config cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select source, sink, "recv flows to system"

如何改进查询语句,以便找到level2和level3的路径?</p>

4

0 回答 0