$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
(09-07-2025, 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
#5
(09-07-2025, 12:42 AM)cyclone Wrote:
(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))'


I have 4 GPU, but used only 1...How to change my runing script? Speed is ~600p/s on GPU RTX 4090, it's normal?
Reply
#6
(09-25-2025, 12:46 PM)zamgold Wrote: I have 4 GPU, but used only 1...How to change my runing script? Speed is ~600p/s on GPU RTX 4090, it's normal?

That dynamic bridge only uses the CPU, hence why your GPUs aren't really doing anything interesting. A proper module would have to be created, which I'll take a look into in a few hours
Reply
#7
Wink 
(09-25-2025, 12:52 PM)penguinkeeper Wrote:
(09-25-2025, 12:46 PM)zamgold Wrote: I have 4 GPU, but used only 1...How to change my runing script? Speed is ~600p/s on GPU RTX 4090, it's normal?

That dynamic bridge only uses the CPU, hence why your GPUs aren't really doing anything interesting. A proper module would have to be created, which I'll take a look into in a few hours

Will you share your implementation later? Smile
Reply
#8
(09-25-2025, 12:57 PM)zamgold Wrote: Will you share your implementation later? Smile

Yeah, I'll PR it and let you know in here when it's done
Reply
#9
PRed but not yet merged: https://github.com/hashcat/hashcat/pull/4512
Reply
#10
I recommend that you check the encryption algorithm of such hashes yourself again, if possible. You need to try creating an account with a known password yourself. The hashes that were previously provided to me for experiments. I was able to verify this successfully. But I also tried to find at least one password from the large number of hashes posted on the forums. The search was unsuccessful. It is possible that very complex passwords are installed there. Or maybe the encryption algorithm doesn't match.
test hashes
https://privatebin.io/?b589004336180226#...p2dHsHwY1m
Reply