# Write Up Capture The Flag Hology 8.0 TelSec - Peserta

---
Category
<a href="#misc"> misc </a>
* <a href="#25"> Free Flag </a>
<a href="#web"> web </a>
* <a href="#21"> pyjail? </a>
<a href="#rev"> rev </a>
* <a href="#23"> ObligatoryFlagCheckerThatIsPacked </a>
* <a href="#24"> Hidden Factory </a>
* <a href="#10"> Bit Buffet </a>
<a href="#crypto"> crypto </a>
* <a href="#15"> The Architect’s Hasty Encryption </a>
<a href="#foren"> foren </a>
* <a href="#17"> Paranoid Archivist </a>
## <a id=misc> misc </a>
### <center><a id="25"> Free Flag </a></center>
<center>50</center>
<center>Give us critique and you'll get a free flag.
https://forms.gle/tUUTVkiBm5VzacSNA
Author: Current HOLOGY CTF Probset</center>
**Flag : **
---
## <a id=web> web </a>
### <center><a id="21"> pyjail? </a></center>
<center>100</center>
<center>I hope I patched all the unintended ways...
Author: avocado</center>

SANITY CHECK INI MAH WKWK
**Flag : HOLOGY8{h0l1_m0l1_r3g3x_g07_pwn3d??_51ff8a6c}**
---
## <a id=rev> rev </a>
### <center><a id="23"> ObligatoryFlagCheckerThatIsPacked </a></center>
<center>100</center>
<center>Title should suffice.
Author: OFF5E7</center>
#### Ringkasan Challenge
- Binary: `packed_rev` (ELF 64-bit, statically linked)
- Gejala: Saat dijalankan meminta flag lewat STDIN, output “THATS NOT RIGHT” jika salah.
- Petunjuk: “Title should suffice.” → indikasi binary dipack.
#### 1) Deteksi Packing
- Cek header dan strings cepat:
- `xxd` menunjukkan signature `UPX!` → UPX-packed.
- `file packed_rev` menampilkan “statically linked, no section header” → ciri packed.
#### 2) Unpack Biner
Gunakan UPX untuk meng-unpack:
```bash
upx -d -o /tmp/packed_rev.unpacked packed_rev
file /tmp/packed_rev.unpacked
```
Hasil: ELF 64-bit, BuildID terlihat, tidak di-strip (lebih mudah dianalisis).
#### 3) String Menarik & .rodata
Cari strings pada biner hasil unpack:
```bash
rg -n -a "easy_key|WHATS THE FLAG|THATS NOT RIGHT|YAY YOU GOT IT RIGHT" /tmp/packed_rev.unpacked
```
Dan dump .rodata di alamat terkait:
```bash
objdump -s --start-address=0x47a000 --stop-address=0x47a0d0 /tmp/packed_rev.unpacked
```
Potongan penting:
- `0x47a050`: `easy_key` (kunci XOR berulang 8 byte)
- `0x47a010 .. 0x47a02f`: `partA` (30 byte)
- `0x47a030 .. 0x47a04f`: `partB` (30 byte)
- Pesan: “WHATS THE FLAG, SEARGEANT.”, “THATS NOT RIGHT”, “YAY YOU GOT IT RIGHT”
#### 4) Analisis Disassembly
Disassembly fungsi `main` (ringkas):
- Cetak prompt dan baca input hingga 0x100 byte.
- Set `len = 0x1e (30)` dan tolak jika panjang tidak sesuai.
- Bangun array target `T[i]` dari dua konstanta di .rodata:
- `T[i] = partA[i] XOR rol8(partB[i], 3)`
- Ambil key 8-byte `key = "easy_key"` dan validasi:
- `if ( (input[i] XOR key[i%8]) != T[i] )` → salah.
- Jika semua cocok → benar.
Terlihat jelas ada fungsi `rol8` dan loop pembentukan target, lalu loop verifikasi terhadap input yang di-XOR dengan key.
#### 5) Rekonstruksi Flag
Karena `input[i] XOR key[i%8] == T[i]`, maka `input[i] = T[i] XOR key[i%8]`.
Ekstrak bytes `partA`, `partB`, dan hitung flag:
```python
import subprocess, re
def parse_line(line):
m = re.match(r"\s*([0-9a-fA-F]{6,})\s((?:[0-9a-fA-F]{8}\s){3}[0-9a-fA-F]{8})", line)
if not m:
return None
hexgroups = m.group(2).strip().split()
bs = bytearray()
for g in hexgroups:
for i in range(0,8,2):
bs.append(int(g[i:i+2],16))
return bytes(bs)
def get_bytes(start, stop):
out = subprocess.check_output(['objdump','-s',f'--start-address={start}',f'--stop-address={stop}','/tmp/packed_rev.unpacked']).decode()
bs = bytearray()
for line in out.splitlines():
part = parse_line(line)
if part:
bs.extend(part)
return bytes(bs)
partA = get_bytes('0x47a010','0x47a030')[:30]
partB = get_bytes('0x47a030','0x47a050')[:30]
key = b'easy_key'
rol8 = lambda x,n: ((x<<n)|(x>>(8-n))) & 0xff
T = bytes([a ^ rol8(b,3) for a,b in zip(partA, partB)])
flag = bytes([T[i] ^ key[i%len(key)] for i in range(len(T))])
print(flag.decode())
```
Output:

