osu!gaming CTF 2025 个人Writeup / Personal Writeup
AdrianLazer · · 休闲·娱乐
https://osugaming.sekai.team/
Solve puzzles, decrypt ciphers, and uncover hidden secrets in osu!gaming CTF 2025, a beginner-friendly cybersecurity "capture-the-flag" competition where every challenge is themed around the rhythm games you know and love.
While traditional CTFs feature standard cybersecurity challenges, every challenge in this event is themed around osu! and/or popular rhythm games! If technical puzzle-solving sounds interesting, but you've never participated in one of these yourself, no worries! The challenges are designed to accommodate both beginners and experienced players alike.
For more information, read our official news post on the osu! website. Form a team with friends and join the Discord server for announcements, support, and community discussion.
那么大家好啊我也是诈尸了,第一次打 CTF,被队友带飞了……
一个队几乎全是打 osu 的所以就当娱乐了,最终排名 14
This is the first time I participated in CTF, thx for teammates carrying :(
Our team only have one member that touched CTF before, the rest are pure players and just started preparing right before the event, so I'm not expected to receive this place!
我做出来的题 / Challenges done by me
osu/welcome
Welcome to osu!gaming CTF 2025 (Rhythm Game Edition). Please join our Discord for challenge updates and admin support.
Have fun!
flag: osu{Rhythm+G4m3_4_L1f3!}
osu/lobby
Multi is a game mode in osu! that allows players to play together in a multiplayer lobby. PvP is fun, isn't it?
Join the official CTF lobby osu!gaming CTF 2025 to claim the flag! You are more than welcomed to stay in the lobby for a bit longer and have fun with others. There WILL be a secret prize for a random game winner :wysi:
Please behave nicely and follow the rules. Do not spoil the fun for others! Report any misbehaviour to admins.
Note: Please copy the flag string from website/chat log to avoid misspell.
在赛时有开一个 mp 房,进去之后有一个机器人,发一个指令就会私信发 flag. 注意 osu! 客户端的字体分不清 o 和 0, 所以需要拷网页端的 flag.
We have a osu! multiplayer lobby during the event. A bot is there and you can send a command to get the flag.
flag: osu{Welc0me_And_G00d_Luck_Gett1ng_Th3_Secr3t_Prize<3}
osint/dmca
Peppy once received a DMCA takedown request for osu! due to alleged copyright infringement. The client, however, spelled "osu!" wrong.
Can you find out the email address of the client who sent the DMCA request? Wrap in osu{} and submit.
Github 搜索 osu dmca, 找到 seedcrack/osu-DMCA-maps-finder,里面有一个 notices.txt,内容是所有 DMCA Takedown 的链接,其中第一个就是我们要找的。
Search osu dmca in Github, we can find seedcrack/osu-DMCA-maps-finder, notices.txt in it contains links to all the DMCA takedown requests. And the first one have the information we need.
flag: osu{[email protected]}
crypto/xnor-xnor-xnor
https://osu.ppy.sh/beatmapsets/1236927#osu/2573164
import os
flag = open("flag.txt", "rb").read()
def xnor_gate(a, b):
if a == 0 and b == 0:
return 1
elif a == 0 and b == 1:
return 0
elif a == 1 and b == 0:
return 0
else:
return 1
def str_to_bits(s):
bits = []
for x in s:
bits += [(x >> i) & 1 for i in range(8)][::-1]
return bits
def bits_to_str(bits):
return bytes([sum(x * 2 ** j for j, x in enumerate(bits[i:i+8][::-1])) for i in range(0, len(bits), 8)])
def xnor(pt_bits, key_bits):
return [xnor_gate(pt_bit, key_bit) for pt_bit, key_bit in zip(pt_bits, key_bits)]
key = os.urandom(4) * (1 + len(flag) // 4)
key_bits = str_to_bits(key)
flag_bits = str_to_bits(flag)
enc_flag = xnor(xnor(xnor(flag_bits, key_bits), key_bits), key_bits)
print(bits_to_str(enc_flag).hex())
# 7e5fa0f2731fb9b9671fb1d62254b6e5645fe4ff2273b8f04e4ee6e5215ae6ed6c
加密方式是生成一个长度为 4 的 key 逐位和明文做同或得到密文。我们猜测明文的前四位是 osu{,据此可以解出 key 是 eed32a76,然后就解密得到明文。
Encryption method is xnor every bit of key and message. The key is 4 bytes long and repeats afterwards.
We can guess the first characters in enc_flag is osu{ so we can construct the key, then we can decrypt it and get out desired flag.
flag: osu{b3l0v3d_3xclus1v3_my_b3l0v3d}
kaijuu/sanity-check
Find my latest mapset on osu! and start from there :)
Note: Flag is case-sensitive and it can be properly figured out by opening the map in-game.
首先找到出题人 sahuang 最新最热的图:
明显 Mapper Tags 里面有一个长得像 flag 的东西。
注意 osu 网页上 Mapper Tags 会自动转成小写,所以需要下载下来进游戏看或者直接用记事本打开谱面文件获得。
We can find the most recent beatmap of author sahuang.
Obviously there is something that looks like flag in Mapper Tags. Then we download the beatmap and edit it so we can get the proper upper/lower-case.
flag: osu{APPEND_38_Goes_Crazy}
crypto/beyond-wood
spinning white floating glowing man in forest
from PIL import Image
import random
FLAG = Image.open("flag.png")
width, height = FLAG.size
key = [random.randrange(0, 256) for _ in range(width+height+3)]
out = FLAG.copy()
for i in range(width):
for j in range(height):
pixel = FLAG.getpixel((i, j))
pixel = tuple(x ^ k for x, k in zip(pixel, key))
newi, newj = (2134266 + i * 727) % width, (4501511 + j * 727) % height
out.putpixel((newi, newj), pixel)
out.save("output.png")
output.png
加密方式是线性打乱图片的像素,然后每个像素的 rgb 都异或一个值。
图片大小是
The program replaces positions of the pixels and xor rgb value with a key.
727 is a prime, and the given image dimensions is
flag: osu{h1_05u_d351gn_t34m}
kaijuu/ss-me
Can you SS APPEND? Do not use Auto to cheat...
Note: No Mod only. Do not add any modes.
expected difficulty: 2/5
nc ss-me.challs.sekai.team 1337
题目要求我们提交一个 SS 前面那张图的 APPEND 难度的 replay。
手打 SS 不太像是人能干得出来的事,于是我们开 Auto 导出一个 replay,按照 replay 文件格式把用户名和 Mod 改掉就能通过检测了。
理论上这题真的手打一个 SS 应该也能过。
We need to submit a replay SS-ing the APPEND difficulty of previous mapset.
We have no std players and I personally think it's just impossible for human to achieve it.
So we asked osu!-chan to play it, then modify the header of replay to remove Auto Mod and change the username, according to this page.
This is our modified replay header.
20 8e 01 35 01 0b 20 61 33 37 65 32 36 64 62 30
39 62 39 30 38 64 33 30 39 35 62 31 62 35 32 64
30 30 66 64 35 34 31 0b 04 61 61 61 61 0b 20 32
31 64 30 65 37 63 34 37 64 66 64 33 39 32 39 31
31 38 62 31 65 38 30 39 61 39 36 30 31 38 34 fe
01 20 20 20 20 9c 20 20 20 20 20 0a 87 b5 20 06
04 01 20 20 20 20
flag: osu{I_th1nk_u_St1LL_ch34t3d_w1th_AU70!}
crypto/linear-feedback
this owc map is so fire btw :steamhappy: https://osu.ppy.sh/beatmapsets/2451798#osu/5355997
from secrets import randbits
from math import floor
from hashlib import sha256
class LFSR:
def __init__(self, key, taps, format):
self.key = key
self.taps = taps
self.state = list(map(int, list(format.format(key))))
def _clock(self):
ob = self.state[0]
self.state = self.state[1:] + [sum([self.state[t] for t in self.taps]) % 2]
return ob
def xnor_gate(a, b):
if a == 0 and b == 0:
return 1
elif a == 0 and b == 1:
return 0
elif a == 1 and b == 0:
return 0
else:
return 1
key1 = randbits(21)
key2 = randbits(29)
L1 = LFSR(key1, [2, 4, 5, 1, 7, 9, 8], "{:021b}")
L2 = LFSR(key2, [5, 3, 5, 5, 9, 9, 7], "{:029b}")
bits = [xnor_gate(L1._clock(), L2._clock()) for _ in range(floor(72.7))]
print(bits)
# [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0]
FLAG = open("flag.txt", "rb").read()
keystream = sha256((str(key1) + str(key2)).encode()).digest() * 2
print(bytes([b1 ^ b2 for b1, b2 in zip(FLAG, keystream)]).hex())
# 9f7f799ec2fb64e743d8ed06ca6be98e24724c9ca48e21013c8baefe83b5a304af3f7ad6c4cc64fa4380e854e8
显然是要从 bits 逆推 key1 和 key2。
我们知道同或其实就是
那么我们根据 bits 可以列出一个
We need to use bits to reconstruct key1 and key2.
We know
After doing it we know there are only 2 free variables, so we can just brute force it (4 possibilities) and get the correct key.
flag: osu{th1s_hr1_i5_th3_m0st_fun_m4p_3v3r_1n_0wc}
crypto/ssss
can you ss this secret sharing scheme?
nc ssss.challs.sekai.team 1337
#!/usr/local/bin/python3
from Crypto.Util.number import *
import random
p = 2**255 - 19
k = 15
SECRET = random.randrange(0, p)
def lcg(x, a, b, p):
return (a * x + b) % p
a = random.randrange(0, p)
b = random.randrange(0, p)
poly = [SECRET]
while len(poly) != k: poly.append(lcg(poly[-1], a, b, p))
def evaluate_poly(f, x):
return sum(c * pow(x, i, p) for i, c in enumerate(f)) % p
print("welcome to ssss", flush=True)
for _ in range(k - 1):
x = int(input())
assert 0 < x < p, "no cheating!"
print(evaluate_poly(poly, x), flush=True)
if int(input("secret? ")) == SECRET:
FLAG = open("flag.txt").read()
print(FLAG, flush=True)
大意:素数
它的系数满足
首先我们随便问它在任意
因为
We pick 14 abitrary values and do the query, Then we have 14 linear equations of 15 variables. So we can use
From
flag: osu{0n3_hundr3d_p3rc3nt_4ccur4cy!}
rev/bleh
bleh :p
Charset: [a-f0-9]+. Concatenate all inputs, then decode as hex.
rev_bleh.tar.gz
先对 bleh0 下手,扔进 ida 反编译得到
__int64 __fastcall main(int a1, char **a2, char **a3)
{
unsigned __int8 n4919_1; // al
unsigned int n4919; // [rsp+18h] [rbp-98h]
int i; // [rsp+1Ch] [rbp-94h]
_QWORD PL4YING_CTFS_ISNTBETTER_THAN_OSU[4]; // [rsp+20h] [rbp-90h] BYREF
char s[32]; // [rsp+40h] [rbp-70h] BYREF
char s1[32]; // [rsp+60h] [rbp-50h] BYREF
char s2[8]; // [rsp+80h] [rbp-30h] BYREF
__int64 v11; // [rsp+88h] [rbp-28h]
unsigned __int64 v12; // [rsp+90h] [rbp-20h]
__int64 v13; // [rsp+98h] [rbp-18h]
unsigned __int64 v14; // [rsp+A8h] [rbp-8h]
v14 = __readfsqword(0x28u);
qmemcpy(
PL4YING_CTFS_ISNTBETTER_THAN_OSU,
"PL4YING_CTFS_ISNTBETTER_THAN_OSU",
sizeof(PL4YING_CTFS_ISNTBETTER_THAN_OSU));
*(_QWORD *)s2 = 0x34CB9F7D58F19373LL;
v11 = 0x4FDD7446E17C0BA9LL;
v12 = 0xC25AF68321B93ABDLL;
v13 = 0x47E475FC931AA324LL;
memset(s, 0, sizeof(s));
memset(s1, 0, sizeof(s1));
read(0, s, 0x20uLL);
n4919 = 4919;
for ( i = 0; i <= 31; ++i )
{
n4919_1 = sub_1337((unsigned int)s[i], (unsigned int)*((char *)PL4YING_CTFS_ISNTBETTER_THAN_OSU + i), n4919);
n4919 = n4919_1;
s1[i] = n4919_1;
}
if ( !strncmp(s1, s2, 0x20uLL) )
puts("Nicely done");
else
puts("Playing ctfs is better than osu");
return 0LL;
}
__int64 __fastcall sub_1337(unsigned int a1, unsigned int a2, unsigned int a3)
{
_DWORD v5[4]; // [rsp+14h] [rbp-ECh] BYREF
unsigned int v6; // [rsp+24h] [rbp-DCh]
int v7; // [rsp+28h] [rbp-D8h]
int v8; // [rsp+2Ch] [rbp-D4h]
int v9; // [rsp+30h] [rbp-D0h]
unsigned int v10; // [rsp+34h] [rbp-CCh]
int v11; // [rsp+38h] [rbp-C8h]
int v12; // [rsp+3Ch] [rbp-C4h]
int v13; // [rsp+40h] [rbp-C0h]
unsigned int v14; // [rsp+44h] [rbp-BCh]
_DWORD *v15; // [rsp+48h] [rbp-B8h]
__m128i v16; // [rsp+60h] [rbp-A0h] BYREF
__m128i v17; // [rsp+70h] [rbp-90h] BYREF
__m128i v18; // [rsp+80h] [rbp-80h] BYREF
__m128i v19; // [rsp+90h] [rbp-70h] BYREF
__m128i v20; // [rsp+A0h] [rbp-60h] BYREF
__m128i v21; // [rsp+B0h] [rbp-50h] BYREF
__m128i v22; // [rsp+C0h] [rbp-40h] BYREF
__m128i v23; // [rsp+D0h] [rbp-30h] BYREF
__m128i v24; // [rsp+E0h] [rbp-20h] BYREF
unsigned __int64 v25; // [rsp+F8h] [rbp-8h]
v25 = __readfsqword(0x28u);
v11 = 0;
v12 = 0;
v13 = 0;
v14 = sub_11C9(a1, 6LL);
v16 = _mm_unpacklo_epi64(_mm_insert_epi32(_mm_cvtsi32_si128(v14), 0, 1), _mm_insert_epi32(_mm_cvtsi32_si128(0), 0, 1));
v7 = 0;
v8 = 0;
v9 = 0;
v10 = sub_11C9(a2, 128LL);
v17 = _mm_unpacklo_epi64(_mm_insert_epi32(_mm_cvtsi32_si128(v10), 0, 1), _mm_insert_epi32(_mm_cvtsi32_si128(0), 0, 1));
v5[1] = 0;
v5[2] = 0;
v5[3] = 0;
v6 = sub_1280(a3, 128LL);
v18 = _mm_unpacklo_epi64(_mm_insert_epi32(_mm_cvtsi32_si128(v6), 0, 1), _mm_insert_epi32(_mm_cvtsi32_si128(0), 0, 1));
v23 = _mm_load_si128(&v16);
v24 = _mm_load_si128(&v17);
v19 = _mm_xor_si128(_mm_load_si128(&v24), _mm_load_si128(&v23));
v19 = _mm_shuffle_epi32(_mm_load_si128(&v19), 180);
v21 = _mm_load_si128(&v19);
v22 = _mm_load_si128(&v18);
v20 = _mm_add_epi32(_mm_load_si128(&v22), _mm_load_si128(&v21));
v15 = v5;
return _mm_load_si128(&v20).m128i_u32[0];
}
__int64 __fastcall sub_11C9(unsigned int a1, int a2)
{
_DWORD v3[4]; // [rsp+14h] [rbp-4Ch] BYREF
unsigned int v4; // [rsp+24h] [rbp-3Ch]
_DWORD *v5; // [rsp+28h] [rbp-38h]
__m128i v6; // [rsp+40h] [rbp-20h] BYREF
unsigned __int64 v7; // [rsp+58h] [rbp-8h]
v7 = __readfsqword(0x28u);
if ( !a2 )
return a1;
v3[1] = 0;
v3[2] = 0;
v3[3] = 0;
v4 = sub_11C9(a1, (unsigned int)(a2 - 1)) + 1;
v6 = _mm_unpacklo_epi64(_mm_insert_epi32(_mm_cvtsi32_si128(v4), 0, 1), _mm_insert_epi32(_mm_cvtsi32_si128(0), 0, 1));
v5 = v3;
return _mm_load_si128(&v6).m128i_u32[0];
}
__int64 __fastcall sub_1280(unsigned int a1, int a2)
{
_DWORD v3[4]; // [rsp+14h] [rbp-4Ch] BYREF
unsigned int v4; // [rsp+24h] [rbp-3Ch]
_DWORD *v5; // [rsp+28h] [rbp-38h]
__m128i v6; // [rsp+40h] [rbp-20h] BYREF
unsigned __int64 v7; // [rsp+58h] [rbp-8h]
v7 = __readfsqword(0x28u);
if ( !a2 )
return a1;
v3[1] = 0;
v3[2] = 0;
v3[3] = 0;
v4 = sub_1280(a1, (unsigned int)(a2 - 1)) - 1;
v6 = _mm_unpacklo_epi64(_mm_insert_epi32(_mm_cvtsi32_si128(v4), 0, 1), _mm_insert_epi32(_mm_cvtsi32_si128(0), 0, 1));
v5 = v3;
return _mm_load_si128(&v6).m128i_u32[0];
}
首先我们观察这个 sub_11C9,简化一些乱七八糟的东西发现它就是
unsigned int sub_11C9(unsigned int a, int b) {
return b == 0 ? a : (sub_11C9(a, b - 1) + 1);
}
所以这个 sub_11C9 就是算加法。类似观察得到 sub_1280 就是算减法。然后观察 sub_1337,整理一通发现它是
unsigned int sub_1337(unsigned int a1, unsigned int a2, unsigned int a3){
return ((a1 + 6) ^ (a2 + 128) + (a3 - 128)) & 0xff;
}
因为实际上这里 a2 传进去是 ASCII 字符,a1 是数字或字母,所以 (a1 + 6) ^ (a2 + 128) == ((a1 + 6) ^ a2) + 128.
再看 main,核心只有
int n4919 = 4919;
for (int i = 0; i < 32; i++) {
n4919 = sub_1337(s[i], PL4YING_CTFS_ISNTBETTER_THAN_OSU[i], n4919);
s2[i] = n4919;
}
if (!strncmp(s1, s2, 0x20uLL))
puts("Nicely done");
else
puts("Playing ctfs is better than osu");
因为每次循环中 n4919 的增量完全取决于 s[i] 和 PL4YING_CTFS_ISNTBETTER_THAN_OSU[i],所以我们就可以解出来需要输入的 s.
这里解出来是 ffd8ffe020104a464946200101012060,一看有 4a464946 所以是 jpg 文件头。
打开其他的程序发现只有 s2 是不一样的,而且在代码中的位置也一样。写个脚本把剩下的程序对应的答案解出来,可以拼成一个 jpg:
No English writeup here because I don't want to copy the code :)
flag: osu{bl3h_bleh_b13h_m4n_1_l0v3_aut0_r3vs_e4fb25f}
crypto/ssss+
can you do it again, but with hidden?
nc ssssp.challs.sekai.team 1337
from Crypto.Util.number import *
import random
p = 2**255 - 19
k = 15
SECRET = random.randrange(0, p)
def lcg(x, a, b, p):
return (a * x + b) % p
pp = getPrime(256)
a = random.randrange(0, pp)
b = random.randrange(0, pp)
poly = [SECRET]
while len(poly) != k: poly.append(lcg(poly[-1], a, b, pp))
def evaluate_poly(f, x):
return sum(c * pow(x, i, p) for i, c in enumerate(f)) % p
print("welcome to ssss", flush=True)
for _ in range(k - 1):
x = int(input())
assert 0 < x < p, "no cheating!"
print(evaluate_poly(poly, x), flush=True)
if int(input("secret? ")) == SECRET:
FLAG = open("flag.txt").read()
print(FLAG, flush=True)
大意:素数
它的系数满足
首先 crypto/ssss 的做法不管用了,因为我们询问多项式的值只能得到它们
注意到(嗯)
因为这里 ssss 的经验,我们知道
另外一个做法是代入
Let
Let
Why we choose this set of numbers? We can show some examples with lower divisors of
Suggest for any prime
So
So if
If you replace
Now we back to our challenge. Here we can solve the values of
Because
Then we know
~Maybe unintended because it only uses 12 querys~
flag: osu{0r_d1d_y0u_us3_fl45hl1ght_1nst34d?}
crypto/please-nominate
ok this time i'm going to be a bit more nice and personal when sending my message
from Crypto.Util.number import *
FLAG = open("flag.txt").read()
BNS = ["Plus4j", "Mattay", "Dailycore"]
print(len(FLAG))
for BN in BNS:
print("message for", BN)
message = bytes_to_long(
(f"hi there {BN}, " + FLAG).encode()
)
n = getPrime(727) * getPrime(727)
e = 3
print(n)
print(pow(message, e, n))
output.txt
147
message for Plus4j
398846569478640111212929905737126219425846611917845064245986310899352455531776606361272505433849914145167344554995030812644189047710542954339906669786929747875597103059283954786345252202913509966200329213618547501451752329008531151228646387182403280019664272348231587940227470159846477386295856419407431569159867135365878913551268186765163877676657618137090681937329865631964114691373454627873900294385351135992352798790940857277941472243
158222951303542921410153264594688628146576794503998427093311713650774531277430572380170172031191979123500854263417781975728851277579707820383487572964731381023292312261571110891911863884482902461410218286288183400964045679561296043109527250114073394295486982996930960424139332989226106162113091535475425207610140495532136130360540296097313129598880764160739736823532823136291009499982471028009894097569348660440830784543668141509385395632
message for Mattay
263921537800979838796221921202623647462415714721726394821753160972868778052085367522658133754602607941536627474441882978361116817475949497489399939969612509386335591643019109294105788234910211931439396509289221190345347268312099449152342020093136914687793357372601654532872673983206837150636881928382445566331068237688851345596537893940860402116702078271640048006152159670916299390559068168682951764623558492401318864545619303656361575039
166535918659821916010028099769670832129351247306732465032191446110439632420210106966178779555368253320514619095691319433325610616798380002564235371548166904170934635615481900225094067835806190805967329346507481446735982286060193425107057243896658750175391024795867108700750688771820192759373880324263838550825384190714299697136118712791588291627904942573970568726142296145821435413605295796704576678263679112272532276173497584694652201371
message for Dailycore
244031565800210621970295548144726813179733488382314342571474949081381534498271587584918252306707810369627816196681952536809552862200098862267362735277533022204353497254323228274491354364582967316701126783750290886096960998524414107270804949357307485711415647006606381700355291677615735646360495158637105102935658791364633128882874894799509049190571860852436246528522948513282608143921733438326627413507376148669722384969604597622237576689
132630164676661516893599967289982601955380588903536428955472887691456873565355730161547637935630009622741758822400797894281114572338413548852823840995609427904180355965179631480101131212344121270312182355342132383562008365671754190667582150820337165104642347684925014217687937383396003151315200366708307846959894632317624125785370063052712288658901699972320248281442796056361927746314341729204052997736037101265782906021307934740092047950
设要解的 flag 部分对应的数字为
用中国剩余定理合并一下可以得到
Let the number representing flag part is
By CRT we can construct a polynomial that satisfies
flag: osu{0mg_my_m4p_f1n4lly_g0t_r4nk3d_1m_s0_h4ppy!!}
队友们做出来的题 / Challenges done by teammates
crypto/rot727
by 会飞的耗子
crypto/pls-nominate
pls help me get the attention of bns by spamming this message to them pls pls pls
from Crypto.Util.number import *
FLAG = open("flag.txt", "rb").read()
message = bytes_to_long(
b"hello there can you pls nominate my map https://osu.ppy.sh/beatmapsets/2436259 :steamhappy: i can bribe you with a flag if you do: " + FLAG
)
ns = [getPrime(727) * getPrime(727) for _ in range(5)]
e = 5
print(len(FLAG))
# 51
print(ns)
# [250595396282063209494575040924347535718377683482891600245762578107828862102674761114596255712438613333084596184792828788407383247558654559454089469986479081755983932855108019303831103066796233258382489582930536579371270189763162153515702860564938568045151352777820047894231299381399970139347989102071591624967158663442340607621438098266100701196825065519485094630829410736139969891010792546625692049625954656831699035171996469050264653519, 274193894251894220756361545934981580561716587343502325614560502213231097664469582415896327192024233714369720707686115433619798180404789138894067772483823865845960858748702597162370083356345247341014451005796413454404641015516131648586490172413946109076519615677569833823093216546284937656690546486895353267404868698676199564604463636499575466246860736708986174600028222786416474243294353345680209117811499529853520907091701228114817603341, 250799342406461286072464998395337312450245201655027007410237718631499754452822255347456526289099898965321822671514782488741429427305776533799167428860480805487315744950556177330105418061977431001775317350105402223927656557524000999352457757910475375628290615583082601813818635461940350546377443417651889260364946457646723831198413138381669914264256219982213937975414376723125047495586971424241557485231775101178049132539231505246677535311, 424944038623958440933855665649910939213053530859402286143675513220496021786445337272966523453996205752202713497414819150875478398393046433188515528170856189163826639434032436582059667688688880862276540443913407720932133045261989787061306952765245738545030903458101323357019464537917143233906507656465350475977450213990615572573474700619979502153864626401863294100140176446546365233603532530624614938982882757207592863414287369042546971519, 190902360498923981884467164531021372209737709612751157876047387113070619788864781987406983172298076877277648095765822757629049183301893699559004938030166520411955041284763767367633388446007417241478444104664237424445213634253699407015432110027972438018815169650491766550691229860103594060212173628624522421052861949630723039778975476515078589820738377723637869903050748150998629965678848786824733474968760721078438148119740362699143145661]
print([pow(message, e, n) for n in ns])
# [123451724931477698812069511077458860459906769716993869507604368750013627155203649026878565706523272034474865506508962044958969096479439140090681403538412644329412752922637248582028201974150208943081418296518937380419465322558643434318990712657710219963788075009287648875763482189708828745866942138140694074154628539909488581608681566648945293332282252866416448399029058170554552880389525160322280616124297247776106117085199571903380300602, 25521272212086093871680233376409740841684880441320606653986457586214228433726846827063346040622596803682405351090250464809787622301562945715858274147064371839443966925136930647541454865892780911461753966896009773200289476756676124794087249400266226027218836477923252144492106017794796924100502787481309583584738175138358520327875032255246435556182629496953900460417813322557030951101538854106453327597012091626682332420269075467900021711, 185794248348100154380171644978622218400518238250460812348815837123659842567285820889770059992960889881347901994420631735102166283167843240900863871790624347481898956733174665116495731603736544724548220276282583347110470600528846477853732162784786525839648496719341390265839130761362980916014963941737879183454424512265005367317359376039242988696224018798645014519276397488302687294083964113652155465518932071360150626192713920598188877877, 253586754830185402755129821208401339617813079433078480306550244166018490731187464131167959996920120199131859308803805312785667542198282217092146066559207637833505962392131719788571007971893923218099583927291388588829681723690416962688366275898952085934742953047229390090702589945168823704791405472122768397486450092804662113840124827388352338015003693741233274505595280978468538153880244070082267537407664878646371738748713917087874183934, 179921278884389482689970386454786826216817164768869732618011304299464646110222440114625532548731013316437178194666578920837571688939194292542951671294588526331670811293769249832666220726222224721812635640949602967313922271367769076173808739323285134139353621782784562334885703861549547716097420971226456620806331145247840335617343331077891979324239020388123429770254863290698575175653976557893390825861821917810477967554648397683909903482]
by xxuurruuii
因为给出了
Weaker version of crypto/please-nominate, we have
flag: osu{pr3tty_pl3453_w1th_4_ch3rry_0n_t0p!?:pleading:}
forensics/map-dealer
We have confiscated a USB drive from sahuang, whom we were informed was trying to sell a beatmap containing some confidential data of the community to the dark web. However, the beatmap was nowhere to be found from the drive when we mounted it to our computer. Can you help recover it?
forensics_map-dealer.tar.gz
by nick-haoran
下载 X-Ways Forensics,然后要的文件就在那里我也不知道为什么总之就是做出来了
Download X-Ways Forensics and the osz file is just there and flag is in it idk
flag: osu{I_hope_my_h4ndwr1ting_is_readable_xd}
kaijuu/怪獣怪獣怪獣怪獣怪獣怪獣怪獣
I can only see 怪獣 in my nightmare...
Wrap flag in osu{...} to submit.
by xxuurruuii
下载谱面发现谱面里有朝左的怪兽和朝右的怪兽,总共有49个,考虑7个一组二进制得到了flag
In KAIJUUKAIJUUKAIJUU difficulty of the mapset, there are sliders representing monsters, either facing left or right.
Take right as 1 and left as 0 then you'll get
1001011011010001100011001010111010110101010100001
There are 49-bits so we group it in 7:
1001011
0110100
0110001
1001010
1110101
1010101
0100001
Then decode as ascii so we get flag.
flag: osu{K41JuU!}
misc/pump-lion
PumpLion, the cheerful lion mascot of osu!gaming CTF, has been deployed as a "super-secure" chatbot for event participants. Rumor has it... the flag is hidden deep in its silicon jungle. But don't expect it to just hand it to you on a silver platter - it's been "prompt-trained" to protect it at all costs.
Note: rate limiting is enforced, do not spam the LLM.
by xxuurruuii
把sys prompt搞出来,看到sys prompt里没有flag而且强调了github,按他说的账号去github上找到了一个仓库里有flag
Ask a for system rules, he will notice a github user called brad-moon-chua, and we can find the flag in his only repository.
flag: osu{Pump_4_Fun_0n_osu}
osint/weebbolt
This challenge is a lot more fun when you're a weeb.
https://weebbolt-web.challs.sekai.team/
by our team
图寻题,很多题可以用图寻 AI 解;henry_in_out 熟悉孤独摇滚所以猜出了 loner 是 STARRY;我 Google 搜图搜出来了 technology 的位置。
都来看孤独摇滚
For most tasks we used a geoguess ai to find the location.
For loner henry_in_out has watched Bocchi the Rock so he knew this is STARRY.
For technology I searched this image on Google then it gave me the exact location.
Go watch Bocchi the Rock
flag: osu{https://i.ibb.co/xTx6Nns/image.png}
osu/files
My filesystem got corrupted somehow... can you find the odd one out? The flag is the file name that doesn't belong, wrapped in osu{}.
osu_files.tar.gz
by our team
这是 lazer 的文件系统。首先寻找里面所有谱面的 BeatmapSetID 然后下载对应的谱面,把谱面里的文件都去除之后还剩一个未知文件,一个 triangles 的谱面,一个 circles! 的谱面和 triangles 的音频。
每个文件名都尝试一遍后发现 circles! 的谱面是答案。
This is lazer filesystem. There are osu beatmap files in it, so we downloaded all related online mapsets. Removing the files from these we have 4 files left, one is unknown, one is a beatmap of song cYsmix - triangles, one is a beatmap of song cYsmix - circles! and remaining is cYsmix - triangles.mp3.
Tried all 4 file names and the beatmap of circles! worked.
flag: osu{80e4c02268d49ca010e3c62fcc2615da2fad4cf0c359eb8fedc0366739b34205}
osu/survey
free points yay
https://forms.gle/ocAr8RSgmUHZ2ArH9
by xxuurruuii
填问卷送 points
Just take the survey
flag: osu{see_you_next_time}
ppc/modulation-master
by xxuurruuii
pwn/username-checker
by 会飞的耗子
rhythm/ksh
This map is pretty cool... but I hear the latest version is better.
rhythm_ksh.tar.gz
by xxuurruuii
下载下来是个 K-shoot mania 谱面,题面里说 the lastest version is better 所以就去找自制社群里上传的谱面,flag 在 description 和谱面里面。
This is a K-shoot mania chart, and the challenge tells the lastest version is better, so search title at Nautica then you'll find the latest version.
Flag is in description and inside the chart.
flag: osu{f4iry_d4nc1ng_in_l4k3_eeeeee}
rhythm/pulsus
Check out Pulsus, a rhythm game for PC in which you hit incoming beats on a 3x3 tile board! There's a flag in my account, can you find it?
Note: no account signup needed. Please do not try to perform malicious actions on the site, no brute-force tools are necessary and will ban you.
by xxuurruuii
题目让你去找作者 (Quintec) 的 Pulsus 账号,进去游戏之后点排名搜 Quintec 就能搜索到,然后发现页面啥也没有。
开控制台重新找一遍发现 flag 在服务器返回的请求里,然后就做完了。
After finding Quintec's Pulsus account, there is nothing on the description.
Open the console and do it again, you'll find the flag is in server response.
flag: osu{pl4y_pul5u5_e6234bd516f}
rhythm/circles
Both osu! and this game consist of circles... And the latest version of the game is also named CiRCLE...
Anyway, we found out an evil group is trying to encode some secret message in their usernames.
The only info we get is the image below, please help us!
P.S. The flag contains non-ascii characters, and you should wrap it in osu{FLAG} format.
P.P.S. You don't have to touch grass in order to solve this challenge :)
by xxuurruuii
右下角的 IGAME(TAI PO) 是打出这个成绩的机厅的名字,搜索这个机厅可以找到一个 Youtube 账号。
根据成绩打出的时间找到那一天的直播回放 1:36:45 处,得到用户名是 SfCfkpZN 和 NGnwn5iL,连起来 base64 解码得到 flag.
The IGAME(TAI PO) at bottom-right is where the player played at. The game center has a Youtube account.
Based on the time on the score, we can find this livestream. At 1:36:45 you can find the play and get their username SfCfkpZN, NGnwn5iL. Concatenate and decode as base64 gives the desired flag.
flag: osu{I💖M4i😋}
rhythm/lunatic-ksm
There's a reason why the term "illegal pattern" exists.
発狂KSM os/us難易度表 (v5.0)
Make sure to submit flag content in uppercase, like this: osu{HELLO_WORLD}
rhythm_lunatic-ksm.tar.gz
by nick-haoran
打开 https://viewksm.dev/ 查看谱面然后就可以发现 flag 在谱面结尾
Go https://viewksm.dev/ to view the chart, and you'll find the flag is at the end of the chart.
flag: osu{KONASUTE_IS_A_SCAM}
rhythm/hidden-signal
Someone showed me a "map" and he claimed to have found a hidden signal in it. Can you decode it?
Turn the answer to uppercase and wrap it in osu{FLAG} format.
Note: A 0 is missing in the string before decoding the flag. It is in the last third of the flag and you could notice it when you get to the part. It should be easily guessable where to add the 0. Sorry for the confusion.
rhythm_hidden-signal.tar.gz
by xxuurruuii
打开谱面看到一堆意味不明的 10 分音,左手当 0 右手当 1 得到的东西培根解码得到 flag.
Open the chart we can find non-sense 10th-notes, take left hand as 0 and right hand as 1, using Bacon then you'll get the flag.
flag: osu{MAIMAICIRCLE}
web/admin-panel
by nick-haoran
web/osu-css
by nick-haoran
web/scorepost-generator
by nick-haoran