🍞
mirai
  • Hi!
  • CTF
    • TCP1P CTF Special Ramadan 2025
      • Web Exploitation
      • Forensics
      • Cryptography
      • Binary Exploitation
      • Reverse Engineering
      • Blockchain
      • OSINT
      • Miscellaneous
    • Cyber Jawara International 2024
      • Intro to ETH
Powered by GitBook
On this page
  • Raw Diary
  • Description
  • Initial Analysis
  • Code Analysis
  • Solve
  • Mencari PW
  • Description
  • Initial Analysis
  • Code Analysis
  • Solve
  • nomolog
  • Description
  • Initial Analysis
  • Code Analysis
  • Solve
  • Gacor
  • Description
  • Initial Analysis
  • Code Analysis
  • Solve
  • ffiishy (TBU)
  • Description
  • Initial Analysis
  • Code Analysis
  • Solve
  1. CTF
  2. TCP1P CTF Special Ramadan 2025

Reverse Engineering

Name
Solves

13

13

6

4

ffiishy (TBU)

1

Raw Diary

Description

Author: .effie

I put a digital sign on this diary ^-^

Initial Analysis

We are given a file:

┌─[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/Raw Diary]
└──╼ $file chall
chall: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=9edbed209686e8fd38cc522ae3f08453c9262498, for GNU/Linux 3.2.0, stripped

Code Analysis

Decompile using IDA:

main()
__int64 __fastcall main(int a1, char **a2, char **a3)
{
  char v4; // bl
  char v5; // [rsp+3h] [rbp-3Dh]
  int i; // [rsp+4h] [rbp-3Ch]
  int n; // [rsp+8h] [rbp-38h]
  unsigned int seed; // [rsp+Ch] [rbp-34h]
  FILE *stream; // [rsp+10h] [rbp-30h]
  char *s; // [rsp+18h] [rbp-28h]
  FILE *v11; // [rsp+20h] [rbp-20h]
  const char *v12; // [rsp+28h] [rbp-18h]

  stream = fopen("flag.txt", "r");
  if ( stream )
  {
    fseek(stream, 0LL, 2);
    n = ftell(stream);
    fseek(stream, 0LL, 0);
    s = (char *)malloc(n + 4);
    if ( s )
    {
      fgets(s, n, stream);
      fclose(stream);
      seed = time(0LL);
      srand(seed);
      printf("%d\n", seed);
      v11 = fopen("output.txt", "w");
      if ( v11 )
      {
        v12 = (const char *)sub_1349();
        if ( v12 )
        {
          fprintf(v11, "\n[%s %s]\n%s\n", "Mar  2 2025", "15:24:49", v12);
          for ( i = 0; i < n; ++i )
          {
            v4 = s[i];
            v5 = v4 ^ rand();
            fputc(v5, v11);
          }
          fputc(10, v11);
          fclose(v11);
          return 0LL;
        }
        else
        {
          fwrite("i'm too tired for this.\n", 1uLL, 0x18uLL, stderr);
          return 1LL;
        }
      }
      else
      {
        perror("what's wrong with you? -_-\n");
        return 1LL;
      }
    }
    else
    {
      perror("aaaa! can't malloc D:\n");
      return 1LL;
    }
  }
  else
  {
    perror("eepy! flag.txt is GONE.\n");
    return 1LL;
  }
}

This code essentially opens 2 files, flag.txt and output.txt. Then it initiate a PRNG using the current time as a seed. It then encrypt the content if flag.txt using XOR against a randomly generated number. After that, it will output the encrypted flag to output.txt

Solve

To decrypt the flag, we first need to find out what seed is used when initiating the PRNG.

When we are using the same seed for some PRNG. The sequence of the generated random value will always be the same.

But when i try to decrypt using the exact timestamp given on the output.txt, it doesn't outputs a flag.

[Mar  2 2025 15:24:49]

So my instant thought is to bruteforce the timestamp, with the range of 10 minutes before and 10 minutes after. And we will get the flag.

solve.py
from ctypes import CDLL
libr = CDLL("/lib/x86_64-linux-gnu/libc.so.6")

def decrypt(seed, flag_enc):
    libr.srand(seed)
    flag = b""
    for byte in flag_enc:
        flag += bytes([byte ^ (libr.rand() % 0x100)])
    return flag


with open("output.txt", "rb") as f:
    for i in range(68):
        f.readline()
    flag_enc = f.readline().strip()

seed = 1740929089
for s in range(seed - 600, seed + 601):
    flag = decrypt(s, flag_enc)
    if b"RAMADAN{" in flag:
        print(f"Seed: {s}")
        print(flag)
        break

