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/
相关推荐
情缘晓梦.2 小时前
Linux指令和权限
linux·运维·服务器
autho2 小时前
conda
linux·python·conda
Ydwlcloud2 小时前
个人博客与内容站部署在AWS:2026年的理性选择与更优策略
大数据·服务器·人工智能·云计算·aws
知乎的哥廷根数学学派2 小时前
基于注意力机制的多尺度脉冲神经网络旋转机械故障诊断(西储大学轴承数据,Pytorch)
人工智能·pytorch·python·深度学习·神经网络·机器学习
Stuomasi_xiaoxin2 小时前
记录一次Cursor remote ssh 代理连接失败问题,附解决方案!!!
运维·ssh
测试19982 小时前
用Postman测WebSocket接口
自动化测试·软件测试·python·websocket·测试工具·接口测试·postman
l1t2 小时前
数独优化求解C库tdoku-lib的使用
c语言·开发语言·python·算法·数独
柳鲲鹏2 小时前
断电重启和reboot,还是有很大差异
linux·运维·服务器
遇见火星2 小时前
部署DNS主从服务器
运维·服务器·dns·bind9