CTF Writeups
WebsiteDiscordSocials..
  • CryptoCat's CTF writeups
  • 2025
    • Tsuku
      • Web
        • len_len
        • Flash
        • YAMLwaf
    • CTF@CIT
      • Web
        • Breaking Authentication
        • Commit & Order: Version Control Unit
        • How I Parsed your JSON
        • Mr. Chatbot
        • Keeping Up with the Credentials
  • 2024
    • CryptoCat
      • Summar-AI-ze
    • Intigriti
      • Warmup
        • BabyFlow
        • In Plain Sight
        • IrrORversible
        • Layers
        • Rigged Slot Machine 1
      • Game
        • Bug Squash 1
        • Bug Squash 2
      • Rev
        • Secure Bank
      • Web
        • Biocorp
        • Cat Club
        • Pizza Paradise
        • SafeNotes 2.0
      • Misc
        • Quick Recovery
        • Triage Bot 2
      • Pwn
        • Floormat Sale
        • Retro2Win
        • Rigged Slot Machine 2
        • UAP
      • Crypto
        • Schrodinger's Pad
      • Mobile
        • Cold Storage
      • OSINT
        • No Comment
        • Trackdown
        • Trackdown 2
      • Forensics
        • CTF Mind Tricks
        • Hoarded Flag
        • Password Management
    • CSAW
      • Web
        • Playing on the Backcourts
        • Log Me In
        • Lost Pyramid
        • BucketWars
    • CyberSpace
      • Web
        • Feature Unlocked
    • UIU
      • Web
        • Fare Evasion
        • Log Action
    • Wani
      • Web
        • Bad Worker
        • PoW
        • One Day One Letter
    • Akasec
      • Web
    • HTB Cyber Apocalypse
      • Web
        • Flag Command
        • TimeKORP
        • KORP Terminal
        • Labyrinth Linguist
        • Locktalk
        • SerialFlow
        • Testimonial
  • 2023
    • Intigriti
      • Gamepwn
        • Dark Secrets
      • Misc
        • Triage Bot
      • OSINT
        • Photographs
      • Pwn
        • Floormat Store
      • Web
        • Bug Report Repo
        • My Music
    • Imaginary
      • Web
        • Blank
        • IDORiot
        • Inspection
        • Login
        • Perfect Picture
        • Roks
    • Google
      • Pwn
        • Write-Flag-Where
    • Cyber Apocalypse
      • AI
        • Last Hope
        • Mysterious Learning
      • Crypto
        • Perfect Synchronization
      • Pwn
        • Getting Started
        • Labyrinth
        • Pandora's Box
        • Void
      • Rev
        • Cave System
        • Hunting License
        • Needle in a Haystack
        • Shattered Tablet
        • She Sells Sea Shells
    • Sekai
      • Rev
        • Azusawa's Gacha World
    • Amateurs
      • Web
        • Sanity
        • Waiting an Eternity
    • NahamCon
      • Web
        • Hidden Figures
        • Marmalade 5
        • Obligatory
        • Star Wars
        • Stickers
    • Angstrom
      • Pwn
        • Leek
  • 2022
    • Imaginary (iCTF)
      • Crypto
        • ASE
      • Pwn
        • Links 1
        • Links 2
        • Links 3
        • Open Doors
    • SEETF
      • Pwn
        • 4mats
        • Easy Overflow
      • Rev
        • BabyReeee
      • Web
        • Super-Secure-Requests-Forwarder
    • HTB Cyber Apocalypse
      • Pwn
        • Hellbound
    • Angstrom
      • Pwn
        • Really Obnoxious Problem
        • Wah
        • Whats My Name
        • Where Am I
      • Web
        • Crumbs
        • Xtra Salty Sardines
    • NahamCon
      • Pwn
        • Baby Steps
      • Web
        • Flaskmetal Alchemist
        • Hacker Ts
        • Two for One
    • Pico
      • Forensics
        • Side Channel
      • Pwn
        • Buffer Overflow 1
        • Buffer Overflow 2
        • Buffer Overflow 3
        • Flag Leak
        • Function Overwrite
        • ROPfu
        • RPS
        • Stack Cache
        • Wine
        • X-Sixty-What
      • Rev
        • Wizardlike
      • Web
        • Noted
    • Space Heroes
      • Pwn
        • Vader
      • Web
        • Flag in Space
    • Intigriti
      • Pwn
        • Bird
        • Cake
        • Easy Register
        • Search Engine
    • Dice
      • Pwn
        • Interview Opportunity
  • 2021
    • Pico
      • Pwn
        • Unsubscriptions Are Free
    • Crusaders of Rust (COR)
      • Crypto
        • Fibinary
      • Pwn
        • Chainblock
    • HTB Cyber Santa
      • Crypto
        • Meet Me Halfway
        • Xmas Spirit
      • Pwn
        • Minimelfistic
        • Mr. Snowy
        • Naughty List
        • Sleigh
      • Rev
        • Infiltration
        • Intercept
    • K3rn3l
      • Crypto
        • Badseed
        • Twizzty Buzzinezz
    • HTB x Synack RedTeamFive
      • Misc
        • Context
        • Hotel
      • Pwn
        • Air Supplies
        • Injection Shot
        • Library
        • Recruitment
      • Rev
        • Knock Knock
        • Split
    • KillerQueen
      • Pwn
        • A Kind of Magic
        • Tweety Birb
        • Zoom2Win
    • HacktivityCon
      • Pwn
        • Retcheck
        • The Library
        • Yabo
      • Web
        • Availability
    • CSAW
      • Pwn
        • Alien Math
        • Password Checker
      • Rev
        • Checker
    • HackyHolidays
      • Crypto
        • Cute Invoice
        • Mineslazer
      • Forensics
        • Injection Traffic
        • Power Snacks
      • Pwn
        • Deleted Flag
        • Engine Control
      • Web
        • Skylark
    • HTB Cyber Apocalypse
      • Crypto
        • Phasestream
      • Misc
        • Alien Camp
        • Build Yourself In
      • Pwn
        • Controller
        • System Drop
      • Web
        • Blitzprop
        • E-Tree
        • Wild Goose Hunt
    • Angstrom
      • Pwn
        • Sanity Checks
        • Secure Login
        • Sticky Stacks
        • Tranquil
      • Rev
        • Free Flags
        • Jailbreak
      • Web
        • Jar
