0x00 前言本文記錄從零開始搭建VMware Workspace ONE Access漏洞調試環境的細節。
0x01 簡介本文將要介紹以下內容:
VMware Workspace ONE Access安裝
VMware Workspace ONE Access漏洞調試環境配置
常用知識
0x02 VMware Workspace ONE Access安裝參考資料:
https://docs.vmware.com/en/VMware-Workspace-ONE-Access/20.01/workspace_one_access_install.pdf
1.下載OVA文件下載頁面:
https://customerconnect.vmware.com/downloads/search?query=workspace%20one%20access
下載前需要先註冊用戶,之後選擇需要的版本進行下載
VMware Workspace ONE Access 21.08.0.1的下載頁面:https://customerconnect.vmware.com/downloads/details?downloadGroup=WS1A_ONPREM_210801productId=1269
下載文件identity-manager-21.08.0.1-19010796_OVF10.ova
2.安裝(1)在VMware Workstation中導入OVA文件
注:
VMware Workstation版本需要大於14,否則報錯提示無法導入
在安裝頁面設置Host Name,如果配置了DHCP,其他選項不用設置,我的配置指定了靜態IP,配置如下圖
等待OVA文件導入完成後,將會自動開機進行初始化,初始化完成後如下圖
(2)配置
修改本機的hosts文件,將192.168.1.11指向workspaceone.test.com
訪問配置頁面https://workspaceone.test.com:8443
設置admin、root和sshuser用戶的口令,口令需要包含大寫字母、小寫字母、數字和特殊字符
注:
我的測試結果顯示,口令長度需要設置為14,否則無法登陸root和sshuser用戶
我的測試環境設置口令為Password@12345,如下圖
設置數據庫,為了便於環境搭建,這裡選擇Internal Database
等待安裝完成,如下圖
3.設置允許root用戶遠程登錄ssh
需要登錄VMware Workspace ONE Access,修改系統的配置文件,有以下兩種登錄方法:
(1)在虛擬機中直接登錄root用戶
選擇Login,輸入root和口令Password@12345
(2)通過ssh登錄sshuser用戶
登錄後再切換至root
切換至root用戶後,依次執行以下命令:
vi/etc/ssh/sshd_config設置PermitRootLogin從no變為yes
systemctlrestartsshd4.開啟遠程調試功能
修改文件:/opt/vmware/horizon/workspace/bin/setenv.sh
修改參數JVM_OPTS,添加參數:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
如下圖
重新啟動系統
打開防火牆:iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT
IDEA設置遠程調試參數,如下圖
注:
IDEA的完整配置方法可參考之前的文章《Zimbra漏洞调试环境搭建》
0x03 常用知識1.常用命令
查看系統服務狀態: chkconfig --list
查看所有服務狀態: systemctl status
查看IP地址: ip addr show
查看Host Name: hostname
日誌路徑: /opt/vmware/horizon/workspace/logs/
2.查看系統版本
需要root權限執行命令: vamicli version --appliance
查看系統版本的實現細節:
#!/usr/bin/envpython2
importsys
sys.path.append('/opt/vmware/lib/python/site-packages/')
importpywbem
defgetCIMConnection(url,namespace):
cred={}
cred['cert_file']='/opt/vmware/etc/sfcb/client.pem'
cred['key_file']='/opt/vmware/etc/sfcb/file.pem'
cliconn=pywbem.WBEMConnection(url,None,namespace,cred)
returncliconn
defshowVersion():
try:
cliconn=getCIMConnection('https://localhost:5489','root/cimv2')
esis=cliconn.EnumerateInstances('VAMI_ElementSoftwareIdentity')
except:
print('error')
return
foresiinesis:
ess=esi['ElementSoftwareStatus']
if(ess==[2,6]):
inst=cliconn.GetInstance(esi['Antecedent'])
print('Version-'+inst['VersionString'])
print('Description-'+inst['Description'])
showVersion()需要root權限是因為訪問文件/opt/vmware/etc/sfcb/client.pem和/opt/vmware/etc/sfcb/file.pem需要root權限
3.數據庫連接口令
連接數據庫的明文口令位置為:/usr/local/horizon/conf/db.pwd
連接數據庫的口令加密保存在文件/usr/local/horizon/conf/runtime-config.properties中,文件內容示例:
datastore.jdbc.url=jdbc:postgresql://localhost/saas?stringtype=unspecified
datastore.jdbc.userName=horizon
secure.datastore.jdbc.password=BAACs8MW1xyMe7/8ONd2QwtG3mw37wF1/1pQ6D09xXqf56ncfRtCun6y8A1XFtjajhU60V1QNYnCOxk3t1m0dV0JvA==其中,BAACs8MW1xyMe7/8ONd2QwtG3mw37wF1/1pQ6D09xXqf56ncfRtCun6y8A1XFtjajhU60V1QNYnCOxk3t1m0dV0JvA==為加密口令
需要以下文件作為解密密鑰:
/usr/local/horizon/conf/configkeystore.pass
/usr/local/horizon/conf/configkeystore.bcfks4.數據庫中的加密信息
admin用戶的口令加密存儲在數據庫中
查詢命令:saas=SELECT 'passwordAuthData' FROM 'PasswordInformation';
查詢結果如下圖
加密的主要實現代碼1:
privateStringAES_encrypt(@Nonnullbyte[]clearData,@Nonnullbyte[]key,@NonnullEncryptionAlgorithmsencAlg)throwsEncryptionServiceException{
Preconditions.checkNotNull(clearData);
Preconditions.checkNotNull(key);
Preconditions.checkNotNull(encAlg);
Preconditions.checkArgument(clearData.length!=0);
try{
StringcipherName=encAlg.getCipherName();
Ciphercipher=Cipher.getInstance(cipherName,provider);
intnonceSize=encAlg.getNonceSize(cipher.getBlockSize());
IvParameterSpecivSpec=null;
StringencodedIv;
if(nonceSize0){
byte[]iv=newbyte[nonceSize];
srand.nextBytes(iv);
ivSpec=newIvParameterSpec(iv);
encodedIv=newString(Hex.encode(iv),StandardCharsets.US_ASCII);
}else{
encodedIv='';
}
if(encAlg.forcePadding()){
clearData=ArrayUtils.add(clearData,(byte)1);
}
SecretKeysecret=newSecretKeySpec(key,cipherName);
cipher.init(1,secret,ivSpec,srand);
byte[]data=cipher.doFinal(clearData);
Stringoutput=Integer.toString(4)+':'+encodedIv+':'+newString(Hex.encode(data),StandardCharsets.US_ASCII);
returnoutput;
}catch(InvalidKeyException|BadPaddingException|IllegalBlockSizeException|InvalidAlgorithmParameterException|NoSuchPaddingException|NoSuchAlgorithmException|FipsUnapprovedOperationErrorvar12){
log.error('FailedtoencryptwithAES:'+var12.getMessage());
thrownewEncryptionServiceException(var12);
}
}加密的主要實現代碼2:
StringencryptedData=Integer.toString(1)+','+encKey.getSafeUuid().toString()+','+this.AES_encrypt(clearData,aesKey,encAlg);5.8443端口登錄口令
登錄口令加密保存在文件/usr/local/horizon/conf/config-admin.json
加密的主要實現代碼:
privatevoidsetPassword(StringnewPassword,booleanisSet)throwsAdminAuthException{
intic=this.passwordAuthenticationUtil.getIc(iterationCountBase,iterationCountRange);
try{
StringnewEncryptedPassword=this.passwordAuthenticationUtil.createPWInfo('admin','admin',ic,newPassword);
PasswordInfonewPasswordInfo=newPasswordInfo(newEncryptedPassword,isSet);
if(this.passwordInfo!=null){
newPasswordInfo.setAttemptDelay(this.passwordInfo.getAttemptDelay());
newPasswordInfo.setMaxAttemptCount(this.passwordInfo.getMaxAttemptCount());
}
objectMapper.writeValue(this.passwordInfoFile,newPasswordInfo);
}catch(IOException|EncryptionServiceExceptionvar7){
thrownewAdminAuthException('Failedtosetpassword'+var7.getMessage(),var7);
}
try{
this.loadEncryptedPasswordFromFile();
}catch(IOExceptionvar6){
thrownewAdminAuthException('Failedtoloadstoredpassword'+var6.getMessage(),var6);
}
}0x04 小結在我們搭建好VMware Workspace ONE Access漏洞調試環境後,接下來就可以著手對漏洞和數據庫口令的解密方法進行學習。