44
55> [ GitHub - Hardw01f/Vulnerability-goapp: Web application build Golang with Vulnerability] ( https://github.com/Hardw01f/Vulnerability-goapp )
66
7- 这里能看到执行命令的`` exec.Command`,命令通过拼接传入,所以可以利用管道符,把命令拼在后面。
7+ 这里能看到执行命令的` exec.Command ` ,命令通过拼接传入,所以可以利用管道符,把命令拼在后面。
88
99![ image-20240923104010179] ( img/GoVul/image-20240923104010179.png )
1010
@@ -45,7 +45,7 @@ sec-ch-ua-platform: "Windows"
4545
4646> [ GitHub - Hardw01f/Vulnerability-goapp: Web application build Golang with Vulnerability] ( https://github.com/Hardw01f/Vulnerability-goapp )
4747
48- ` pkg/image/imageUploader.go ` ,这里保存文件,路径是拼接的,且没有检验
48+ ` pkg/image/imageUploader.go ` ,这里保存文件,路径是拼接的,且没有检验后缀
4949
5050![ image-20240923160617852] ( img/GoVul/image-20240923160617852.png )
5151
@@ -85,6 +85,20 @@ go版本太高就无法复现了,也没查到具体哪个版本更新的,靶
8585
8686> [ GitHub - Hardw01f/Vulnerability-goapp: Web application build Golang with Vulnerability] ( https://github.com/Hardw01f/Vulnerability-goapp )
8787
88+ 这个项目在从cookie中获取uid之前,做了一步对cookie的有效性进行校验
89+
90+ ![ image-20240924152332293] ( img/GoVul/image-20240924152332293.png )
91+
92+ ` CheckSessionID ` 里有一个` ValidateCorrectCookie ` 的方法校验cookie
93+
94+ ![ image-20240924152633020] ( img/GoVul/image-20240924152633020.png )
95+
96+ ValidateCorrectCookie通过将用户输入的cookie和后台数据库存储的信息进行比对
97+
98+ ![ image-20240924152755689] ( img/GoVul/image-20240924152755689.png )
99+
100+ 这样就可以避免越权
101+
88102
89103
90104## 整数反转/溢出
@@ -167,9 +181,7 @@ func NewSource(seed int64) Source {
167181
168182
169183
170- ## net/http
171-
172- ### net/http < 1.11 CRLF注入
184+ ## net/http < 1.11 CRLF注入
173185
174186在HTTP协议中,HTTP header之间是由一个CRLF字符序列分隔开的,HTTP Header与Body是用两个CRLF分隔的,浏览器根据这两个CRLF来取出HTTP内容并显示出来。所以如果用户的输入在HTTP返回包的Header处回显,便可以通过CRLF来提前结束响应头,在响应内容处注入攻击脚本。因此CRLF Injection又叫HTTP响应拆分/截断(HTTP Response Splitting)简称HRS。
175187
@@ -183,7 +195,7 @@ Date:Fri,26Jun 2018 17:00:05 GMT
183195Content-type:text/html
184196Contet-Length:155
185197Connection:close
186- Location: http://www.sinay.com.cn
198+ ? Location= http://www.sinay.com.cn%0d%0aSet-Cookie:JSPSESSID%3Dhackingsite
187199
188200```
189201
@@ -211,31 +223,6 @@ Set-Cookie:JSPSESSID=hackingsite
211223
212224现在会看到存在限制,我们无法传入` \r\n ` 的字符
213225
214-
215-
216- ### weird stuff
217-
218- 在之前的[ justCTF] ( https://ctftime.org/event/1050 ) 中,出现了一道go题。题目原本的漏洞是由出题人发现的一个issuehttps://github.com/golang/go/issues/40940 加上其对fileServer一些代码的魔改组合的。
219-
220- 简单陈述下的话,题目提供了一个go http起的FileServer
221-
222- ```
223- http.Handle("/", http.FileServer(http.Dir("/tmp")))
224- ```
225-
226- flag就在其提供文件服务的文件夹下,但是,出题人加上了web服务的flag路由,从而使得我们没法通过直接访问` /flag ` 来获取文件。而是得到` /flag ` 路由的回显。
227-
228- http的` Fileserver ` 在我们访问时,会先根据我们访问的url进行一系列处理,杜绝路径穿越的url之后进行文件读取返回给用户
229-
230- 但是比较有意思的时,比赛中出现了一个非预期读flag的方式
231- ` curl --path-as-is -X CONNECT http://gofs.web.jctf.pro/../flag `
232-
233- 简单说就是用CONNECT请求+路径穿越的url读取到了文件。我们看看源码是怎么处理的
234- ![ img] ( img/GoVul/upload_f9abcabe3b0a17bac5f8e41a586d74ab.png )
235- 如果是CONNECT方式请求,就不会处理url中的特殊字符。导致直接读取flag.其他的请求方法都会在` cleanPath ` 中被处理url
236-
237- golang1.16处理了这个我问题。
238-
239226## slice
240227
241228```
@@ -272,20 +259,24 @@ type slice struct {
272259slice结构中的cap是按2的倍数扩容的。所以说当我们` append(3) ` 时会发生第一次扩容,此时len为3,cap为` 2*2=4 ` .
273260执行` b := append(a, 4) ` 时,我们的4会被放在指针ptr的第四个位置。然后返回ptr len=4 cap=4给b。不过这并没有改变a的结构(slice只是指向内存的指针)之后进行` c := append(a, 5) ` 时,由于a没变,新元素只会覆盖之前b那放上的4.
274261
262+ ` b := append(a, 4) ` 语句将元素 4 追加到切片 ` a ` 中,并将返回的新切片赋值给 ` b ` 。同样,` c := append(a, 5) ` 语句也将元素 5 追加到切片 ` a ` 中,并将返回的新切片赋值给 ` c ` 。
263+
264+ 由于 ` b ` 和 ` c ` 都是通过向切片 ` a ` 追加元素生成的,它们实际上共享相同的底层数组。因此,向 ` a ` 中追加元素 4 或 5 会影响到 ` b ` 和 ` c ` ,因为它们都指向相同的底层数组。
265+
275266## 目录遍历
276267
277268```
278269filepath.Join()
279270filepath.Clean()
280271```
281272
282- ` Join ` 将任意数量的路径元素合并成一个单一的路径,并用操作系统特定的分隔符进行分隔。先对路径做一些` Clean() ` 处理,但不能完全避免路径目录遍历
273+ ` Join ` 将任意数量的路径元素合并成一个单一的路径,并用操作系统特定的分隔符进行分隔。先对路径做一些` Clean() ` 处理,但不能避免目录遍历
283274
284275![ image-20240923223106640] ( ./img/GoVul/image-20240923223106640.png )
285276
286- 我们看如下测试代码来验证我们的猜想 :
277+ 测试代码 :
287278
288- ```
279+ ``` go
289280package main
290281
291282import (
@@ -313,7 +304,7 @@ func main() {
313304
314305![ image-20240923222514199] ( ./img/GoVul/image-20240923222514199.png )
315306
316- ` filepath.Clean() ` 函数的作用如下:
307+ ` filepath.Clean() ` 函数的作用如下:(其实就是根据先拼接,再去掉没用的地方,例如 ` a/./../ ` ,这种情况搞来搞去还是当前目录,就会被直接去掉)
317308
318309```
3193101.用一个分隔符元素替换多个分隔符元素。
@@ -322,12 +313,14 @@ func main() {
3223134.消除以根路径开头的 .. 元素:也就是说,假设分隔符是“/”,将路径开头的“/..”替换为“/”。
323314```
324315
325- 可以看到该` filepath.Clean() ` 函数专门允许 ` switch-case ` '../../../../' 类型的输入。
316+ 可以看到该` filepath.Clean() ` 函数允许 ` switch-case ` '../../../../' 类型的输入。
326317
327318![ image-20240923223511699] ( ./img/GoVul/image-20240923223511699.png )
328- 那么我们对上述代码改为如下代码,添加了一层 ` filepath.Clean() ` 函数,我们再次运行会发现最后一句打印语句还是` ../ ` 开头,这说明我们不需要在花心思在 ` filepath.Join() ` 函数中,因为 ` Clean() ` 它已经内置了。
319+ 那么我们对上述代码改为如下代码,再添加一层 ` filepath.Clean() ` 函数,我们再次运行会发现最后一句打印语句还是` ../ ` 开头
329320
330- ```
321+ 这个故事告诉我们,` filepath.Clean() ` 函数加上也不能放置目录遍历。
322+
323+ ``` go
331324package main
332325
333326import (
@@ -401,7 +394,7 @@ goroutine 的有趣之处在于,调用函数不必等待它们返回即可返
401394
402395在其基本用法中,我们可以向通道发送数据或从通道接收数据:
403396
404- ```
397+ ``` go
405398import (
406399 " fmt"
407400)
@@ -425,11 +418,11 @@ func main() {
425418
426419该代码展示了如何使用 Goroutines 和 channels 来并发地计算两个数字范围内的数值,并找出能被特定数字整除的第一个数。
427420
428- 在这个例子中,我们有 * 阻塞、无缓冲的* 通道。这两者是相辅相成的,因为无缓冲通道用于同步操作,程序在从通道接收到数据之前无法继续,因此它会阻止进一步的执行。
421+ 在这个例子中,使用** 阻塞、无缓冲的* *通道。这两者是相辅相成的,因为无缓冲通道用于同步操作,程序在从通道接收到数据之前无法继续,因此它会阻止进一步的执行。
429422
430423当无缓冲通道没有机会在其通道上发送数据时,就会发生 Goroutine 泄漏,因为其调用函数已经返回。这意味着挂起的 Goroutine 将保留在内存中,因为垃圾收集器将始终看到它在等待数据。举个例子:
431424
432- ```
425+ ` ` ` go
433426package main
434427
435428import (
@@ -473,12 +466,8 @@ func main() {
473466
474467这个简单的示例用于模拟需要用户交互但超时值很低的功能。这意味着,除非我们的用户反应非常快,否则超时会在它做出选择之前发生,因此goroutine内的userChoice()函数将永远不会返回,从而导致泄漏。
475468
476- ### 安全问题
477-
478469此类漏洞的安全影响在很大程度上取决于具体的情况,但最有可能导致拒绝服务的情况。因此,只有当程序的生命周期足够长,并且启动了足够多的 goroutine 来大量消耗内存资源时,这才会成为问题。因此该问题主要是取决于用例和环境才会导致该漏洞产生更严重的影响。
479470
480- ### 修复方式
481-
482471最简单的解决方法是使用缓冲通道,这意味着 goroutines 具有非阻塞(异步)行为:
483472
484473` ` `
@@ -514,7 +503,7 @@ resp, err := http.Post(filepath.Join("https://victim.site/", URI), "application/
514503
515504因此我们有如下两种解决方案:
516505
517- 1.使用` %q ` 格式化动词 ,它将创建一个带编码控制字符的引号字符串
506+ 1.使用` %q` 格式化 ,它将创建一个带编码控制字符的引号字符串
518507
5195082.可以使用` strconv.Quote ()` ,它将引用字符串并编码控制字符
520509
@@ -543,11 +532,11 @@ rawPointer := uintptr(unsafe.Pointer(pointer))
543532
544533如果从 unsafe.Pointer 转换为 uintptr 并在 syscall 中使用时触发垃圾收集机制,我们可能会向系统调用传递一个完全不同的内存结构。这是因为垃圾收集器可能会在内存中移动对象,但它不会更新 uintptr,因此该地址可能与我们执行转换时完全不同。
545534
546- ### 安全问题
535+ ** 安全问题**
547536
548537同样,与其他Go异常类似,该漏洞的影响实际上取决于上下文。首先,由于垃圾回收而更改内存的机率非常低。但是,这种机率会随着我们拥有的 goroutine 数量和程序运行时间的增加而显著增加。最有可能的是,我们会得到一个无效指针解引用异常,但有可能将这样一个漏洞变成一个利用点。
549538
550- ### 修复方式
539+ ** 修复方式**
551540
552541使用如下代码可有效防御该问题:
553542
@@ -559,9 +548,9 @@ _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), request, uintptr(unsaf
559548
560549## OS.EXECUTABLE()
561550
562- ` OS.EXECUTABLE() ` 函数如何处理符号链接取决于操作系统 ,我们可以看如下代码:
551+ ` OS.EXECUTABLE ()` 函数作用是获取当前程序的路径。它如何处理符号链接取决于操作系统 ,我们可以看如下代码:
563552
564- ```
553+ ` ` ` go
565554func withoutEval () string {
566555 execBin , _ := os.Executable ()
567556 path , err := filepath.Abs (filepath.Dir (execBin))
@@ -625,10 +614,10 @@ Number of bytes read: 16
625614Bytes: AAAAAAAAAAAAAAAA
626615` ` `
627616
628- ### 安全问题
617+ ** 安全问题**
629618
630619假设我们有一个长期运行的 Go 二进制文件,例如服务或类似文件,位于受保护的位置,以防止低权限用户访问,并且配置文件规定了一些安全选项,例如对服务器或类似文件的主机证书验证。在 Windows 和 MacOS 上,即使对于权限较低的用户,我们也可以在可控制的位置创建指向此二进制文件的符号链接,并在那里添加修改后的配置文件,程序将在下次运行时读取该文件。实际上,这使得攻击者能够从低权限用户帐户覆盖那里的安全设置。
631620
632- ### 修复方式
621+ ** 修复方式**
633622
634623修复方法相对简单。我们只需要将结果传递` os.Executable ()` 给` os.EvalSymlinks ()` 。此函数将检查路径是否为符号链接,如果是,它将返回链接指向的绝对路径。
0 commit comments