0xGame 2024 WriteUp
Misc
我叫曼波
没什么难度,对照着写出解密算法即可
- 将曼波转为base3编码
 - base3编码每5位化为一组,一组对应一个字符
 - 带着密钥直接RC4解密
 
1  | import base64  | 
哈哈哈,现在想想我也是个神人了,人工在这手工复制粘贴一个晚上,复制粘贴了96次。
然而,这是一场漫长的等待,硬控了我一个晚上,如果我会用脚本就好了。。。

总之,一个个手动输入得到flag:0xGame{OH_yEah_Wow_Duang_HajiMi_u_MADE_it!_and_MaY_5e_Y0u_hAv4_HeArD_7he_ST0ry_0f_Gu_Gao_MaN_B0}
Crypto
Diffie-Hellman
分析代码,先验证,再交换密钥,再发密文
写出解密的代码,先爆破验证码,再生成私钥、公钥,交换后用共享密钥解密即可
1  | from string import ascii_letters, digits  | 
这是运行过程
1  | ┌──(root㉿Spreng)-[~]  | 
1  | 请输入proof: zDiTjZjxIV6pJH98  | 
Elgamal
这道题是Elgamal已知签名伪造,算法基于以下结论:
其中 可用CRT求
1  | #!/usr/local/bin/python  | 
运行过程:
1  | ┌──(root㉿Spreng)-[~]  | 
1  | 请输入proof: 0ERfrggK1aHpr73u  | 
LFSR-baby
这道题就是逆推原始状态,先描述一下顺推一次的过程,output^=mask & state
1  | output ^= mask[i] & state[i]  | 
由于提供的状态是顺推了128次的,等于state长度,所以我们知道一个完整的状态,下面描述逆推:
1  | # state: [1, 1, 0, 1]  | 
脚本如下:
1  | from hashlib import md5  | 
说几个点:
- 这里mask的第一位必须是1,不然逆推不了
 - 两组输出只有127位,需要在前面补个0
 - 虽然有两组输出,但只要用第一个逆推就可以了
 
LFSR-eazy
这道题就是根据给出的数据算出mask,需要对这种布尔运算有一定敏感度(我也是现学的),关键就是构造线性方程组:
这里n=128,c表示mask的各个位,k表示state的各个位,k长度为2n即可求解,虽然有两组输出加初始状态,只要用两个就够了。
这里的线性方程组因为是二进制的,没法用numpy,就自己写了(学线代学的)
脚本如下:
1  | from hashlib import md5  | 
RC4
脚本:
一般来说RC4一次一密安全,但这里的keystream并没有变化,只要逆推出密钥流即可求解。
一个注意的点是明文的长度要足够长,我的正好和flag一样长
1  | import findProof  | 
运行过程:
1  | ┌──(root㉿Spreng)-[~]  | 
1  | 请输入proof: A2GqA4fgP7eMaAIK  | 
RSA-Ⅳ
总之就是写脚本算
1  | import gmpy2  | 
这是运行过程
1  | ┌──(root㉿Spreng)-[~]  | 
Reverse
BabyUPX
先用exeinfope查壳,发现有upx加壳,用upx脱壳,使用IDA解析
1  | int __cdecl main(int argc, const char **argv, const char **envp)  | 
只要获取encdata并解码即可,这是python代码:
1  | def decode(encoded_bytes):  | 
FirstSight-Jar
先丢到在线jar反编译网站上,得到:
1  | import java.util.Scanner;  | 
编写解密脚本
1  | def decrypt(encrypted_str):  | 
FisrtSight-Pyc
先丢到在线python反编译网站上,AI修复后,得到:
1  | #!/usr/bin/env python  | 
修改代码,
1  | # user_input = input("请输入神秘代号:")  | 
运行得到flag:0xGame{2f0ef0217bf3a7c598d381b077672e09}
Xor::Ramdom
首先读码可知flag长度为38,内容30,random应当取以0x77u为种子的第二个随机数123
1  | 
  | 
可以看出flag应当从v13, v14, v15, v16还原
不难发现这4个整数不算0的话恰好有30个字节,那就把他们转成字节解密
1  | def int64_to_bytes_list(*ints):  | 
先是直接拼接v13, v14, v15, v16,再尝试反转,得到了有点奇怪的flag:
1  | 0xGame{ndom'!w4ys_'Ra5_n0t_alr4nd0m_i}  | 
于是尝试拼接v16, v15, v14, v13,再反转,得到flag:
1  | 0xGame{r4nd0m_i5_n0t_alw4ys_'Random'!}  | 
ZzZ | Review
美化一下关键代码,显然有 x1,x5,需要解带位运算的方程组
1  | scanf("0xGame{%8llx-%4s-%4s-%4s-%12llx}", x1, x2, x3, x4, x5);  | 
使用 z3 求解器求解:
1  | from z3 import *  | 
OSINT
互联网的一角
提供的网页只有一条提示:这个网址好像指向了另一个网址…
既然是OSINT,那就用搜索引擎查一下找到GitHub

哈哈,原来是上传了再改掉

给我干哪来了,这还是国内吗??

注意到文字:SUPER ST-BERNARD

在Google地图上通过文字找到地址:Bourg-Saint-Bernard 2, 1946 Bourg-Saint-Pierre, 瑞士
搜索地址的 国家_州_区_城市 得到flag:0xGame{Switzerland_Valais_Entremont_Bourg-Saint-Pierre}
