前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记一次开源工具某模块的基础二次开发

记一次开源工具某模块的基础二次开发

作者头像
FB客服
发布2019-11-26 18:08:07
5220
发布2019-11-26 18:08:07
举报
文章被收录于专栏:FreeBufFreeBufFreeBuf

近日看到一些关于工具的文章,很多人对于写工具类文章都是蜻蜓点水,写搭建,写基础使用,但是基础的开源工具在生产环境上的使用其实是比较困难的,有很多需要二次开发做到与生产环境适配,今天写这篇文章的目的就在于开启开源工具二次开发的思路,其中一个模块的二次开发很简单,大家基本都能看懂,就以这篇简单易懂的代码改动举例。本次开源工具二次开发以cobra代码审计为例。

适用范围:代码初学者、有一定python基础与协议基础

需求明确

首先要先明确自己的需求,我们的需求是在上线前做关联性代码审计,我采用的是cobra,至于为什么要使用cobra就不多说了,这是评估期间做的事情,文章主要写二次开发。

显示情况

我们的生产环境使用gitlab作为代码库,仅允许ssh方式下拉代码,而不允许http公开拉代码,这么做是为了安全,但是同样的也对cobra的使用造成了一定的麻烦。因为基础的cobra是没有ssh下拉功能的,需要我们自己做二次开发

代码改动

首先在原基础的cobra上我们做一个拉代码的测试

好像很叼的样子,没有漏洞,但是有层script提示没有选择目标

后台定位问题发现如下错误

一般出现这个问题不是分支错误就是路径错误,反正是找不到文件的,那直接用git clone试试原路径是否存在吧

500,询问了gitlab负责人才知道是根本没有开放http下拉代码的功能,统一使用ssh进行下拉。

那原基础的cobra能直接用ssh拉代码吗?试试看好了

提示请输入URL,也就是输入格式不对,那我们换一种方式输入

还是一样的提示,那看看后端是什么情况吧

一切正常。

首先对问题进行定位

命令为find ./ -name “*.py”|xargs grep “Please input a valid URL”

命令意思为在本级目录级下级目录搜索内容为Please input a valid URL的py脚本

找到了api.py,让我们进去看看这是什么

果然只限定了http与https,那根据咱们的需求加上ssh吧

原代码:

  if re.match(r'http://|https://', t):
                    arg = (t, formatter, output, rule, a_sid, is_del)
                    producer(task=arg)
                else:
                    return {"code": 1004, "msg": "Please input a valid URL"}
            result = {
                'msg': 'Add scan job successfully.',
                'sid': a_sid,
                'total_target_num': len(target),
            }
        else:
            if re.match(r'http://|https://', target):
                arg = (target, formatter, output, rule, a_sid, is_del)
                producer(task=arg)
            else:
                return {"code": 1004, "msg": "Please input a valid URL"}

改动后代码:

        if re.match(r'http://|https://|ssh://', t):
                    arg = (t, formatter, output, rule, a_sid, is_del)
                    producer(task=arg)
                else:
                    return {"code": 1004, "msg": "Please input a valid URL"}
            result = {
                'msg': 'Add scan job successfully.',
                'sid': a_sid,
                'total_target_num': len(target),
            }
        else:
            if re.match(r'http://|https://|ssh://', target):
                arg = (target, formatter, output, rule, a_sid, is_del)
                producer(task=arg)
            else:
                return {"code": 1004, "msg": "Please input a valid URL"}

重新试一下吧

后台提示需要输入root密码

我的环境是做了git@code.xxx的免密推送,root用户密码我不知道啊,就算有权限难道把密码写在配置文件里又安全吗?明文密码泄露的事情可是发生不少,于是继续看代码找问题

find ./ -name "*.py" |xargs grep "git clone"

看他的推送方式是什么

配置文件为./cobra/pickup.py

如果配置文件中没有输入用户名或密码,便是公开链接,直接clone,如果有用户名密码,则分割填入用户名和密码进行加密clone,如果这放在http协议中这个逻辑完全没有问题,但是放在ssh下拉代码里,就会存在很大的逻辑问题了

逻辑问题在于ssh的免密钥登录不需要密码,如果单纯以用户名密码作为判断依据那免密钥的作用就为零了,为了适配免密钥,实际上在代码中指定免密钥的用户即可,同时为保证其他基础功能不遭受破坏,增加的功能应使用判断前缀的方式进行代码改写,具体如下:

原代码:

         if self.repo_username is None or self.repo_password is None:
            # public repo
            clone_address = self.repo_address
        else:
            # private repo
            clone_address = self.repo_address.split('://')[0] + '://' + quote(self.repo_username) + ':' + \
                            quote(self.repo_password) + '@' + self.repo_address.split('://')[1]
        # clone repo with username and password
        
        # "http[s]://username:password@gitlab.com/username/reponame"
        # !!! if add password in the url, .git/config will log your url with password
        cmd = 'git clone ' + clone_address + ' "' + self.repo_directory + '" -b ' + self.repo_branch 

改后代码:

     if self.repo_username is None or self.repo_password is None:
            # public repo
            if (self.repo_address.split('://')[0] == 'ssh'):
                clone_address = 'ssh://' + 'git@' + \
                self.repo_address.split('://')[1]
            else:
            clone_address = self.repo_address
        else:
            # private repo
            if (self.repo_address.split('://')[0] == 'ssh'):
                clone_address = 'ssh://' + 'git@' + \
                self.repo_address.split('://')[1]
            else:
            clone_address = self.repo_address.split('://')[0] + '://' + quote(self.repo_username) + ':' + \
                            quote(self.repo_password) + '@' + self.repo_address.split('://')[1]
        # clone repo with username and password
        # "http[s]://username:password@gitlab.com/username/reponame"
        # !!! if add password in the url, .git/config will log your url with password
        cmd = 'git clone ' + clone_address + ' "' + self.repo_directory + '" -b ' + self.repo_branch

增加前缀判断,如果前缀为ssh,则统一使用通用用户git进行ssh登录代码拉取

进行测试

如此完成了一次很简单的模块二次开发。

二次开发重要是需求与实现,将自己的需求完整的实现出来即可,不一定是框架意义上的开发才算二次开发,一定要明白自己需要的是什么,代码逻辑是什么,掌握好代码逻辑,二次开发也不算是很难的事情。

*本文原创作者:煜阳yuyang,本文属于FreeBuf原创奖励计划,未经许可禁止转载

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeBuf 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求明确
  • 显示情况
  • 代码改动
  • 进行测试
相关产品与服务
代码审计
代码审计(Code Audit,CA)提供通过自动化分析工具和人工审查的组合审计方式,对程序源代码逐条进行检查、分析,发现其中的错误信息、安全隐患和规范性缺陷问题,以及由这些问题引发的安全漏洞,提供代码修订措施和建议。支持脚本类语言源码以及有内存控制类源码。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档