最近、感謝を伝えられていますか?
こちらはYuruvent Advent Calendar 2025 24日目の記事です️。
はじめに
どうも!chamaです。
クリスマスに大学へ行こうとしたのですが、雨が降っていたので家でぬくぬくしていました。 早速ですがみなさん、最近友達や家族といった周りの人に感謝を伝えていますか? 最近自分が考えていたことを、せっかくなのでYuruventの記事として書いてみようと思い、筆を取りました。
ただ、内容はいつもの雰囲気とは少し違うかもしれません。そこは許してください。
なお、この記事には個人的な話が含まれます。苦手な方はここでそっと閉じていただけると嬉しいです。
感謝を伝えられなかったあの日
私は今年、本厄です(早生まれなので)。普段はあまり気にしていなかったのに、今年はいろいろなことが重なりました。
小学校からの友達が、この世を去りました。
11月にご飯を食べに行ったとき、「来月、忘年会しような!」と約束していたのに。 その約束が、叶うことはありませんでした。
あの日からしばらく経ったある日、友達のお母さんから連絡が来ました。友達が亡くなった、と。
いつもの日常は、当たり前に続くものだと思っていました。 でも、それは突然終わってしまいました。後悔の念は一生消えないかもしれないし、ふとしたときにまた自分を責めてしまうかもしれません。 ただ、今年はお世話になった方がたくさんいます。今回の話とは直接関係ないですが、いろいろな経験をすることができましたし、たくさん心配もかけてしまいました。
それに、自分が明日生きている保証もありません。だからこそ、伝えられるときに伝えるべきだと思います。 みなさま、今年1年お世話になりました。 みなさまのおかげで、ここまで無事に過ごしてこられたと思います。 来年も、ゆるゆると研究も勉強も頑張っていきたいと思いますので、これからもよろしくお願いします。
そして私は、感謝を伝える機会を永遠に失ってしまいました。
私は今うつ病の治療中で、この出来事は自分にとってとても大きく、つらい出来事でした。 「自分がいるから厄を振りまいてしまった」「自分なんていなければいい」と何度も思いました。 けれど涙は出ず、苦しさだけが長く残っていました。
当たり前って実は当たり前じゃない
友達とお別れしてから、この記事を書いている今で数週間が経ちました。 それでも後悔の念は、いまだに消えていません。 まあ、そんなにすぐ消えるはずもないのですが。
考えてみれば、当たり前のことです。将来どうなっているか、来月何をしているかはある程度想像できても、明日の自分に何が起こるかは正直わかりません。 もしかしたら、明日大地震が来るかもしれません。
スケールの大きい話じゃなくても、友達と喧嘩して、そのまま疎遠になるかもしれない。 本当に些細なことが原因で、関係が崩れてしまうこともあります。 そして、その一度の出来事がきっかけで、いろいろなものが終わってしまうこともある。
わかってはいるのに、それが日常になっていると、何も感じなくなってしまいます。 「いつも通り」が続くと、つい当然だと思ってしまう。 感謝の気持ちも、いつの間にか薄れてしまうでしょう。
実際、「親しき中にも礼儀あり」ってことわざがあるくらいですし。
勇気をだして感謝を伝えてみよう
意外と忘れがちですが、近くにいる人ほど感謝の気持ちは伝えそびれます。 実際、自分もそうでした。そして、心残りがあると、それは一生、心にこびりついてしまいます。
さて、みなさんは最近「ありがとう」って伝えましたか?
まだ伝えてないあなた! すぐに伝えましょう! いざ伝えようとすると恥ずかしいですが、ちょっぴり勇気を出して「ありがとう」と言ってみると、伝える側も受け取る側も嬉しくなると思います。 この記事を投稿したら、Yuruventのメンバーにも「ありがとう」を伝えに行きます。
おわりに
後悔の念は一生消えないかもしれないし、ふとしたときにまた自分を責めてしまうかもしれません。 ただ、今年はお世話になった方がたくさんいます。今回の話とは直接関係ないですが、いろいろな経験をすることができましたし、たくさん心配もかけてしまいました。
それに、自分が明日生きている保証もありません。だからこそ、伝えられるときに伝えるべきだと思います。
みなさま、今年1年お世話になりました。 みなさまのおかげで、私は無事に一日一日を過ごしてこられたのだと思います。 来年は、心配をかけないように、ときに休息をとりつつ、ゆるゆると研究も勉強も頑張りたいと思います。これからもよろしくお願いします。
それでは、チャオ!
0xl4ugh CTF 2024 writeup
I participated in the 0xl4ugh CTF 2024. Due to time constraints, I was only able to solve one challenge.
My_Vault
problem
I love saving my chats with my friends on my laptop but I should protect them, they have info can make you a billionaire 😎, so to protect them well I decided to protect each chat with a different password, so I will protect each one with the year I knew him at and his country (example is 2013brazil) now I'm sure I'm the only one who know these info.
import base64 import hashlib from cryptography.fernet import Fernet # Function to generate a key from the password def generate_key(password): # Hash the password to generate a consistent key password_bytes = password.encode('utf-8') key = hashlib.sha256(password_bytes).digest() # SHA256 to get a 32-byte key return base64.urlsafe_b64encode(key) # Fernet requires the key to be in base64 format # Function to encrypt the file def encrypt_file(file_name, password): # Generate a key based on the password key = generate_key(password) cipher = Fernet(key) # Read the original file content with open(file_name, 'rb') as file: file_data = file.read() # Encrypt the data encrypted_data = cipher.encrypt(file_data) # Save the encrypted content to a new file with open(f"encrypted_{file_name}", 'wb') as encrypted_file: encrypted_file.write(encrypted_data) print(f"File encrypted successfully! Encrypted file saved as 'encrypted_{file_name}'.") # Main script def main(): # Prompt the user for file name and password file_name = input("Enter the file name to encrypt: ") password = input("Enter the password to use for encryption: ") # Encrypt the file encrypt_file(file_name, password) if __name__ == "__main__": main()
Solve
It starts with gAAAAA and, based on the source code, it is encrypted using Fernet. Additionally, the problem statement indicates that it is the year + country name, making it possible to decrypt it through brute force.
import base64 import hashlib from cryptography.fernet import Fernet def generate_key(password): password_bytes = password.encode('utf-8') key = hashlib.sha256(password_bytes).digest() return base64.urlsafe_b64encode(key) def decrypt(encrypted_file, password): key = generate_key(password) cipher = Fernet(key) with open(encrypted_file, 'rb') as file: encrypted_data = file.read() try: decrypted_data = cipher.decrypt(encrypted_data) print(f"Success! Password: {password}") output_file = f"decrypted_{encrypted_file}" with open(output_file, 'wb') as decrypted_file: decrypted_file.write(decrypted_data) print(f"Decrypted file saved as: {output_file}") return True except Exception: return False def brute_force(encrypted_file, years, countries): for year in years: for country in countries: password = f"{year}{country.lower()}" # Combine year and country print(f"Trying password: {password}") if decrypt(encrypted_file, password): return # Stop if successful print("Password not found in the given range.") def load_countries(): return [ "Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Antigua and Barbuda", "Argentina", "Armenia", "Australia", "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Brazil", "Brunei", "Bulgaria", "Burkina Faso", "Burundi", "Cabo Verde", "Cambodia", "Cameroon", "Canada", "Central African Republic", "Chad", "Chile", "China", "Colombia", "Comoros", "Congo", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Eswatini", "Ethiopia", "Fiji", "Finland", "France", "Gabon", "Gambia", "Georgia", "Germany", "Ghana", "Greece", "Grenada", "Guatemala", "Guinea", "Guinea-Bissau", "Guyana", "Haiti", "Honduras", "Hungary", "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica", "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Korea", "Kuwait", "Kyrgyzstan", "Laos", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Mauritania", "Mauritius", "Mexico", "Micronesia", "Moldova", "Monaco", "Mongolia", "Montenegro", "Morocco", "Mozambique", "Myanmar", "Namibia", "Nauru", "Nepal", "Netherlands", "New Zealand", "Nicaragua", "Niger", "Nigeria", "North Macedonia", "Norway", "Oman", "Pakistan", "Palau", "Palestine", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Poland", "Portugal", "Qatar", "Romania", "Russia", "Rwanda", "Saint Kitts and Nevis", "Saint Lucia", "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Sao Tome and Principe", "Saudi Arabia", "Senegal", "Serbia", "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands", "Somalia", "South Africa", "South Sudan", "Spain", "Sri Lanka", "Sudan", "Suriname", "Sweden", "Switzerland", "Syria", "Tajikistan", "Tanzania", "Thailand", "Timor-Leste", "Togo", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", "Tuvalu", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "United States", "Uruguay", "Uzbekistan", "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Yemen", "Zambia", "Zimbabwe" ] # Main script if __name__ == "__main__": encrypted_files = ['encrypted_friend1.txt', 'encrypted_friend2.txt', 'encrypted_friend3.txt'] for file in encrypted_files: years = [str(year) for year in range(1800, 2024)] # Adjust year range as needed countries = load_countries() brute_force(file, years, countries)
0xL4ugh{sad!__no_easy_challsanymore}
ASIS CTF Final 2024 Writeup
Our team, full_weak_engineer, achieved 9th place globally and 3rd place in Japan.

