Joern服务器启动后cpgqls-client结合python编程进行扫描

关键词:SAST,静态代码分析,漏洞分析

1. 引入

本想使用python-joern(参考1)进行测试,发现pip在python3.9、3.11都无法安装了,再看了一下python-joern的github(参考2),发现这个库已经是2016年就停止维护了。

后来找到官网中(参考3)使用cpgqls-client也可以做到通过python编程,连接joern server后进行扫描。这种方式也能实现自动化,本文记录该方法的测试过程。

2. 具体过程

  1. 安装Joern,参考5,本文在ubuntu22.04下进行
shell 复制代码
wget https://github.com/joernio/joern/releases/latest/download/joern-install.sh
chmod +x ./joern-install.sh
sudo ./joern-install.sh

注意,如果网速慢,需要打开joern-install.sh,对其中curl命令加proxy(curl -x "http:xxxxyyyzzzeeeddd")。

本文使用的joern版本为Version: 4.0.388。

  1. 将如下有有缺陷的c语言代码保存为 /home/aaa/a.c

这段代码为doubao生成:

c 复制代码
#include <stdio.h>
#include <stdlib.h>

// 计算两个整数的和
int add(int a, int b) {
    return a + b;
}

// 打印欢迎信息
void greet(const char* name) {
    printf("Hello, %s!\n", name);
}

// 潜在的空指针解引用
void unsafe_operation() {
    int* ptr = NULL;
    *ptr = 42; // 危险:空指针解引用
}

// 可能安全的内存操作
void safe_operation(size_t size) {
    int* arr = (int*)malloc(size * sizeof(int));
    if (arr != NULL) {
        *arr = 100; // 安全
        free(arr);
    }
}

int main() {
    int result = add(3, 5);
    printf("3 + 5 = %d\n", result);
    
    greet("World");
    
    // 注释掉危险操作,实际测试时可取消注释
    unsafe_operation();
    
    safe_operation(10);
    
    // 潜在的空指针解引用(没有检查malloc返回值)
    int* data = (int*)malloc(5 * sizeof(int));
    *data = 200; // 潜在危险:如果malloc失败,data为空指针
    free(data);
    
    return 0;
}
  1. 启动joern server
shell 复制代码
joern --server --server-port 9000

在9000启动server。具体命令参数用法可参考 joern --help 输出。

  1. python编程调用cpgqls_client

在同一台服务器上,运行如下代码,注意代码路径要设置为绝对路径。

这段代码为doubao生成,多次实验、修复报错后,最终能在python3.9下成功运行:

python 复制代码
from cpgqls_client import CPGQLSClient, import_code_query
import re

server = "localhost:9000"
client = CPGQLSClient(server)

# 导入代码
import_query = import_code_query("/home/aaa/", "my-c-project")
import_result = client.execute(import_query)
print("代码导入结果:", import_result)

# 函数列表
functions = client.execute("""
cpg.method.filter(!_.isExternal).name.l
""")
print("\n函数:", re.findall(r'"([^"]+)"', functions.get("stdout", "")))

# printf格式化字符串
printf = client.execute("""
cpg.call.name("printf").argument(1).code.l
""")
print("\nprintf格式化字符串:", re.findall(r'"([^"]+)"', printf.get("stdout", "")))

# 空指针解引用(修复转义)
null_deref = client.execute(r"""
cpg.call.name("malloc").argument(1).inAssignment.lhs.typeFullName(".*\\*").outE("REF").inNode.code(".*\\*.*").code.l
""")
print("\n空指针解引用:", re.findall(r'"([^"]+)"', null_deref.get("stdout", "")))

这段代码,分别运行了3条CPGQL语句,并输出其结果。

  1. 运行python代码后的输出结果

    代码导入结果: {'success': True, 'uuid': '63b7b98c-1300-44af-b105-4c9ef5b2fe2c', 'stdout': '\x1b[33mval\x1b[0m \x1b[36mres36\x1b[0m: io.shiftleft.codepraph[208 nodes]]\n'}

    函数: ['add', '<global>', 'greet', 'unsafe_operation', 'safe_operation', 'main', '<global>']

    printf格式化字符串: ['Hello, %s!\n', ', ', '3 + 5 = %d\n']

    空指针解引用: ['malloc', '.\\', 'REF', '.\\.*']

结果可以对照C语言代码进行理解。

3. 总结

用joern命令启动server后,就能在python编程中,调用cpgqls-client的接口,对代码使用CPGQL扫描,并输出结果。

4. 参考

  1. python-joern文档。https://joern.readthedocs.io/en/latest/access.html
  2. https://github.com/octopus-platform/joern/tree/master
  3. cpgqls-client。https://joern.io/integrate/
  4. joern官方查询语句说明,https://queries.joern.io/
  5. 深入浅出Joern(一)Joern与CPG是什么,https://lorexxar.cn/2023/08/21/joern-and-cpg/
相关推荐
sdm07042714 分钟前
yum和开发工具vim/gcc
linux·服务器·centos
zhaoyufei13314 分钟前
RK3568-11.0 设置WiFi p2p静态IP
服务器·tcp/ip·p2p
zm-v-1593043398618 分钟前
Python 数据挖掘从入门到精通:回归 / 分类 / 聚类 / 关联分析完整教程
python·数据挖掘·回归
Leinwin5 小时前
OpenClaw 多 Agent 协作框架的并发限制与企业化规避方案痛点直击
java·运维·数据库
2401_865382506 小时前
信息化项目运维与运营的区别
运维·运营·信息化项目·政务信息化
qq_417695056 小时前
机器学习与人工智能
jvm·数据库·python
漫随流水6 小时前
旅游推荐系统(view.py)
前端·数据库·python·旅游
漠北的哈士奇6 小时前
VMware Workstation导入ova文件时出现闪退但是没有报错信息
运维·vmware·虚拟机·闪退·ova
如意.7596 小时前
【Linux开发工具实战】Git、GDB与CGDB从入门到精通
linux·运维·git
运维小欣6 小时前
智能体选型实战指南
运维·人工智能