**Flag : HOLOGY8{n33d3d_4_4_r3v_p4ck3r}**
---
### <center><a id="24"> Hidden Factory </a></center>
<center>100</center>
<center>
Welcome to the "Hidden Factory"! A secretive manufacturing facility has protected their critical blueprints using an intricate multi-layer encryption system. The factory's security engineers have implemented a sophisticated data transformation pipeline that processes sensitive information through multiple encoding chambers. Can you unravel their encryption methodology and extract the original blueprint? The solution requires dissecting their security architecture, reversing each protective layer, and recovering the authentic manufacturing documentation.
</center>
<center>author: Lorem</center>
<center>`nc ctf.hology.id 1000`</center>
---
#### Ciphertext (dari `hasil nc ctf.hology.id 1000`):
Ciphertext (dari `hasil nc ctf.hology.id 1000`):
```
Sd9CG5TC4Xrz6ISW830mryN0qzBXwV/lyRt+cA2ifxAxXJPRAbLYR65qQWzv1HrKAJb1CBEwt+F8tvNnYfsBdAoQifQnjNi/GLHB
```
#### Analisis Biner (chall.c)
Dari `chall.c` (yang dihasilkan dari `chall.pyx`) terlihat kelas `HiddenFactory` dengan tiga tahap transformasi sebelum output akhir dicetak:
1) _stage1_transform (Caesar shift pada alfabet kustom)
- Alfabet: `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789{}_` (panjang 65)
- Operasi: untuk setiap char `c` yang ada di alfabet,
- `old = alphabet.index(c)`
- `new = (old + magic_offset) % len(alphabet)` dengan `magic_offset = 23`
- gantikan `c` dengan `alphabet[new]`
- Karakter di luar alfabet dibiarkan utuh.
2) _stage2_scramble (XOR posisi)
- Untuk setiap indeks `i` dan char `c` hasil tahap 1, hitung `val = (i * secret_multiplier + magic_offset) % 256` dengan `secret_multiplier = 7` dan `magic_offset = 23`.
- Keluarkan `chr(ord(c) ^ val)`.
3) _stage3_encode (Base64 + substitusi alfabet)
- Konversi string hasil tahap 2 ke bytes Latin‑1.
- Base64 standar terhadap bytes → string `encoded`.
- Substitusi alfabet Base64 standar ke alfabet kustom:
- Standar: `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`
- Kustom: `0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/`
- Setiap karakter Base64 standar pada posisi `i` dipetakan menjadi karakter alfabet kustom pada posisi `i` yang sama.
Output akhir yang dicetak service adalah hasil tahap 3.
#### Strategi Dekripsi (membalik tahap)
Urutan balik dari output tahap 3 ke plaintext:
1) Balik tahap 3 (Base64 + substitusi alfabet)
- Peta balik tiap char `c` di ciphertext dari alfabet kustom → indeks → ambil char pada indeks sama dari alfabet Base64 standar.
- Lakukan Base64 decode → dapatkan bytes, decode `latin-1` → string tahap 2.
2) Balik tahap 2 (XOR posisi)
- Operasi XOR adalah involutif (membalik dengan operasi yang sama).
- Untuk setiap indeks `i` dan char `c` dari string tahap 2: `val = (i*7 + 23) % 256` lalu `c_rev = chr(ord(c) ^ val)` → string tahap 1.
3) Balik tahap 1 (Caesar shift)
- Lakukan pergeseran mundur sebesar 23 pada alfabet `A‑Za‑z0‑9{}_` (panjang 65):
- Jika `c` ada di alfabet: `new = (alphabet.index(c) - 23) % 65`, ambil `alphabet[new]`.
- Selain itu: biarkan apa adanya.
#### Solver
Kode Python berikut menerapkan seluruh pembalikan:
```python
import base64
enc = "Sd9CG5TC4Xrz6ISW830mryN0qzBXwV/lyRt+cA2ifxAxXJPRAbLYR65qQWzv1HrKAJb1CBEwt+F8tvNnYfsBdAoQifQnjNi/GLHB"
# Tahap 3 (balik substitusi alfabet Base64 kustom → standar, lalu base64-decode)
standard = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
custom = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"
mapped = ''.join(standard[custom.index(c)] if c in custom else c for c in enc)
s2_bytes = base64.b64decode(mapped)
s2 = s2_bytes.decode('latin-1')
# Tahap 2 (balik XOR posisi — pakai operasi yang sama)
secret_multiplier = 7
magic_offset = 23
s1_chars = []
for i, ch in enumerate(s2):
val = (i*secret_multiplier + magic_offset) % 256
s1_chars.append(chr(ord(ch) ^ val))
s1 = ''.join(s1_chars)
# Tahap 1 (balik Caesar shift −23 pada alfabet kustom)
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789{}_"
L = len(alphabet)
plain = []
for ch in s1:
if ch in alphabet:
old = alphabet.index(ch)
new = (old - 23) % L
plain.append(alphabet[new])
else:
plain.append(ch)
print(''.join(plain))
```
**Flag : HOLOGY8{f4ct0ry_r3v3rs3_3ng1n33r1ng_m4st3r_0f_th3_h1dd3n_bluepr1nt_cr4ck3r}**
---
### <center><a id="10"> Bit Buffet </a></center>
<center>499</center>
<center>gurt : yo pc, run this rq
pc : (consumes bits)
Author: avocado</center>
#### Deskripsi Singkat
Diberikan satu berkas `FLAG.bin` yang berisi deretan bit “0/1”. Jika didekode per 8‑bit, hasilnya adalah kode mesin x86‑64 (flat binary, bukan ELF). Kode tersebut menyalin sebuah tabel pointer fungsi lalu memanggil setiap entri. Sejumlah fungsi “leaf” masing‑masing mengembalikan satu karakter (melalui `mov eax,<imm8>; pop rbx; ret`). Dengan merekonstruksi urutan pemanggilan berdasarkan tabel pointer, kita bisa merangkai seluruh karakter menjadi flag.
---
#### Berkas
- `FLAG.bin` — ASCII bitstring (satu baris sangat panjang)
- Panjang bit: 163,712 bit → 20,464 byte
- SHA256: `a1083f6e2546689173047e6f881232165d2d92225f7820d086d5f2da3a65a5cd`
#### Recon Cepat
- `file FLAG.bin` menunjukkan “ASCII text … with no line terminators”.
- Dikonversi per 8‑bit → bytes → terlihat pola x86‑64:
- Banyak instruksi `f3 0f 1e fa` (ENDBR64), setup stack, loop, dsb.
- Bukan ELF; ini semacam “.text” flat dengan data di ekor file.
#### Inti Analisis
1. Decode bit → byte, lalu disassembly sebagai x86‑64 “binary”:
- Gunakan `objdump -b binary -m i386:x86-64 -M intel --adjust-vma=0x401000`.
- Terlihat routine yang:
- Menyalin array fungsi dari `0x406020` ke stack (`rep movs`),
- Lalu melakukan loop: `call [rbx]`, `rbx += 8`, sampai `rbx == rbp`.
2. Cari fungsi “leaf” yang meng-encode karakter flag:
- Pola epilog: `mov eax,<imm8>; pop rbx; ret`.
- Masing‑masing `imm8` adalah ASCII 1 karakter.
- Jika hanya dibaca “urutan kemunculan di file”, string yang didapat tampak acak karena urutan pemanggilan ditentukan oleh tabel pointer, bukan urutan layout di file.
3. Tabel pointer fungsi:
- Dekat ekor file terdapat qword‑qword alamat fungsi (little‑endian).
- Contoh hexdump (offset sekitar `0x4eb0`):
```
a03a400000000000 -> 0x403aa0
1028400000000000 -> 0x402810
804b400000000000 -> 0x404b80
8015400000000000 -> 0x401580
b024400000000000 -> 0x4024b0
...
```
- Itulah urutan panggilan fungsi “leaf”; setiap entri memetakan ke fungsi yang mengembalikan satu byte ASCII.
4. Rangkai karakter sesuai urutan tabel:
- Mapping alamat fungsi → dekatnya epilog `mov eax,<imm8>; pop rbx; ret`.
- Hasil penyusunan karakter berdasarkan tabel menghasilkan flag yang valid.
#### Langkah Reproduksi
##### 1) Konversi bitstring → bytes
```bash
# Decode dari bitstring setiap 8-bit ke byte
python3 - << 'PY'
bits = open('FLAG.bin','rt').read().strip()
bs = bytes(int(bits[i:i+8], 2) for i in range(0, len(bits), 8))
open('blob.bin','wb').write(bs)
print('wrote', len(bs), 'bytes')
PY
```
Opsional: intip tipe/hex:
```bash
file blob.bin
hexdump -C blob.bin | head
```
##### 2) Disassembly cepat (opsional, untuk verifikasi)
```bash
objdump -b binary -m i386:x86-64 -D -M intel --adjust-vma=0x401000 blob.bin | sed -n '1,220p'
```
Perhatikan di sekitar `0x4010a0` ada `rep movs` yang menyalin tabel fungsi dan loop `call [rbx]`.
##### 3) Ekstrak flag dari tabel pointer
Script Python yang:
- Mencari semua fungsi “leaf” dengan pola `B8 ?? 00 00 00 5B C3` (mov eax, imm8; pop rbx; ret),
- Membaca qword tabel pointer (di ekor file),
- Memetakan tiap alamat ke fungsi “leaf” terdekat,
- Menyusun karakter sesuai urutan tabel.
```python
import struct
from pathlib import Path
bs = Path('blob.bin').read_bytes()
base = 0x401000
# 1) Kumpulkan lokasi fungsi return 1-char: B8 imm8 00 00 00 5B C3
ret_sites = []
for i in range(len(bs) - 7):
if bs[i] == 0xB8 and i + 6 < len(bs) and bs[i+5] == 0x5B and bs[i+6] == 0xC3:
ret_sites.append(i)
# 2) Baca qword table dekat ekor (heuristik: mulai 0x4eb0)
entries = []
for i in range(0x4eb0, len(bs) - 8, 8):
q = struct.unpack('<Q', bs[i:i+8])[0]
if q != 0:
entries.append((i, q)) # (file_offset, vma)
# 3) Untuk tiap alamat di tabel, cari fungsi 'leaf' terdekat sesudahnya
def char_from_addr(addr):
off = addr - base
for j in ret_sites:
if 0 <= j - off <= 0x300:
return chr(bs[j+1]) # imm8
return None
flag_chars = []
for off, addr in entries:
c = char_from_addr(addr)
if c:
flag_chars.append((off, addr, c))
flag_chars.sort() # urutkan sesuai urutan di tabel
flag = ''.join(c for _,_,c in flag_chars)
print('Recovered:', flag)
```

