go 代码审计去的一些其他漏洞
文件操作、路径穿越、重定向、CORS

一个go写的WEB漏洞靶场,实际自己写一下,加固一下知识

https://github.com/godzeo/go-gin-vul

GIN框架 整个web框架是go-gin-Example 上面改的,没有前端框架,只有一个swagger,直接发包吧

0x04 File Operation 文件操作

0x041 path traversing 路径穿越

在执行文件操作时,如果对从外部传入的文件名没有限制,则可能导致任意文件读取或任意文件写入,这可能严重导致代码执行。

0x0411 arbitrary file read 任意文件读

routers/api/unAuth/path.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func FileRead(c *gin.Context) {
path := c.Query("filename")

// Unfiltered file paths
data, _ := ioutil.ReadFile(path)

c.JSON(200, gin.H{
"success": "read: " + string(data),
})

}

func Dirfile(c *gin.Context) {
path := c.Query("filename")
data, _ := ioutil.ReadFile(filepath.Join("/Users/zy", path))

c.JSON(200, gin.H{
"success": "read: " + string(data),
})

}
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
GET /api/vul/read?filename=/../../../../../../../../../../etc/passwd HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1

GET /api/vul/dir?filename=/../../etc/passwd HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1


0x0412 arbitrary file write 任意文件写

routers/api/unAuth/path.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func Unzip(c *gin.Context) {
path := c.Query("filename")
text := c.Query("text")
file_path := filepath.Join("/Users/zy/", path)
r, _ := zip.OpenReader(file_path)

var abspath string
for _, f := range r.File {
abspath, _ = filepath.Abs(f.Name)
ioutil.WriteFile(abspath, []byte(text), 0640)
}

data, _ := ioutil.ReadFile(abspath)

c.JSON(200, gin.H{
"success": "read: " + string(data),
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
GET /api/vul/unzip?filename=radconfig.zip&text=Zeo666 HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1


0x0413 arbitrary file remove 任意文件删除

1
2
3
4
5
//arbitrary file remove
func Fileremove(c *gin.Context) {
path := c.Query("path")
os.Remove(path)
}

0x0414 FIX 修复

routers/api/unAuth/path.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
func Unzipsafe(c *gin.Context) {
path := c.Query("filename")
file_path := filepath.Join("/Users/zy/", path)
r, err := zip.OpenReader(file_path)
if err != nil {
fmt.Println("read zip file fail")
c.JSON(500, gin.H{
"success": "err: " + err.Error(),
})
}
for _, f := range r.File {
if !strings.Contains(f.Name, "..") {
p, _ := filepath.Abs(f.Name)
ioutil.WriteFile(p, []byte("present"), 0640)
} else {
c.JSON(500, gin.H{
"success": "err: " + err.Error(),
})
}
}
c.JSON(200, gin.H{
"success": "OK",
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
GET /api/safe/unzip?filename=../../radconfig.zip&text=Zeo666 HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1

HTTP/1.1 500 Internal Server Error
Content-Type: application/json; charset=utf-8
Date: Sat, 05 Nov 2022 08:04:40 GMT
Content-Length: 65
Connection: close

{"success":"err: open /radconfig.zip: no such file or directory"}

0x042 File access permissions 文件权限

根据创建文件的敏感度设置不同级别的访问权限,以防止具有任意权限的用户读取敏感数据。例如,将文件权限设置为: -rw-r -—-

1
ioutil.WriteFile(p, []byte("present"), 0640)
1
2
3
4
5
6
7
8
-rw------- (600)    只有拥有者有读写权限。
-rw------- (640) 只有拥有者和属组用户有读写权限。
-rw-r--r-- (644) 只有拥有者有读写权限;而属组用户和其他用户只有读权限。
-rwx------ (700) 只有拥有者有读、写、执行权限。
-rwxr-xr-x (755) 拥有者有读、写、执行权限;而属组用户和其他用户只有读、执行权限。
-rwx--x--x (711) 拥有者有读、写、执行权限;而属组用户和其他用户只有执行权限。
-rw-rw-rw- (666) 所有用户都有文件读、写权限。
-rwxrwxrwx (777) 所有用户都有读、写、执行权限。

0x05 Open Redirect 重定向

不要直接重定向到用户可控制的地址。

1
2
3
4
func redirect(c *gin.Context) {
loc := c.Query("redirect")
c.Redirect(302, loc)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
GET /api/vul/redirect?redirect=https://www.qq.com HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1


0x42 FIX 修复

1
2
3
4
5
func SafeRedirect(c *gin.Context) {
baseUrl := "https://baidu.com/path?q="
loc := c.Query("redirect")
c.Redirect(302, baseUrl+loc)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
GET /api/safe/redirect?redirect=https://www.qq.com HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1


0x05 CORS

CORS请求保护不当会导致敏感信息泄露,因此应严格设置Access-Control-Allow-Origin以使用同源策略进行保护。

任意源

1
2
3
4
5
6
7
func Cors1(c *gin.Context) {

c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
GET /api/vul/cors1 HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1

HTTP/1.1 200 OK
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin: *
Date: Sat, 05 Nov 2022 09:05:18 GMT
Content-Length: 0
Connection: close


任意添加源

1
2
3
4
5
6
7
func Cors2(c *gin.Context) {

origin := c.Request.Header.Get("Origin")
c.Header("Access-Control-Allow-Origin", origin)
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
GET /api/vul/cors2 HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Origin: zeo.cool

HTTP/1.1 200 OK
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin: zeo.cool
Date: Sat, 05 Nov 2022 09:06:33 GMT
Content-Length: 0
Connection: close

FIX 修复

直接白名单

code:

1
2
3
4
5
6
func corsDemo2(c *gin.Context) {
allowedOrigin := "https://test.com"

c.Header("Access-Control-Allow-Origin", allowedOrigin)
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
GET /api/safe/cors HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Origin: zeo.cool

HTTP/1.1 200 OK
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin: https://test.com
Date: Sat, 05 Nov 2022 09:09:53 GMT
Content-Length: 0
Connection: close