Misc/Thuesday
Introduction
On Thuesday, your task is straightforward: simply send an array of numbers that fulfill the requirements.
#!/usr/bin/env python3
import sys
from random import randint
from flag import flag
def die(*args):
pr(*args)
quit()
def pr(*args):
s = " ".join(map(str, args))
sys.stdout.write(s + "\n")
sys.stdout.flush()
def sc():
return sys.stdin.buffer.readline()
def POW(S, k):
Sk = 0
for s in S:
Sk += s ** k
return Sk
def main():
border = "┃"
pr( "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓")
pr(border, ".::: Welcome to the Thuesday PPC task! ::.", border)
pr(border, ".:: Your mission is to find flag by solving the Thuesday puzzle ::.", border)
pr( "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛")
nbit, _b, LEVEL = 2, False, 11
while True:
pr(f"{border} Options: \n{border}\t[I]nfos! \n{border}\t[S]olve the challenge! \n{border}\t[Q]uit")
ans = sc().decode().strip().lower()
if ans == 'i':
pr(border, f'{nbit = }')
elif ans == 's':
pr(border, f'Please send the elements of first set I_1: ')
I_1 = sc().decode()
pr(border, f'Now please send the elements of second set I_2: ')
I_2 = sc().decode()
try:
I_1 = [int(_) for _ in I_1.split(',')]
I_2 = [int(_) for _ in I_2.split(',')]
if (
set(I_1) & set(I_2) == set()
and 2**(nbit - 1) <= len(I_1) + len(I_2) <= 2**nbit - 1
and min(I_1) + min(I_2) >= 3
):
_b = True
except:
die(border, "Your inputs are not valid! Bye!!")
if _b:
r = randint(2, nbit)
for _ in range(r):
k = randint(1, nbit - 1)
if POW(I_1, k) == POW(I_2, k):
continue
else:
die(border, "Your inputs are not correct! Bye!!")
pr(border, f'Good job, try the next step now :)')
nbit += randint(1, 2)
_b = False
if nbit >= LEVEL:
die(border, f"Congratz! You got the flag: {flag}")
else:
die(border, f"Your input does not meet the requirements!!")
elif ans == 'q':
die(border, "Quitting...")
else:
die(border, "Bye...")
if __name__ == '__main__':
main()
By inserting numbers into , the numbers randomly selected from 1 to nbit become the exponents, and
are raised to these powers. If the sums are equal, nbit is randomly increased by 1 or 2. If nbit reaches 11 or higher, the challenge is cleared.
Upon researching "equal sums of like powers," I found a paper that searches for sets x and y such that:
Σxk =Σ yk
for a given k. However, the following conditions must be met:
- No Overlap Between Sets 1 and 2: The elements in I1 and I2 must be distinct.
- Total Number of Elements: The sum of the number of elements in both sets must be between 2level-1and2level - 1 (initially, nbit=2).
- Minimum Value Constraint: The smallest element in both sets must be at least 3.
solve
I found the following websites that are relevant to this problem:
mathworld.wolfram.com These types of equations are known as Multigrade Equations. Although they go up to the 10th power, they include negative numbers, which violate the third condition mentioned above.
Further research led me to another site:
On April 8, 2023, Jaroslaw Wroblewski sent the "first known prime solution to the Prouhet–Tarry–Escott problem of degree 11" [32058169621, 32367046651, 32732083141, 33883352071, 34585345321, 35680454791, 36915962911, 38011072381, 38713065631, 39864334561, 40229371051, 40538248081] = [32142408811, 32198568271, 32900561521, 33658714231, 34978461541, 35315418301, 37280999401, 37617956161, 38937703471, 39695856181, 40397849431, 40454008891] All the 24 above terms are (11-digit) prime numbers and the sum of k-th powers of left terms is equal to the sum of k-th powers of right terms for any k=1,2,3,...,11. This solution corresponds to one of the two questions from the Problem 67, from this site, probably posed during the year 2016 or shortly after.
Based on the above resources, the approach can proceed as follows: For k=2:
m={1,6,8} and n={2,4,9}
For k=3:
m={1,5,8,12} and n={2,3,10,11}
For k=4:
m={1,5,8,12,18,19} and n={2,3,9,13,16,20}
Up to k=11 (if the number of elements is at least 24):
[32058169621, 32367046651, 32732083141, 33883352071, 34585345321, 35680454791, 36915962911, 38011072381, 38713065631, 39864334561, 40229371051, 40538248081] = [32142408811, 32198568271, 32900561521, 33658714231, 34978461541, 35315418301, 37280999401, 37617956161, 38937703471, 39695856181, 40397849431, 40454008891]
These can be used to go up to the 11th power. Addressing Conditions 1 and 2 Condition 1 ensures that there is no overlap between I1 and I2, which is currently being enforced. Condition 2 requires the total number of elements to be within the specified range. This can be satisfied by adding a large number of zeros since there is no restriction on the elements of I1 and I2other than the overlap constraint. Thus, the remaining task is simply to implement the solution.
from pwn import * HOST = "5.75.193.99" PORT = 11311 PTE_PRIMES_LHS = [ 32058169621, 32367046651, 32732083141, 33883352071, 34585345321, 35680454791, 36915962911, 38011072381, 38713065631, 39864334561, 40229371051, 40538248081 ] PTE_PRIMES_RHS = [ 32142408811, 32198568271, 32900561521, 33658714231, 34978461541, 35315418301, 37280999401, 37617956161, 38937703471, 39695856181, 40397849431, 40454008891 ] def make_num(nbit): if nbit == 2: return [1, 2], [3] elif nbit == 3: return [1, 6, 8], [2, 4, 9] elif nbit == 4: return [1, 5, 8, 12, 18, 19], [2, 3, 9, 13, 16, 20] lhs = PTE_PRIMES_LHS[:] rhs = PTE_PRIMES_RHS[:] lower = 2 ** (nbit - 1) current_size = len(lhs) + len(rhs) if current_size < lower: add_zero = lower - current_size lhs.extend([0]*add_zero) return lhs, rhs LEVEL = 0 def main(): r = remote(HOST, PORT) while True: try: data = r.recvuntil(b"Options:").decode() r.sendline(b"I") line = r.recvline().decode().strip() while True: line = r.recvline().decode().strip() print(f"Received line: {line}") if "nbit =" in line: try: nbit = int(line.split("=")[-1].strip()) LEVEL = nbit print(f"Parsed nbit: {nbit}") break except ValueError: print("Failed to parse nbit.") break print(LEVEL) data = r.recvuntil(b"Options:").decode() print("--- Server menu again ---") print(data) r.sendline(b"s") r.recvuntil(b"Please send the elements of first set I_1: ") I1, I2 = make_num(nbit) print(f"[SOLVE] I1={I1}") print(f"[SOLVE] I2={I2}") r.sendline(",".join(map(str, I1)).encode()) r.recvuntil(b"Now please send the elements of second set I_2: ") r.sendline(",".join(map(str, I2)).encode()) if LEVEL >= 9: try: line = r.recvline().decode() line = r.recvline().decode() flag = r.recvline().decode() print(repr(flag)) r.close() except: pass except EOFError: print("EOFError: The server closed the connection unexpectedly.") break except Exception as e: print(f"Exception occurred: {e}") break r.close() if __name__ == "__main__": main()
The server sends a message that includes the flag embedded within a byte string representation:
"┃ Congratz! You got the flag: b'ASIS{tH3_Prouhet_Thue_Morse_5Equenc3_in_PPC!}'\n"
Here, the actual flag is ASIS{tH3_Prouhet_Thue_Morse_5Equenc3_in_PPC!}.
CODE BLUE2024体験記
TsukuCTF2023 writeup
初めてOSINT系のCTFでました。しかも、大学院の後輩と出まして、24位と満足の結果でした! とても楽しく解けたので余韻に浸りながら解いた問題をまとめていきます。
Web
basic
保護されていない通信ではパスワードはまる見えダゾ! e.g. パスワードが Passw0rd! の場合、フラグは TsukuCTF23{Passw0rd!} となります。"
Passwords are fully visible in unencrypted connections! e.g. If the password is Passw0rd!, the flag is TsukuCTF23{Passw0rd!}.
basicと書かれているので、basic認証だろうと予想します。
httpでフィルターかけてみると、以下のパケットが見れる。
一番下のパケットが怪しいので見てみると、以下の情報が見れる。
![]()
TsukuCTF23{2929b0u4}
OSINT
CtrlAltPrtSc 427pt
仕事中にCtrl + Alt + PrtScでウィンドウのスクリーンショットを撮ったよ。
つくし君がサボって使用していたサービスの名前を答えよ。 フラグはTsukuCTF23{サービスの名前}の形式です。
Tsukushi-kun took a screenshot of a window at work using Ctrl + Alt + PrtSc. Please give the name of the service that Tsukushi-kun used when he was slacking off from work. Flag format is TsukuCTF23{Service name}

