Go 安全 Golang的一些简单漏洞测试 1azy_fish. 2023-10-17 2024-02-20 前言:Golang的一些简单漏洞测试,用于熟悉Golang
经典的整数反转/溢出问题 golang 存在非常经典的整数反转/溢出问题
对无符号数的反转
1 2 3 4 5 6 7 func main () { var a uint32 = 2147483648 var b uint32 = 2147483648 var sum = a + b fmt.Println(reflect.TypeOf(sum)) fmt.Printf("Sum is : %d" ,sum) }
想要直接声明一个大小已经溢出的数自然不会通过编译,因此出现反转的话,主要是在变量的相加这样的计算才会会导致标志CF位反转
有符号数的溢出
1 2 3 4 5 6 7 func main () { var a int8 = 127 var b int8 = 1 var sum int8 = a + b fmt.Println(reflect.TypeOf(sum)) fmt.Printf("Sum is : %d" ,sum) }
在math包的const.go包里面有以下定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 const ( MaxFloat32 = 0x1 p127 * (1 + (1 - 0x1 p-23 )) SmallestNonzeroFloat32 = 0x1 p-126 * 0x1 p-23 MaxFloat64 = 0x1 p1023 * (1 + (1 - 0x1 p-52 )) SmallestNonzeroFloat64 = 0x1 p-1022 * 0x1 p-52 ) const ( intSize = 32 << (^uint (0 ) >> 63 ) MaxInt = 1 <<(intSize-1 ) - 1 MinInt = -1 << (intSize - 1 ) MaxInt8 = 1 <<7 - 1 MinInt8 = -1 << 7 MaxInt16 = 1 <<15 - 1 MinInt16 = -1 << 15 MaxInt32 = 1 <<31 - 1 MinInt32 = -1 << 31 MaxInt64 = 1 <<63 - 1 MinInt64 = -1 << 63 MaxUint = 1 <<intSize - 1 MaxUint8 = 1 <<8 - 1 MaxUint16 = 1 <<16 - 1 MaxUint32 = 1 <<32 - 1 MaxUint64 = 1 <<64 - 1 )
而当进行类型转换时,从较大的整型向较小的整型转换可能会导致截断问题。这意味着较大整型的高位字节会被截断,只保留较小整型能表示的范围内的字节。
举例来说,在 Golang 中,将一个 int16
类型的变量 a
的值设为 256,然后将其转换为 int8
类型的变量 b
。由于 int8
类型只能表示 -128 到 127 之间的值,所以在转换时发生了截断。结果打印出的值为 0,因为高位字节被截断了。
类似的情况也可以在其他类型转换中出现。例如,在使用 strconv.Atoi
函数将字符串转换为整数时,如果目标类型是 int32
,而原始值超出了 int32
的表示范围,就会发生截断。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package mainimport ( "fmt" "math" ) func main () { var a int16 = 128 var b int8 = int8 (a) fmt.Println("Truncated value:" , b) var c int16 = 256 var d int8 if c > math.MaxInt8 { d = math.MaxInt8 } else if c < math.MinInt8 { d = math.MinInt8 } else { d = int8 (c) } fmt.Println("转换失败,返回:math.MaxInt8" , d) }
在Go 1.20之前的math/rand伪随机数的种子问题 原漏洞代码
1 var globalRand = New(&lockedSource{src: NewSource(1 ).(*rngSource)})
这个已经修复的东西,emmm
Golang的SSTI Golang SSTI(服务器端模板注入)是指在使用Golang编写的服务器端应用程序中,存在模板注入漏洞的情况。模板注入漏洞是一种安全漏洞,攻击者可以通过注入恶意模板代码来执行任意代码或获取敏感信息。
Golang提供了两个模板包,分别是text/template
和html/template
。其中,text/template
对XSS(跨站脚本攻击)或任何类型的HTML编码没有保护,因此不适合用于构建Web应用程序。而html/template
相对安全一些,它提供了HTML编码等安全保护,更适合用于构建Web应用程序。
在Golang的模板中,使用{{}}
来表示模板的动态内容,其中的操作称为pipeline。常用的基本语法包括:
{{.}}
:表示当前对象。{{.FieldName}}
:表示对象的某个字段。{{range ...}}{{end}}
:类似于Go语言中的for…range循环。{{with ...}}{{end}}
:表示当前对象的值,上下文。{{if ...}}{{else}}{{end}}
:类似于Go语言中的if-else条件选择。{{xxx | xxx}}
:表示将左边的输出作为右边的输入。{{template "navbar"}}
:引入子模板。当使用模板引擎时,需要注意安全性。在使用text/template
时,如果传入的参数可控,就有可能实现XSS攻击。而html/template
会对特殊字符进行转义,从而防止XSS攻击。
在Golang中,检测SSTI并不像发送{{7*7}}
并在源代码中检查结果是否为49那么简单。需要浏览文档以了解Go原生模板中的行为,最常见的是占位符.
,表示当前作用域的当前对象。
以下是一个示例代码,演示了Golang中的SSTI漏洞:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package mainimport ( "net/http" "text/template" ) type User struct { ID int Name string Email string Password string } func StringTpl2Exam (w http.ResponseWriter, r *http.Request) { user := &User{1 , "1azy_fish" , "test@example.com" , "*********" } r.ParseForm() tpl := `<h1>Hi, {{ .Name }}</h1><br>Your Email is {{ . }}` data := map [string ]string {"Name" : user.Name, "Email" : user.Email} html := template.Must(template.New("login" ).Parse(tpl)) html.Execute(w, data) } func main () { server := http.Server{Addr: "127.0.0.1:8888" } http.HandleFunc("/string" , StringTpl2Exam) server.ListenAndServe() }
在上述示例中,模板中的动态内容{{ . }}
会将整个数据对象打印出来,这样就可以检测是否存在SSTI漏洞。
访问得到