**Flag : HOLOGY8{Wh0_4t3_a11_mY_b1t5_a3f9c8b2}**
---
## <a id=crypto> crypto </a>
### <center><a id="15"> The Architect’s Hasty Encryption </a></center>
<center>200</center>
<center>An emergency ping from the System crackles through your interface. The Architect’s module spins up, whispering of keys tempered in unstable instant magic and relics humming with old power. The gate won’t open itself. Plug in, look around, and figure out what the System wants from you.
`nc ctf.hology.id 31337`
Author: R1v3r</center>
---
#### Bahan dari server (nc ctf.hology.id 31337)
##### Mission
```
n = 1189752…56133103109
e = 7872299…6277646485925
c = 1489592…534759588584
```
##### Artefacts
```
ART-A:
nA = 8960178…7435739883181
eA = 65537
cA = 3716410…268954488372
ART-B:
nB = 7149376…041023108447
eB = 65537
cB = 7043932…781336498428
```
---
#### Langkah Teknis
##### 1) Artefacts: shared prime via `gcd`
Hitung `g = gcd(nA, nB)` → ketemu **prime bersama p** berukuran **512-bit**.
Faktorkan:
* `p = g`
* `qA = nA / p`, `qB = nB / p`
* `φA = (p-1)(qA-1)`, `φB = (p-1)(qB-1)`
* `dA = eA^-1 mod φA`, `dB = eB^-1 mod φB`
* Dekripsi:
`mA = cA^dA mod nA` → **“This path is flawed.”**
`mB = cB^dB mod nB` → **“The artefact is void.”**
→ jelas ini **decoy**, tapi kita simpan nilai `g`.
##### 2) Mission: Wiener’s attack (small-d)
Jalankan **Wiener** pada `(n, e)` Mission → dapat `d`.
Dekripsi: `m = c^d mod n` → bytes ke string:
```
"SYSTEM-KEY:Arise.Now!"
```
##### 3) Unlock
Prompt “Key Entry” minta **HEX** dari plaintext penuh (termasuk prefiks).
ASCII → HEX:
```
SYSTEM-KEY:Arise.Now! -> 53 59 53 54 45 4D 2D 4B 45 59 3A 41 72 69 73 65 2E 4E 6F 77 21
HEX: 53595354454D2D4B45593A41726973652E4E6F7721
```
Masukkan itu untuk membuka sistem.
##### 4) Susun Flag (“gabungkan” + “trim its echo”)