左上をよく見てみると、YouTubeの文字がありますね。(よく研究してるときにやる手法だからすぐわかったのは秘密)
TsukuCTF23{YouTube}
perfume 198pt
とある施設でいろいろな香水を見かけたが、施設の場所が思い出せない。 この施設の場所を調べ、教えてほしい。
フラグはTsukuCTF23{緯度_経度}であり、小数点第三桁まで有効である。
I saw various perfumes at one facility, but I cannot remember where the facility is located. Please find out where this facility is located and tell me. Flag format is TsukuCTF23{latitude_longitude} And is valid to the third decimal place.

複数の香水が置いてあるのでなんとなく博物館的な場所かなと予想する。 まずが、Google Lensを見てみると、とある人の旅日記に似た写真が載っており場所は大分香りの博物館だった。
後はそれっぽいところをGuess
TsukuCTF23{33.312_131.488}
castle 100pt
この前、お城に行ってこの写真を取ってきたんだ! どこにあるかわかるかい?
フラグのフォーマットは、TsukuCTF23{緯度_軽度} です。 小数点は第三桁まで有効とします。
I took this picture in a castle last time. Do you know where it is?
The flag format is TsukuCTF23{latitude_longitude}, and is valid to the third decimal place.

見たことある気もするけど、Google Lens先生に聞いたらわかりました。
場所は太陽公園で、写真と同じ場所を探せばOK
TsukuCTF23{34.886_134.630}
mab 228pt
mab.main.jpが使用しているレンタルサーバサービスを特定し、そのWebサイトのドメイン名を答えてください。Flagフォーマットは TsukuCTF23{ドメイン名}です。 Please identify the rental server service used by mab.main.jp and answer me with the domain name of the website. The flag format is TsukuCTF23{domain_name}.
Whoisで検索をすると、
[Name Server] sv.madame.jp [Name Server] dns2.lolipop.jp
と出てくる。dns2.lolipop.jpの方が多そうなので、そっちをGuess。 ちなみに、main.jpはlolipop.jpらしい。勉強になった。
TsukuCTF23{lolipop.jp}
green_bridge 180pt
この写真が撮影されたのはどこですか...? Flagフォーマットは TsukuCTF23{緯度_経度} です。 端数は少数第4位を四捨五入して小数点以下第3位の精度で回答してください。
Where is the picture taken? The flag format is TsukuCTF23{latitude_longitude}. Round fractions to the nearest fourth decimal place and answer the third decimal place.