Powered by GitBook
On this page
  • Video walkthrough
  • Challenge Description
  • Solution
  • Static Analysis
  • Dynamic Analysis
  • Solve.py
  1. 2024
  2. Intigriti
  3. Rev

Secure Bank

Writeup for Secure Bank (Rev) - 1337UP LIVE CTF (2024) 💜

PreviousRevNextWeb

Last updated 4 months ago

Video walkthrough

Challenge Description

Can you crack the bank?

Solution

Players try to login to the secure bank but don't have the correct pin.

./secure_bank
****************************************
*         Welcome to SecureBank        *
*    Your trusted partner in security  *
****************************************

========================================
=   SecureBank Superadmin Login System =
========================================

Enter superadmin PIN: 1234
Access Denied! Incorrect PIN.

Checking the strings will uncover the plaintext flag (different for remote) but no pin.

strings -n 10 secure_bank

Access Granted! Welcome, Superadmin!
INTIGRITI{fake_flag}
Here is your flag: %s
Access Denied! Incorrect 2FA code.
Enter superadmin PIN:
Access Denied! Incorrect PIN.
Enter your 2FA code:
GCC: (Debian 12.2.0-14) 12.2.0

We could try a tool like ltrace to see if the pin comparison is displayed.

printf("Enter superadmin PIN: ")                                         = 22
__isoc99_scanf(0x55d5a141b1ea, 0x7ffe6418d938, 0, 0Enter superadmin PIN: 1234
)                     = 1
puts("Access Denied! Incorrect PIN."Access Denied! Incorrect PIN.
)                                    = 30
+++ exited (status 1) +++

Unfortunately, it is not. Let's check the decompiled code with ghidra.

Static Analysis

banner();
login_message();
printf("Enter superadmin PIN: ");
__isoc99_scanf(&%u,&pin);
if (pin == 1337) {
  valid_code = generate_2fa_code(1337);
  printf("Enter your 2FA code: ");
  __isoc99_scanf(&%u,&user_code);
  validate_2fa_code(user_code,valid_code);
}
else {
  puts("Access Denied! Incorrect PIN.");
}
return pin != 1337;

Classic 1337, so predictable is almost unpredictable 🤔🧠

./secure_bank
****************************************
*         Welcome to SecureBank        *
*    Your trusted partner in security  *
****************************************

========================================
=   SecureBank Superadmin Login System =
========================================

Enter superadmin PIN: 1337
Enter your 2FA code: 1234
Access Denied! Incorrect 2FA code.

Checking the generate_2fa_code function, it looks a little complicated.

