SCTF2021

团队在SCTF中喜获两枚flag

web

loginme

下载源码发现是go语言的web框架题

其实对go一点不熟,之前也没有学过,很难受,那就现场学习一下吧

首先需要本地登录

image-20211225102304811

但是源码要求x-forwarded-for和x-client-ip均为空

image-20211225102411236

搜gin模块ClientIP()的使用方法发现默认方法有[X-Forwarded-For, X-Real-Ip]

image-20211225102526951

那直接构造请求包参数X-Real-Ip:127.0.0.1成功登录

image-20211225102652833

分析route.go源码中Login方法逻辑保证传入id参数为0,可以取到admin的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func Login(c *gin.Context) {
idString, flag := c.GetQuery("id")
if !flag {
idString = "1"
}
id, err := strconv.Atoi(idString)
if err != nil {
id = 1
}
TargetUser := structs.Admin
for _, user := range structs.Users {
if user.Id == id {
TargetUser = user
}
}

age := TargetUser.Age
if age == "" {
age, flag = c.GetQuery("age")
if !flag {
age = "forever 18 (Tell me the age)"
}
}

这里存在一个模板渲染函数,渲染参数为age支持用户自定义输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

if err != nil {
c.AbortWithError(500, err)
}

html := fmt.Sprintf(templates.AdminIndexTemplateHtml, age)
if err != nil {
c.AbortWithError(500, err)
}

tmpl, err := template.New("admin_index").Parse(html)
if err != nil {
c.AbortWithError(500, err)
}

tmpl.Execute(c.Writer, TargetUser)
}

百度一下go模板渲染方式,其实跟python的ssti很像,于是构造age={{.}}直接取出flag

最终payload:?id=0&age={{.}}

image-20211225103210803

MISC

This_is_A_tree

下载附件发现是二叉树

整理得到

左子树

1cscsacas

右子树

image-20211225154423793

按根节点-左节点-右节点的顺序遍历,并在又子树yEhO处分割,得到两断base64加密密文

Q2hpbmVzZSB0cmFkaXRpb25hbCBjdWx0dXJlIGlzIGJyb2FkIGFuZCBwcm9mb3VuZCEgU28gSSBXYW50IEdpdmUgWW91IE15IEZsYWcgQnV0IFlvdSBOZWVkIERlY29kZSBJdC5FbmpveSBUaGUgRmxhZyEh

OuW4iCDlhZEg5aSNIOaNnyDlt70g6ZyHIOaZiyDlp6Qg5aSn6L+HIOiuvCDlmazll5Eg6ZyHIOaBkiDoioIg6LGrIA==

解密得到:Chinese traditional culture is broad and profound! So I Want Give You My Flag But You Need Decode It.Enjoy The Flag!!:师 兑 复 损 巽 震 晋 姤 大过 讼 噬嗑 震 恒 节 豫

按伏羲六十四卦解密

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
s='师兑复损巽震晋姤大过讼噬嗑震恒节豫'
dic={'坤': '000000', '剥': '000001', '比': '000010', '观': '000011', '豫': '000100', '晋': '000101', '萃': '000110', '否': '000111', '谦': '001000', '艮': '001001', '蹇': '001010', '渐': '001011', '小过': '001100', '旅': '001101', '咸': '001110', '遁': '001111', '师': '010000', '蒙': '010001', '坎': '010010', '涣': '010011', '解': '010100', '未济': '010101', '困': '010110', '讼': '010111', '升': '011000', '蛊': '011001', '井': '011010', '巽': '011011', '恒': '011100', '鼎': '011101', '大过': '011110', '姤': '011111', '复': '100000', '颐': '100001', '屯': '100010', '益': '100011', '震': '100100', '噬嗑': '100101', '随': '100110', '无妄': '100111', '明夷': '101000', '贲': '101001', '既济': '101010', '家人': '101011', '丰': '101100', '离': '101101', '革': '101110', '同人': '101111', '临': '110000', '损': '110001', '节': '110010', '中孚': '110011', '归妹': '110100', '睽': '110101', '兑': '110110', '履': '110111', '泰': '111000', '大畜': '111001', '需': '111010', '小畜': '111011', '大壮': '111100', '大有': '111101', '夬': '111110', '乾': '111111'}
li=[]
k=0
for i in range(len(s)):
if k ==1:
k=0
continue
try:
li.append(dic[s[i]])
except:
t=''
t=t+s[i]+s[i+1]
li.append(dic[t])
k=1
ss=''.join(li)
print(ss)
enc=''
for i in range(0,len(ss),8):
enc+=chr(eval('0b'+ss[i:i+8]))
print(enc)

得到flag

Ch1nA_yyds!

作者

丨greetdawn丨

发布于

2021-12-25

更新于

2023-05-06

许可协议

评论