Instruksi author: hex yang dipakai untuk Unlock **digabung** dengan nilai dari Art A & B (yakni `g`), lalu dihitung **token** (SHA-256 full hex). Versi yang benar di sini adalah:
* **gabung sebagai bytes**:
`payload = b"SYSTEM-KEY:Arise.Now!" + str(g).encode()` ← `str(g)` = **ASCII desimal** dari `g`
* **flag = sha256(payload).hexdigest()**
Hasilnya cocok dengan flag yang valid:
```
7ec2c6c4821ffe2bd9fa2045ef69791a22e595425e2948844e9b1fd3b37d54ca
```
---
#### Skrip Solver
```python
import math, hashlib
# ==== paste angka dari server ====
nA = int("89601783146076639326364551407391502056271453443585246403649518438739752197494453923912974590899704931799581808032848316945260608111602748641703034997071964641315226587094382131797946753938962375613837592569299860517918221636743443778609978573146453307287583692315622846949125803253541040690934297435739883181")
eA = 65537
cA = int("37164104401076955077929653377412649499999712575049262615292256531432516530571888616103801152199060505086659571068915973058637089017531878490869019675349634664132877152506966368040680398438581696665793537909931060790220071739813385689555564918515689872228674428349534724902336052648318438921439321268954488372")
nB = int("71493767682388193849018589142479453283796995156288303116503481698801388306223320772707598662122426469246149798256468802035651070345590713963988243090267155746488347787303474889624656335696596744993627750777136008351227588332875099728429462600325768652684066344324632574166525422011238099309853433041023108447")
eB = 65537
cB = int("70439328908161407341748425421351243758222210153608544322212776759779840716935385163189188990383591871234782470265831205164904425451219055808713980664935582721819455648294588980175137551394128412355820943736415438043996050633633784118117657930546568264457192232822394652221065226217230553865130964781336498428")
n = int("118975278847882844478683131487868863553725152941956385376607379430849467048838708654069858644026954641749865240483330886219744793766833535926332100442592236221964464629086823731578384477967425988583085618036341173204020994858998976972451248939014925597663289020083223001589858821506863031665806280615633043109")
e = int("78722994310795625787105874655414923877307070249189124463403140397655605380213935536641528349788466972195773144530181458717471436560300040208738019374063797133171592591063777462750908244973898762467133495510521814795449800707766962786128955094379100191369241506884856300121048756989959313055477346277646485925")
c = int("1489592032962799350792622713559294238291304015341650628646017299080863217451013943513044691837221873369753719076665779904675468457738769104175316344931340145854665918203359431685266438359786079681976203346113217786542373724335126764982653802084157053665772223172341072257906623599220597555287161534759588584")
# =================================
# helper
def i2b(x): return x.to_bytes((x.bit_length()+7)//8, "big")
# 1) shared prime
g = math.gcd(nA, nB)
# (opsional) verifikasi decoy
phiA = (g-1) * (nA//g - 1)
phiB = (g-1) * (nB//g - 1)
dA = pow(eA, -1, phiA)
dB = pow(eB, -1, phiB)
mA = i2b(pow(cA, dA, nA)) # b'This path is flawed.'
mB = i2b(pow(cB, dB, nB)) # b'The artefact is void.'
# 2) Wiener's attack (ringkas)
import math
def cont_frac(n, d):
out = []
while d:
a = n // d
out.append(a)
n, d = d, n - a*d
return out
def convs(cf):
h1, h2 = 1, 0
k1, k2 = 0, 1
for a in cf:
h = a*h1 + h2
k = a*k1 + k2
yield h, k
h2, h1 = h1, h
k2, k1 = k1, k
def wiener(e, n):
for h, k in convs(cont_frac(e, n)):
if h == 0 or k == 0:
continue
if (e*k - 1) % h != 0:
continue
phi = (e*k - 1)//h
s = n - phi + 1
disc = s*s - 4*n
if disc < 0:
continue
t = math.isqrt(disc)
if t*t != disc:
continue
p = (s + t)//2
q = (s - t)//2
if p*q == n:
return k # d
return None
d = wiener(e, n)
plaintext = i2b(pow(c, d, n)) # b'SYSTEM-KEY:Arise.Now!'
# 3) flag: concat bytes + ascii decimal(g), sha256
payload = b"SYSTEM-KEY:Arise.Now!" + str(g).encode()
flag = hashlib.sha256(payload).hexdigest()
print("HOLOGY8{" + flag + "}")
```
Output:

---
**Flag : HOLOGY8{7ec2c6c4821ffe2bd9fa2045ef69791a22e595425e2948844e9b1fd3b37d54ca}**
---
## <a id=foren> foren </a>
### <center><a id="17"> Paranoid Archivist </a></center>
<center>323</center>
<center>this guy uses way too much passwords, i also heard he likes using edge for some reason
(no bruteforce needed)
https://drive.google.com/file/d/1K0ilDreURzWnPkYb7wmgvc0OKO5s7WLE/view?usp=sharing
password: 9xD4Lo72HWE12XcFBZ7m
Author: avocado</center>
Diberikan sebuah file .ad1, yang berisi folder dari C:\Users\. Melihat dari deskripsi challenge, ini ada sesuatu yang berhubungan dengan Browser Edge.
#### 1. Mount file ad1
Menggunakan tools AD1-Tools, kita dapat menggunakan ad1mount untuk membuka file tersebut
dari situ, saya menemukan beberapa file menarik:
- `AppData/Local/Microsoft/Edge/User Data/Default/History` (History Edge)
- `/home/bbayugt/Downloads/AD1-tools/AD1Tools/out/Documents/flag.docx` (Dokumen flag yang terenskripsi password)
- `/home/bbayugt/Downloads/AD1-tools/AD1Tools/out/Downloads/1000.zip` (Zip yang terenskripsi password)
#### 2. Mencari password zip file
Dengan menggunakan tools sqlite viewer, kita dapat menemukan sebuah link pastebin

