记录有趣的CTF题目:WMCTF2020_gogogo
2022-8-22 10:30:35 Author: NOVASEC(查看原文) 阅读量:83 收藏

△△△点击上方“蓝字”关注我们了解更多精彩
0x00 免责声明

在学习本文技术或工具使用前,请您务必审慎阅读、充分理解各条款内容。

1、本团队分享的任何类型技术、工具文章等文章仅面向合法授权的企业安全建设行为与个人学习行为,严禁任何组织或个人使用本团队技术或工具进行非法活动

2、在使用本文相关工具及技术进行测试时,您应确保该行为符合当地的法律法规,并且已经取得了足够的授权。如您仅需要测试技术或工具的可行性,建议请自行搭建靶机环境,请勿对非授权目标进行扫描。

3、如您在使用本工具的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任。

4、本团队目前未发起任何对外公开培训项目和其他对外收费项目,严禁任何组织或个人使用本团队名义进行非法盈利。

5、本团队所有分享工具及技术文章,严禁不经过授权的公开分享。

如果发现上述禁止行为,我们将保留追究您法律责任的权利,并由您自身承担由禁止行为造成的任何后果

0x01 Preface 

新加入了咱们的novasec团队,发现文章类别较多于渗透测试、造工具、免杀技术、代码审计这一块文章,CTF这类还是比较少的。

寻思或许能填补一下团队里的空白,虽说不能做到全面覆盖整个安全技术,但是觉得团队中每个人的技术点不一样,覆盖面就多一点,形成多方面知识,更利于整个团队的成长,造就多方面发展。

本次汇总成文章写出来与大家分享,一是为了将所学习到的知识再输出来,看看本次收获多少的知识,二也作为抛砖引玉,寻找志同道合的表哥们一起学习。

如有更好的解答题欢迎各位表哥留言,一起学习,共同成长。

本人在CTF上也属于新手级别,这次写一篇关于CTF文章,是羊城杯中的一道题,题看到蛮有意思的,然后在看EDI安全发了wp后,原来出题的思路是来自WMCTF2020。

去找了赛棍师傅拿到了源码。

0x02 审计逻辑

简单捋一下本道题逻辑,思路如下:

1、main.go里初始化了一些数据库操作,还利用loadPulgin来载入plugin面就是一些路由的定义。2、handler.go中定义了一些路由请求处理。3、utiil.go顾名思义就是工具类。4、admin_handler.go 就是加载.so还有一些后台的路由。

开始审计:

直接找关键路由,看一下/auth/下路由的处理逻辑。

就是对uname、pwd进行简单的判断,成功就设置key为uname的session,并且跳转到/profile 路由,跟过去。

就是根据uname获取用户信息的信息。可以看到没对数据库做过滤操作,这个可能是利用的一个点。(后面去查了一下,其实是没有注入的)。

关于go的sql注入:https://learnku.com/docs/build-web-application-with-golang/094-avoids-sql-injection/3212https://learnku.com/go/t/49692https://studygolang.com/articles/26988https://www.gushiciku.cn/pl/pJFI/zh-tw

接下来继续看,来到下半部分的路由。

这里就是进行验证,用session中获取用户信息。

这两个方法通过注释来看,Req是发起HTTP请求的,另外一个Read是读取文件的,这两个方法似乎写在了plugin里面,这个具体引用还不太了解,回头得查阅一下资料。

这个方法利用go进行命令执行,但是其中没有参数可以让我们控制,无法利用。

这里有个上传接口,上传plugin,然而对访问接口的ip进行了限制,必须是本地发起请求。

至此,现在所拥有的信息是:数据库表结构,还有可能存在的文件读取、ssrf以及文件上传,但是这几个接口都需要admin用户的权限,文件上传限制了ip,必须由本地发起,但是问题来了,我们的ssrf触发点在post的参数里面,只能发起get请求,没办法控制路由与参数,同时还要admin权限。

0x03 随机数漏洞->Cookie伪造

首先,经过上面的分析,是通过session来判断admin权限的,去看看生成的方法。

从上面代码可以看到,生成cookie的值是通过go的math/rand这个库来生成16位的伪随机数,然而并没有指定种子,没有调用seed函数的时候,默认随机数种子为1,同时判断是否为管理员的方法是从session中取出uname键是否等于"admin"。

因此我们可以考虑伪造Cookie,将Cookie中的uname改为admin,从而取得管理员权限。所以我们只要在本地调用同样的方法就可以生成对应的随机数。

参考代码如下:

package main
import ( "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" "math/rand")
func main() { r := gin.Default() storage := cookie.NewStore(randomChar(16)) r.Use(sessions.Sessions("o", storage)) r.GET("/a",cookieHandler) r.Run("0.0.0.0:8002")}func cookieHandler(c *gin.Context){ s := sessions.Default(c) s.Set("uname", "admin") s.Save()}func randomChar(l int) []byte { output := make([]byte, l) rand.Read(output) return output}

