Skip to content

Latest commit

 

History

History
89 lines (67 loc) · 4.68 KB

代码注入.md

File metadata and controls

89 lines (67 loc) · 4.68 KB

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)
	}
}

cve-2018-6574

影响版本

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,如果存在,进一步判断是否调用外部可控的代码执行命令。

参考:https://github.com/he1m4n6a/Go_Security_Study/tree/master/%E7%BC%96%E7%A0%81%E5%AE%89%E5%85%A8/WEB%E5%AE%89%E5%85%A8#web