使用 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>