记录一下hgame比赛。
目录
WEB
easy_auth
打开题目是一个登录框
题目描述里有admin,那就随便输个弱口令抓包看一下
看见返回包有这个,就想到这个题肯定考察js,为验证一下想法看一下源代码,里面存在login.js打开看一下发现确实是前端验证的
之后就注册一个账号登录看一下登录成功的返回包
登录成功返回的结果如下:
{"code":2000,"message":"success","count":0,"data":[{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6ODc1LCJVc2VyTmFtZSI6InF3ZWFzZHp4YyIsIlBob25lIjoiIiwiRW1haWwiOiIiLCJleHAiOjE2NDI5NTkxODIsImlzcyI6Ik1KY2xvdWRzIn0.YRikdNAYXA1aXo8Q5OGDWToW96MM9QP_eY3XrIyJ-5k"}]}
发现code的值和前端验证里的一样是2000,message的值是success,并且有data的值里有token,那就是jwt伪造登录admin账号,伪造前先看一下jwt每个字段的意思:
JWT 规定了7个官方字段,供选用
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
下面用JSON Web Tokens - jwt.io这个网站开始伪造:
字段中的ID改为1,UserName改成admin,exp改成未来的一个时间戳
之后用admin账户登录并用burp抓包同时拦截这个请求的响应,将admin账户登录失败的返回结果进行更改
{"code":15002,"message":"用户名或密码错误","count":0,"data":null}
data的值改成刚伪造的token,message的值改成success,code的值改成2000,更改结果如下:
{"code":2000,"message":"success","count":0,"data":[{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6MSwiVXNlck5hbWUiOiJhZG1pbiIsIlBob25lIjoiIiwiRW1haWwiOiIiLCJleHAiOjE2NDI5MjA1MDcsImlzcyI6Ik1KY2xvdWRzIn0.W5jSh0LIJXC2gcrrvvVHV_JAlUNBSLrDqd4D6HNF9GU"}]}
最后发包即可在网页中看到flag
flag:hgame{S0_y0u_K1n0w_hOw_~JwT_Works~1l1lL}
蛛蛛...嘿嘿♥我的蛛蛛
打开题目看见点我试试按钮,发现进入第二关并进行了跳转,按F12看看源码发现href标签
再点几个还是一样,一层套了一层,估计套了不少层,那就写个脚本不断的访问
# coding=utf-8
from bs4 import BeautifulSoup
import requests
# 定义一个获取url页面下label标签的attr属性的函数
def getHtml(url, label, attr):
response = requests.get(url)
response.encoding = 'utf-8'
html = response.text
soup = BeautifulSoup(html, 'html.parser');
print(soup)
for target in soup.find_all(label):
try:
value = target.get(attr)
except:
value = ''
if value:
return value
if __name__ == '__main__':
result = ""
while True:
url = "https://hgame-spider.vidar.club/83e7510b40"
label = 'a'
attr = 'href'
payload = result
try:
result = getHtml(url+payload,label,attr)
print(result)
except:
break
运行结果如下:
看到最后一个网页返回结果里没有flag,标题写了一个猜猜我在哪。那就访问最后一个网页看一下,最后在响应头里看见了flag
flag:hgame{87d5fc19fbe5f452064028e1347e200155a2157af92b85a1a86bed3ff3a96fce}
Tetris plus
这个题是个游戏说是要超过3000分,但是这种网页小游戏,从前端代码的逻辑里基本都能拿到flag,那就去前端代码里看看,先看main.js里面有一些checkGameOver这类的函数不过没什么用,最后在checking.js里面看见了一个base64,和一个jsfuck,如图
依次解密之后发现base64写的是flag被藏起来了,jsfuck就是flag
flag:hgame{jsfuck_1s_S0_fUu1n}
Fujiwara Tofu Shop
打开题目看一下
看见“想成为车神,你需要先去一趟秋名山(qiumingshan.net)”这句话,这个就是http协议里的Referer,Referer的意思就是表明产生请求的网页URL,这个属性可以用来跟踪Web请求是从什么网站来的。用burp抓包加上下面这个就行。
Referer: qiumingshan.net
发包后返回包如下:
这个要将User-Agent改成Hachi-Roku,User-Agent就是客户浏览器名称
User-Agent: Hachi-Roku
发包后返回包如下:
这个是加上cookie,将cookie的flavor值设置为Raspberry,为什么是flavor,因为在返回包里的set-cookie有flavor=Strawberry;Strawberry是草莓这里改成树莓加到请求包里即可。
flavor=Raspberry;
发包后返回包如下:
这个要加汽油值为100,那汽油的字段不清楚,和cookie一样看看返回包,返回包里有Gasoline: 0,而Gasoline就是汽油的意思,所以同样在请求包里加Gasoline:100即可。
Gasoline: 100
发包后返回如下:
这个做题时第一反应就是加X-Forwarded-For:127.0.0.1,但是加了之后返回结果是
然后卡了很久,百度查一下和X-Forwarded-For相关的几个头部,最后用X-Real-IP:127.0.0.1也就是在请求包里加
X-Real-IP:127.0.0.1
看返回包就有flag
flag:hgame{I_b0ught_4_S3xy_sw1mSu1t}
REVERSE
easyasm
用IDA打开,按照汇编代码逻辑,自己写个c程序得到flag
#include<iostream>
int main()
{
char ds[0x1c]={0x91,0x61,0x1,0xc1,0x41,0xa0,0x60,0x41,0xd1,0x21,0x14,0xc1,0x41,0xe2,0x50,0xe1,0xe2,0x54,0x20,0xc1,0xe2,0x60,0x14,0x30,0xd1,0x51,0xc0,0x17};
short ax,bx;
char al,bl;
char c;
for(int i=0;i<0x1c;i++){
c = ds[i];
c = c^0x17;
for(char j=0;j<128;j++){
ax = 0;
al = j;
al = al << 4;
ax += al;
bx = 0;
bl = j;
bl = bl >> 4;
bx += bl;
ax += bx;
al = (ax << 8) >> 8;
if(al == c){
printf("%c",j);
break;
}
}
}
}
flag: hgame{welc0me_to_4sm_w0rld}
Flag Checker
一个apk,进行反编译在MainActivity里找到了用RC4加密的密文和秘钥,在线网站解密即可拿到flag
密文:mg6CITV6GEaFDTYnObFmENOAVjKcQmGncF90WhqvCFyhhsyqq1s=
秘钥:carol
解密如下:
flag:hgame{weLC0ME_To-tHE_WORLD_oF-AnDr0|D}
MISC
欢迎欢迎!热烈欢迎!
签到题,关注“奇安信技术研究院”微信公众号,发送 HelloHGAME2022
获得flag
这个压缩包有点麻烦
打开压缩包看见注释说六位以内的数字密码不安全,那就可能这个压缩包密码就是六位数字
爆破一下看见密码是483279
解压之后,里面的flag.zip依旧被加密,README写的是我不知道把所有密码写下来是不是一个好主意,看见password-note里面有很多密码是个字典那就是用字典进行爆破。爆破出来flag.zip的密码是&-`;qpCKliw2yTR\
解压后里面又是个压缩包,和一个README,再打开压缩包看一下下一层压缩包里有一个flag.jpg和一个README,然后发现已经解压出来的README和最后一层压缩包里未解压的README的crc32一样。
那就是明文攻击了,压缩README,进行明文攻击
之后就将文件解压出来了,看到了flag.jpg
用binwalk看一下图片下面还有个zip
分离出来一个加密的压缩包,看到标志位是个伪加密,解除伪加密之后解压,看到真正的flag。
flag:hgame{W0w!_y0U_Kn0w_z1p_3ncrYpt!}
好康的流量
打开流量包,发现是SMTP流量,在流量包最后有一张图片
导出用base64解压另存为png得到图片,用StegSolve看一下在Green plane2通道发现了一个条形码,手机扫描条形码得到flag前半部分
之后根据题目描述猜测是lsb再用zsteg看一下,找到了后半部分flag
flag:hgame{ez_1mg_Steg4n0graphy}
群青(其实是幽灵东京)
拿到音频先放到AU里面看看频谱
看起来像是一个密码,首先猜测是SilentEye,密码应该是Yoasobi,使用SilentEye进行解密果然有东西是音频一个网址
将音频下载下来,音频名字是sstv,百度了一下是sstv指慢扫描电视,这是业余无线电爱好者的一种主要图片传输方法,慢扫描电视通过无线电传输和接收单色或彩色静态图片。那这个题应该就是无线电SSTV慢扫描,于是就用RX-SSTV接收信息。首先安装虚拟声卡VirtualAudioCable,然后在系统声音设置里面将Line 1设置为默认的输出输入,之后将Audio Repeater设置如下
最后播放音乐在robot36模式下接收信息,出来一个二维码
最后扫描二维码拿到flag
flag:hgame{1_c4n_5ee_the_wav}
IoT
饭卡的uno
下载附件文件是.hex后缀直接拿到010Editor里面看一下,结果直接看见了flag
flag:hgame{F1rst_5tep_0F_IOT}
CRYPTO
Easy RSA
就是最基础的rsa,写个脚本每组数依次解密就行
import gmpy2
c = [(12433, 149, 197, 104), (8147, 131, 167, 6633), (10687, 211, 197, 35594), (19681, 131, 211, 15710), (33577, 251, 211, 38798), (30241, 157, 251, 35973), (293, 211, 157, 31548), (26459, 179, 149, 4778), (27479, 149, 223, 32728), (9029, 223, 137, 20696), (4649, 149, 151, 13418), (11783, 223, 251, 14239), (13537, 179, 137, 11702), (3835, 167, 139, 20051), (30983, 149, 227, 23928), (17581, 157, 131, 5855), (35381, 223, 179, 37774), (2357, 151, 223, 1849), (22649, 211, 229, 7348), (1151, 179, 223, 17982), (8431, 251, 163, 30226), (38501, 193, 211, 30559), (14549, 211, 151, 21143), (24781, 239, 241, 45604), (8051, 179, 131, 7994), (863, 181, 131, 11493), (1117, 239, 157, 12579), (7561, 149, 199, 8960), (19813, 239, 229, 53463), (4943, 131, 157, 14606), (29077, 191, 181, 33446), (18583, 211, 163, 31800), (30643, 173, 191, 27293), (11617, 223, 251, 13448), (19051, 191, 151, 21676), (18367, 179, 157, 14139), (18861, 149, 191, 5139), (9581, 211, 193, 25595)]
flag = ""
for i in c:
p =gmpy2.mpz(i[1])
q =gmpy2.mpz(i[2])
e =gmpy2.mpz(i[0])
fn= (p - 1) * (q - 1)
n=p*q
d = gmpy2.invert(e, fn)
c=gmpy2.mpz(i[3])
m=pow(c,d,n)
flag += chr(m)
print(flag)
脚本运行结果就是flag
flag:hgame{L00ks_l1ke_y0u've_mastered_RS4!}
English Novel
附件里有两个文件夹,每个里面都有很多txt,一个是一篇文章加密过后并将文章分成很多部分,分别放在txt里同时将txt顺序打乱,另外一个是原文也同样分成很多部分,分别放在txt里进行了顺序打乱,里面还有flag.enc是我们要解密的密文,encrypt.py是加密文章时候的加密函数。
def encrypt(data, key):
assert len(data) <= len(key)
result = ""
for i in range(len(data)):
if data[i].isupper():
result += chr((ord(data[i]) - ord('A') + key[i]) % 26 + ord('A'))
elif data[i].islower():
result += chr((ord(data[i]) - ord('a') + key[i]) % 26 + ord('a'))
else:
result += data[i]
return result
观察加密函数就会发现只有大小写字母会移位特殊符号是不变的,例如A -> E移动了4位也就是key[i]要为4,那么想解密flag.enc就得先通过给的这些文章片段找秘钥,文章太多了而且顺序全部被打乱,所以先用文件对比软件看看
果然发现了part105和part289文件对比有问题打开发现正常文章文件夹里的part105和加密文章文件夹里part289这两个txt对应,一个是明文一个是加密过的密文。写个脚本反推秘钥并将flag.enc解密。
ps:这里因为文章有非字母的符号,而加密函数对于这些符号不进行加密,也就推不出来对应的秘钥,脚本中将推不出来的秘钥全部用~符号代替。
flag = '''e appeared to be that Napoleon and Mr. Pilkington had each played an ace of spades simultaneously.
Twelve voices were shouting in anger, and they were all alike. No question, now, what had happened to the faces of the pigs. The creatures outside looked from pig to man, and from man to pig, and from pig to man again; but already it was impossible to say which was which.
November 1943-February 1944'''
data = '''h sbqctbno uw ox fbay Rbyalrkq pnz Vs. Dwonbnolun chk kuld cteafx ze qbb iz bhktox cismkalhnqxprn.
Jibcir zuluxv tgkr kmmezppq wx aksac, ulj jufr jaqj tzg ssgwx. Wp ocvfkzyc, psr, xwot hos hwjwtvnk qk bti fvczs ri znk uejr. Zdy ykbhuimhw dmcliwc vipnhj dnhx fdi yu szu, yrc lifp yhz cz oqg, dab rraf vvf do owr avxxo; rzm laynqdl nw iaq ndeemnloit rb wzq wbplx rmu shfbt.
Pbgydbwi 1943-Bgqijwgz 1944'''
s = "klsyf{W0_j0v_ca0z_'Ks0ao-bln1qstxp_juqfqy'?}"
key = list()
def get_key(flag,data):
for j in range(0,27):
if flag.isupper():
result = chr((ord(flag) - ord('A') + j) % 26 + ord('A'))
if result == data:
key.append(j)
break
else:
continue
elif flag.islower():
result = chr((ord(flag) - ord('a') + j) % 26 + ord('a'))
if result == data:
key.append(j)
break
else:
continue
else:
key.append('~')
break
def decrypt(s, key):
assert len(s) <= len(key)
result = ""
for i in range(len(s)):
if s[i].isupper():
if key[i] == "~":
result += "~"
continue
else:
result += chr((ord(s[i]) - ord('A') - int(key[i])) % 26 + ord('A'))
elif s[i].islower():
if key[i] == '~':
result += "~"
continue
else:
result += chr((ord(s[i]) - ord('a') - int(key[i])) % 26 + ord('a'))
else:
result += s[i]
print(result)
if __name__ == '__main__':
for i in range(len(flag)):
get_key(flag[i],data[i])
decrypt(s,key)
脚本运行结果如下:
下面就是猜单词了,很明显第一个~那个位置对应hgame,之后依次是,kn0w、pla1ntext、attack。
flag:hgame{D0_y0u_kn0w_'Kn0wn-pla1ntext_attack'?}