Google Lensで調べると、サイクリング日記を書いている人の写真が出てきた。 この場所はもみじ谷大吊橋というらしく恋人の聖地らしい。
そんな情報はどうでも良くて、今回聞かれているのは撮影者の位置なので、Google Mapから予測をしてGuess。
TsukuCTF23{36.956_139.880}
kiZOU 321pt
ここは日本で一番のリゾート地!少し歩くと目の前に素敵な像が見えたから写真を撮ったつもりだったんだけど、見返したら端っこしか写ってない!困ったなぁ、この像についてもっと知りたかったんだけどなぁ。僕の代わりにこの像について調べてくれないか? フラグ形式は TsukuCTF23{像を寄贈した人物の名前} です。
This is the best resort in Japan! I took a picture when I saw the nice statue in front of me. However, I noticed only the edge is in the picture. So, could you please investigate for the statue instead of me. The flag format is TsukuCTF23{the person name who donated the statue}.
まず、右側のガラスを見ると、au style NAHAと書かれているため、場所を調べる。 そうすると、デパートリウボウとパレット久茂地(くもじ)がでてきた。
多分、くもじと久茂地が出てきたから古い情報もあるだろう読みでシーザーの情報を調べると、島常賀さんという人間国宝の話が出てきた。
寄贈の形を作ったのが島常賀さんらしい。後は、島常賀 パレット久茂地 寄贈と調べるとTwitterXで上原清善氏が寄贈したという情報が出てきた。
高専カンファ沖縄でこのデパートでバス降りたの思い出しました。なつかしいな。
TsukuCTF23{上原清善}
big_statue 354pt
大きなドリアンだ!どこにあるんだろう?? フラグの形式は TsukuCTF23{緯度_経度} です。例えば、この像が東京の渋谷駅にある場合、フラグは TsukuCTF23{35.6580_139.7016} となります。
What a big durian! Where is this?? The flag format is TsukuCTF23{latitude_longitude}. If this statue is at Shibuya station in Tokyo, the flag would be TsukuCTF23{35.6580_139.7016}.
Google Lens で似たような場所で動画を取っている投稿をFaceBookで見つけた。
その人の投稿を見ると、Lexus Durian King - Upper Serangoonで実際に見てみると全く同じだった。 後は、写真と地点を見つけてGuess
TsukuCTF23{1.3623_103.8873}
travel_with_tsukushi 281pt
旅が好きなつくしくんは、空港の写真からそれがどこの空港かすぐにわかります。 つくしくんからの挑戦状! これがどこの空港かわかるかな? Flagフォーマットは TsukuCTF23{空港の3レターコード(IATA)} です。
Tsukushi, who loves to travel, can easily tell the airport where it is taken in. This is a challenge from him. Do you know which airport this is? The flag format is TsukuCTF23{3 letter code of the airport (IATA)}.\
まず、3つの飛行機の会社を調べると、エア・アラビア、バティック・エア、マレーシア航空だった。 後は、この3つが止まる飛行場を探してあげたらOK。
今回はクアランプール国際空港
TsukuCTF23{KUL}
free_rider 463
https://www.fnn.jp/articles/-/608001 私はこのユーチューバーが本当に許せません! この動画を見たいので、元のYouTubeのURLを教えてください。 また、一番上の画像(「非難が殺到」を含む)の再生位置で指定してください。 フラグフォーマットは、TsukuCTF23{https://www.youtube.com/watch?v=REDACTED&t=REDACTEDs}
https://www.fnn.jp/articles/-/608001 I really can't stand this YouTuber! I would like to watch this video, so please tell me the original YouTube URL. Also, please specify the playback position of the top image (including 「非難が殺到」). Flag format is TsukuCTF23{https://www.youtube.com/watch?v=REDACTED&t=REDACTEDs}
何かYouTubeで見た記憶があります。 まずは、この外国人が誰かを探すため調べると、Fidias Panayiotouであることがわかりました。
この人のチャンネルに行ったが、残念ながらYouTubeポリシーに違反したため削除されてしまったので、Archive.todayでFidiasのチャンネルに飛び、該当動画を開くと動画IDがDg_TKW3sS1Uであることが分かった。 後は適当に無断転載している動画から時間を探せばOK
TsukuCTF23{https://www.youtube.com/watch?v=Dg_TKW3sS1U&t=175s}
fiction 491pt
「座標を教えてくれ」 フラグフォーマットは、TsukuCTF23{緯度_経度}です。 小数点以下5位を切り捨てて、小数点以下4桁で答えてください。
"Give me the coordinates." The flag format is TsukuCTF23{latitude_longitude}. Round down to 5 decimal places and submit your answer to 4 decimal places.
どうみてもValorantのサンセットのマップです。
Valorantを知らなくても画像検索である程度は出てくると思います。
これはTipsですが、Valorantは実在する場所を参考にしてマップを作成しています。今回のサンセットはアメリカのロサンゼルスになります。
また、ゲーム内でマップが表示されているときの左側に座標が載っています。
今回の場合、サンセットは34° 2' C' N, 118° 12' YT Wとなります。
また、このサイトによると、Valorantは一部を文字として表します。
詳しくはサイトを見てください。
今回C->2 YT -> 16となるため、34°2'2" N 118°12'16" Wとなります。
後は変換して終わり。
TsukuCTF23{34.0338_-118.2044}
laser 433pt
光源の座標を正確に教えてください。 フラグフォーマットは、TsukuCTF23{緯度_経度}です。 小数点以下5位を切り捨てて、小数点以下4桁で答えてください。
Please tell me the exact coordinates of the light source. The flag format is TsukuCTF23{latitude_longitude}. Round down to 5 decimal places and submit your answer to 4 decimal places.
前に横浜の乃木坂ライブで似たようなニュースがあったことを思い出したので、都会 緑色 レーザーと調べたらそれらしきニュースが。
御堂筋イルミネーションでランドマークレーザーを打ち上げているとのこと。
後は、御堂筋イルミネーションの画像を探して似た場所を探せばOK
TsukuCTF23{34.7015_135.4991}
river 469pt
弟のたくしから、「ボールが川で流されちゃった」と写真と共に、連絡がきた。 この場所はどこだ? Flagフォーマットは TsukuCTF23{緯度_経度} です。 端数は少数第5位を切り捨てて小数点以下第4位の精度で回答してください。
I received a call "My ball got washed away in the river" with a picture from my younger brother, Takushi Where is this place? Flag format is TsukuCTF23{latitude_longitude}. Please answer to the fourth decimal place with fractions rounded down to the fifth decimal place.
左側を見るとnewqinと見えてnewginの専用駐車場が見える。
パチンコの直営店が出てきて探すのに戸惑ったが、会社概要 | newgin ニューギンで一覧を取得できる。
風景的に都会にあるとは考えにくいという考察のもと探していくと、(株)ニューギン 鹿児島営業所の近くに似ている場所があった。
後は、実際の場所から少し離れたところでポチポチしてたらうまくいった
TsukuCTF23{31.5757_130.5533}
RegexCrossword 484pt
クロスワードなんぞ解きたくない! ということで、解くのは諦め検索するが大学で出されたような情報しか出てこない。そんな時、Twitterで検索したら誰かがツイートしてるんじゃね?と思って調べたらビンゴ
このツイートを見ると、見覚えのあるクロスワードが! 後は、会津大学 正規表現 ナプキンと調べたら解いている天才がおった。 これを作った会社は株式会社Eyes, JAPANで会津大学のベンチャー企業らしい。
TsukuCTF23{965-0872}
sunset 499pt
TsukuCTF運営の1人であるshioが、今年に開催されたあるイベントが終わった後に夕日を撮影した。 この写真が撮影された日時を求めよ。 フラグフォーマットはTsukuCTF23{YYYY/MM/DD_hh:mm}である。 例えば、TsukuCTF2023の開始日時はTsukuCTF23{2023/12/09_12:20} なお、誤差は1分まで許容され、日本標準時を用いる。
shio, one of the TsukuCTF admins, took a picture of the sunset after an event held this year. I need you to find the date and time this photo was taken. The flag format is TsukuCTF23{YYYY/MM/DD_hh:mm}. For example, the start date and time of TsukuCTF2023 is TsukuCTF23{2023/12/09_12:20}. Note that an error of up to 1 minute is allowed and the answer is based on Japan Standard Time.
今回の写真を見ると、奥に陸地が見れることから日本海だと考察する。また、天気が曇りであることも覚えておく。
次にどこ行ったかを確認するために、運営shioさんのTwitterを探す。
どうやら、shioさんはセキュリティ・ミニキャンプ in 新潟 2023に講師として参加していることがわかる。
講師してました https://t.co/GqlKtiE2qQ
— しお (@shio_sa1t) 2023年9月10日
Google Mapでミニキャンプ会場を見てみると、写真と似たような場所があり映っている場所は日和山浜海水浴場であると予想する。
今回新潟にいたのは9/9 or 9/10のどちらかのため、これを絞り込む必要がある。 気象庁の過去データから9日の1時間ごとの値と10日の1時間ごとの値を、日の入り情報を見るために、日の出日の入りカレンダー辺りを参考に見てみる。
すると、9/10が曇りであることからこの写真は9月10日に投稿されたと考えられる。
日の入りは18:01なので、一度guessするがダメだった。日の入りの定義を見てみると上辺が水平線に触れたらとのことなので18:01より前だと予想する。 後は勘でやってみよう。18:53でやってもダメ。手を震わせながらサマーウォーズみたいに18:55でやったら無事通りました。 俺の勝ちや!!!!
TsukuCTF23{2023/09/10_17:55}
hunter 498pt
名前をメールで聞こうとしたところ、相手のGmailの一部が分からなくなってしまいました。 大変お忙しいところ恐縮ですが、暇なときに調査してください。 qeinijo#iby#@gmail.com #が不明な部分です。 なお、外部サービスに短期間で多くのアクセスをしないようにしてください。
I tried to email you to ask for the name, but I lost track of part of the person's Gmail. I apologize for the inconvenience, but please investigate in your space time. qeinijo#iby#@gmail.com #is the part I don't understand. Please avoid accessing many external services in a short period of time."
qeinijo#iby#@gmail.comの#に関して、1文字しか入らないので総当たりでパターンは作れる。 しかし、その後どうしようかと迷っていたら、こんな記事をTwitterで見つけた。 これらの情報を元にプログラムを作成した。
import subprocess import time from itertools import product def generate_mail(base_string, replacement_chars): replace_positions = [pos for pos, char in enumerate(base_string) if char == '#'] combinations = product(replacement_chars, repeat=len(replace_positions)) results = [] for comb in combinations: temp_string = list(base_string) for pos, char in zip(replace_positions, comb): temp_string[pos] = char results.append("".join(temp_string)) return results def execute_curl_commands(emails): with open('flag.txt', 'w') as file: # ここでcurlで処理を行う(10秒ごと) email= "qeinijo#iby#" char = '0123456789.' mail= generate_mail(email, char) execute_curl_commands(mail)
短期間で多くのアクセスをしないように、10秒に設定しておいた。また、短期間でアクセスが必要ない=アルファベットはないのでは?というメタ読みで数字ピリオドで回してみた。 するとqeinijo.iby8がset-cookieが書かれていたので、これがメールアドレスであることが判明した。後は、GHuntで確認をしてみると名前がフラグになっていた。

TsukuCTF23{GHun7_i5_u5efu1}
まとめ
初めてのOSINT参加でしたが、めちゃくちゃ楽しめました!運営の方々も優しく対応してくださったので楽しい1日を過ごせました。 CTF欲がめちゃくちゃ出てきたのでもっと精進します!! 後、BugHunterロール貰えて嬉しかったです。それでは!
TsukuCTF2023 後輩と出て24位でした!初めてにしては上出来!
— chama (@PotyaExe) 2023年12月10日
また出ます:)
sunset解けてよかった#TsukuCTF pic.twitter.com/geawFFECn8
2022年振り返りと2023年の抱負
あけましておめでとうございます。今年も宜しくお願いします。
昨年度の目標なんだったかなと思って調べたら
今年の目標は風呂場で寝ないことです
— chama (@PotyaExe) December 31, 2021
"風呂場で寝ない"でした。ちゃんと守りました!偉い!
ということで、振り返りです。
2022年振り返り
2022年は人との出会いの1年だったなと思います。 今年の抱負のほとんどは、出会った方々の影響な気がします。
実際、アコギをまた触り始めたり、韓国語を勉強始めたのは出会えた人たちのおかげです。 感謝しかない。
大学院入試受けたり(落ちましたが)、コロナかかったり、後輩とお酒飲んだりとハチャメチャな1年だったとも思います。 後は、自分から挑戦をあまりしなかった1年だなと思います。どこかで弱気になってたところがあるのが心残りです。
2023年の抱負
2023年は以下を抱負に頑張ります!
・韓国語で会話する ・TOEICの点数800点超える ・セキュリティの資格勉強 ・研究を進める ・イモータル行く ・人の前でアコギ弾き語りできるようにする ・触れたことのない分野に挑戦する ・韓国に旅行しに行って韓国の友達と韓国語で会話する
今年の目標
— chama (@PotyaExe) 2023年1月7日
・韓国語で会話する
・TOEICの点数800点超える
・セキュリティの資格勉強
・研究を進める
・イモータル行く
・人の前でアコギ弾き語りできるようにする
・触れたことのない分野に挑戦する
・韓国に旅行しに行って韓国の友達と韓国語で会話する
去年は、風呂で寝ないだけだったので、もっと多くの抱負を立てました! 抱負が豊富ってな...!!!!
今年は、色々なことに全力で挑戦してもっと前に進みたいと思います。
こんな僕ですが、今年もよろしくお願いします:) 이런 저지만 올해도 잘 부탁드립니다.:)
Let's make this new year a great one!!!!
離散数学 備忘録
グラフ理論
用語
頂点集合(vertex set)、ニ頂点を結ぶ辺集合(edge set)からなる構造のこと。 形式的には、グラフGは頂点集合V(G)、辺集合E(G)と表す。
例えば、以下のようなグラフGを考える。

V(G) = {A, B, C, D}
E(G) = {AD, BD, CD}
となる。
あるグラフGとその一つの頂点vに対して、vと辺で結ばられている頂点の集合のことをvの近傍(neighborhood)という。
vから出ている辺の数をvのGでの次数(degree)という。
握手補題
任意のグラフGで全頂点の次数の和はGの辺数の2倍である。
特殊グラフ
完全グラフ
V(G)が全て辺で結ばれているグラフを完全グラフ(complete graph)という。
頂点数がnの完全グラフをと書く。
また、握手補題を用いると、以下の定理が導かれる。
の辺の数は
である。
2部グラフ
グラフGのV(G)を"A,B内に辺がない"を満たすA,Bへ分割できるとき、2部グラフ(bipartite graph)という。
A,Bに分割したとき、Aの全頂点がBの全頂点と結ばれているグラフを完全二部グラフ(complete bipartite graph)という。
Aの頂点数がr, Bの頂点数がsのときの完全二部グラフはと書く。
二部グラフと歩道の関係について以下の定理が成り立つ。
二部グラフの閉じた歩道の長さは偶数である。 (続)






