• Semgrep结合GitLab实现代码审计实践-服务端


    一、背景

    前段时间在做代码审计,发现很多项目都存在安全隐患,大多数是来自于参数未过滤所造成的;为了解决这个问题,我将Web安全开发规范手册V1.0进行了培训,但是效果并不是太理想,原因是培训后开发者的关注点主要在功能完成度上,安全编码对于他们来说并不是核心指标;

    为了能让开发者时时刻刻关注安全问题,我在gitlab服务端放了一个钩子,这个钩子主要是将本次提交的代码文件进行了检测,遇到可能存在安全风险的问题将其输出出来,这样开发者能够对培训的内容有更深的感受,更注重编码时候的安全问题。

    二、操作步骤

    1. 搭建环境
    2. 创建项目
    3. 创建钩子
    4. 钩子实验

    三、搭建环境

    3.1 安装gitlab

    在正式部署到服务器之前,我需要在本地搭建一个gitlab服务,用于钩子的开发和测试,这里我用docker搭建速度比较快,执行的命令如下

    docker run --detach  --publish 443:443 --publish 80:80  --name gitlab --restart always  gitlab/gitlab-ce
    

    命令执行之后,返回的信息如下所示

    在上图中可以看到容器已经运行成功,使用浏览器访问gitlab的地址

    http://127.0.0.1
    

    访问之后需要设置一个管理员的密码,如下图所示

    填写密码之后,确认修改密码,会跳转到gitlab的主页,如下图所示

    这gitlab中创建一个项目用于钩子测试,如下图所示

    创建项目成功之后,注意留意页面中的Project ID:2,把这个2记录一下,后续会使用到;接下来需要开始钩子的开发和部署,钩子可以使用各种语言开发,这里我比较熟悉php,因此采用php开发。

    3.2 安装依赖

    gitlab的容器默认不支持php语言,需要先安装php,安装命令如下所示

    apt update -y && apt install php -y
    
    

    命令执行之后,返回的信息如下所示

    在上图中可以看到php已经安装成功,为了验证php命令是否可以运行,这里我使用如下命令进行验证

    php -v
    

    命令执行之后,返回的信息如下所示

    在上图中可以看到php的版本是7.4.3 ,说明php已经安装成功。

    3.3 安装semgrep

    钩子程序中需要调用semgrep,这个程序gitlab中也没有安装,需要安装一下,这里采用pip安装,不过需要先升级pip的版本才行,升级的命令如下所示

    pip3 install --upgrade pip
    

    命令执行之后,返回的信息如下所示

    在上图中可以看到pip的版本已经升级到21.1.2,说明升级成功了

    semgrep还依赖setuptools模块,需要用pip先升级一下,升级的命令如下所示

    pip3 install --upgrade setuptools
    

    命令执行之后,返回的信息如下所示

    在上图中可以看到setuptools模块已经升级成功

    接下来就可以正式安装semgrep了,安装的命令如下所示

    cd /usr/local/bin/ && python3 -m pip install semgrep
    

    命令执行之后,返回的信息如下所示

    在上图中可以看到semgrep已经安装完成,这里我需要再次使用semgrep命令来验证一下,执行的命令如下所示

    semgrep --version
    

    命令执行之后,返回的信息如下所示

    在上图中可以看到semgrep的版本信息为0.52.0,确认安装成功了。

    3.4 查看hash

    现在我们需要在刚才创建的项目中添加钩子,这里需要找到项目的存放路径,在项目页中

    echo -n 2 | sha256sum
    

    命令执行之后,返回的信息如下所示

    find / -iname d4
    

    命令执行之后,返回的信息如下所示

    在上图中可以看到项目存放的位置,返回了两个路径,这两个路径其中有一个是软连接,通过cd命令进入进入项目的存放位置

    cd /var/opt/gitlab/git-data/repositories/@hashed/d4
    

    命令执行之后,再次执行ls命令,得到的信息如下所示

    在上图中可以看到有一个73的文件夹,这是gitlab的命名规则,进入此文件夹,命令如下所示

    cd 73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git/
    

    命令执行之后,返回的信息如下所示

    在上图中可以看到此项目的所有文件,我需要在这个位置开发钩子文件

    五、创建钩子

    自定义钩子需要存放在custom_hooks目录下,默认没有此文件夹所以需要创建此文件夹,执行命令如下所示

    mkdir custom_hooks  && cd custom_hooks
    

    5.1 新建钩子

    创建custom_hooks文件夹并进入之后,使用vim创建一个钩子文件,命令如下所示

    vim  pre-receive
    

    进入vim编辑器界面之后,将如下钩子代码添加进去,代码如下所示

    #!/usr/bin/php
    <?php
    
    
    fwrite(STDOUT, 'please input:');
    list($oldVer, $newVer, $ref_name) = explode(" ", fgets(STDIN));
    
    //ob_start();
    $cmd = "git diff --name-only  {$oldVer}..{$newVer}";
    echo $cmd . PHP_EOL;
    exec($cmd, $result);
    
    $rand = date("Y-m-d-H-i-s");
    $baseDir = "/tmp/11/$rand/";
    $ruleFile = "/semgrep-rule.yaml";
    
    
    
    
    foreach ($result as $value) {
        if (strstr($value, ".php") !== false) {
            $randName = $baseDir . $value;
            if (!is_dir(dirname($randName))) {
    #        if (file_exists($randName) == false) {
                mkdir(dirname($randName), 0777, true);
            }
            $cmd = "git show {$newVer}:$value > $randName";
    
    #        echo $cmd . PHP_EOL;
    
    
            exec($cmd, $result);
        }
    }
    
    
    $cmd = "/opt/gitlab/embedded/bin/semgrep  -f '$ruleFile' $baseDir  -o /tmp/11.txt";
    
    exec($cmd, $result);
    
    
    //ob_clean();
    
    
    $notice = file_get_contents("/tmp/11.txt");
    echo $notice . PHP_EOL;
    
    
    file_put_contents("/tmp/11.txt", "");
    exec("rm -rf $baseDir");
    
    echo 0;
    

    保存并推出此钩子文件,接着需要给自定义钩子目录设置权限,这里我简单粗暴的把权限设置为777,命令如下所示

    chmod -R 777 ../
    

    权限设置好之后,我还需要创建一个semgrep的扫描规则文件,用于判断代码是否正确。

    执行的命令如下所示

    vim /semgrep-rule.yaml 
    

    进入vim编辑器之后,需要将如下规则内容复制进去

    rules:
      - id: assert-use
        patterns:
          - pattern: assert($ASSERT, ...);
          # - pattern-not: assert(<... $ASSERT ...>, ...); - https://github.com/returntocorp/semgrep/issues/2035
          - pattern-not: assert("...", ...);
        message: |
          使用用户输入调用assert等价于eval'。
        metadata:
          references:
            - https://www.php.net/manual/en/function.assert
            - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/AssertsSniff.php
        languages: [ php ]
        severity: ERROR
    
      - id: backticks-use
        pattern: '`...`;'
        message: |
          使用反勾号可能导致命令注入漏洞。
        metadata:
          references:
            - https://www.php.net/manual/en/language.operators.execution.php
            - https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/Security/Sniffs/BadFunctions/BackticksSniff.php
        languages: [ php ]
        severity: ERROR
    

    保存并推出规则文件后,需要修改此规则文件的权限,这里我以777权限距离,命令如下所示

    chmod 777 /semgrep-rule.yaml
    

    设置完规则文件权限之后,还有两个缓存地方需要设置权限,否则会在运行过程当中报错,首先是semgrep的缓存文件,设置权限命令如下

    mkdir -p /var/opt/gitlab/.cache  && chmod -R 777 /var/opt/gitlab/.cache
    

    另外一处是钩子本身的缓存文件,同样需要设置权限,执行的命令如下所示

    echo '' > /tmp/11.txt  && chmod 777 /tmp/11.txt
    

    5.2 测试钩子

    现在可以正式测试钩子的可用性,首先需要拉取刚才创建的项目代码,命令如下所示

    git clone http://127.0.0.1/root/test.git
    

    执行命令之后,返回的信息如下所示

    在上图中可以看到项目已经拉取下来,接下来我需要编辑一个php文件,命令如下所示

    vim index.php
    

    命令执行完毕之后,将测试的代码存放进去

    <?php
    
    phpinfo();
    
    
    $cmd = "ls {$_GET['x']}";
    
    exec($cmd);
    

    保存并退出之后,将代码提交到gitlab中去,命令如下所示

    echo ' ' >> index.php && git add . && git commit . -m 'init' && git push
    

    但git往gitlab服务器推送之后,gitlab就会调用钩子,并将钩子返回的信息输出出来,如下图所示

    在上图中可以看到钩子提示了 index.php文件第8行不安全,此致整个部署完毕。


    作者:汤青松

    日期:2021-06-03

    微信:songboy8888

  • 相关阅读:
    判断平面的一堆点是否在两条直线上
    约数的个数 + 贪心
    划分树板子
    如何获取前端提交来得json格式数据
    post 和php://input 转
    使用Guzzle执行HTTP请求
    redis集群搭建 不用ruby
    systemctl命令
    canal 配置 多个监听 推送到不同mq
    canal 整合RabbitMQ
  • 原文地址:https://www.cnblogs.com/tangqingsong/p/14845844.html
Copyright © 2020-2023  润新知