$wp$2y$10$
#1
Hashes of this format began to appear on the forums.
$wp$2y$10$........................:example
We managed to parse this type of hash. This is not a simple bcrypt
This password is encrypted several times.
The approximate encryption algorithm is as follows.
bcrypt hmac-sha384 base64
 Next, I'll show you how to search for it. But we need to write a module for hashcat, because our search method is very inconvenient. but it's possible.
cat test.dic | ./wp-sha384-hmac.bin | ./hashcat -m 3200 -a 0  3200.hash

You need to compile from the code  wp-sha384-hmac.bin
gcc wp-sha384-hmac.bin.c -O3 -march=native -flto -ffast-math -funroll-loops -o wp-sha384-hmac.bin -lssl -lcrypto

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>

#define HMAC_KEY "wp-sha384"
#define HMAC_KEY_LEN 10

char *trim_whitespace(char *str) {
    if (!str) return NULL;

    while (isspace((unsigned char)*str)) str++;

    if (*str == '\0')
        return str;

    char *end = str + strlen(str) - 1;
    while (end > str && isspace((unsigned char)*end)) end--;

    *(end + 1) = '\0';
    return str;
}

void process_stream(FILE *fp) {
    char *line = NULL;
    size_t len = 0;

    while (getline(&line, &len, fp) != -1) {
        char *clean = trim_whitespace(line);
        size_t linelen = strlen(clean);

        unsigned char hmac[EVP_MAX_MD_SIZE];
        unsigned int hmac_len = 0;

        HMAC(EVP_sha384(),
            HMAC_KEY, HMAC_KEY_LEN,
            (unsigned char *)clean, linelen,
            hmac, &hmac_len);

        BIO *b64 = BIO_new(BIO_f_base64());
        BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
        BIO *bio = BIO_new(BIO_s_mem());
        b64 = BIO_push(b64, bio);

        BIO_write(b64, hmac, hmac_len);
        BIO_flush(b64);

        BUF_MEM *bptr;
        BIO_get_mem_ptr(b64, &bptr);
        fwrite(bptr->data, 1, bptr->length, stdout);
        putchar('\n');

        BIO_free_all(b64);
    }

    free(line);
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        process_stream(stdin);
        return 0;
    }

    for (int i = 1; i < argc; ++i) {
        if (strcmp(argv[i], "-") == 0) {
            process_stream(stdin);
            continue;
        }

        FILE *fp = fopen(argv[i], "r");
        if (!fp) {
            perror(argv[i]);
            continue;
        }

        process_stream(fp);
        fclose(fp);
    }

    return 0;
}
If your dictionary contains the password to your hash. Then you will have to search for it again in some way in your dictionary. That's the whole problem. We need your help with the revision.
If necessary, I can post a hash with a known password for your experiments in this thread.
Reply
#2
(09-06-2025, 10:50 AM)174region174 Wrote: ...$wp$2y$10$...

Hashcat can crack these with the new rust bridge mode -m 74000. 

Code:
echo cyclone | ./hashcat.bin -m 74000 -a0 -w3 --session=bridge --potfile-disable \
    '$2b$12$CnC/yHPQoTI40ISHyVEzCuRXkjDkydxPx.VceRJwUsBji5WDqw5BK*12*CnC/yHPQoTI40ISHyVEzCu' \
    --bridge-parameter1 ./bridges/subs/dynamic_hash.so \
    --bridge-parameter2 'bcrypt2b(cost=$s1,salt=$s2,hmac_sha384:b64(key="wp-sha384",$p))'
~
Reply
#3
Here's a quick rundown:
1. Parse $wp$2... bcrypt hash to hashcat bridge mode (see python3 code below)
2. Set up hashcat bridge mode (see example in my previous post; make sure to use the correct "bcrypt2x" mode in --bridge-parameter2 which must match your hash -- likely bcrypt2y, but bcrypt2b in my example)
3. Run hashcat which should crack the example hash:plaintext 

example wp formatted hash:plain (generated hash)
Code:
$wp$2b$12$CnC/yHPQoTI40ISHyVEzCuRXkjDkydxPx.VceRJwUsBji5WDqw5BK:cyclone

example hashcat bridge formatted hash:plain (generated hash)
Code:
$2b$12$CnC/yHPQoTI40ISHyVEzCuRXkjDkydxPx.VceRJwUsBji5WDqw5BK*12*CnC/yHPQoTI40ISHyVEzCu:cyclone

./wp2hashcat.py < wp_hash.txt
Code:
#!/usr/bin/env python3
import sys

for line in sys.stdin:
    s = line.strip().removeprefix("$wp$")
    if not s.startswith("$"):
        s = "$" + s
    _, algo, cost, rest = s.split("$", 3)
    print(f"{s}*{cost}*{rest[:22]}")
~
Reply
#4
(Yesterday, 02:30 AM)cyclone Wrote: Here's a quick rundown:
1. Parse $wp$2... bcrypt hash to hashcat bridge mode (see python3 code below)
2. Set up hashcat bridge mode (see example in my previous post; make sure to use the correct "bcrypt2x" mode in --bridge-parameter2 which must match your hash -- likely bcrypt2y, but bcrypt2b in my example)
3. Run hashcat which should crack the example hash:plaintext 

example wp formatted hash:plain (generated hash)
Code:
$wp$2b$12$CnC/yHPQoTI40ISHyVEzCuRXkjDkydxPx.VceRJwUsBji5WDqw5BK:cyclone

example hashcat bridge formatted hash:plain (generated hash)
Code:
$2b$12$CnC/yHPQoTI40ISHyVEzCuRXkjDkydxPx.VceRJwUsBji5WDqw5BK*12*CnC/yHPQoTI40ISHyVEzCu:cyclone

./wp2hashcat.py < wp_hash.txt
Code:
#!/usr/bin/env python3
import sys

for line in sys.stdin:
    s = line.strip().removeprefix("$wp$")
    if not s.startswith("$"):
        s = "$" + s
    _, algo, cost, rest = s.split("$", 3)
    print(f"{s}*{cost}*{rest[:22]}")

Thank you for the work you have done. I think many users will need this. Not everyone is aware of this type of encryption yet. And they are trying to find the password for these hashes, just like for regular bcrypt.
Reply