确实是高质量比赛,学到了很多知识、认识到了很多的不足。
任重而道远啊...
hgame_week1
web
Classic Childhood Game
F12检查源码,打开Events.js
发现
\x59\x55\x64\x6b\x61\x47\x4a\x58\x56\x6a\x64\x61\x62\x46\x5a\x31\x59\x6d\x35\x73\x53\x31\x6c\x59\x57\x6d\x68\x6a\x4d\x6b\x35\x35\x59\x56\x68\x43\x4d\x45\x70\x72\x57\x6a\x46\x69\x62\x54\x55\x31\x56\x46\x52\x43\x4d\x46\x6c\x56\x59\x7a\x42\x69\x56\x31\x59\x35
cyberchef解码

Show Me Your Beauty
文件上传
在一张图片内写入
上传用burpsuite抓包
修改文件名为pHp

上传成功
回到网页,右键头像打开,测试phpinfo();
)
成功,连接蚁剑,根目录下找到flag:hgame{Unsave_F1L5_SYS7em_UPL0ad!}
Become A Member
(赛后复现) 比赛时改错头了一直没回显...直接尬住
考点就是 ⼏个常规的HTTP考点+请求数据构造
题⽬提⽰⾝份证明(Cute-Bunny),尝试 User-Agent
Vidar的邀请码(code),可以看⼀开始的http请求头当中有⼀个 Set-Cookie:code=guest ,将 guest 修改为 Vidar 即可
来⾃ bunnybunnybunny.com 的申请,提⽰了请求来源,将 referer 的值修改为bunnybunnybunny.com
最后⼀个是本地请求,这个⽐较常⻅,添加 X-Forwarded-For: 127.0.0.1 的请求头即可
然后给了 password 和 username ,按正常的json数据格式发请求数据即可(注意需要指定Content-Type 为 application/json ,请求⽅式是 GET )
)
得到flag:hgame{H0w_ArE_Y0u_T0day?}
Guess Who I Am
(赛后复现) 这是一道爬虫题,写脚本这一块还得不断加强才行啊..
F12看到hint,去GitHub把成员信息扒下来,写成json文件,改成这种形式

⽐较快捷的办法的话⽐如说⽤像vsode之类的编辑器来做批量的编辑。可以ctrl + f选中所有需要编辑的信息后,右键更改所有匹配项,让每⼀个 "avatar" 前⾯都出现光标,再⽤shift + ⽅向键,就可以⽤多个光标批量选中删除啦。
下一步我们要做的内容就是读⼊json⽂件并且解析内容,请求获取成员介绍,通过json⾥读进来的内容匹配出对应的ID,⽤这个ID去请求验证答案的接⼝,当得分超过100时去关注返回的⻚⾯看看有没有什么不⼀样的信息。
步骤一:
读⼊json⽂件并且解析内容- import json
- with open('member.json',encoding='UTF-8') as f:
- member = json.load(f)
- print(member)
复制代码 这里要加encoding='UTF-8',不然可能会出现 UnicodeDecodeError: 'gbk' codec can't decode byte 0xa7 in position 58: illegal multibyte sequence 的编码问题
json.load():json文件中读取数据

步骤二:
看到正常输出了,接下来F12看⼀下⽹站的后端接⼝设计,请求对应的后端接⼝拿到所需的各种信息
提问信息的地址:http://week-1.hgame.lwsec.cn:32230/api/getQuestion
分数的地址:http://week-1.hgame.lwsec.cn:32230/api/getScore
答题的地址:http://week-1.hgame.lwsec.cn:32230/api/verifyAnswer 此处是POST

这⾥可能就会考虑⼀个问题,⽹站是怎么对于不同⽤⼾的信息进⾏判断的呢,这⾥也没有什么登陆啊,我能不能直接让服务端认为我已经拿到了100分呢?站点通过Cookie中的session来记录了⽤⼾信息,⽽session是通过Key来加密的,所以不知道Key的⽤⼾是没有办法做到在客⼾端修改分数的。
步骤三:
我们这⾥要带着session去请求 /api/getQuestion 的接⼝来获取问题。

这⾥我们获得了⼀个json格式的数据,我们的⽬标是去提取我们想要的成员介绍的内容,但是请求得到的数据类型是str,所以需要转换成Dict。
所以加上这两句- rs = json.loads(res.text)
- print(rs['message'])
复制代码 得到

详解:
cookies:初始化cookies字典变量res=requests.get("url",cookies=cookies)将cookies添加到get方法中,获取到的res.content中就是我们将cookies信息添加到get中后访问网页所获取的内容json.loads():将str类型的数据转换为dict类型res.text查看响应内容,response.text 返回的是Unicode格式的数据步骤四:
获取到对应的成员介绍后我们就在成员信息中匹配到对应的ID- answer = ''
- for i in member:
- if i['intro'] == rs['message']:
- answer = i['id']
- break
- print(answer)
复制代码 验证答案

答案正确,可以进行下一步的脚本编写
由于后端⽤的语⾔是Golang,开发框架是Gin,鉴权⽤的session中间件是客⼾端session的形式,也就是说包括分数包括问题都是存储在session中,那么我们每次答对题⽬分数和问题都是会改变的,在⻚⾯上我们答对问题会有 set-cookie 的响应头来重新设置新的session,但是我们编写脚本就得⾃⼰来处理这个问题,需要从set-cookie中拿到新的session然后再开始新⼀轮的⾃动答题
步骤五:
获取页面的session- data = {'id':answer}
- res = requests.post(url+"/api/verifyAnswer",cookies=cookies,data=data)
- rs=json.loads(res.text)
- print("[*] Result: "+ rs['message'])
- cookies['session'] = res.cookies['session']
复制代码 步骤六:
补上对于分数接⼝的请求,外层加上⼀个While循环,判断分数到达100时退出,因为后端接⼝总共
也就只有获取问题,获取分数,验证答案三个,那么我们可以判断分数到达100时肯定是从这三个接⼝会能够返回和Flag相关的信息
完整版EXP:
[code]import jsonimport requests# 读取json⽂件并且解析with open('member.json', encoding='UTF-8') as f: member = json.load(f)cookies={}answer=''score=0# 靶机地址url="http://week-1.hgame.lwsec.cn:31628" #注意此处不要多复制‘/’,会造成‘//’现象直接报错# 当前页面的sessioncookies['session']='MTY3NDIxMjQ0OHxEdi1CQkFFQ180SUFBUkFCRUFBQU9fLUNBQUlHYzNSeWFXNW5EQTBBQzJOb1lXeHNaVzVuWlVsa0EybHVkQVFDQUF3R2MzUnlhVzVuREFnQUJuTnZiSFpsWkFOcGJuUUVBZ0FzfLcGFI3K5NeFt3s0VGWxGso8KEtNu96yx9qX70XNWqjK'while score |