local_10 = param_1 * 0xbeef;
local_c = local_10;
for (local_14 = 0; local_14 < 10; local_14 = local_14 + 1) {
  local_c = obscure_key(local_c);
  local_10 = ((local_10 ^ local_c) << 5 | (local_10 ^ local_c) >> 0x1b) +
             (local_c << ((char)local_14 + (char)(local_14 / 7) * -7 & 0x1fU) ^
             local_c >> ((char)local_14 + (char)(local_14 / 5) * -5 & 0x1fU));
}
return local_10 & 0xffffff;

Nothing that a little variable renaming can't fix!

key = pin * 0xbeef;
code = key;
for (i = 0; i < 10; i = i + 1) {
  code = obscure_key(code);
  key = ((key ^ code) << 5 | (key ^ code) >> 27) +
        (code << ((char)i + (char)(i / 7) * -7 & 31U) ^
        code >> ((char)i + (char)(i / 5) * -5 & 31U));
}
return key & 0xffffff;

Much better! The obscure_code function is quite simple.

return ((code ^ 0xa5a5a5a5) << 3 | (code ^ 0xa5a5a5a5) >> 29) * 0x1337 ^ 0x5a5a5a5a;

Dynamic Analysis

Actually, we want to break right after the function (offset 0x1386).

pwndbg> breakrva 0x1386
Breakpoint 1 at 0x555555555386
pwndbg> run

****************************************
*         Welcome to SecureBank        *
*    Your trusted partner in security  *
****************************************

========================================
=   SecureBank Superadmin Login System =
========================================

Enter superadmin PIN: 1337

Breakpoint 1, 0x0000555555555386 in main ()

─────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]─────────────────────────────────────────
   0x555555555381 <main+112>    call   generate_2fa_code           <generate_2fa_code>

 â–º 0x555555555386 <main+117>    mov    dword ptr [rbp - 4], eax     [0x7fffffffda8c] <= 0x568720
   0x555555555389 <main+120>    lea    rax, [rip + 0xe7b]           RAX => 0x55555555620b ◂— 'Enter your 2FA code: '
   0x555555555390 <main+127>    mov    rdi, rax                     RDI => 0x55555555620b ◂— 'Enter your 2FA code: '
   0x555555555393 <main+130>    mov    eax, 0                       EAX => 0
   0x555555555398 <main+135>    call   printf@plt                  <printf@plt>

See the value being moved from the EAX register onto the stack? 0x568720 in decimal is 5670688, let's try it!

./secure_bank
****************************************
*         Welcome to SecureBank        *
*    Your trusted partner in security  *
****************************************

========================================
=   SecureBank Superadmin Login System =
========================================

Enter superadmin PIN: 1337
Enter your 2FA code: 5670688
Access Granted! Welcome, Superadmin!
Here is your flag: INTIGRITI{pffft_what_2fa?!}

Solve.py

Another option is to make a solve script according to the decompiled code. I like to copy/paste from ghidra to ChatGPT and get a python script to run.

def obscure_key(key):
    key ^= 0xA5A5A5A5
    # Make sure it stays within 32 bits
    key = (key << 3) & 0xFFFFFFFF | (key >> 29)
    key *= 0x1337
    key &= 0xFFFFFFFF  # Keep it within 32-bit unsigned integer bounds
    key ^= 0x5A5A5A5A
    return key

def generate_2fa_code(pin):
    key = pin * 0xBEEF
    key &= 0xFFFFFFFF  # Ensure it's 32-bit
    code = key

    for i in range(10):
        key = obscure_key(key)
        code ^= key
        code = (code << 5) & 0xFFFFFFFF | (
            code >> 27)  # Rotate and ensure 32 bits
        code += (key >> (i % 5)) ^ (key << (i % 7))
        code &= 0xFFFFFFFF  # Keep it within 32-bit unsigned integer bounds

    code &= 0xFFFFFF  # Ensure the 2FA code is 24 bits (6 digits)
    return code

if __name__ == "__main__":
    pin = 1337  # The superadmin PIN
    expected_code = generate_2fa_code(pin)
    print(f"Expected 2FA Code: {expected_code}")
python solve.py
Expected 2FA Code: 5670688

Flag: INTIGRITI{pfff7_wh47_2f4?!}

There's a lot of different ways to solve the challenge from here. One easy way might be to run the binary in a debugger like gdb (I like ) and set a breakpoint around the generate_2f_code function (or validate_2fa_code).

pwndbg