Flag: RAMADAN{1_60nn4_b3_m3}

Mencari PW

Description

Author: b4r

Mas bisa bantu aku buat login? Aku lupa passwordnya :(

Initial Analysis

We are given a file:

┌─[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/Mencari PW]
└──╼ $file chall
chall: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=8485f6953c06d12b9865185ba3466fdbf9b4a65c, for GNU/Linux 2.6.32, stripped

If we try to run it, we will get this error:

┌─[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/Mencari PW]
└──╼ $./chall
[PYI-198843:ERROR] Failed to load Python shared library '/tmp/_MEIQpunxn/libpython3.13.so': dlopen: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.38' not found (required by /tmp/_MEIQpunxn/libpython3.13.so)

We identify that it is a PyInstaller executable:

Code Analysis

chall.py (Decompiled)
# Decompiled with PyLingual (https://pylingual.io)
# Internal filename: chall.py
# Bytecode version: 3.13.0rc3 (3571)
# Source timestamp: 1970-01-01 00:00:00 UTC (0)

import tkinter
import string
from tkinter import messagebox
import time
window = tkinter.Tk()
window.title('Login Form')
window.geometry('400x500')
window.configure(bg='#0d0d0d')
password = ['qswaefrdthy_gukojplzcxvbmn', 'pkolihu_jyftgrsedwaqmzbxvc', 'mlnkbjvhcgxfzdsapqowueyr_t', 'plokijuhygtfrdeswaqmnbvcxz', 'qswdefrgthyjukilopmnbzvcx_', 'qswaefrgthyjukilpom_znxbcv', 'zqwsedrftgyhuji_kolpxcvbnm', 'qaedwsrf_tgujyhikpomznxbcv', 'mxnzbcvqsplokwdij_efuhrgyt', 'plokmnzbxvcijuygtfrdeswa_q', 'plmoknijbuhvygctfxrdzeswaq', 'qazwsxedcrfvtgbyhnujmikol_', 'wqzsxedcrfvt_gbyhnujmikolp', 'qazwxedcrf_vtgbyhnplmokiju', 'okmplijnuhbygvtfcrdxewqaz_', 'ygvtfcrd_xeszqaplmoknijbuh', 'ijnkmpluhbygvtfc_rdxeszwqa', 'tyuioplkjhgfdsaqwezxcvb_nm', 'mkolpijnuhbygv_tfcrxeszwaq', 'hubijnmkoplygvtfcrdxeszwaq', 'swxedcr_fvtgbynujmikolpqaz', 'trqwyuioplkjhgfdsazxcvbn_m', 'klopmijn_ubygvtfcrdxeszaqw', 'bvnmczxlaksjdhfgp_qowiruty']

def login():
    username = 'TCP1P'
    entered_username = username_entry.get()
    entered_password = password_entry.get()
    if entered_username != username or len(entered_password) != len(password):
        messagebox.showerror(title='Error', message='Invalid Login')
    return None
frame = tkinter.Frame(bg='#0d0d0d')
login_label = tkinter.Label(frame, text=' Login ', bg='#0d0d0d', fg='#ff00ff', font=('Courier', 30, 'bold'))
username_label = tkinter.Label(frame, text='Username', bg='#0d0d0d', fg='#00ffcc', font=('Courier', 16))
username_entry = tkinter.Entry(frame, font=('Courier', 16), bg='#262626', fg='#00ffcc', insertbackground='#00ffcc', relief='flat')
password_label = tkinter.Label(frame, text='Password', bg='#0d0d0d', fg='#00ffcc', font=('Courier', 16))
password_entry = tkinter.Entry(frame, show='*', font=('Courier', 16), bg='#262626', fg='#00ffcc', insertbackground='#00ffcc', relief='flat')
login_button = tkinter.Button(frame, text='Login cik', bg='#ff00ff', fg='#0d0d0d', font=('Courier', 16), relief='flat', command=login)
login_label.pack(pady=40)
username_label.pack(anchor='w')
username_entry.pack(pady=10, ipadx=50, ipady=5)
password_label.pack(anchor='w')
password_entry.pack(pady=10, ipadx=50, ipady=5)
login_button.pack(pady=30)
frame.pack(expand=True)
window.mainloop()

There is no password checker logic, but when we look at the python bytecode:

There is some python bytecode, that is checking our input:

chall.pyc (Bytecode)
60 LOAD_GLOBAL 15 (NULL + zip)
62 LOAD_FAST 2 (entered_password)
64 LOAD_GLOBAL 8 (password)
66 CALL 2
68 GET_ITER
70 FOR_ITER 56 (to 118)
72 UNPACK_SEQUENCE 2
74 STORE_FAST_STORE_FAST 52 (char, pw_string)

76 LOAD_FAST_LOAD_FAST 52 (char, pw_string)
78 CONTAINS_OP 0 (in)
80 POP_JUMP_IF_TRUE 25 (to 98)
82 LOAD_FAST 3 (char)
84 LOAD_GLOBAL 16 (string)
86 LOAD_ATTR 18 (ascii_lowercase)
88 LOAD_CONST 5 ("_")
90 BINARY_OP 0 (+)
92 CONTAINS_OP 1 (not in)
94 POP_JUMP_IF_TRUE 2 (to 98)
96 JUMP_BACKWARD 35 (to 68)

98 LOAD_GLOBAL 10 (messagebox)
100 LOAD_ATTR 12 (showerror)
102 PUSH_NULL
104 LOAD_CONST 2 ("Error")
106 LOAD_CONST 6 ("masih salah atau coba tambahin underscore mas")
108 LOAD_CONST 4 (('title', 'message'))
110 CALL_KW 2
112 POP_TOP

114 POP_TOP
116 RETURN_CONST 0 (None)

118 END_FOR
120 POP_TOP

There are two conditions that it needs to pass:

This code checks if char is in pw_string:

76 LOAD_FAST 52 (char, pw_string)
78 CONTAINS_OP 0 (in)
80 POP_JUMP_IF_TRUE 25 (to 98)

This code checks if it is not in the range of [a-z_]

82 LOAD_FAST 3 (char)
84 LOAD_GLOBAL 16 (string)
86 LOAD_ATTR 18 (ascii_lowercase)
88 LOAD_CONST 5 ("_")
90 BINARY_OP 0 (+)
92 CONTAINS_OP 1 (not in)
94 POP_JUMP_IF_TRUE 2 (to 98)
96 JUMP_BACKWARD 35 (to 68)

So it will not jump this this condition:

98 LOAD_GLOBAL 10 (messagebox)
100 LOAD_ATTR 12 (showerror)
102 PUSH_NULL
104 LOAD_CONST 2 ("Error")
106 LOAD_CONST 6 ("masih salah atau coba tambahin underscore mas")
108 LOAD_CONST 4 (('title', 'message'))
110 CALL_KW 2
112 POP_TOP

So for every password list it needs to:

  1. Is in the range of [a-z_]

  2. For every char[i], is not in password[i]

Solve

Based on the two condition above, i write a script and get the flag:

solve.py
alphabet = "abcdefghijklmnopqrstuvwxyz_"
pw_list = [
    "qswaefrdthy_gukojplzcxvbmn",
    "pkolihu_jyftgrsedwaqmzbxvc",
    "mlnkbjvhcgxfzdsapqowueyr_t",
    "plokijuhygtfrdeswaqmnbvcxz",
    "qswdefrgthyjukilopmnbzvcx_",
    "qswaefrgthyjukilpom_znxbcv",
    "zqwsedrftgyhuji_kolpxcvbnm",
    "qaedwsrf_tgujyhikpomznxbcv",
    "mxnzbcvqsplokwdij_efuhrgyt",
    "plokmnzbxvcijuygtfrdeswa_q",
    "plmoknijbuhvygctfxrdzeswaq",
    "qazwsxedcrfvtgbyhnujmikol_",
    "wqzsxedcrfvt_gbyhnujmikolp",
    "qazwxedcrf_vtgbyhnplmokiju",
    "okmplijnuhbygvtfcrdxewqaz_",
    "ygvtfcrd_xeszqaplmoknijbuh",
    "ijnkmpluhbygvtfc_rdxeszwqa",
    "tyuioplkjhgfdsaqwezxcvb_nm",
    "mkolpijnuhbygv_tfcrxeszwaq",
    "hubijnmkoplygvtfcrdxeszwaq",
    "swxedcr_fvtgbynujmikolpqaz",
    "trqwyuioplkjhgfdsazxcvbn_m",
    "klopmijn_ubygvtfcrdxeszaqw",
    "bvnmczxlaksjdhfgp_qowiruty",
]
result = []
for pw_string in pw_list:
    for c in alphabet:
        if c not in pw_string:
            result.append(c)
            break
final_pw = "".join(result)
print("RAMADHAN{" + final_pw + "}")

Flag: RAMADHAN{ini_adalah_password_hehe}

nomolog

Description

Author: .effie

D.I.D. i do that??

Initial Analysis

We are given two files:

┌─[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/nomolog/wu]
└──╼ $tree .
.
├── look
└── output.txt

1 directory, 2 files
┌─[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/nomolog/wu]
└──╼ $file look 
look: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=2193600f0adbd69c95356ec4443a3052a47477ab, for GNU/Linux 3.2.0, with debug_info, not stripped
output.txt
vinnie: 😭 g what are you doin in my room 💀💀
.effie: ====REDACTED====
.effie: dw i aint doin ya dirty if im paid first ;>
vinnie: yeah aight here some $699
.effie: 111312211{111312211_13211213211s13211713211h111312211_111312211d1113122110111312211n1113122117111312211_111312211l132112132110111312211k111312211_1113122110111312211r111312211_11131221151113122114111312211y111312211_1113122114111312211n111312211y1113122117111312211h31131122211n1113122116111312211_132123211o13211813211k111312211?111312211_111312211}
vinnie: what?? i cant understand this! anyway idk help >_<

Code Analysis

We open the file in IDA:

look::main()
// local variable allocation has failed, the output may be wrong!
void __cdecl look::main()
{
  __int64 v0; // rax
  core::result::Result<(),std::io::error::Error> v1; // rax
  __int64 v2; // rax
  core::result::Result<usize,std::io::error::Error> v3; // rax OVERLAPPED
  core::result::Result<usize,std::io::error::Error> v4; // rdi
  __int64 v5; // rcx
  _str v6; // rax
  usize v7; // rdx
  __int64 v8; // rax
  core::result::Result<(),std::io::error::Error> v9; // rax
  __int64 v10; // rax
  core::result::Result<usize,std::io::error::Error> v11; // rax OVERLAPPED
  core::result::Result<usize,std::io::error::Error> v12; // rdi
  __int64 v13; // rcx
  _str v14; // rax
  _str v15; // rax
  _str v16; // rdx
  usize v17; // rax
  _str v18; // [rsp+0h] [rbp-1A8h]
  core::fmt::Arguments v19; // [rsp+10h] [rbp-198h] BYREF
  __int64 v20; // [rsp+40h] [rbp-168h]
  alloc::string::String self; // [rsp+48h] [rbp-160h] BYREF
  __int64 v22; // [rsp+60h] [rbp-148h]
  core::fmt::Arguments v23; // [rsp+68h] [rbp-140h] BYREF
  __int64 v24; // [rsp+98h] [rbp-110h]
  alloc::string::String v25; // [rsp+A0h] [rbp-108h] BYREF
  __int64 v26; // [rsp+B8h] [rbp-F0h]
  core::result::Result<usize,core::num::error::ParseIntError> v27; // [rsp+C0h] [rbp-E8h] BYREF
  alloc::vec::Vec<alloc::string::String,alloc::alloc::Global> v28; // [rsp+D0h] [rbp-D8h] BYREF
  core::fmt::Arguments v29; // [rsp+E8h] [rbp-C0h] BYREF
  core::fmt::rt::Argument args[1]; // [rsp+118h] [rbp-90h] BYREF
  alloc::string::String *v31; // [rsp+128h] [rbp-80h]
  core::result::Result<(),core::fmt::Error> *(__cdecl *v32)(core::result::Result<(),core::fmt::Error> *__return_ptr __struct_ptr, alloc::string::String *, core::fmt::Formatter *); // [rsp+130h] [rbp-78h]
  core::fmt::Arguments v33; // [rsp+138h] [rbp-70h] BYREF
  u8 *data_ptr; // [rsp+168h] [rbp-40h]
  usize v35; // [rsp+170h] [rbp-38h]
  usize v36; // [rsp+178h] [rbp-30h]
  alloc::string::String *v37; // [rsp+180h] [rbp-28h]
  core::result::Result<(),core::fmt::Error> *(__cdecl *v38)(core::result::Result<(),core::fmt::Error> *__return_ptr __struct_ptr, alloc::string::String *, core::fmt::Formatter *); // [rsp+188h] [rbp-20h]
  alloc::string::String *v39; // [rsp+190h] [rbp-18h]
  core::result::Result<(),core::fmt::Error> *(__cdecl *v40)(core::result::Result<(),core::fmt::Error> *__return_ptr __struct_ptr, alloc::string::String *, core::fmt::Formatter *); // [rsp+198h] [rbp-10h]
  alloc::string::String *v41; // [rsp+1A0h] [rbp-8h]

  <core::fmt::Arguments>::new_const::<1>(&v19, (_str (*)[1])pieces);
  std::io::stdio::_print();
  std::io::stdio::stdout();
  v20 = v0;
  <std::io::stdio::Stdout as std::io::Write>::flush();
  <core::result::Result<(), std::io::error::Error>>::expect(v1, (_str)__PAIR128__(17LL, "{_d0_m3_4_f4v0r_}"));
  <alloc::string::String>::new(&self);
  std::io::stdio::stdin();
  v22 = v2;
  std::io::stdio::Stdin::read_line();
  v4 = v3;
  *(_QWORD *)&v3.gap0[8] = "{_n0_c0n73x7_}";
  v5 = 14LL;
  <core::result::Result<usize, std::io::error::Error>>::expect(v4, *(_str *)((char *)&v3 + 8));
  v6 = <alloc::string::String as core::ops::deref::Deref>::deref(&self);
  v18.data_ptr = (u8 *)<str>::trim((_str *)v6.data_ptr, (_str)__PAIR128__(v6.length, v6.length));
  v18.length = v7;
  data_ptr = v18.data_ptr;
  v35 = v7;
  <core::fmt::Arguments>::new_const::<1>(&v23, (_str (*)[1])off_44B290);
  std::io::stdio::_print();
  std::io::stdio::stdout();
  v24 = v8;
  <std::io::stdio::Stdout as std::io::Write>::flush();
  <core::result::Result<(), std::io::error::Error>>::expect(v9, (_str)__PAIR128__(14LL, "{_y34h_416h7_}"));
  <alloc::string::String>::new(&v25);
  std::io::stdio::stdin();
  v26 = v10;
  std::io::stdio::Stdin::read_line();
  v12 = v11;
  *(_QWORD *)&v11.gap0[8] = "{_4_P4P_P4P!_}";
  v13 = 14LL;
  <core::result::Result<usize, std::io::error::Error>>::expect(v12, *(_str *)((char *)&v11 + 8));
  v14 = <alloc::string::String as core::ops::deref::Deref>::deref(&v25);
  v15.data_ptr = (u8 *)<str>::trim((_str *)v14.data_ptr, (_str)__PAIR128__(v14.length, v14.length));
  <str>::parse::<usize>(&v27, v15);
  *(_QWORD *)v12.gap0 = &v27;
  *(_QWORD *)&v12.gap0[8] = "{_74lk1n_0n_my_6uy5_}";
  v16.data_ptr = (u8 *)21;
  v16.length = (usize)&off_44B308;
  v36 = <core::result::Result<usize, core::num::error::ParseIntError>>::expect(
          (core::result::Result<usize,core::num::error::ParseIntError>)v12,
          v16);
  look::look_and_say(&v28, v18, v36 / 0x64);
  v17 = <alloc::vec::Vec<alloc::string::String>>::len(&v28);
  v39 = <alloc::vec::Vec<alloc::string::String> as core::ops::index::Index<usize>>::index(&v28, v17 - 1);
  v40 = <alloc::string::String as core::fmt::Display>::fmt;
  v41 = v39;
  v37 = v39;
  v38 = <alloc::string::String as core::fmt::Display>::fmt;
  v31 = v39;
  v32 = <alloc::string::String as core::fmt::Display>::fmt;
  *(_QWORD *)args[0].ty.gap0 = v39;
  *(_QWORD *)&args[0].ty.gap0[8] = <alloc::string::String as core::fmt::Display>::fmt;
  <core::fmt::Arguments>::new_v1::<2, 1>(&v29, (_str (*)[2])off_44B338, (core::fmt::rt::Argument (*)[1])args);
  std::io::stdio::_print();
  <core::fmt::Arguments>::new_const::<1>(&v33, (_str (*)[1])off_44B3B0);
  std::io::stdio::_print();
  core::ptr::drop_in_place::<alloc::vec::Vec<alloc::string::String>>(&v28);
  core::ptr::drop_in_place::<alloc::string::String>(&v25);
  core::ptr::drop_in_place::<alloc::string::String>(&self);
}mm

This is a rust binary. I am not really familiar with Rust. (And i don't really understand how this code works :b). So i do output based analysis.

Solve

Analyzing Program Behavior

We are given an encrypted string:

111312211{111312211_13211213211s13211713211h111312211_111312211d1113122110111312211n1113122117111312211_111312211l132112132110111312211k111312211_1113122110111312211r111312211_11131221151113122114111312211y111312211_1113122114111312211n111312211y1113122117111312211h31131122211n1113122116111312211_132123211o13211813211k111312211?111312211_111312211}

Our objective is to match our input with the encrypted string.

from pwn import *
from string import printable

elf = ELF('./look', checksec=False)
context.log_level = 'warn'
count = 0
for i in printable:
    io = process(elf.path)
    io.sendlineafter(b'.effie:', i.encode())
    io.sendlineafter(b'vinnie:', b'699')
    io.recvuntil(b': ')
    print(i, io.recvline().decode().strip(), count)
    io.close()
    count += 1

io.interactive()

This will outputs all possible chars and this is what it will look like when encoded:

0 1113122110 0
1 312211 1
2 1113122112 2
3 1113122113 3
4 1113122114 4
5 1113122115 5
6 1113122116 6
7 1113122117 7
8 1113122118 8
9 1113122119 9
a 111312211a 10
b 111312211b 11
c 111312211c 12
d 111312211d 13
e 111312211e 14
f 111312211f 15
g 111312211g 16
h 111312211h 17
i 111312211i 18
j 111312211j 19
k 111312211k 20
l 111312211l 21
m 111312211m 22
n 111312211n 23
o 111312211o 24
p 111312211p 25
q 111312211q 26
r 111312211r 27
s 111312211s 28
t 111312211t 29
u 111312211u 30
v 111312211v 31
w 111312211w 32
x 111312211x 33
y 111312211y 34
z 111312211z 35
A 111312211A 36
B 111312211B 37
C 111312211C 38
D 111312211D 39
E 111312211E 40
F 111312211F 41
G 111312211G 42
H 111312211H 43
I 111312211I 44
J 111312211J 45
K 111312211K 46
L 111312211L 47
M 111312211M 48
N 111312211N 49
O 111312211O 50
P 111312211P 51
Q 111312211Q 52
R 111312211R 53
S 111312211S 54
T 111312211T 55
U 111312211U 56
V 111312211V 57
W 111312211W 58
X 111312211X 59
Y 111312211Y 60
Z 111312211Z 61
! 111312211! 62
" 111312211" 63
# 111312211# 64
$ 111312211$ 65
% 111312211% 66
& 111312211& 67
' 111312211' 68
( 111312211( 69
) 111312211) 70
* 111312211* 71
+ 111312211+ 72
, 111312211, 73
- 111312211- 74
. 111312211. 75
/ 111312211/ 76
: 111312211: 77
; 111312211; 78
< 111312211< 79
= 111312211= 80
> 111312211> 81
? 111312211? 82
@ 111312211@ 83
[ 111312211[ 84
\ 111312211\ 85
] 111312211] 86
^ 111312211^ 87
_ 111312211_ 88
` 111312211` 89
{ 111312211{ 90
| 111312211| 91
} 111312211} 92
~ 111312211~ 93
  run with `RUST_BACKTRACE=1` environment variable to display a backtrace 94
         run with `RUST_BACKTRACE=1` environment variable to display a backtrace 95

 ParseIntError { kind: Empty } 96
 run with `RUST_BACKTRACE=1` environment variable to display a backtrace 97
\x0b run with `RUST_BACKTRACE=1` environment variable to display a backtrace 98
\x0c run with `RUST_BACKTRACE=1` environment variable to display a backtrace 99

So for every character, it will have the prefix 111312211 then is followed by the character. 1 is a special case where it becomes 312211

Knowing that, we will first try to look which character have the prefix 111312211 :

We found some character, that is:

{__d0n7_lk_0r_54y_any76_k?}

While analyzing, we noticed some characters not following the prefix, so i thought that it was a multiple character:

┌─[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/nomolog/wu]
└──╼ $./look 
vinnie: 😭 g what are you doin in my room 💀💀
.effie: ss
.effie: dw i aint doin ya dirty if i paid first ;>
vinnie: yeah aight here some $699
.effie: 13211213211s
vinnie: what?? i cant understand this! anyway idk help >_<

We found that it matches part of the encrypted flag:

The flag becomes:

{_ss_d0n7__0r_54y_any76_k?}

We continue:

┌─[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/nomolog/wu]
└──╼ $./look
vinnie: 😭 g what are you doin in my room 💀💀
.effie: {_sshhhhhhh
.effie: dw i aint doin ya dirty if i paid first ;>
vinnie: yeah aight here some $699
.effie: 111312211{111312211_13211213211s13211713211h
vinnie: what?? i cant understand this! anyway idk help >_<
{_sshhhhhhh_d0n7_lk_0r_54y_any76_k?}

┌─[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/nomolog/wu]
└──╼ $./look
vinnie: 😭 g what are you doin in my room 💀💀
.effie: {_sshhhhhhh_d0n7_
.effie: dw i aint doin ya dirty if i paid first ;>
vinnie: yeah aight here some $699
.effie: 111312211{111312211_13211213211s13211713211h111312211_111312211d1113122110111312211n1113122117111312211_
vinnie: what?? i cant understand this! anyway idk help >_<

┌─[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/nomolog/wu]
└──╼ $./look
vinnie: 😭 g what are you doin in my room 💀💀
.effie: {_sshhhhhhh_d0n7_l00k_
.effie: dw i aint doin ya dirty if i paid first ;>
vinnie: yeah aight here some $699
.effie: 111312211{111312211_13211213211s13211713211h111312211_111312211d1113122110111312211n1113122117111312211_111312211l132112132110111312211k111312211_
vinnie: what?? i cant understand this! anyway idk help >_<
{_sshhhhhhh_d0n7_l00k_0r_54y_any76_k?}

┌─[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/nomolog/wu]
└──╼ $./look 
vinnie: 😭 g what are you doin in my room 💀💀
.effie: {_sshhhhhhh_d0n7_l00k_0r_54y_4ny7h1n6_
.effie: dw i aint doin ya dirty if i paid first ;>
vinnie: yeah aight here some $699
.effie: 111312211{111312211_13211213211s13211713211h111312211_111312211d1113122110111312211n1113122117111312211_111312211l132112132110111312211k111312211_1113122110111312211r111312211_11131221151113122114111312211y111312211_1113122114111312211n111312211y1113122117111312211h31131122211n1113122116111312211_
vinnie: what?? i cant understand this! anyway idk help >_<
{_sshhhhhhh_d0n7_l00k_0r_54y_4ny7h1n6_k?}

You get the idea. After some trial and error, we will get the correct flag:

┌─[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/nomolog/wu]
└──╼ $./look 
vinnie: 😭 g what are you doin in my room 💀💀
.effie: {_sshhhhhhh_d0n7_l00k_0r_54y_4ny7h1n6_oookkkkkkkk?_}
.effie: dw i aint doin ya dirty if i paid first ;>
vinnie: yeah aight here some $699
.effie: 111312211{111312211_13211213211s13211713211h111312211_111312211d1113122110111312211n1113122117111312211_111312211l132112132110111312211k111312211_1113122110111312211r111312211_11131221151113122114111312211y111312211_1113122114111312211n111312211y1113122117111312211h31131122211n1113122116111312211_132123211o13211813211k111312211?111312211_111312211}
vinnie: what?? i cant understand this! anyway idk help >_<

When submitted to the platform, the flag doesn't use the flag format so...

Flag: {_sshhhhhhh_d0n7_l00k_0r_54y_4ny7h1n6_oookkkkkkkk?_}

Gacor

Description

Author: .effie

i did not have gaming relation with that balatro

Initial Analysis

We are given 3 files:

┌─[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/Gacor]
└──╼ $tree -a .
.
├── chall
├── .effie
└── output.txt

1 directory, 4 files
┌─[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/Gacor/wu]
└──╼ $file chall 
chall: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=6a88d64b2e0eb767a6445a6020f127dc25c412b0, for GNU/Linux 3.2.0, stripped
.effie
(SO35<?BT,W24IRL4=JL<55E"24EVN,/;68WYS8CW8H8?NAMSPSUYHJKQHQLUIJUTOVSTVRSTUVWVYX
output.txt
14:55:42  !  effie  ~thedaa@user/effie  has joined #gamabargabukber
14:55:42   effie  heyy, anyone wanna play poker? :p
[#gamabargabukber] 
14:55:42   effie  okay, whatever! here's the deck!! ;)
                 Black  6       Clubs
                 Black  6       Clubs
                 Red    6       Clubs
                 Red    7       Clubs
                 Black  7       Clubs
                 Black  8       Clubs
                 Red    10      Clubs
                 Red    Jack    Clubs
                 Red    King    Clubs
                 Red    Hero    Clubs
                 Black  Hero    Clubs
                 Black  Hero    Clubs
                 Red    Hero    Clubs
                 Red    Hero    Clubs
                 Black  Hero    Clubs
                 Black  Hacker  Clubs
                 Red    Hacker  Clubs
                 Black  Hacker  Clubs
                 Black  Hacker  Clubs
                 Red    Queen   Clubs
                 Black  Queen   Clubs
                 Red    Queen   Clubs
                 Black  Queen   Clubs
                 Red    Queen   Clubs
                 Red    4       Diamonds
                 Red    6       Diamonds
                 Black  6       Diamonds
                 Red    6       Diamonds
                 Black  6       Diamonds
                 Red    6       Diamonds
                 Red    7       Diamonds
                 Black  10      Diamonds
                 Red    Jack    Diamonds
                 Black  Jack    Diamonds
                 Red    King    Diamonds
                 Red    King    Diamonds
                 Red    King    Diamonds
                 Red    King    Diamonds
                 Black  King    Diamonds
                 Red    Hero    Diamonds
                 Red    Hacker  Diamonds
                 Red    Hacker  Diamonds
                 Red    Hacker  Diamonds
                 Black  Queen   Diamonds
                 Red    Queen   Diamonds
                 Red    Queen   Diamonds
                 Black  Queen   Diamonds
                 Black  3       Hearts
                 Black  4       Hearts
                 Black  5       Hearts
                 Black  5       Hearts
                 Black  6       Hearts
                 Black  6       Hearts
                 Black  7       Hearts
                 Black  8       Hearts
                 Black  9       Hearts
                 Black  Jack    Hearts
                 Black  Jack    Hearts
                 Black  Jack    Hearts
                 Red    King    Hearts
                 Black  King    Hearts
                 Black  King    Hearts
                 Black  King    Hearts
                 Black  Hero    Hearts
                 Red    Hero    Hearts
                 Black  Hero    Hearts
                 Red    Hero    Hearts
                 Black  Hacker  Hearts
                 Black  3       Spades
                 Black  5       Spades
                 Red    5       Spades
                 Black  6       Spades
                 Red    6       Spades
                 Black  7       Spades
                 Red    9       Spades
                 Black  10      Spades
                 Black  10      Spades
                 Black  Jack    Spades
                 Black  Jack    Spades
                 Black  Jack    Spades
                 Red    King    Spades
                 Black  King    Spades
                 Red    King    Spades
                 Black  King    Spades
                 Red    King    Spades
                 Black  King    Spades
                 Black  Hero    Spades
                 Red    Hero    Spades
                 Black  Hacker  Spades
                 Black  Hacker  Spades
[#gamabargabukber] 
14:55:42  !  connection error! disconnected from #gamabargabukber

Code Analysis

We decompile in IDA:

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  char v4; // al
  int v5; // [rsp+4h] [rbp-23Ch]
  int i; // [rsp+8h] [rbp-238h]
  int j; // [rsp+Ch] [rbp-234h]
  time_t timer; // [rsp+18h] [rbp-228h] BYREF
  char v9[256]; // [rsp+20h] [rbp-220h] BYREF
  char s[264]; // [rsp+120h] [rbp-120h] BYREF
  unsigned __int64 v11; // [rsp+228h] [rbp-18h]

  v11 = __readfsqword(0x28u);
  timer = time(0LL);
  qword_4050 = (__int64)localtime(&timer);
  printf(
    "%d:%d:%d  !  effie  ~thedaa@user/effie  has joined #gamabargabukber\n",
    *(_DWORD *)(qword_4050 + 8),
    *(_DWORD *)(qword_4050 + 4),
    *(_DWORD *)qword_4050);
  printf(
    "%d:%d:%d   effie  heyy, anyone wanna play poker? :p\n",
    *(_DWORD *)(qword_4050 + 8),
    *(_DWORD *)(qword_4050 + 4),
    *(_DWORD *)qword_4050);
  printf("[#gamabargabukber] ");
  if ( fgets(s, 256, stdin) )
  {
    v5 = strlen(s);
    if ( v5 > 0 && s[v5 - 1] == 10 )
      s[--v5] = 0;
    for ( i = 0; i < v5; ++i )
    {
      if ( s[i] < 0 )
      {
        printf(
          "%d:%d:%d   effie  HEH what did you just said??? D:\n",
          *(_DWORD *)(qword_4050 + 8),
          *(_DWORD *)(qword_4050 + 4),
          *(_DWORD *)qword_4050);
        sub_1705();
        return 1LL;
      }
      if ( (i & 1) != 0 )
        v4 = -1;
      else
        v4 = 1;
      v9[i] = sub_12E9((unsigned int)(char)(s[i] + (i % 12 + 1) / 2 * v4));
    }
    sub_13F5(v9, (unsigned int)v5);
    printf(
      "\n%d:%d:%d   effie  okay, whatever! here's the deck!! ;)\n",
      *(_DWORD *)(qword_4050 + 8),
      *(_DWORD *)(qword_4050 + 4),
      *(_DWORD *)qword_4050);
    for ( j = 0; j < v5; ++j )
      sub_1555(&v9[j]);
    puts("[#gamabargabukber] ");
    sub_1705();
    return 1LL;
  }
  else
  {
    fwrite("you don't wanna play?? >:/\n", 1uLL, 0x1BuLL, stderr);
    return 1LL;
  }
}

Solve

ffiishy (TBU)

Description

Author: f4r4w4y

Foreign Function Interface is FFIishy (or ffiilthy?)

Initial Analysis

TBU

Code Analysis

TBU

Solve

TBU

PreviousBinary ExploitationNextBlockchain

Last updated 2 months ago

Raw Diary

Mencari PW

nomolog

Gacor

To get the code, we need to extract the .pyc files first, we can use .

We decompile chall.pyc using :

pyinstxtractor
pylingual
🥈
🥉
🥉
🥈