访问http://127.0.0.1:8002/a 接口的cookie就是admin权限的cookie

o=MTY2MDQ4NDIwOXxEdi1CQkFFQ180SUFBUkFCRUFBQUpQLUNBQUVHYzNSeWFXNW5EQWNBQlhWdVlXMWxCbk4wY21sdVp3d0hBQVZoWkcxcGJnPT18qtZt-_dTDUWYOd40Giq_sK9Ku2_wO1toeBHpNHdMOJ8=

0x04 SSRF+任意文件读取

admin_handler函数中存在两个方法

fn := c.PostForm("fn")
// func Req(string) ([]byte, error) // http request// func Read(string) ([]byte, error) // read fileif fn != "Req" && fn != "Read" { c.String(200, "No such function") return}
arg := c.PostForm("arg")
symbol, err := plg.LooReqkup(fn)if err != nil { c.String(200, "No such function") return}
ff, ok := symbol.(func(string) ([]byte, error))if !ok { c.String(200, "Wrong signature") return}
bs, err := ff(arg)c.String(200, fmt.Sprintf("%s\n%s", err, string(bs)))

通过注释,可以知道Req方法用于发送http请求,Read方法则是用于读取文件。尝试构造一下。

文件读取:

SSRF:

从返回的报错看出来是使用了Go的net/http库。

0x05 GetFlag

利用任意文件读取漏洞时,在不知道默认路径的情况下,我们可以尝试读取 /proc/self/environ https://www.anquanke.com/post/id/241148

直到这里已经读到了flag

0x06 go version <=1.11 net/http CRLF漏洞

参考github issue https://github.com/golang/go/issues/30794go版本低于1.11以下 net/http 库存在CRLF漏洞,通过该漏洞构造任意的HTTP请求。

但是发现后端go使用的是 1.9.7版本,因此存在CRLF漏洞。由于go plugin中的Req方法能够造成SSRF,且能够访问任意站点,通过上面发现存在使用了 net/http库发送GET请求,参数为arg。

构造CRLF Payload

后续可以利用该漏洞绕过ip限制进行文件上传,且后续编译go plugin需要保持版本相同 通过HTTP请求接口CRLF注入一个上传请求,访问到上传接口,上传覆盖plugins/base.so,达成代码执行。

0x07 Summary 总结

1、伪数据数漏洞:(各种语言实现的方式存在差异,可以去看看php(我记得赛博星球有总结php的)、python、go)

https://wooyun.x10sec.org/static/drops/tips-16053.html(其实这里面还有其他很多案例)

实战案例:

(1)https://wy.zone.ci/bug_detail.php?wybug_id=wooyun-2014-054785

(2)http://wy.zone.ci/bug_detail.php?wybug_id=wooyun-2015-0124026

2、关于SSRF危害升级(这是我自己目前看到了,打算记一下积累积累,说不定会遇到呢)

1)CRLF,拆分HTTP请求,通过这次CTF赛题可以看到CRLF的强大之处

实战案例:https://www.anquanke.com/post/id/86336(没错,是我大p牛的。。。无敌)

2)利用代码库HTTP请求的特性

实战案例:https://www.anquanke.com/post/id/248821(是鸭王师傅的,审计贼6)。

攻击路径分析:参数及路由均不可控POST类型的SSRF -> requests 30X跳转特性 -> 参数和路由均可控的GET类型SSRF -> 文件名部分可控的文件上传 -> 多点结合攻击本地服务

3、任意文件读取漏洞新姿势(其实也不算新,之前面试题遇到过)

就是在遇到存在任意文件读取时,找不到软件的目录的时候,可以通过读取/proc/self/environ这个路径来获取当前系统环境变量,一些运维人员为了方便通常都会配置系统环境变量,当然这个特性仅限于Linux。

参考引用:

详细的WP可以查看如下:

https://annevi.cn/2020/08/14/wmctf2020-gogogo-writeup/

https://github.com/wm-team/WMCTF2020-WriteUp/blob/master/WMCTF%202020%E5%AE%98%E6%96%B9WriteUp.md

END

如您有任何投稿、问题、建议、需求、合作、后台留言NOVASEC公众号!

或添加NOVASEC-余生 以便于及时回复。

感谢大哥们的对NOVASEC的支持点赞和关注

加入我们与萌新一起成长吧!

本团队任何技术及文件仅用于学习分享,请勿用于任何违法活动,感谢大家的支持!


文章来源: http://mp.weixin.qq.com/s?__biz=MzUzODU3ODA0MA==&mid=2247487969&idx=1&sn=4e3c9ef752ad2ebe39ad7e2e0523b988&chksm=fad4ccf6cda345e08f762526111248eba81c7b3ca5bfb47599dc03370dea7377539ee573d6a6#rd
如有侵权请联系:admin#unsafe.sh