2025hgame week1
- hgame2025开打了,趁着寒假有时间,也就顺便打一下了。
- 今年的hgame只有两周,并非新生赛了,2024的hgame还有四周,前两周还是偏向新生的,可惜当时没坚持牢下来QAQ。
签到
TEST NC
- 直接就是测试
nc连接

flag:hgame{YOUr-c@N_C0NNect-t0_THe_rem0TE_ENv1rOnmeNt-To_g3t-F1Ag0}
从这里开始的序章
- flag在这边

flag:hgame{Now-I-kn0w-how-to-subm1t-my-fl4gs!}
Crypto
suprimeRSA
- 原来的附件出现了非预期,这边也放出来一下
1 | from Crypto.Util.number import * |
- 这边也给出更新后的附件
1 | from Crypto.Util.number import * |
- 这边我是先对一开始的附件进行思考,发现可能可以用
coppersmith攻击,去打p的低位,之后问了出题人,发现不是coppersmith打p的低位,这时就反复思考。还是往p、q的二进制位去想,也有想到p、q生成的形式问题。 - 之后上新附件后,我才确定就是
p = k*M + pow(e,a,M)这个素数的生成漏洞,这时就去往这个方向搜素。 - 直到搜索到了这篇论文:
1 | Attacks on the RSA Cryptosystem |
- 在这篇论文快结束的时候就看到了一个公司的RSA加密bug

- 这个时候就往
Infineon这个公司去搜索,这样就搜索到了CVE-2017-15361,同时搜索到了这两篇博客。发现该题就是ROCA攻击
ROCA攻击——CVE-2017-15361 | crumbling’s secret room
Analysis of the ROCA vulnerability · Bitsdeep
- 同时发现了这篇论文
- 所以就照着学了一遍,之后就直接套脚本
1 | from sage.all import * |
flag:hgame{ROCA_ROCK_and_ROll!}
MISC
Hakuya Want A Girl Friend
- 打开附件发现是一大堆的十六进制。

- 这可能是某个文件的二进制形式,就将这个文本转换为二进制形式进行输出
1 |
|
- 然后使用
010editor查看这个二进制文件,发现好像是zip的文件头

- 所以把文件的后缀改为
zip,就会发现压缩包中有flag,但是需要密码

- 这时再翻到这个文件二进制形式的结尾,发现这边是个png头颠倒过来。

- 所以就再将这个二进制位倒序输出到另一个文件中。这时就会出现一个
png的图片

- 再使用
010editor打开该png文件,发现格式png的格式有点问题

- 这时我们尝试修改图片的宽、高,原宽高为

- 修改后的宽高为

- 打开修改后的图片就会发现密码

- 这时就能解密压缩包了,这样就可以得到
flag文件了 - flag:
hagme{h4kyu4_w4nt_gir1f3nd_+q_931290928}

PWN
counting petals
- 先来查看一下保护机制,发现保护全开

- 反编译一下该程序,分析程序逻辑。
- 先初始化一下输入、输出,然后再生成一个随机数。
- 接下来要求用户输入一个数,这个数
小于等于16 - 这个我们就可以对
v7这个数组进行输入(注意这边可以对数组越界访问,可以覆盖其他地址的值) - 然后对
v7[0]这个地方进行修改

- 之后的程序执行流程如下:
- 会逐个输出
v7数组中的值(这里可能会因为数组的越界访问,会导致地址的泄露),并且将这些值加入到v7[0]中 - 还会将之前的一个随机数加到
v7[0]上 - 检查
v7[0]的最后1位是否为0,如果为0就会退出循环 - 还会检查
v4是否大于0,如果v4大于0也会退出循环
- 会逐个输出

- 接下来进行动态调试,现在发现在循环的时候我们写入栈中的数据范围如下,这时我们可以溢出图中箭头指向的位置。之后我们就可以通过之后的循环加法输出从而泄露栈
- 图中箭头指向的位置刚好是变量
v8、变量v5所存储的位置,低地址为变量v8,高地址为变量v9 - 这里还要注意一下,虽然是
scanf("%ld"),但是可以读入8字节的整数,这时我们需要溢出修改v9、v8的值然后就可以进行泄露。 - 这里还要注意一点就是
v8的值一定要小于v9这样才会跳出循环,所以我构造85899345939即(0x1400000013)

- 之后就可以泄露
canary、libc的地址,之后会再一次循环,这次循环我们修改v8、v9的值为-8589934569即(0xFFFFFFFE00000017)这时我们就可以修改v4使其大于0,这样必然可以退出循环,不必考虑随机数的问题 - 之后我们修改
v8、v9我们的循环此时还没退出,还要继续输入,这时我们再趁机修改v8、v9的值为73014444057(即0x11 0000 0019) - 这样我们就可以构造
rop链,从而getshell - exp如下:
1 | from pwn import * |

format
- 这题的泄露地址和
XYCTF中的一题比较像,先来查看一下保护机制,发现没有开pie和canary

- 接下来反编译分析一下程序
- 该程序会先让我们读入,我们格式化输入输出的此时,注意这边有字符串格式化漏洞(这边需要使用
%p泄露栈地址),因为scanf("%3s")已经限制了输入只能3个字符(所以不能使用%7$p) - 之后又存在一个栈溢出
v5这边是int类型
- 该程序会先让我们读入,我们格式化输入输出的此时,注意这边有字符串格式化漏洞(这边需要使用

- 但是
vuln这边对于参数传递过去的v5就会变成unsigned int类型

- 这就会导致溢出,接下来我们进行动态调试,由动态调试可以得知,我们
read(0,buf,a1)中buf的位置在栈上中上面一个红色框的范围中 - 我们注意到
printf(format)中的format存储在箭头指向的地址,此时我们就可以先通过栈溢出,修改format的值为%9$p,从而泄露libc的地址,并且这时候在format之前会覆盖返回地址,这时我们覆盖返回地址为0x4012CF,这样我们就可以泄露libc地址,并且还可以重新再利用read进行一次栈溢出,从而构造rop链getshell


- exp如下:
1 | from pwn import * |

WEB
Level 24 Pacman
- 打开靶机,发现游戏题,直接去看
js。一开始是在inpage.js这边看js,发现并没有什么与flag相关的东西。

- 这时候去看
html文件,发现还引用了三个js文件,逐一排查文件

- 最后发现
flag藏在index.js文件中,搜索flag发现没结果,但是在这边看到了一个gift

- 这时在搜素
gift发现还有二个


1 | gift:aGFldTRlcGNhXzR0cmdte19yX2Ftbm1zZX0= |
base64解码后得到:
1 | haeu4epca_4trgm{_r_amnmse} |
- 栅栏密码解密后如下:
1 | hgame{u_4re_pacman_m4ster} |
- 提交后发现正确的flag为这个:
flag:hgame{u_4re_pacman_m4ster}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 iyheart的博客!

