前言
Go 语言主要用作服务器端开发语言, 适合于很多程序员一起开发大型软件, 并且开发周期长, 支持云计算的网络服务. Go 语言能够让程序员快速开发, 并且在软件不断的增长过程中, 它能让程序员更容易地进行维护和修改. Go 语言是强类型语言, 它融合了传统编译型语言的高效性和脚本语言的易用性和富于表达性.
由于 Go 语言代码审计资料较少, 这里就把最近学习的对 Vulnerability-goapp 项目的审计过程分享一下. 整个审计过程结合代码安全扫描工具和人工审计, 期间也发现代码安全审计工具的漏报误报问题, 以下将会细述.
审计对象
经过在 GitHub 上查找, 发现 这个项目适合入门, 涵盖了常见的 go web 安全漏洞. Gitclone 之后在 goland IDE 里打开看到如下项目结构:
Asserts 目录是静态资源文件, 跳过.
Pkg 目录是使用 go 实现的业务逻辑代码, 重点关注.
Runenv 是数据库配置文件和生成数据库的脚本, 简单看下就好.
Trap 目录是一个 CSRF 漏洞的演示, 重点关注.
Views 目录是前端视图页面, 简单看下就好.
代码安全扫描
首先我们使用代码安全扫描工具扫描, 发现 4 类高危, 2 类中危漏洞, 我们分别进行验证.
命令注入 - 数据流分析
在 pkg/admin/admin.go 的 52 行发现命令注入, 直观可以看出取出 cookie 的内容拼接命令语句执行.
我们看一下污点跟踪过程:
我们通过污点跟踪分析过程可以确认这是一个高危漏洞.
接下来在实际环境中演示一下, 通过 nc 接收数据确认可执行 shell 命令.
不安全的传输 - 语义分析
在 main.go 的 156 行, 使用了 http 协议进行通信, 存在明文传输数据的问题
秘钥硬编码 - 代码结构分析
在 asserts/JS/Bootstrap.bundle.JS 文件的 360 行发现秘钥硬编码, 不过人工确认这里不是秘钥, 是工具的误报
用户隐私泄露 - 数据流分析
在 pkg/admin/admin.go 的 86 行检测到用户隐私泄露, 这里看到直接把用户输入的密码打印到控制台了, 是一种不安全的处理方式.
cookie 未启用 httponly - 代码结构分析
在 pkg/admin/admin.go 的 110 行检测到 cookie 未启用 httponly, 低危漏洞.
不安全的随机数 - 代码结构分析
在 asserts/JS/Bootstrap.bundle.JS 文件的 135 行发现使用了伪随机数, 不过这个漏洞可以忽略, 危害太小了.
人工代码审计
经过对代码扫描工具识别出的漏洞进行分析, 我们发现存在一些误报, 那么是否存在漏报呢, 毕竟我们工具的扫描规则只有 400 多条, 我们接下来通过人工分析代码发现可能存在的漏报
XSS - 数据流分析
在 pkg/post/post.go 里我们发现 Posts 结构体, 内有 Uids,UserPosts,Created_at,UserImages 结构体变量, 猜测这里跟论坛发帖有关, 我们人工进行一下污点数据跟踪分析:
通过 ShowAddPostPage 的 post 请求传入帖子内容写入数据库, 然后通过 ShowAddPostPage 的 get 请求读出数据库内容写入前端页面, 整个过程没有做特殊字符的净化处理, 可以确定这里存在存储 XSS 中危漏洞.
我们在实际环境演示一下漏洞:
输入 xss payload 保存后再次刷新页面触发 xss 弹框
反射 xss 低危漏洞分析过程类似, 不再重复描述.
Sql 注入 - 数据流分析
在 pkg/search/search.go 里我们发现 searchPosts 方法, sql 查询是直接拼接 sql 语句:
在拼接前并未对用户输入做净化处理, 因此可确认这是一个 sql 注入的高危漏洞.
我们在实际环境中演示一下这个问题:
Csrf - 代码结构分析
对于 CSRF 的分析我找了两处写数据库的接口进行尝试, 一个接口是存在 csrf, 一个接口不存在 csrf, 首先看修改密码的接口:
在 pkg/user/usermanager.go 里我们发现 ConfirmPasswdChange 方法, 不过这里进行了 referer() 的检查, 在实战中 referer 校验虽然不像加 token 那样可以完全避免 csrf, 但伪造 referer 成本较高, 所以这里不作为审计发现漏洞.
而在另一个更新用户个人信息的方法里却忽视了对 referer 的校验, 可以确认存在 csrf 漏洞.
我们在实际环境中进行演示确实存在 csrf 漏洞.
任意文件上传 - 数据流分析
在 pkg/image/imageUploader.go 里发现处理上传文件的方法, 没有对文件名和文件内容进行校验
可以上传任意文件, 不过由于 Web 路由的限制好像解析不了 go 语言代码, 解析静态资源文件是可以的, 这里尝试着目录穿越写文件到其他目录.
以下在实际环境中进行漏洞演示:
利用条件挺苛刻, 需要等着重启 crontab 服务, 加载定时任务
越权 - 数据流分析
以 pkg/user/usermanager.go 为例来看, 这里的功能是展示用户个人信息, 通过取出 cookie 里的 uid 在数据库进行查询得到用户基本信息, 在查询前有对 cookie 的有效性进行校验, 避免修改 cookie 实现水平越权.
CheckSessionId 里有一个 ValidateCorrectCookie 的方法校验 cookie
ValidateCorrectCookie 通过将用户输入的 cookie 和后台数据库存储的信息进行比对, 如发现 uid 被篡改就返回 404 页面.
经过在实际环境验证, 在读写操作数据库操作前使用 cookie.CheckSessionID() 对 cookie 做校验是不会存在越权问题, 而这个安全校验一旦去掉, 越权问题就出现了.
服务器敏感信息泄露 - 代码结构分析
数据库异常, go 的异常都有捕获在服务端打印 log, 没有向前端 Web 页面返回, Web 页面报错统一跳转自定义 404 页面, 服务器敏感信息泄露问题不存在.
如下是 main.go 里统一的记录 http 异常日志的代码:
不安全配置 - 配置文件分析
Web 路由配置正常, 没有引用不安全的第三方库.
资源泄露, 空指针分析 - 控制流分析
数据库, 文件等资源文件使用完成后及时释放, 未发现异常的控制流.
总结
本次审计经过语义分析, 数据流分析, 代码结构分析, 配置文件分析和控制流分析, 共审计 14 类常见安全漏洞, 发现存在 10 类漏洞, 另外 4 类漏洞确认不存在, 汇总信息如下:
目前代码安全扫描工具存在对 golang 的规则数量比较少, 存在漏报问题, 另外还有一定的误报, 仍有比较大的优化提升空间.
来源: http://www.tuicool.com/articles/JvAjAbb