Skip to content

Commit

Permalink
Merge pull request #2273 from connortechnology/fix_rce
Browse files Browse the repository at this point in the history
use json_encode/decode instead of serialize/unserialize to pass onvif…
  • Loading branch information
knight-of-ni committed Oct 30, 2018
2 parents 073193e + 2024df4 commit f790eac
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 61 deletions.
1 change: 1 addition & 0 deletions web/lang/en_gb.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@
'Cause' => 'Cause',
'CheckMethod' => 'Alarm Check Method',
'ChooseDetectedCamera' => 'Choose Detected Camera',
'ChooseDetectedProfile' => 'Choose Detected Profile',
'ChooseFilter' => 'Choose Filter',
'ChooseLogFormat' => 'Choose a log format',
'ChooseLogSelection' => 'Choose a log selection',
Expand Down
2 changes: 1 addition & 1 deletion web/skins/classic/views/monitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ function fourcc( $a, $b, $c, $d ) {
}
}
if ( !empty($_REQUEST['probe']) ) {
$probe = unserialize(base64_decode($_REQUEST['probe']));
$probe = json_decode(base64_decode($_REQUEST['probe']));
foreach ( $probe as $name=>$value ) {
if ( isset($value) ) {
# Does isset handle NULL's? I don't think this code is correct.
Expand Down
118 changes: 58 additions & 60 deletions web/skins/classic/views/onvifprobe.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//

if ( !canEdit( 'Monitors' ) ) {
if ( !canEdit('Monitors') ) {
$view = 'error';
return;
}
Expand Down Expand Up @@ -73,26 +73,26 @@ function probeCameras( $localIp ) {
} elseif ( $tokens[1] == 'location' ) {
// $camera['location'] = $tokens[2];
} else {
Logger::Debug('Unknown token ' . $tokens[1] );
Logger::Debug('Unknown token ' . $tokens[1]);
}
}
} // end foreach token
$cameras[] = $camera;
}
} // end foreach line
}
return( $cameras );
}
} // end if results from execOnvif
return $cameras;
} // end function probeCameras

function probeProfiles( $device_ep, $soapversion, $username, $password ) {
$profiles = array();
if ( $lines = @execONVIF( "profiles $device_ep $soapversion $username $password" ) ) {
foreach ( $lines as $line ) {
$line = rtrim( $line );
if ( preg_match( '|^(.+),\s*(.+),\s*(.+),\s*(.+),\s*(.+),\s*(.+),\s*(.+)\s*$|', $line, $matches ) ) {
if ( preg_match('|^(.+),\s*(.+),\s*(.+),\s*(.+),\s*(.+),\s*(.+),\s*(.+)\s*$|', $line, $matches) ) {
$stream_uri = $matches[7];
// add user@pass to URI
if ( preg_match( '|^(\S+://)(.+)$|', $stream_uri, $tokens ) ) {
if ( preg_match('|^(\S+://)(.+)$|', $stream_uri, $tokens) ) {
$stream_uri = $tokens[1].$username.':'.$password.'@'.$tokens[2];
}

Expand All @@ -106,38 +106,36 @@ function probeProfiles( $device_ep, $soapversion, $username, $password ) {
'Profile' => $matches[1],
'Name' => $matches[2],
'Encoding' => $matches[3],

);
$profiles[] = $profile;
} else {
Logger::Debug("Line did not match preg: $line");
}
}
}
return( $profiles );
}

} // end foreach line
} // end if results from execONVIF
return $profiles;
} // end function probeProfiles

//==== STEP 1 ============================================================

$focusWindow = true;

xhtmlHeaders(__FILE__, translate('MonitorProbe') );