Didalamnya terdapat 1000 line password

#### 3. Unzip file menggunakan password
Gunakan shell script ini untuk unzip secara rekursif
```shell=
#!/bin/bash
# Add newline to the password file if it doesn't exist
if [ -n "$(tail -c1 pastebin_passwords_unix.txt)" ]; then
echo "" >> pastebin_passwords_unix.txt
fi
zip_file="1000.zip"
# Loop from 1000 down to 1
for i in $(seq 1000 -1 1); do
if [ ! -f "$zip_file" ]; then
echo "File $zip_file not found. Stopping."
break
fi
echo "Cracking ${zip_file}..."
# Get the i-th password from the file
password=$(sed -n "${i}p" pastebin_passwords_unix.txt)
# Try to extract the zip file with the current password
if 7z x -y -p"$password" "$zip_file" > /dev/null 2>&1; then
echo "Password for ${zip_file} is: ${password}"
else
echo "Password not found for ${zip_file} with password: $password"
break
fi
# Update zip_file for the next iteration
next_i=$((i-1))
if [ "$next_i" -gt 0 ]; then
zip_file="${i}/${next_i}.zip"
fi
done
```
#### 4. Decode notes
pada `1`, terdapat notes yang berisi
```!
VE9QIFNFQ1JFVCBSRUNJUEUNCjIvMyB0ZWFzcG9vbiBzYWx0DQoxLzIgdGVhc3Bvb24gdGh5bWUNCjEvMiB0ZWFzcG9vbiBiYXNpbA0KMS8zIHRlYXNwb29uIG9yZWdhbm8NCjEgdGVhc3Bvb24gY2VsZXJ5IHNhbHQNCjEgdGVhc3Bvb24gYmxhY2sgcGVwcGVyDQoxIHRlYXNwb29uIGRyaWVkIG11c3RhcmQNCjQgdGVhc3Bvb25zIHBhcHJpa2ENCjIgdGVhc3Bvb25zIGdhcmxpYyBzYWx0DQoxIHRlYXNwb29uIGdyb3VuZCBnaW5nZXINCjMgdGVhc3Bvb25zIHdoaXRlIHBlcHBlcg0KDQpteSBzZWNyZXQgd29yZCBmaWxlIHBhc3N3b3JkLCBqdXN0IGluIGNhc2UgaSBmb3Jnb3QNCml2Qm9qVUFGcVdjTGRTRG51bGdRSzZMQThhRkhkREM2
```
yang dapat di decode dengan base64 menjadi
```!
TOP SECRET RECIPE
2/3 teaspoon salt
1/2 teaspoon thyme
1/2 teaspoon basil
1/3 teaspoon oregano
1 teaspoon celery salt
1 teaspoon black pepper
1 teaspoon dried mustard
4 teaspoons paprika
2 teaspoons garlic salt
1 teaspoon ground ginger
3 teaspoons white pepper
my secret word file password, just in case i forgot
ivBojUAFqWcLdSDnulgQK6LA8aFHdDC6
```
#### 5. Membuka flag.docx pada Documents
Setelah mendekripsi password, hanya ada ini, kemungkinan text hidden

Pada OnlyOffice, kita dapat menghapus enkripsi dengan fitur protect -> Delete password
lalu extract dengan 7z
ada text tersembunyi yang berisi:
`SECRETs EveRyWhere whiSper aloNg HallWayS`
Setelah menganalisa text, ternyata flag nya ada di font pada hidden text, bukan text itu sendiri, dan kapital dari huruf hidden tersebut menentukan apakah font tersebut harus kapital atau tidak
```python=
import xml.etree.ElementTree as ET
def get_final_flag(xml_file):
tree = ET.parse(xml_file)
root = tree.getroot()
flag = ""
# The namespace for the 'w' prefix
ns = {'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'}
count = 0
for r_element in root.findall('.//w:r', ns):
vanish = r_element.find('.//w:rPr/w:vanish', ns)
if vanish is not None:
count += 1
if count % 2 == 0:
# Get the hidden text character
t_element = r_element.find('.//w:t', ns)
hidden_char = ''
if t_element is not None and t_element.text is not None:
hidden_char = t_element.text
if hidden_char.isspace():
continue
# Get the font name
rfonts = r_element.find('.//w:rPr/w:rFonts', ns)
if rfonts is not None:
font_name = rfonts.get('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}ascii')
if font_name:
first_letter = font_name[0]
if hidden_char.isalpha():
if hidden_char.islower():
flag += first_letter.lower()
else:
flag += first_letter.upper()
else:
flag += first_letter
return flag
if __name__ == "__main__":
xml_file = "output/word/document.xml"
final_flag = get_final_flag(xml_file)
print(f"HOLOGY8{{{final_flag[7:]}}}")
```

walaupun beberapa teks duplikat, tetapi sudah ada yang terbaca, dan menambahkan underscore pada setiap kata, kita mendapatkan flag nya!
**Flag : HOLOGY8{Su5PiC1ou5_looKing_fonT_zM7k3X6aB}**
---