if( !isset($_REQUEST['step']) || ($_REQUEST['step'] == "1")) {
if ( !isset($_REQUEST['step']) || ($_REQUEST['step'] == '1') ) {

$monitors = array();
foreach ( dbFetchAll( "select Id, Name, Host from Monitors where Type = 'Remote' order by Host" ) as $monitor ) {
if ( preg_match( '/^(.+)@(.+)$/', $monitor['Host'], $matches ) ) {
//echo "1: ".$matches[2]." = ".gethostbyname($matches[2])."<br/>";
$monitors[gethostbyname($matches[2])] = $monitor;
} else {
//echo "2: ".$monitor['Host']." = ".gethostbyname($monitor['Host'])."<br/>";
$monitors[gethostbyname($monitor['Host'])] = $monitor;
}
foreach ( dbFetchAll("SELECT Id, Name, Host FROM Monitors WHERE Type = 'Remote' ORDER BY Host") as $monitor ) {
if ( preg_match( '/^(.+)@(.+)$/', $monitor['Host'], $matches ) ) {
//echo "1: ".$matches[2]." = ".gethostbyname($matches[2])."<br/>";
$monitors[gethostbyname($matches[2])] = $monitor;
} else {
//echo "2: ".$monitor['Host']." = ".gethostbyname($monitor['Host'])."<br/>";
$monitors[gethostbyname($monitor['Host'])] = $monitor;
}
}

$detcameras = probeCameras( '' );
$detcameras = probeCameras('');
foreach ( $detcameras as $camera ) {
if ( preg_match( '|([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|', $camera['monitor']['Host'], $matches ) ) {
$ip = $matches[1];
Expand All @@ -157,13 +155,13 @@ function probeProfiles( $device_ep, $soapversion, $username, $password ) {
}
*/
// $sourceDesc = htmlspecialchars(serialize($camera['monitor']));
$sourceDesc = base64_encode(serialize($camera['monitor']));
$sourceString = $camera['model'].' @ '.$host . ' using version ' . $camera['monitor']['SOAP'] ;
$cameras[$sourceDesc] = $sourceString;
$sourceDesc = base64_encode(json_encode($camera['monitor']));
$sourceString = $camera['model'].' @ '.$host . ' using version ' . $camera['monitor']['SOAP'] ;
$cameras[$sourceDesc] = $sourceString;
}

if ( count($cameras) <= 0 )
$cameras[0] = translate('NoDetectedCameras');
$cameras[0] = translate('NoDetectedCameras');

?>
<body>
Expand All @@ -180,22 +178,23 @@ function probeProfiles( $device_ep, $soapversion, $username, $password ) {
<?php echo translate('OnvifProbeIntro') ?>
</p>
<p>
<label for="probe"><?php echo translate('DetectedCameras') ?></label><?php echo buildSelect( "probe", $cameras, 'configureButtons( this )' ); ?>
<label for="probe"><?php echo translate('DetectedCameras') ?></label>
<?php echo htmlSelect('probe', $cameras, null, array('onchange'=>'configureButtons(this)')); ?>
</p>
<p>
<?php echo translate('OnvifCredentialsIntro') ?>
</p>
<p>
<label for="username"><?php echo translate('Username') ?></label>
<input type="text" name="username" value="" onChange="configureButtons( this )" />
<input type="text" name="username" value="" onChange="configureButtons(this)"/>
</p>
<p>
<label for="password"><?php echo translate('Password') ?></label>
<input type="password" name="password" value=""onChange="configureButtons( this )" />
<input type="password" name="password" value=""onChange="configureButtons(this)"/>
</p>
<div id="contentButtons">
<input type="button" value="<?php echo translate('Cancel') ?>" onclick="closeWindow()"/>
<input type="submit" name="nextBtn" value="<?php echo translate('Next') ?>" onclick="gotoStep2( this )" disabled="disabled"/>
<input type="submit" name="nextBtn" value="<?php echo translate('Next') ?>" onclick="gotoStep2(this)" disabled="disabled"/>
</div>
</form>
</div>
Expand All @@ -205,44 +204,42 @@ function probeProfiles( $device_ep, $soapversion, $username, $password ) {
<?php

//==== STEP 2 ============================================================
}
else if($_REQUEST['step'] == "2")
{
} else if($_REQUEST['step'] == '2') {
if ( empty($_REQUEST['probe']) )
Fatal("No probe passed in request. Please go back and try again.");
Fatal('No probe passed in request. Please go back and try again.');
#|| empty($_REQUEST['username']) ||
#empty($_REQUEST['password']) )

$probe = unserialize(base64_decode($_REQUEST['probe']));
$probe = json_decode(base64_decode($_REQUEST['probe']));
Logger::Debug(print_r($probe,true));
foreach ( $probe as $name=>$value ) {
if ( isset($value) ) {
$monitor[$name] = $value;
}
if ( isset($value) ) {
$monitor[$name] = $value;
}
}
$camera['monitor'] = $monitor;

//print $monitor['Host'].", ".$_REQUEST['username'].", ".$_REQUEST['password']."<br/>";

$detprofiles = probeProfiles( $monitor['Host'], $monitor['SOAP'], $_REQUEST['username'], $_REQUEST['password']);
$detprofiles = probeProfiles($monitor['Host'], $monitor['SOAP'], $_REQUEST['username'], $_REQUEST['password']);
foreach ( $detprofiles as $profile ) {
$monitor = $camera['monitor'];

$sourceString = "${profile['Name']} : ${profile['Encoding']}" .
" (${profile['Width']}x${profile['Height']} @ ${profile['MaxFPS']}fps)";
// copy technical details
$monitor['Width'] = $profile['Width'];
$monitor['Height'] = $profile['Height'];
// The maxfps fields do not work for ip streams. Can re-enable if that is fixed.
// $monitor['MaxFPS'] = $profile['MaxFPS'];
// $monitor['AlarmMaxFPS'] = $profile['AlarmMaxFPS'];
$monitor['Path'] = $profile['Path'];
// $sourceDesc = htmlspecialchars(serialize($monitor));
$sourceDesc = base64_encode(serialize($monitor));
$profiles[$sourceDesc] = $sourceString;
$monitor = $camera['monitor'];

$sourceString = "${profile['Name']} : ${profile['Encoding']}" .
" (${profile['Width']}x${profile['Height']} @ ${profile['MaxFPS']}fps)";
// copy technical details
$monitor['Width'] = $profile['Width'];
$monitor['Height'] = $profile['Height'];
// The maxfps fields do not work for ip streams. Can re-enable if that is fixed.
// $monitor['MaxFPS'] = $profile['MaxFPS'];
// $monitor['AlarmMaxFPS'] = $profile['AlarmMaxFPS'];
$monitor['Path'] = $profile['Path'];
$sourceDesc = base64_encode(json_encode($monitor));
$profiles[$sourceDesc] = $sourceString;
}

if ( count($profiles) <= 0 )
$profiles[0] = translate('NoDetectedProfiles');
$profiles[0] = translate('NoDetectedProfiles');

?>
<body>
Expand All @@ -254,23 +251,24 @@ function probeProfiles( $device_ep, $soapversion, $username, $password ) {
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<input type="hidden" name="view" value="none"/>
<input type="hidden" name="mid" value="<?php echo validNum($_REQUEST['mid']) ?>"/>
<input type="hidden" name="step" value=""/>
<input type="hidden" name="step"/>
<p>
<?php echo translate('ProfileProbeIntro') ?>
</p>
<p>
<label for="probe"><?php echo translate('DetectedProfiles') ?></label><?php echo buildSelect( 'probe', $profiles, 'configureButtons( this )' ); ?>
<label for="probe"><?php echo translate('DetectedProfiles') ?></label>
<?php echo htmlSelect('probe', $profiles, null, array('onchange'=>'configureButtons(this)')); ?>
</p>
<div id="contentButtons">
<input type="button" name="prevBtn" value="<?php echo translate('Prev') ?>" onclick="gotoStep1( this )"/>
<input type="button" name="prevBtn" value="<?php echo translate('Prev') ?>" onclick="gotoStep1(this)"/>
<input type="button" value="<?php echo translate('Cancel') ?>" onclick="closeWindow()"/>
<input type="submit" name="saveBtn" value="<?php echo translate('Save') ?>" onclick="submitCamera( this )" disabled="disabled"/>
<input type="submit" name="saveBtn" value="<?php echo translate('Save') ?>" onclick="submitCamera(this)" disabled="disabled"/>
</div>
</form>
</div>
</div>
</body>
</html>
<?php
}
} // end if step 1 or 2
?>

0 comments on commit f790eac

Please sign in to comment.