initial commit of SVN release repo

This commit is contained in:
Ryan Prather
2018-05-07 10:51:08 -04:00
committed by Ryan Prather
parent 2c25d5e577
commit 8c38a6cdb9
4369 changed files with 728576 additions and 0 deletions

284
ste/basic-info.inc Normal file
View File

@ -0,0 +1,284 @@
<?php
/**
* File: basic-info.inc
* Author: Ryan Prather
* Purpose: Display the basic information from the target
* Created: Sep 1, 2016
*
* Copyright 2016: Cyber Perspectives, All rights reserved
* Released under the Apache v2.0 License
*
* See license.txt for details
*
* Change Log:
* - Sep 1, 2016 - File created
* - Mar 4, 2017 - Changed AJAX to use /ajax.php instead of /cgi-bin/ajax.php
*/
?>
<style type='text/css'>
#basic-info {
border: solid 1px black;
height: 170px;
text-align: left;
}
#osSoftware {
float: right;
text-align: right;
height: 62px;
}
#availableOS {
position: absolute;
text-align: left;
background-color: white;
border: solid 1px black;
z-index: 100;
overflow-x: scroll;
height: 250px;
width: 400px;
}
.swmouseover {
background-color:#1D57A0;
color:#fff;
cursor:pointer;
}
.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
.ui-timepicker-div dl { text-align: left; }
.ui-timepicker-div dl dt { float: left; clear:left; padding: 0 0 0 5px; }
.ui-timepicker-div dl dd { margin: 0 10px 10px 40%; }
.ui-timepicker-div td { font-size: 90%; }
.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
.ui-timepicker-div .ui_tpicker_unit_hide{ display: none; }
.ui-timepicker-rtl{ direction: rtl; }
.ui-timepicker-rtl dl { text-align: right; padding: 0 5px 0 0; }
.ui-timepicker-rtl dl dt{ float: right; clear: right; }
.ui-timepicker-rtl dl dd { margin: 0 40% 10px 10px; }
/* Shortened version style */
.ui-timepicker-div.ui-timepicker-oneLine { padding-right: 2px; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,
.ui-timepicker-div.ui-timepicker-oneLine dt { display: none; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time_label { display: block; padding-top: 2px; }
.ui-timepicker-div.ui-timepicker-oneLine dl { text-align: right; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd,
.ui-timepicker-div.ui-timepicker-oneLine dl dd > div { display:inline-block; margin:0; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_minute:before,
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_second:before { content:':'; display:inline-block; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_millisec:before,
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_microsec:before { content:'.'; display:inline-block; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide,
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide:before{ display: none; }
</style>
<link
href="/script/jQueryUI/css/ui-lightness/jquery-ui-1.10.3.custom.min.css"
rel="stylesheet" type="text/css" />
<script src='/script/jQueryUI/jquery-ui-timepicker-addon.js' type='text/javascript'></script>
<script type='text/javascript'>
$(function () {
$('#last_boot').datetimepicker({dateFormat: "YY-mm-dd", timeFormat: "HH:mm:ss", pickerTimeFormat: "HH:mm:ss", showSecond: true});
});
/**
*
*/
function filter_os() {
if ($('#os_filter').val().length < 3) {
$('#availableOS').html('');
$('#availableOS').hide();
return;
}
$.ajax('/ajax.php', {
data: {
action: 'os_filter',
tgt_id: '<?php print isset($_REQUEST['tgt']) ? $_REQUEST['tgt'] : '' ?>',
filter: $('#os_filter').val()
},
success: update_os_filter,
dataType: 'html',
method: 'post'
});
}
/**
*
*/
function update_os_filter(data) {
$('#availableOS').html(data);
$('#availableOS').show();
$('#availableOS div').each(function () {
$(this).on("mouseover", function () {
$(this).addClass("swmouseover");
});
$(this).on("mouseout", function () {
$(this).removeClass("swmouseover");
});
$(this).on("click", function () {
$('#availableOS').hide();
$('#osSoftware').html($(this).text() + "<input type='hidden' name='osSoftware' value='" + $(this).attr('sw_id') + "' />");
});
});
}
</script>
<div class='title'>Basic Information (<?php print $sys->get_Name() . ", " . $site->get_Name() . ", " . $ste->get_Eval_Start_Date()->format("d M, Y"); ?>)</div>
<div id='basic-info'>
<div class='data-row' style='width:190px;'>
<input type='text' name='name' class='auto-update-text' placeholder='Name...' value='<?php
if (!empty($tgt)) {
print $tgt->get_Name();
}
?>' /><br />
<input type='text' id='os_filter' title='CPE string' placeholder='Filter OS...' onkeyup="javascript:filter_os();" autocomplete="off" /><br />
<div id="availableOS" onmouseover="$(this).show();" onmouseout="$(this).hide();" style="display:none;"></div>
<input type='text' name='location' class='auto-update-text' placeholder='Location...' value="<?php
if (!empty($tgt)) {
print $tgt->get_Location();
}
?>" /><br />
<select name='classification' style='width:173px;' class='auto-update-select'>
<option>-- Classification --</option>
<option value="U"<?php
if (!empty($tgt) && $tgt->classification == 'U') {
print " selected";
}
?>>Public/UNCLASSIFED</option>
<option value="FOUO"<?php
if (!empty($tgt) && $tgt->classification == 'FOUO') {
print " selected";
}
?>>Sensitive/FOUO</option>
<option value="S"<?php
if (!empty($tgt) && $tgt->classification == 'S') {
print " selected";
}
?>>Classified/SECRET</option>
</select><br />
<input type='text' id='last_boot' name='last_boot' class='auto-update-text' placeholder='Last Boot' value="<?php
if (!empty($tgt) && is_a($tgt->get_Last_Boot(), "DateTime")) {
print $tgt->get_Last_Boot()->format("Y-m-d H:i:s");
}
else {
print "1970-01-01 00:00:00";
}
?>" />
</div>
<div class='data-row' style='width:190px;'>
<label for='vm'>Virtual Machine?</label>
<input type='checkbox' name='vm' id='vm' class='auto-update-check' value='1' <?php
if (!empty($tgt) && $tgt->is_VM()) {
print "checked";
}
?> /><br />
<span id="osSoftware">
<?php
if (isset($_REQUEST['tgt'])) {
$os = $db->get_Software($tgt->get_OS_ID())[0];
print $os->get_SW_String();
print "<input type='hidden' name='osSoftware' value='" . $os->get_ID() . "' />";
}
?>
</span><br />
<input type='text' name='wmi_pid' class='auto-update-text' placeholder="WMI PID" value="<?php
if (!empty($tgt)) {
print $tgt->get_WMI_PID();
}
?>" /><br />
<input type='text' name='last_login' class='auto-update-text' placeholder='Last Login...' value="<?php
if (!empty($tgt)) {
print $tgt->get_Last_Login();
}
?>" />
</div>
<div class='data-row' style='width:190px;'>
Auto: <select name='auto_status' class='auto-update-select'>
<?php
if (!empty($tgt)) {
$status_id = !is_null($tgt->get_Auto_Status_ID()) ? $tgt->get_Auto_Status_ID() : 5;
}
else {
$status_id = 5;
}
foreach ($task_status as $key => $val) {
print "<option value='$key'" . ($key == $status_id ? " selected " : "") . ">$val</option>";
}
?>
</select><br />
Manual: <select name='man_status' class='auto-update-select'>
<?php
if (!empty($tgt)) {
$status_id = !is_null($tgt->get_Man_Status_ID()) ? $tgt->get_Man_Status_ID() : 5;
}
else {
$status_id = 5;
}
foreach ($task_status as $key => $val) {
print "<option value='$key'" . ($key == $status_id ? " selected " : "") . ">$val</option>";
}
?>
</select><br />
Data: <select name='data_status' class='auto-update-select'>
<?php
if (!empty($tgt)) {
$status_id = !is_null($tgt->get_Data_Status_ID()) ? $tgt->get_Data_Status_ID() : 5;
}
else {
$status_id = 5;
}
foreach ($task_status as $key => $val) {
print "<option value='$key'" . ($key == $status_id ? " selected " : "") . ">$val</option>";
}
?>
</select><br />
FP/Cat I: <select name='fp-cat1_status' class='auto-update-select'>
<?php
if (!empty($tgt)) {
$status_id = !is_null($tgt->get_FP_Cat1_Status_ID()) ? $tgt->get_FP_Cat1_Status_ID() : 5;
}
else {
$status_id = 5;
}
foreach ($task_status as $key => $val) {
print "<option value='$key'" . ($key == $status_id ? " selected " : "") . ">$val</option>";
}
?>
</select><br />
<input type='text' name='login' class='auto-update-text' placeholder='Login...' value='<?php
if (!empty($tgt)) {
print $tgt->get_Login();
}
?>' />
</div>
<div class='data-row' style='width:579px;'>
<textarea name='notes' class='auto-update-text' cols=79 rows=10><?php
if (!empty($tgt)) {
print $tgt->get_Notes();
}
?></textarea>
</div>
</div>

514
ste/bulk_edit.php Normal file
View File

@ -0,0 +1,514 @@
<?php
/**
* File: bulk_edit.php
* Author: Ryan Prather
* Purpose: Allow for multiple hosts in a category to be editted in specific ways
* Created: May 14, 2014
*
* Portions Copyright 2016: Cyber Perspectives, All rights reserved
* Released under the Apache v2.0 License
*
* Portions Copyright (c) 2012-2015, Salient Federal Solutions
* Portions Copyright (c) 2008-2011, Science Applications International Corporation (SAIC)
* Released under Modified BSD License
*
* See license.txt for details
*
* Change Log:
* - May 14, 2014 - File created
* - Sep 1, 2016 - Copyright updated and functions for class merger
* Converted ajax to php instead of cgi
* Standardized other content
* - Mar 4, 2017 - Changed AJAX to use /ajax.php instead of /cgi-bin/ajax.php
* - Apr 5, 2017 - Formatting
* - Aug 28, 2017 - Fixed bugs #285 & #269, cleaned up code, & use filter_input method
* - Aug 31, 2017 - Fixed bug #269, #289, & #290
*/
include_once 'config.inc';
include_once 'helper.inc';
include_once 'database.inc';
$db = new db();
$int = array(
'filter' => FILTER_VALIDATE_INT,
'flag' => FILTER_NULL_ON_FAILURE
);
$string = array(
'filter' => FILTER_SANITIZE_STRING,
'flag' => FILTER_NULL_ON_FAILURE
);
$boolean = array(
'filter' => FILTER_VALIDATE_BOOLEAN,
'flag' => FILTER_NULL_ON_FAILURE
);
$args = array(
'action' => $string,
'cat' => $int,
'selected_tgts' => $string,
'osSoftware' => $int,
'location' => $string,
'auto_status' => $int,
'man_status' => $int,
'data_status' => $int,
'fp_cat1_status' => $int,
'remove_existing' => $boolean,
'checklists' => array(
'filter' => FILTER_VALIDATE_INT,
'flags' => FILTER_REQUIRE_ARRAY
),
'post_process' => $boolean
);
$post = filter_input_array(INPUT_POST, $args);
$cat = filter_input(INPUT_GET, 'cat', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
$ste = filter_input(INPUT_COOKIE, 'ste', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
$tgts = $db->get_Target_By_Category($cat);
$task_statuses = $db->get_Task_Statuses();
$task_statuses[null] = 'Not Reviewed';
if ($post['action'] == 'update_bulk') {
set_time_limit(300);
$sel_tgts = json_decode(html_entity_decode($post['selected_tgts']));
foreach ($sel_tgts as $tgt_id) {
$tgt = $db->get_Target_Details($ste, $tgt_id)[0];
if ($post['cat']) {
$tgt->set_Cat_ID($post['cat']);
}
if ($post['osSoftware']) {
$os = $db->get_Software($post['osSoftware']);
if (is_array($os) && count($os) && isset($os[0]) && is_a($os[0], 'software')) {
$tgt->set_OS_ID($os[0]->get_ID());
$tgt->set_OS_String($os[0]->get_Shortened_SW_String());
}
}
if ($post['location']) {
$tgt->set_Location($post['location']);
}
if ($post['auto_status']) {
$tgt->set_Auto_Status_ID($post['auto_status']);
}
if ($post['man_status']) {
$tgt->set_Man_Status_ID($post['man_status']);
}
if ($post['data_status']) {
$tgt->set_Data_Status_ID($post['data_status']);
}
if ($post['fp_cat1_status']) {
$tgt->set_FP_Cat1_Status_ID($post['fp_cat1_status']);
}
if ($post['remove_existing']) {
foreach ($tgt->checklists as $key => $chk) {
unset($tgt->checklists[$key]);
}
$db->delete_Target_Checklists($tgt);
}
if ($post['checklists']) {
$chks = array();
foreach ($post['checklists'] as $key => $chk) {
$tgt->checklists[] = $db->get_Checklist($chk)[0];
}
}
$pp = ($post['post_process'] ? true : false);
$db->save_Target($tgt, $pp);
}
header("Location: /ste");
}
include_once 'header.inc';
?>
<script src='ste_script.js' type='text/javascript'></script>
<style type="text/css">
.header {
width: auto;
background-color: #31363C;
display: table-cell;
}
.left_cat_header {
width: 200px;
float: left;
}
.right_cat_header {
width: 200px;
float: right;
}
.cat_icons {
background-size: 20px 20px;
vertical-align: middle;
width: 20px;
height: 20px;
}
.not_reviewed,.not_applicable,.not_planned,.complete,.in_progress {
text-align: center;
width: 92px;
}
.not_reviewed {
color: #fff;
background-color: #ff0000;
}
.not_applicable {
color: #000;
background-color: #8db4e2;
}
.not_planned {
color: #fff;
background-color: #000;
}
.complete {
color: #000;
background-color: #92d050;
}
.in_progress {
color: #000;
background-color: #ffff66;
}
.checklists {
display: inline;
width: 300px;
height: 150px;
}
.checklist_image {
width: 32px;
vertical-align: middle;
}
.notes {
width: 100%;
}
#osSoftware {
display: inline-block;
width: 300px;
text-align: right;
}
#availableOS {
position: absolute;
text-align: left;
background-color: white;
border: solid 1px black;
z-index: 100;
overflow-y: scroll;
height: 250px;
width: 400px;
}
.swmouseover {
background-color:#1D57A0;
color:#fff;
cursor:pointer;
}
</style>
<script type='text/javascript'>
/**
* Function to filter the checklists via AJAX
*
* @param {boolean} bln_hide_old
*/
function filter_checklists(bln_hide_old) {
if ($('#chk_filter').val().length < 3) {
return;
}
$.ajax('/ajax.php', {
data: {
action: 'chk_filter',
filter: $('#chk_filter').val(),
hide_old: bln_hide_old
},
success: function (data) {
$('#checklists option').remove();
for (var x in data) {
$('#checklists').append("<option " +
"value='" + data[x].id + "'>" +
data[x].name + " V" + data[x].ver + "R" + data[x].release + " (" + data[x].type + ")</option>");
}
},
dataType: 'json',
method: 'post'
});
}
/**
* Function to filter the operating systems via AJAX
*/
function filter_os() {
if ($('#os_filter').val().length < 3) {
$('#availableOS').html('');
$('#availableOS').hide();
return;
}
$.ajax('/ajax.php', {
data: {
action: 'os_filter',
filter: $('#os_filter').val()
},
success: function (data) {
$('#availableOS div').remove();
$('#availableOS').show();
for (var x in data) {
$('#availableOS').append("<div sw_id='" + data[x].sw_id + "' cpe='" + data[x].cpe + "'>" + data[x].sw_string + "</div>");
}
$('#availableOS div').each(function () {
$(this).on("mouseover", function () {
$(this).addClass("swmouseover");
});
$(this).on("mouseout", function () {
$(this).removeClass("swmouseover");
});
$(this).on("click", function () {
$('#availableOS').hide();
$('#osSoftware').html($(this).text() + "<input type='hidden' name='osSoftware' value='" + $(this).attr('sw_id') + "' />");
$('#installedSoftware').append("<option value='" + $(this).attr('sw_id') + "' ondblclick='$(this).remove();'>" + $(this).html() + "</option>");
$(this).remove();
});
});
},
dataType: 'json',
method: 'post'
});
}
/**
* Function to validate the form before submitting
*/
function validate_bulk() {
$('#selected_tgts').val(JSON.stringify(sel_tgts));
form.submit();
}
/**
* Function to toggle to checkbox selections (what was check is now uncheck and visa versa)
*/
function toggle_selection() {
$('.tgt_chk').each(function () {
$(this).prop('checked', !$(this).is(":checked"));
update_tgt_chk(this);
});
}
</script>
<div id='wrapper'>
<div id='main-wrapper'>
<div class='12u' id='main-contnt'>
<div id='tableContainer' class='tableContainer'>
<form method='post' name='form'>
<input type='hidden' name='action' value='update_bulk' />
<input type='hidden' name='selected_tgts' id='selected_tgts' />
<input type='hidden' name='ste' value='<?php print ($ste ? $ste : ''); ?>' />
To change multiple targets:<br />
<ol style='font-size:small;'>
<li>Check the targets you want to change above</li>
<li>Select only the fields below you want to change</li>
<li>Click the Save button</li>
</ol>
<input type='button' name='update_bulk' value='Save' onclick='validate_bulk();' />
<table>
<tbody>
<tr>
<th>Category:</th>
<td>
<select name='cat'>
<option value='0'>-- do not change --</option>
<?php
$cats = $db->get_STE_Cat_List($ste);
foreach ($cats as $cat):print $cat->get_Option();
endforeach;
?>
</select>
</td>
</tr>
<tr>
<th>Operating System:</th>
<td class="Control">
<input type='text' id='os_filter' style="display:inline;" title='CPE string' placeholder='Filter...' onkeyup="javascript:filter_os();" autocomplete="off" />
<span id="osSoftware">
<input type='hidden' name='osSoftware' />
</span>
<div id="availableOS" onmouseover="$(this).show();" onmouseout="$(this).hide();" style="display:none;"></div>
</td>
</tr>
<tr>
<th>Location:</th>
<td><input type='text' name='location' placeholder='-- do not change --' /></td>
</tr>
<tr>
<th>Automated Status:</th>
<td>
<select name='auto_status'>
<option value='0'>-- do not change --</option>
<?php
foreach ($task_statuses as $key => $status):print "<option value='$key'>$status</option>";
endforeach;
?>
</select>
</td>
</tr>
<tr>
<th>Manual Status:</th>
<td>
<select name='man_status'>
<option value='0'>-- do not change --</option>
<?php
foreach ($task_statuses as $key => $status):print "<option value='$key'>$status</option>";
endforeach;
?>
</select>
</td>
</tr>
<tr>
<th>Data Gathering Status:</th>
<td>
<select name='data_status'>
<option value='0'>-- do not change --</option>
<?php
foreach ($task_statuses as $key => $status):print "<option value='$key'>$status</option>";
endforeach;
?>
</select>
</td>
</tr>
<tr>
<th>FP/Cat1 Status:</th>
<td>
<select name='fp_cat1_status'>
<option value='0'>-- do not change --</option>
<?php
foreach ($task_statuses as $key => $status):print "<option value='$key'>$status</option>";
endforeach;
?>
</select>
</td>
</tr>
<tr>
<th title='Select to change' style='vertical-align:bottom;'>
Checklists:<br />
<input type='text' name='chk_filter' id='chk_filter' placeholder="Filter..." onkeyup="javascript:filter_checklists($('#hide_old').is(':checked'));" style='width:132px;' /><br />
Remove Existing Checklists:
<input type='checkbox' name='remove_existing' value='1' />
</th>
<td>
<select name='checklists[]' class='checklists' id="checklists" multiple='multiple'>
<?php
$all_chks = $db->get_Checklist();
foreach ($all_chks as $key => $chk):print $chk->print_Option();
endforeach;
?>
</select>
</td>
</tr>
<tr>
<th>Post Processing?</th>
<td>
<input type='checkbox' name='post_process' value='1' />
</td>
</tr>
</tbody>
</table>
<table class=''>
<thead>
<tr>
<th class="header" style='text-align:left;'>
<input type='button' value='Toggle Selection' onclick='javascript:toggle_selection();' />&nbsp;&nbsp;Name
</th>
<th class="header">OS</th>
<th class="header">Location</th>
<th class="header">Auto</th>
<th class="header">Manual</th>
<th class="header">Data</th>
<th class="header">FP/Cat1</th>
<th class="header">Checklists</th>
</tr>
</thead>
<tbody id='targets'>
<?php
$odd = true;
foreach ($tgts as $key => $tgt) {
$os = $db->get_Software($tgt->get_OS_ID())[0];
$auto_status = $task_statuses[$tgt->get_Auto_Status_ID()];
$man_status = $task_statuses[$tgt->get_Man_Status_ID()];
$data_status = $task_statuses[$tgt->get_Data_Status_ID()];
$fpcat1_status = $task_statuses[$tgt->get_FP_Cat1_Status_ID()];
$checklists = $db->get_Target_Checklists($tgt->get_ID());
$icons = array();
foreach ($checklists as $key2 => $chk) {
$current_icon = $chk->get_Icon();
if (array_key_exists($current_icon, $icons)) {
$icons[$current_icon]['title'] .= "\n- {$chk->get_Name()} V{$chk->get_Version()}R{$chk->get_Release()} ({$chk->get_type()})";
}
else {
$icons[$current_icon] = array(
'icon' => $current_icon,
'title' => "- {$chk->get_Name()} V{$chk->get_Version()}R{$chk->get_Release()} ({$chk->get_type()})"
);
}
}
print "<tr class='" . ($odd ? 'odd' : 'even') . "_row'>" .
"<td><input type='checkbox' class='tgt_chk' value='{$tgt->get_ID()}' onclick='javascript:update_tgt_chk(this);'/>{$tgt->get_Name()}</td>" .
"<td>{$os->get_Name()} {$os->get_Version()}</td>" .
"<td>{$tgt->get_Location()}</td>" .
"<td class='" . strtolower(str_replace(' ', '_', $auto_status)) . "'>{$auto_status}</td>" .
"<td class='" . strtolower(str_replace(' ', '_', $man_status)) . "'>{$man_status}</td>" .
"<td class='" . strtolower(str_replace(' ', '_', $data_status)) . "'>{$data_status}</td>" .
"<td class='" . strtolower(str_replace(' ', '_', $fpcat1_status)) . "'>{$fpcat1_status}</td>" .
"<td>";
foreach ($icons as $icon_key => $icon) {
print "<img src='/img/checklist_icons/$icon_key' class='checklist_image' title='{$icon['title']}' />";
}
print "</td>" .
"</tr>";
$odd = !$odd;
}
?>
</tbody>
</table>
</form>
</div>
</div>
</div>
</div>
<?php
include_once 'footer.inc';

Binary file not shown.

336
ste/echecklist_iframe.php Normal file
View File

@ -0,0 +1,336 @@
<?php
/**
* File: echecklist_iframe.php
* Author: Ryan Prather
* Purpose: Display the eChecklist in a iFrame popup on the ST&E Mgmt page
* Created: Sep 20, 2013
*
* Portions Copyright 2016-2017: Cyber Perspectives, LLC, All rights reserved
* Released under the Apache v2.0 License
*
* Portions Copyright (c) 2012-2015, Salient Federal Solutions
* Portions Copyright (c) 2008-2011, Science Applications International Corporation (SAIC)
* Released under Modified BSD License
*
* See license.txt for details
*
* Change Log:
* - Sep 20, 2013 - File created
* - Mar 14, 2017 - Formatting and converted direct $_REQUEST to filter_input calls
* - Apr 5, 2017 - Formatting
* - May 29, 2017 - Fixed bugs
*/
include_once 'config.inc';
include_once 'database.inc';
include_once 'helper.inc';
$db = new db();
set_time_limit(0);
$ste = filter_input(INPUT_GET, 'ste', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
if (!$ste) {
$ste = filter_input(INPUT_COOKIE, 'ste', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
}
$cat = filter_input(INPUT_GET, 'cat', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
if (!$cat) {
$cat = filter_input(INPUT_POST, 'cat', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
}
$checklists = $db->get_Category_Checklists($cat);
$summary = $db->get_Checklist_Summary($cat);
$cat_tgts = $db->get_Target_By_Category($cat);
$system = $db->get_System_By_STE_ID($ste);
if (!is_a($system, 'system')) {
die("Could not determine System from ST&amp;E");
}
?>
<!DOCTYPE HTML>
<html>
<head>
<script type='text/javascript' src='/style/5grid/jquery-1.11.3.min.js'></script>
<link rel='stylesheet' type='text/css' href='/style/style.css' />
<link rel='stylesheet' type='text/css' href='/style/style-desktop.css' />
<style type="text/css">
body {
/*font-family: undefined;*/
line-height: 1em;
}
.header {
background-color: #ddd9c4;
font-weight: bold;
color: #000;
border: solid 1px #000;
}
.not_reviewed,.not_applicable,.not_a_finding,.open,.no_data,.false_positive,.cat_I,.cat_II,.cat_III,.nr,.na,.nf,.nd,.fp {
text-align: center;
}
td {
font-size: 14px;
border: solid 1px black;
}
</style>
<script type='text/javascript'>
$(function () {
$('.button').mouseover(function () {
$(this).addClass('mouseover');
});
$('.button').mouseout(function () {
$(this).removeClass('mouseover');
});
});
function check(chk) {
var val = $(chk).attr('meta:chk') + '-' + $(chk).attr('meta:host');
$('#' + val).val($(chk).is(':checked') ? '1' : '0');
$('#export_top,#export_bottom').removeAttr('disabled');
}
</script>
</head>
<?php flush(); ?>
<body style='margin: 0; height: 100%;'>
<a id='top'></a>
<a class='button' href="javascript:void(0);" id='export_top'
onclick="$('#export').submit();$('.export').attr('disabled', true);">Export</a>&nbsp;&nbsp;
<a class='button' href="javascript:void(0);"
onclick="parent.close_box();">Cancel</a>
<div style=''>
<table style='width:100%;border:solid 1px black;border-collapse:collapse;'>
<tbody>
<tr>
<td>&nbsp;</td>
<?php
if (is_array($summary['tgts']) && count($summary['tgts'])) {
foreach ($summary['tgts'] as $name) {
print "<td>$name</td>";
}
}
?></tr>
<?php
$x = 1;
foreach ($summary['summary'] as $chk_key => $chklst) {
print "<tr><td style='width:400px;'><a href='#checklist_{$x}'>{$summary['checklists'][$chk_key]}</a></td>";
foreach ($summary['summary'][$chk_key] as $host_key => $host) {
if ($host || $summary['checklists'][$chk_key] == 'Orphan V1R1') {
print "<td><input type='checkbox' name='chk[$chk_key][$host_key]' meta:chk='$chk_key' meta:host='$host_key' value='1' onclick='javascript:check(this);' checked /></td>";
}
else {
print "<td>&ndash;</td>";
}
}
print "</tr>";
$x++;
}
?>
</tbody>
</table>
<br /><?php flush(); ?>
<table style='border-collapse: collapse;'>
<thead>
<tr>
<td class='header' colspan=2 style='width: 153px;'>Open Cat I:</td>
<td class='open cat_I' style='width: 31px;' id='open_cat_1'><?php print $db->get_Finding_Count_By_Status($cat, "Open", 1); ?></td>
<td class='header' style='width: 151px;'>System:</td>
<td
style='background-color: #ff0; color: #000; font-weight: bold; width: 344px;'><?php print $system->get_Name(); ?></td>
<td class='header' style='width: 104px;'>Classification:</td>
<td style='background-color: #ff0; width: 344px; color: #f00; font-weight: bold; width: 287px;'><?php print $system->get_Classification(); ?></td>
<td rowspan=6 colspan=2 style='width: 375px;'>
<i style='color:#000;'>Fields marked in yellow are required by the scripts<br />
to determine formal System Name, hostnames,<br />
and overall classification. For Classification, use<br />
UNCLASSIFIED or SECRET.
</i><br /><br />
<span style='color: #f00;'>NO SPACES OR SPECIAL CHARS IN HOSTNAMES!</span>
</td>
</tr>
<tr>
<td class='header' colspan=2>Open Cat II:</td>
<td class='open cat_II' id='open_cat_2'><?php print $db->get_Finding_Count_By_Status($cat, "Open", 2); ?></td>
<td class='header'>Hostname(s):</td>
<td></td>
<td class='header'>Date(s) Tested:</td>
<td></td>
</tr>
<tr>
<td class='header' colspan=2>Open Cat III:</td>
<td class='open cat_III' id='open_cat_3'><?php print $db->get_Finding_Count_By_Status($cat, "Open", 3); ?></td>
<td class='header'>IP(s):</td>
<td></td>
<td class='header'>ST&amp;E Team:</td>
<td></td>
</tr>
<tr>
<td class='header' colspan=2>Not a Finding:</td>
<td class='nf' id='not_a_finding'><?php print $db->get_Finding_Count_By_Status($cat, "Not a Finding"); ?></td>
<td class='header'>Netmask:</td>
<td></td>
<td class='header'>OS:</td>
<td></td>
</tr>
<tr>
<td class='header' colspan=2>N/A:</td>
<td class='na' id='not_applicable'><?php print $db->get_Finding_Count_By_Status($cat, "Not Applicable"); ?></td>
<td class='header'>Gateway:</td>
<td></td>
<td class='header'>Hardware:</td>
<td></td>
</tr>
<tr>
<td class='header' colspan=2>Not Reviewed:</td>
<td class='nr' id='not_reviewed'></td>
<td class='header'>Description:</td>
<td></td>
<td class='header'>Location:</td>
<td></td>
</tr>
</thead>
</table>
<br /><?php flush(); ?>
<?php
$x = 1;
$all_nr = 0;
$findings = $db->get_Category_Findings($cat);
foreach ($findings as $worksheet_name => $data) {
print "<a id='checklist_{$x}'></a>";
if (count($findings) > $x) {
print "<a href='#checklist_" . ($x + 1) . "'>Next</a>&nbsp;&nbsp;";
}
if ($x - 1 != 0) {
print "<a href='#checklist_" . ($x - 1) . "'>Back</a>&nbsp;&nbsp;";
}
print "<a href='#bottom'>Bottom</a>";
?>
<table style="border-collapse:collapse;word-break:break-word;">
<tbody id='checklist_<?php print $x; ?>'>
<tr>
<td class='header' style='width:150px;'>Checklist:</td>
<td colspan=8 style='color:#000;'><?php
$chk_arr = array();
$chk_ids = array();
$orphan = false;
foreach ($data['checklists'] as $key => $chk_id) {
$chk = $db->get_Checklist($chk_id)[0];
$chk_arr[] = "{$chk->get_Name()} V{$chk->get_Version()}R{$chk->get_Release()} ({$chk->get_type()})<br />";
$chk_ids[] = $chk->get_ID();
if ($chk->get_Name() == 'Orphan') {
$orphan = true;
}
}
sort($chk_arr);
print implode("", $chk_arr);
?></td>
</tr>
<tr style='font-weight: bolder;border-bottom:black 3px solid;'>
<td>&nbsp;</td>
<td class='cat_I' style='width: 75px;'>I</td>
<td class='cat_II' style='width: 75px;'>II</td>
<td class='cat_III' style='width: 75px;'>III</td>
<td class='na' style='width: 75px;'>NA</td>
<td class='nf' style='width: 75px;'>NF</td>
<td class='fp' style='width: 75px;'>FP</td>
<td class='nd' style='width: 75px;'>ND</td>
<td class='nr' style='width: 75px;'>NR</td>
</tr>
<?php
$cat_1 = 0;
$cat_2 = 0;
$cat_3 = 0;
$na = 0;
$nf = 0;
$fp = 0;
$nd = 0;
$nr = 0;
$total_cat_1 = 0;
$total_cat_2 = 0;
$total_cat_3 = 0;
$total_na = 0;
$total_nf = 0;
$total_fp = 0;
$total_nd = 0;
$total_nr = 0;
foreach ($data['target_list'] as $host_name => $col_id) {
$tgt = $db->get_Target_Details($ste, $host_name)[0];
$total_cat_1 += $cat_1 = $db->get_Host_Finding_Count_By_Status($tgt, "Open", 1, null, $chk_ids, $orphan);
$total_cat_2 += $cat_2 = $db->get_Host_Finding_Count_By_Status($tgt, "Open", 2, null, $chk_ids, $orphan);
$total_cat_3 += $cat_3 = $db->get_Host_Finding_Count_By_Status($tgt, "Open", 3, null, $chk_ids, $orphan);
$total_na += $na = $db->get_Host_Finding_Count_By_Status($tgt, "Not Applicable", null, null, $chk_ids, $orphan);
$total_nf += $nf = $db->get_Host_Finding_Count_By_Status($tgt, "Not a Finding", null, null, $chk_ids, $orphan);
$total_fp += $fp = $db->get_Host_Finding_Count_By_Status($tgt, "False Positive", null, null, $chk_ids, $orphan);
$total_nd += $nd = $db->get_Host_Finding_Count_By_Status($tgt, "No Data", null, null, $chk_ids, $orphan);
$total_nr += $nr = $db->get_Host_Finding_Count_By_Status($tgt, "Not Reviewed", null, null, $chk_ids, $orphan);
$all_nr += $nr;
?>
<tr>
<td><?php print $tgt->get_Name(); ?></td>
<td class="cat_I"><?php print $cat_1; ?></td>
<td class="cat_II"><?php print $cat_2; ?></td>
<td class="cat_III"><?php print $cat_3; ?></td>
<td class="na"><?php print $na; ?></td>
<td class="nf"><?php print $nf; ?></td>
<td class="fp"><?php print $fp; ?></td>
<td class="nd"><?php print $nd; ?></td>
<td class="nr"><?php print $nr; ?></td>
</tr>
<?php
}
?>
<tr style='font-weight:bolder;border-top:black 5px double;'>
<td style='font-size:16px;'>Total</td>
<td style='font-size:16px;' class="cat_I"><?php print $total_cat_1; ?></td>
<td style='font-size:16px;' class="cat_II"><?php print $total_cat_2; ?></td>
<td style='font-size:16px;' class="cat_III"><?php print $total_cat_3; ?></td>
<td style='font-size:16px;' class="na"><?php print $total_na; ?></td>
<td style='font-size:16px;' class="nf"><?php print $total_nf; ?></td>
<td style='font-size:16px;' class="fp"><?php print $total_fp; ?></td>
<td style='font-size:16px;' class="nd"><?php print $total_nd; ?></td>
<td style='font-size:16px;' class="nr"><?php print $total_nr; ?></td>
</tr>
</tbody>
</table>
<a href='#top'>Top</a><br /> <br />
<?php
$x++;
flush();
}
?>
</div>
<script type="text/javascript">
$(function () {
$('#not_reviewed').html(<?php print $all_nr; ?>);
});
</script>
<div id='bottom'>
<form method='post' action='export.php' id='export'>
<input type='hidden' name='ste' id='ste' value='<?php print $ste; ?>' />
<input type='hidden' name='cat' id='cat' value='<?php print $cat; ?>' />
<?php
foreach ($summary['summary'] as $chk_key => $chk) {
foreach ($summary['summary'][$chk_key] as $host_key => $host) {
print "<input type='hidden' name='chk_host[$chk_key][$host_key]' id='{$chk_key}-{$host_key}' value='$host' />";
}
}
?>
<a class='button' href="javascript:void(0);" id='export_bottom'
onclick="$('#export').submit();$('.export').attr('disabled', true);">Export</a>&nbsp;&nbsp;
<a class='button' href="javascript:void(0);"
onclick="parent.close_box();">Cancel</a>
</form>
</div>
</body>
</html>

517
ste/export.php Normal file
View File

@ -0,0 +1,517 @@
<?php
/**
* File: export.php
* Author: Ryan Prather
* Purpose: Export findings to an Excel spreadsheet eChecklist
* Created: Oct 15, 2013
*
* Portions Copyright 2016-2017: Cyber Perspectives, LLC, All rights reserved
* Released under the Apache v2.0 License
*
* Portions Copyright (c) 2012-2015, Salient Federal Solutions
* Portions Copyright (c) 2008-2011, Science Applications International Corporation (SAIC)
* Released under Modified BSD License
*
* See license.txt for details
*
* Change Log:
* - Oct 15, 2013 - File created
* - Dec 12, 2016 - Added Cyber Perspectives license, changed writing to spreadsheet to use constants for company data, and
* Added ST&E ending date to cover page
* - Mar 9, 2017 - Fixed issue with export overwriting columns
* - Apr 15, 2017 - Set text wrapping if enabled on Short Title column
* - May 13, 2017 - Migrated to PHPSpreadsheet library, and add support for other export formats
* - Jun 3, 2017 - Fixed bug #232
* - Jul 23, 2017 - MAS Added comments and rudimentary RMF control support to eChecklist export
* - Dec 27, 2017 - Updating classification info on cover sheet page,
* removed classification from G2,
* fixed invalid function call to stringFromColumnIndex as it was moved to a different class and changed to 1-based instead of 0-based,
* syntax updates, updated PDF writer to Tcpdf class, added die if constant ECHECKLIST_FORMAT is not set as expected
* - Jan 15, 2018 - Formatting, updated use statements, not seeing behavior explained in #373
*/
include_once 'config.inc';
include_once 'database.inc';
include_once 'helper.inc';
require_once 'vendor/autoload.php';
require_once 'excelConditionalStyles.inc';
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Writer\Xls;
use PhpOffice\PhpSpreadsheet\Writer\Ods;
use PhpOffice\PhpSpreadsheet\Writer\Csv;
use PhpOffice\PhpSpreadsheet\Writer\Html;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
set_time_limit(0);
$db = new db();
$checklists = [];
$x = 0;
$fh = fopen(LOG_PATH . "/eChecklist-export-timelog.csv", "a");
$last_time = microtime(true);
$emass_ccis = null;
$chk_hosts = filter_input_array(INPUT_POST, 'chk_host');
$cat_id = filter_input(INPUT_GET, 'cat', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
if (!$cat_id) {
$cat_id = filter_input(INPUT_POST, 'cat', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
}
$ste_id = filter_input(INPUT_COOKIE, 'ste', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
if (!$ste_id) {
$ste_id = filter_input(INPUT_POST, 'ste', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
}
if (!$ste_id || !$cat_id) {
die("Could not find the STE and Category ID");
}
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "calling get_category_findings");
}
if ($chk_hosts) {
$findings = $db->get_Category_Findings($cat_id, $chk_hosts);
}
else {
$findings = $db->get_Category_Findings($cat_id);
}
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "Got findings");
}
$cat = $db->get_Category($cat_id)[0];
if (!is_a($cat, 'ste_cat')) {
Sagacity_Error::err_handler("Error finding category $cat_id", E_ERROR);
}
$ste = $db->get_STE($ste_id)[0];
// Get mapping of eMASS controls to CCIs from DB
if ($ste->get_System()->get_Accreditation_Type() == accrediation_types::RMF) {
$emass_ccis = $db->get_EMASS_CCIs();
}
$log = new Sagacity_Error("{$cat->get_Name()}-echecklist-export.log");
$Reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile("eChecklist-Template.xlsx");
$ss = $Reader->load("eChecklist-Template.xlsx");
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "Loaded template");
}
$ss->setActiveSheetIndexByName('Cover Sheet')
->setCellValue("B5", "{$ste->get_System()->get_Name()} eChecklist")
->setCellValue("B9", "{$ste->get_Eval_Start_Date()->format("m/d/Y")}-{$ste->get_Eval_End_Date()->format("m/d/Y")}")
->setCellValue("B2", ($ste->get_System()->get_Classification() == 'Classified' ? "SECRET" : "UNCLASSIFIED"))
->setCellValue("B12", "by:\r" . COMPANY . "\r" . COMP_ADD)
->setCellValue("B15", "Derived from: " . SCG . "\rReasons: <reasons>\rDeclassify on: " . DECLASSIFY_ON);
// set properties
$ss->getProperties()
->setCreator(CREATOR);
$ss->getProperties()
->setLastModifiedBy(LAST_MODIFIED_BY);
$ss->getProperties()
->setCompany(COMPANY);
$ss->getProperties()
->setTitle("{$cat->get_Name()} eChecklist");
$ss->getProperties()
->setSubject("{$cat->get_Name()} eChecklist");
$ss->getProperties()
->setDescription("{$cat->get_Name()} eChecklist");
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "File properties set");
}
// set active sheet
$ss->setActiveSheetIndex(2);
$host_status = array(
$conditions['open'],
$conditions['exception'],
$conditions['false_positive'],
$conditions['not_a_finding'],
$conditions['not_applicable'],
$conditions['no_data'],
$conditions['not_reviewed'],
$conditions['true'],
$conditions['false']
);
// Iterate over worksheets in the category; populating each with the checklists and finding data
foreach ($findings as $worksheet_name => $data) {
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "Looping through worksheet $worksheet_name");
}
$chk_arr = [];
$named_range = '';
// Build the "Checklist" cell string with titles of all checklists on this worksheet
foreach ($data['checklists'] as $key => $chk_id) {
$checklist = $db->get_Checklist($chk_id)[0];
$chk_arr[] = "{$checklist->get_Name()} V{$checklist->get_Version()}R{$checklist->get_Release()} ({$checklist->get_type()})";
}
$checklist_str = implode(", ", $chk_arr);
if (is_null($sheet = $ss->getSheetByName($worksheet_name))) {
$new_sheet = clone $ss->getSheet(2);
$new_sheet->setTitle($worksheet_name);
$ss->addSheet($new_sheet);
$sheet = $ss->getSheetByName($worksheet_name);
if (is_array($data['target_list']) && count($data['target_list']) > 1) {
$sheet->insertNewColumnBefore("G", count($data['target_list']) - 1);
}
$sheet->setCellValue("B9", $checklist_str);
}
else {
$sheet->setCellValue("B9", "{$sheet->getCellValue("B9")}, {$checklist_str}");
}
$class = 'UNCLASSIFIED';
if (isset($data['highest_class'])) {
switch ($data['highest_class']) {
case 'FOUO':
$class = 'UNCLASSIFIED//FOUO';
break;
case 'S':
$class = 'SECRET';
break;
}
}
else {
if ($ste->get_System()->get_Classification() == 'Sensitive') {
$class = 'UNCLASSIFIED//FOUO';
}
elseif ($ste->get_System()->get_Classification() == 'Classified') {
$class = 'SECRET';
}
}
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "Setting classification");
}
$sheet->setCellValue("A1", $class)
->setCellValue('E2', $ste->get_System()->get_Name());
$sheet->getStyle("A1")
->setConditionalStyles([$conditions['unclass_classification'], $conditions['secret_classification']]);
$row = 11;
$last_tgt_col = Coordinate::stringFromColumnIndex(count($data['target_list']) + 5);
$overall_col = Coordinate::stringFromColumnIndex(count($data['target_list']) + 6);
$same_col = Coordinate::stringFromColumnIndex(count($data['target_list']) + 7);
$notes_col = Coordinate::stringFromColumnIndex(count($data['target_list']) + 8);
$check_contents_col = Coordinate::stringFromColumnIndex(count($data['target_list']) + 9);
// Iterate over checklist items ($stig_id) and populate spreadsheet with status of each
foreach ($data['stigs'] as $stig_id => $tgt_status) {
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "Running through STIG $stig_id");
}
$ia_controls_string = null;
$notes = '';
// If $do_rmf is set, replace CCIs w/ eMASS RMF Control and build string to
// insert into IA Controls cell, otherwise just use CCIs.
if ($ste->get_System()->get_Accreditation_Type() == accrediation_types::RMF) {
$ia_controls = $tgt_status['echecklist']->get_IA_Controls();
$rmf_controls = [];
foreach ($ia_controls as $control) {
// Remove 'CCI-' and leading zeros
$id = ltrim(substr($control, strpos($control, "-") + 1), '0');
// lookup cci in $emass_ccis
$key = array_search($id, array_column($emass_ccis, 'id'));
// Push the control onto $rmf_controls
array_push($rmf_controls, $emass_ccis[$key]['control']);
}
$ia_controls_string = implode(" ", $rmf_controls);
}
else {
$ia_controls_string = $tgt_status['echecklist']->get_IA_Controls_String();
}
$sheet->setCellValue("A{$row}", $stig_id)
->setCellValue("B{$row}", $tgt_status['echecklist']->get_VMS_ID())
->setCellValue("C{$row}", $tgt_status['echecklist']->get_Cat_Level_String())
->setCellValue("D{$row}", $ia_controls_string)
->setCellValue("E{$row}", html_entity_decode($tgt_status['echecklist']->get_Short_Title()));
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "Added STIG info ($stig_id), now to targets");
}
foreach ($data['target_list'] as $host_name => $col_id) {
$status = 'Not Applicable';
if (isset($tgt_status[$host_name])) {
$status = $tgt_status[$host_name];
}
$col = Coordinate::stringFromColumnIndex($col_id);
$sheet->setCellValue("{$col}{$row}", $status);
$sheet->getCell("{$col}{$row}")->setDataValidation(clone $validation['host_status']);
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "Set data validation for target $host_name");
}
}
$overall_str = "=IF(" .
"COUNTIF(F{$row}:{$last_tgt_col}{$row},\"Open\")+" .
"COUNTIF(F{$row}:{$last_tgt_col}{$row},\"Exception\")" .
">0,\"Open\",\"Not a Finding\")";
$same_str = "=IF(" .
"COUNTIF(F{$row}:{$last_tgt_col}{$row},F{$row})=" .
"COLUMNS(F{$row}:{$last_tgt_col}{$row}), TRUE, FALSE)";
$sheet->setCellValue($overall_col . $row, $overall_str);
$sheet->getCell("{$col}{$row}")->setDataValidation(clone $validation['host_status']);
$sheet->setCellValue($same_col . $row, $same_str, true)
->getStyle("{$same_col}11:{$same_col}{$sheet->getHighestDataRow()}")
->setConditionalStyles([$conditions['true'], $conditions['false']]);
//->setDataValidation($validation['true_false']);
$sheet->setCellValue($notes_col . $row, html_entity_decode($tgt_status['echecklist']->get_Notes()))
->setCellValue($check_contents_col . $row, str_replace("\\n", "\r", html_entity_decode($tgt_status['echecklist']->get_Check_Contents())));
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "Added remaining cells");
}
$row++;
}
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "Completed STIG parsing");
}
$sheet->getStyle("F11:" . Coordinate::stringFromColumnIndex(count($data['target_list']) + 6) . $row)
->setConditionalStyles($host_status);
$sheet->getStyle("C11:C{$sheet->getHighestDataRow()}")
->setConditionalStyles(array($conditions['cat_1'], $conditions['cat_2'], $conditions['cat_3']));
$sheet->getStyle("{$notes_col}11:{$notes_col}{$row}")
->setConditionalStyles(array(
$conditions['open_conflict'],
$conditions['nf_na_conflict']
));
if (is_array($data['target_list']) && count($data['target_list']) > 1) {
$sheet->getStyle("G3:{$notes_col}7")
->getFill()
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_NONE);
$sheet->getStyle("G2")
->getFill()
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_NONE);
$sheet->getStyle("G2")
->getFont()
->setBold(false);
$sheet->getStyle("G2")
->getAlignment()
->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_LEFT);
}
$sheet->getStyle("A1:{$sheet->getHighestDataColumn()}{$sheet->getHighestDataRow()}")
->applyFromArray($borders);
$sheet->freezePane("A11");
$sheet->setAutoFilter("A10:{$sheet->getHighestDataColumn()}10");
updateHostHeader($sheet, $data['target_list'], $db);
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "Completed worksheet $worksheet_name");
}
}
$ss->removeSheetByIndex(2);
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "Writing to file");
}
$ct = '';
$writer = null;
switch (ECHECKLIST_FORMAT) {
case 'xlsx':
$writer = new Xlsx($ss);
$writer->setPreCalculateFormulas(false);
$ct = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
break;
case 'ods':
$writer = new Ods($ss);
$writer->setPreCalculateFormulas(false);
$ct = "application/vnd.oasis.opendocument.spreadsheet";
break;
case 'pdf':
\PhpOffice\PhpSpreadsheet\Settings::setPdfRendererName(PhpOffice\PhpSpreadsheet\Settings::PDF_RENDERER_TCPDF);
$writer = new Tcpdf($ss);
$writer->writeAllSheets();
$ct = "application/pdf";
break;
case 'html':
$writer = new Html($ss);
$writer->writeAllSheets();
$writer->setPreCalculateFormulas(false);
$ct = "text/html";
break;
case 'xls':
$writer = new Xls($ss);
$writer->setPreCalculateFormulas(false);
$ct = "application/vnd.ms-excel";
break;
case 'csv':
$writer = new Csv($ss);
$ct = "text/csv";
break;
default:
die("Did not recognize eChecklist format " . ECHECKLIST_FORMAT);
}
$cat_name = str_replace(" ", "_", $cat->get_Name());
header("Content-type: $ct");
header("Content-disposition: attachment; filename='{$cat_name}-eChecklist-{$ste_id}." . ECHECKLIST_FORMAT . "'");
$writer->save("php://output");
if (LOG_LEVEL == E_DEBUG) {
time_log_diff($fh, "Writing complete");
}
fclose($fh);
/**
* Update the header on the worksheet
*
* @param \PhpOffice\PhpSpreadsheet\Worksheet $sheet
* @param array:integer $tgts
* @param db $db
*/
function updateHostHeader($sheet, $tgts, &$db) {
global $ste_id, $log;
$host_names = [];
$ips = [];
$oses = [];
$open_cat_1 = null;
$open_cat_2 = null;
$open_cat_3 = null;
$not_a_finding = null;
$not_applicable = null;
$not_reviewed = null;
foreach ($tgts as $tgt_name => $col_id) {
$log->script_log("tgt_name: $tgt_name\tcol_id: $col_id");
$tgt = $db->get_Target_Details($ste_id, $tgt_name)[0];
$os = $db->get_Software($tgt->get_OS_ID())[0];
$oses[] = "{$os->man} {$os->name} {$os->ver}";
$host_names[] = $tgt->get_Name();
if (is_array($tgt->interfaces) && count($tgt->interfaces)) {
foreach ($tgt->interfaces as $int) {
if (!in_array($int->get_IPv4(), ["127.0.0.1", "", "0.0.0.0", null])) {
$ips[] = $int->get_IPv4();
break;
}
}
}
$col = Coordinate::stringFromColumnIndex($col_id);
$highest_row = $sheet->getHighestDataRow();
$sheet->getColumnDimension($col)
->setWidth(14.14);
$sheet->setCellValue("{$col}8", "=COUNTIFS({$col}11:{$col}{$highest_row}, \"Open\", \$C\$11:\$C\${$highest_row}, \"I\")")
->setCellValue("{$col}9", "=COUNTIF({$col}11:{$col}{$highest_row}, \"Not Reviewed\")")
->setCellValue("{$col}10", $tgt->get_Name());
$sheet->getStyle("{$col}10")
->getFont()
->setBold(true);
$sheet->getStyle("{$col}10")
->getFill()
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
->setStartColor($GLOBALS['yellow']);
if (!is_null($open_cat_1)) {
$open_cat_1 .= "+";
$open_cat_2 .= "+";
$open_cat_3 .= "+";
$not_a_finding .= "+";
$not_applicable .= "+";
$not_reviewed .= "+";
}
else {
$open_cat_1 = "=";
$open_cat_2 = "=";
$open_cat_3 = "=";
$not_a_finding = "=";
$not_applicable = "=";
$not_reviewed = "=";
}
$open_cat_1 .= "COUNTIFS({$col}11:{$col}{$highest_row}, \"Open\", \$C\$11:\$C\${$highest_row}, \"I\")";
$open_cat_2 .= "COUNTIFS({$col}11:{$col}{$highest_row}, \"Open\", \$C\$11:\$C\${$highest_row}, \"II\")";
$open_cat_3 .= "COUNTIFS({$col}11:{$col}{$highest_row}, \"Open\", \$C\$11:\$C\${$highest_row}, \"III\")";
$not_a_finding .= "COUNTIF({$col}11:{$col}{$highest_row}, \"Not a Finding\")";
$not_applicable .= "COUNTIF({$col}11:{$col}{$highest_row}, \"Not Applicable\")";
$not_reviewed .= "COUNTIF({$col}11:{$col}{$highest_row}, \"Not Reviewed\")";
}
$overall_col = Coordinate::stringFromColumnIndex(count($tgts) + 6);
$same_col = Coordinate::stringFromColumnIndex(count($tgts) + 7);
$notes_col = Coordinate::stringFromColumnIndex(count($tgts) + 8);
$check_contents_col = Coordinate::stringFromColumnIndex(count($tgts) + 9);
$sheet->getStyle("{$overall_col}8:{$same_col}8")
->getFill()
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
->setStartColor($GLOBALS['orange']);
$sheet->getStyle("{$overall_col}9:{$same_col}9")
->getFill()
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
->setStartColor($GLOBALS['green']);
$sheet->getStyle("{$overall_col}10:{$same_col}10")
->getFill()
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
->setStartColor($GLOBALS['yellow']);
$sheet->getStyle("{$notes_col}10:{$check_contents_col}10")
->getFill()
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
->setStartColor($GLOBALS['light_gray']);
$sheet->setCellValue("{$overall_col}8", "=COUNTIF({$overall_col}11:{$overall_col}{$highest_row}, \"Open\")")
->setCellValue("{$overall_col}9", "=COUNTIF({$overall_col}11:{$overall_col}{$highest_row}, \"Not a Finding\")")
->setCellValue("{$same_col}8", "=COUNTIF({$same_col}11:{$same_col}{$highest_row}, FALSE)")
->setCellValue("{$same_col}9", "=COUNTIF({$same_col}11:{$same_col}{$highest_row}, TRUE)")
->setCellValue("E3", implode(", ", $host_names))
->setCellValue("E4", implode(", ", $ips))
->setCellValue("G4", implode(", ", array_unique($oses)))
->setCellValue("{$overall_col}10", "Overall Status")
->setCellValue("{$same_col}10", "Consistent")
->setCellValue("{$notes_col}10", "Notes")
->setCellValue("{$check_contents_col}10", "Check Contents");
$sheet->getStyle("{$overall_col}10:{$check_contents_col}10")
->getFont()
->setBold(true);
if (!FLATTEN) {
$sheet->getColumnDimension($overall_col)->setVisible(false);
$sheet->getColumnDimension($same_col)->setVisible(false);
}
if (WRAP_TEXT) {
$sheet->getStyle("{$check_contents_col}11:{$check_contents_col}{$sheet->getHighestDataRow()}")
->getAlignment()->setWrapText(true);
$sheet->getStyle("E11:E{$sheet->getHighestDataRow()}")
->getAlignment()->setWrapText(true);
}
$sheet->setCellValue('C2', $open_cat_1)
->setCellValue('C3', $open_cat_2)
->setCellValue('C4', $open_cat_3)
->setCellValue('C5', $not_a_finding)
->setCellValue('C6', $not_applicable)
->setCellValue('C7', $not_reviewed);
}

621
ste/index.php Normal file
View File

@ -0,0 +1,621 @@
<?php
/**
* File: index.php
* Author: Ryan Prather
* Purpose: Main index page for the ST&E Operations
* Created: Sep 16, 2013
*
* Portions Copyright 2016-2017: Cyber Perspectives, LLC, All rights reserved
* Released under the Apache v2.0 License
*
* Portions Copyright (c) 2012-2015, Salient Federal Solutions
* Portions Copyright (c) 2008-2011, Science Applications International Corporation (SAIC)
* Released under Modified BSD License
*
* See license.txt for details
*
* Change Log:
* - Sep 16, 2013 - File created
* - Sep 1, 2016 - Copyright and file purpose updated,
* Added vertical menu
* - Oct 24, 2016 - Fixed a few display bugs
* - Nov 7, 2016 - Fixed more display bugs
* - Nov 21, 2016 - Added check for presents of scan sources before outputting them
* - Jan 30, 2017 - Formatting
* - Apr 5, 2017 - Removing rename category functionality and replacing with edit category,
* Removed vertical menu code and CSS, removed commented out delete category lightbox,
* STILL WORKING edit category code
* - Apr 7, 2017 - Completed edit category functionality
* - May 13, 2017 - Added Delete Host button (not functional yet)
* Adding import scans popup (not complete)
* - May 19, 2017 - Simplified target selection code, added target deletion from OPs page, and changed buttons to match
* - May 26, 2017 - Added JS to delete hosts from category after deleting host using "Delete Host" button
* - May 30, 2017 - Fixed bug #209 error when saving category after editing
* - Jun 3, 2017 - Fixed bug #236
*/
$title_prefix = "Operations";
include_once 'config.inc';
include_once 'header.inc';
include_once 'database.inc';
set_time_limit(0);
$db = new db();
$cats = [];
$action = filter_input(INPUT_POST, 'action', FILTER_SANITIZE_STRING);
$ste_id = filter_input(INPUT_POST, 'ste', FILTER_VALIDATE_INT);
if (!$ste_id) {
$ste_id = filter_input(INPUT_COOKIE, 'ste', FILTER_VALIDATE_INT);
}
$stes = $db->get_STE();
if ($action) {
if ($action == 'move_to') {
$sel_tgts = json_decode(html_entity_decode(filter_input(INPUT_POST, 'selected_tgts', FILTER_SANITIZE_STRING)));
$db->move_Tgt_To_Cat($sel_tgts, filter_input(INPUT_POST, 'move_to_cat', FILTER_VALIDATE_INT));
}
elseif ($action == 'save_cat') {
$existing_cat = filter_input(INPUT_POST, 'selected_cat', FILTER_VALIDATE_INT);
$new_cat_name = filter_input(INPUT_POST, 'new_cat_name', FILTER_SANITIZE_STRING);
$analyst = filter_input(INPUT_POST, 'analyst', FILTER_SANITIZE_STRING);
$cat = new ste_cat($existing_cat, $ste_id, $new_cat_name, $analyst);
$sources = filter_input(INPUT_POST, 'scan_sources', FILTER_VALIDATE_INT, FILTER_REQUIRE_ARRAY);
if (is_array($sources) && count($sources)) {
foreach ($sources as $src_id) {
$cat->add_Source($db->get_Sources($src_id));
}
}
$db->save_Category($cat);
}
elseif ($action == 'add_cat') {
$name = filter_input(INPUT_POST, 'new_cat', FILTER_SANITIZE_STRING);
$sources = filter_input(INPUT_POST, 'scan_sources', FILTER_VALIDATE_INT, FILTER_REQUIRE_ARRAY);
$ste_cat = new ste_cat(null, $ste_id, $name, null);
if (is_array($sources) && count($sources)) {
foreach ($sources as $idx => $id) {
$ste_cat->add_Source($db->get_Sources($id));
}
}
$db->save_Category($ste_cat);
}
elseif ($action == 'update_auto' || $action == 'update_manual' ||
$action == 'update_data' || $action == 'update_fp_cat1') {
$sel_tgts = json_decode(html_entity_decode(filter_input(INPUT_POST, 'selected_tgts', FILTER_SANITIZE_STRING)));
$new_status = filter_input(INPUT_POST, 'new_status', FILTER_SANITIZE_STRING);
$db->update_Task_Status($action, $sel_tgts, $new_status);
}
elseif ($action == 'assign') {
$cat_id = filter_input(INPUT_POST, 'cat_id', FILTER_VALIDATE_INT);
$analyst = filter_input(INPUT_POST, 'analyst', FILTER_SANITIZE_STRING);
$db->assign_Analyst_To_Category($cat_id, $analyst);
}
elseif ($action == 'autocat') {
$db->auto_Catorgize_Targets($ste_id);
}
elseif ($action == 'import_host_list') {
$file = filter_input(INPUT_POST, 'file', FILTER_SANITIZE_STRING, FILTER_NULL_ON_FAILURE);
if (file_exists(TMP . "/$file")) {
$fh = fopen(TMP . "/$file", "r");
$header = array_flip(array_map('strtolower', fgetcsv($fh)));
if ((isset($header['hostname']) || isset($header['name'])) && isset($header['ip']) && isset($header['os']) && isset($header['category'])) {
while ($row = fgetcsv($fh)) {
if (count($row) >= 4) {
$tgt_id = 0;
if (isset($header['name'])) {
$tgt_id = $db->check_Target($ste_id, $row[$header['name']]);
}
if (empty($tgt_id) && isset($header['hostname'])) {
$tgt_id = $db->check_Target($ste_id, $row[$header['hostname']]);
}
if (empty($tgt_id) && isset($row[$header['ip']])) {
foreach (explode(",", $row[$header['ip']]) as $ip) {
if ($tgt_id = $db->check_Target($ste_id, $ip)) {
break;
}
}
}
if (!empty($tgt_id)) {
continue;
//$tgt = $db->get_Target_Details($ste_id, $tgt_id)[0];
}
else {
$tgt = new target((isset($header['name']) ? $row[$header['name']] : $row[$header['hostname']]));
$tgt->set_STE_ID($ste_id);
}
$os_regex = $db->get_Regex_Array('os');
if (substr($row[$header['os']], 0, 7) == 'cpe:2.3') {
$os = array(0 => new software(null, $row[$header['os']]));
}
elseif (substr($row[$header['os']], 0, 3) == 'cpe') {
$os = array(0 => new software($row[$header['os']], null));
}
else {
$os = software::identify_Software($os_regex, $row[$header['os']]);
}
$os = $db->get_Software($os);
if (is_array($os) && count($os) && isset($os[0]) && is_a($os[0], 'software')) {
$tgt->set_OS_ID($os[0]->get_ID());
$tgt->set_OS_String($os[0]->get_Shortened_SW_String());
}
else {
$sw = new software("cpe:/o:generic:generic:-", "cpe:2.3:o:generic:generic:-:*:*:*:*:*:*");
$os = $db->get_Software($sw)[0];
$tgt->set_OS_ID($os->get_ID());
$tgt->set_OS_String($os->get_Shortened_SW_String());
}
foreach (explode(',', $row[$header['ip']]) as $ip) {
$tgt->interfaces[$ip] = new interfaces(null, null, null, $ip, null, $row[$header['hostname']], (isset($header['fqdn']) ? $row[$header['fqdn']] : null), null);
}
if (!empty($row[$header['category']])) {
$ste_cat = $db->get_STE_Cat_List($ste_id, $row[$header['category']]);
if (is_array($ste_cat) && count($ste_cat) && isset($ste_cat[0]) && is_a($ste_cat[0], 'ste_cat')) {
$tgt->set_Cat_ID($ste_cat[0]->get_ID());
}
else {
$ste_cat = new ste_cat(null, $ste_id, $row[$header['category']], null);
$ste_cat->set_ID($db->save_Category($ste_cat));
$tgt->set_Cat_ID($ste_cat->get_ID());
}
}
$db->save_Target($tgt);
}
}
}
fclose($fh);
unlink(TMP . "/$file");
}
}
}
if ($ste_id) {
$cats = $db->get_STE_Cat_List($ste_id);
}
$task_status = $db->get_Task_Statuses();
$scan_srcs = $db->get_Sources();
?>
<script src="ste_script.js" type="text/javascript"></script>
<link href='/style/style.css' rel='stylesheet' type='text/css' />
<script type="text/javascript">
var sel_tgts = [];
function open_echecklist(id) {
$('#echecklist').attr('src', 'echecklist_iframe.php?ste=<?php print (isset($ste_id) ? $ste_id : 0); ?>&cat=' + id);
$('#echecklist').animate({'opacity': '1.00'}, 300, 'linear');
$('#echecklist').css('display', 'block');
view_box();
}
function toggle_hostname_ip() {
$('.host').toggle();
$('.ip').toggle();
if ($('#toggle_host_ip').val() == 'Show IP')
$('#toggle_host_ip').val("Show Name");
else
$('#toggle_host_ip').val("Show IP");
}
function delete_host() {
if (!confirm("Are you sure you want to delete the selected target(s)")) {
return;
}
$.ajax('/ajax.php', {
data: {
action: 'delete-host',
selected_tgts: JSON.stringify(sel_tgts)
},
success: function (data) {
if (data.error) {
alert(data.error);
}
else if (data.success) {
$('.tgt-sel:checked').parent().parent().slideUp(500);
$('.tgt-sel:checked').parent().parent().remove();
}
},
error: function (xhr, status, error) {
console.error(error);
},
timeout: 5000,
method: 'post',
dataType: 'json'
});
}
$(function () {
$('.button,.button-delete').on('mouseover', function () {
$(this).addClass('mouseover');
});
$('.button,.button-delete').on('mouseout', function () {
$(this).removeClass('mouseover');
});
$('.expand').click(collapse_expand);
});
</script>
<style type="text/css">
.ip {
display: none;
}
.header {
display: inline-table;
width: auto;
background-color: #31363C;
color: #fff;
}
.left_cat_header span {
text-align: center;
min-width: 25px;
display: inline-block;
padding: 0 3px;
}
.right_cat_header {
width: 200px;
float: right;
}
.cat_icons {
background-size: 20px 20px;
vertical-align: middle;
width: 20px;
height: 20px;
padding-right: 2px;
}
.task-nr,.task-na,.task-np,.task-comp,.task-ip {
text-align: center;
width: 62px;
}
.checklist_image {
width: 32px;
vertical-align: middle;
}
.notes {
width: 100%;
}
.table-header {
width: 1200px;
text-align: center;
margin: auto;
}
#mentions {
font-family: verdana, arial, sans-serif;
position: absolute;
bottom : 200px;
left : 10px;
color: #000;
background-color: #ddd;
}
#mentions a {
text-decoration: none;
color: #222;
}
#mentions a:hover{
text-decoration: underline;
}
#waiting {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background: #000;
opacity: 0.0;
filter: alpha(opacity=0);
z-index: 1000;
display: none;
}
#loading {
display: none;
}
</style>
<div id='wrapper'>
<div id='main-wrapper'>
<div class='12u' id='main-content'>
<div class="5grid-layout" style="text-align: right;overflow-y:auto;overflow-x:hidden;">
<div class="row">
<div class="12u">
<div style='float: left; margin-top: 6px;'>
<form method="post" action="#">
ST&amp;E Name:
<select name='ste' style='width: 400px;' id="ste"
onchange="setCookie('ste', this.value);
this.form.submit();">
<option value='0'> -- Please Select an ST&amp;E -- </option>
<?php
if (is_array($stes) && count($stes)) {
foreach ($stes as $ste) {
print "<option value='{$ste->get_ID()}'" .
($ste_id && $ste_id == $ste->get_ID() ? " selected" : "") .
">" .
"{$ste->get_System()->get_Name()}, {$ste->get_Site()->get_Name()}, {$ste->get_Eval_Start_Date()->format("d M Y")}" .
"</option>";
}
}
?>
</select>
</form>
</div>
<div style='float: right;'>
<input type='button' class='button' id='toggle_host_ip' value='Show IP'
onclick="javascript:toggle_hostname_ip();" />
<input type='button' class='button' value='Move To...'
onclick="javascript:open_move_to();" />
<input type='button' class='button' value='Add Category'
onclick="javascript:add_cat();" />
<input type='button' class='button' value='Add Host List'
onclick="javascript:upload_host_list();" />
<input type='button' class='button-delete'
onclick="javascript:delete_host();" value='Delete Host' />
</div>
</div>
</div>
<div id="container">
<div class="table-header">
<span class="header" style="width:100px;">Name</span>
<span class="header" style="width:100px;">OS</span>
<span class="header" style="width:100px;">Location</span>
<span class="header" style="width:60px;">
<form method="post" action="#" style="display:inline-block;">
<input type='hidden' name='action' value='update_auto' />
<input type='hidden' name='selected_tgts' id='auto_selected_tgts' />
<input type='hidden' name='ste' value='<?php print isset($ste_id) ? $ste_id : ''; ?>' />
<select name='new_status' style='width: 60px;'
onchange="$('#auto_selected_tgts').val(JSON.stringify(sel_tgts));
if (update_Status(this))
this.form.submit();">
<option value='0'>Auto</option>
<?php
foreach ($task_status as $key => $val): print "<option value='$key'>$val</option>";
endforeach;
?>
</select>
</form>
</span>
<span class="header" style="width:60px;">
<form method="post" action="#" style="display:inline-block;">
<input type='hidden' name='action' value='update_manual' />
<input type='hidden' name='selected_tgts' id='man_selected_tgts' />
<input type='hidden' name='ste'value='<?php print (isset($ste_id) ? $ste_id : ''); ?>' />
<select name='new_status' style='width: 60px;'
onchange="$('#man_selected_tgts').val(JSON.stringify(sel_tgts));
if (update_Status(this))
this.form.submit();">
<option value='0'>Man</option>
<?php
foreach ($task_status as $key => $val): print "<option value='$key'>$val</option>";
endforeach;
?>
</select>
</form>
</span>
<span class="header" style="width:60px;">
<form method="post" action="#" style="display:inline-block;">
<input type='hidden' name='action' value='update_data' />
<input type='hidden' name='selected_tgts' id='data_selected_tgts' />
<input type='hidden' name='ste' value='<?php print (isset($ste_id) ? $ste_id : ''); ?>' />
<select name='new_status' style='width: 60px;'
onchange="$('#data_selected_tgts').val(JSON.stringify(sel_tgts));
if (update_Status(this))
this.form.submit();">
<option value='0'>Data</option>
<?php
foreach ($task_status as $key => $val): print "<option value='$key'>$val</option>";
endforeach;
?>
</select>
</form>
</span>
<span class="header" style="width:60px;">
<form method="post" action="#" style="display:inline-block;">
<input type='hidden' name='action' value='update_fp_cat1' />
<input type='hidden' name='selected_tgts' id='review_selected_tgts' />
<input type='hidden' name='ste' value='<?php print (isset($ste_id) ? $ste_id : ''); ?>' />
<select name='new_status' style='width: 60px;'
onchange="$('#review_selected_tgts').val(JSON.stringify(sel_tgts));
if (update_Status(this))
this.form.submit();">
<option value='0'>FP/CAT I</option>
<?php
foreach ($task_status as $key => $val): print "<option value='$key'>$val</option>";
endforeach;
?>
</select>
</form>
</span>
<span class="header" style="width:145px;">Scans</span>
<span class='header' style="width:145px;">Checklists</span>
<span class='header' style='width:344px;'>Notes</span>
</div>
</div>
<?php
// print category headers
if ($ste_id) {
$tgts = $db->get_Unassigned_Targets($ste_id);
$odd = true;
if (is_array($tgts) && count($tgts)) {
$cat = new ste_cat(0, $ste_id, "Unassigned", null);
print $cat->get_Table_Row(count($tgts));
foreach ($tgts as $key => $tgt) {
$tgt->get_Table_Row($odd);
$odd = !$odd;
}
}
foreach ($cats as $cat) {
$nr = $db->get_Finding_Count_By_Status($cat->get_ID(), "Not Reviewed");
$na = $db->get_Finding_Count_By_Status($cat->get_ID(), "Not Applicable");
$nf = $db->get_Finding_Count_By_Status($cat->get_ID(), "Not a Finding");
$open = $db->get_Finding_Count_By_Status($cat->get_ID(), "Open");
$count = $db->get_STE_Cat_TGT_Count($cat->get_ID());
print $cat->get_Table_Row($count, [
"open" => $open,
"nf" => $nf,
"na" => $na,
"nr" => $nr
]);
}
}
else {
print "<div style='text-align:center;font-size:18pt;'>No ST&amp;E selected</div>";
}
?>
</div>
</div>
</div>
</div>
<div class="backdrop"></div>
<div id="move_to" class="box">
<form method="post" action="#">
<input type='hidden' name='selected_tgts' id='move_selected_tgts' />
<input type='hidden' name='action' value='move_to' />
<input type='hidden' name='ste' id='move_ste' value='<?php print (isset($ste_id) ? $ste_id : ''); ?>' />
Move to category:
<select name='move_to_cat' onchange="$('#move_selected_tgts').val(JSON.stringify(sel_tgts));
this.form.submit();">
<option value=''>-- Select Category --</option>
<?php
if (is_array($cats) && count($cats)) {
foreach ($cats as $cat) {
print "<option value='{$cat->get_ID()}'>{$cat->get_Name()}</option>";
}
}
?>
</select>
</form>
</div>
<div id="edit_cat" class="box">
<form method="post" action="#">
<input type="hidden" name="selected_cat" id="selected_cat" />
<input type="hidden" name="action" value="save_cat" />
New Name: <input type="text" name="new_cat_name" id="new_cat_name" /><br />
Analyst: <input type='text' name='analyst' id='analyst' /><br />
<select name='scan_sources[]' id="scan_sources" multiple size='8'>
<?php
if (is_array($scan_srcs) && count($scan_srcs)) {
foreach ($scan_srcs as $src) {
print "<option id='src_{$src->get_ID()}' value='{$src->get_ID()}'>{$src->get_Name()}</option>";
}
}
?>
</select><br />
<input type="submit" name="submit" value="Update Category" />
</form>
</div>
<div id="add_cat" class="box">
<form method="post" action="#">
<input type='hidden' name='action' value='add_cat' />
<input type='hidden' name='ste' id='add_ste' value='' />
Category Name: <input type='text' name='new_cat' value='' /><br />
<select name='scan_sources[]' multiple size='8'>
<?php
if (is_array($scan_srcs) && count($scan_srcs)) {
foreach ($scan_srcs as $src) {
print "<option value='{$src->get_ID()}'>{$src->get_Name()}</option>";
}
}
?>
</select><br />
<input type='submit' name='submit' value='Add Category' />
</form>
</div>
<div id="import_host_list" class="box">
<script type="text/javascript" src="/script/dropzone/dropzone.min.js"></script>
<link type="text/css" href="/script/dropzone/dropzone.min.css" rel="stylesheet" />
<link type="text/css" href="/script/dropzone/basic.min.css" rel="stylesheet" />
<script type="text/javascript">
Dropzone.options.dropzone = {
maxFilesize: 10,
success: function (file, res) {
},
error: function (xhr, status, error) {
console.error(xhr);
console.error(error);
},
acceptedFiles: ".csv"
};
Dropzone.prototype.submitRequest = function (xhr, formData, files) {
$('#host-list-file').val(files[0].name);
var dt = new Date(files[0].lastModifiedDate);
xhr.setRequestHeader('X-FILENAME', files[0].name);
xhr.setRequestHeader('X-FILEMTIME', dt.toISOString());
return xhr.send(formData);
};
Dropzone.autoDiscover = false;
$(function () {
var mydz = new Dropzone('#dropzone');
});
</script>
<form class="dropzone" action="/upload.php" id="dropzone">
<div class="fallback">
<input type="file" name="file" multiple />
</div>
</form>
<form method='post' action='#' style='margin-left: 20px;'
onsubmit="$('#submit').attr('disabled', true);
return true;">
<input type='hidden' name='file' id='host-list-file' style='display:none;' />
<input type='hidden' name='action' value='import_host_list' />
<input type='hidden' name='ste' value='<?php print ($ste_id ? $ste_id : ''); ?>' />
<input type='submit' name='submit' id='submit' value='Import Host List' />
</form>
</div>
<div id="add_import" class="box">
<div style='margin-left: 20px;'>
<input type='text' id='location' placeholder='Physical Location...' /><br />
<input type='button' id='add-scan' value='Add Scan Result' onclick='add_scans();' /><br />
<label for='ignore_hidden' id='ignore_label'>Ignore Hidden Tabs in Excel eChecklists</label>
<input type='checkbox' name='ignore_hidden' id='ignore_hidden' value='1' checked />
</div>
</div>
<iframe id='echecklist' class='box' style='width: 80%; height: 80%; top: 10%; left: 10%;'> </iframe>
<div id="waiting"></div>
<div id="loading"></div>
<?php
include_once 'footer.inc';

130
ste/interview.php Normal file
View File

@ -0,0 +1,130 @@
<?php
/**
* File: interview.php
* Author: Ryan Prather
* Purpose: Category Interview page
* Created: Aug 25, 2014
*
* Portions Copyright 2016: Cyber Perspectives, All rights reserved
* Released under the Apache v2.0 License
*
* Portions Copyright (c) 2012-2015, Salient Federal Solutions
* Portions Copyright (c) 2008-2011, Science Applications International Corporation (SAIC)
* Released under Modified BSD License
*
* See license.txt for details
*
* Change Log:
* - Aug 25, 2014 - File created
* - Sep 1, 2016 - Copyright and file purpose updated
* - Dec 27, 2017 - Formatting
* - Jan 2, 2018 - Fixed bug #351
*/
include_once 'config.inc';
include_once 'database.inc';
include_once 'helper.inc';
$db = new db();
$cats = $db->get_Question_Categories();
$type = filter_input(INPUT_POST, 'type', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => "/Unix|Windows/", 'flag' => FILTER_NULL_ON_FAILURE]]);
$cat_id = (int) filter_input(INPUT_POST, 'cat', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
if (!$cat_id) {
$cat_id = (int) filter_input(INPUT_GET, 'cat', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
}
$action = filter_input(INPUT_POST, 'action', FILTER_SANITIZE_STRING, FILTER_NULL_ON_FAILURE);
if ($type) {
$db->set_Questions($type, $cat_id);
}
if ($action) {
$questions = $db->get_Questions($cat_id, $type);
foreach ($questions as $key => $ques) {
$ques->answer = isset($_REQUEST[$ques->key]);
$db->set_QA($cat, $ques);
}
header("Location: /ste");
}
$title_prefix = "Category Interview";
include_once 'header.inc';
?>
<div id="wrapper">
<div id="main-wrapper">
<div class="12u" id="main-content" style="overflow:scroll;">
<div class="5grid-layout 5grid" style="text-align:right;">
<div class="row">
<div class="12u">
<div style="float:left;margin-top:6px;">
<form method="post" action="interview.php">
<?php
if ($cat_id) {
print "<input type='hidden' name='cat' value='$cat_id' />";
}
else {
die("Lost access to the category");
}
?>
Type:
<select name="type" style="width:300px;" id="type" onchange="this.form.submit();">
<option> -- Select Interview Type -- </option>
<?php
foreach ($cats as $key => $cat) {
print "<option" . ($type == $cat ? " selected='true'" : "") . ">$cat</option>";
}
?>
</select>
</form>
</div>
</div>
</div>
<div style='margin-left:20%;'>
<?php
if ($type) {
$questions = $db->get_Questions($cat_id, $type);
if (is_array($questions) && count($questions)) {
?>
<form method='post' action='interview.php' id='tableContainer'>
<div style="text-align:left;">
<input type='submit' name='action' value='Save' />
</div>
<input type='hidden' name='cat' value='<?php print ($cat_id ? $cat_id : ""); ?>' />
<input type='hidden' name='type' value='<?php print ($type ? $type : ""); ?>' />
<table style='width:800px;text-align:left;'>
<thead>
<tr>
<th>Question</th>
<th>Answer</th>
</tr>
</thead>
<tbody>
<?php
$odd = true;
foreach ($questions as $key => $ques) {
$class = ($odd ? 'odd_row' : 'even_row');
$ques->question = preg_replace("/\t/", "<span style='width:20px;display:inline-block;'>&nbsp;</span>", $ques->question);
print "<tr class='$class'><td>" . nl2br($ques->question) . "</td><td><input type='checkbox' name='" . $ques->key . "'" . ($ques->answer ? " checked='true'" : '') . " value='1' /></td></tr>";
$odd = !$odd;
}
?>
</tbody>
</table>
</form>
<?php
}
}
?>
</div>
</div>
</div>
</div>
</div>
<?php
include_once 'footer.inc';

82
ste/ops-top.inc Normal file
View File

@ -0,0 +1,82 @@
<?php
/**
* File: ops-top.inc
* Author: Ryan
* Purpose: Display the ST&E selection drop down and required buttons
* Created: Sep 1, 2016
*
* Copyright 2016: Cyber Perspectives, All rights reserved
* Released under the Apache v2.0 License
*
* See license.txt for details
*
* Change Log:
* - Sep 1, 2016 - File created
* - Jan 15, 2018 - Fixed wrong action on drop-down selection
*/
include_once 'database.inc';
if (!$db) {
$db = new db();
}
if (!isset($ste_id)) {
$ste_id = filter_input(INPUT_POST, 'ste', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
if (!$ste_id) {
$ste_id = filter_input(INPUT_COOKIE, 'ste', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
}
}
$stes = $db->get_STE();
?>
<script type="text/javascript">
$(function () {
$('.button').mouseover(function () {
$(this).addClass("mouseover");
})
.mouseout(function () {
$(this).removeClass('mouseover');
});
});
</script>
<div class="row">
<div class="12u">
<div style='float: left; margin-top: 6px;'>
<form method="post" action="#">
ST&amp;E Name:
<select name='ste' style='width: 400px;' id="ste"
onchange="setCookie('ste', this.value);this.form.submit();">
<option value='0'> -- Please Select An ST&amp;E -- </option>
<?php
if (is_array($stes) && count($stes)) {
foreach ($stes as $ste) {
print "<option value='{$ste->get_ID()}'" .
($ste_id && $ste_id == $ste->get_ID() ? " selected" : "") .
">" .
"{$ste->get_System()->get_Name()}, {$ste->get_Site()->get_Name()}, {$ste->get_Eval_Start_Date()->format("d M Y")}" .
"</option>";
}
}
?>
</select>
</form>
</div>
<div style='float: right;'>
<input type='button' class='button' id='toggle_host_ip'
onclick="javascript:toggle_hostname_ip();" value='Show IP' />
<input type='button' class='button' value='Move To...'
onclick="javascript:open_move_to();" />
<input type='button' class='button' value='Add Category'
onclick="javascript:add_cat();" />
<input type='button' class='button' value='Add Host List'
onclick="javascript:upload_host_list();" />
<input type='button' class='button-delete' value='Delete Host'
onclick="javascript:delete_host();" />
</div>
</div>
</div>

149
ste/orphaned.php Normal file
View File

@ -0,0 +1,149 @@
<?php
/**
* File: orphaned.php
* Author: Ryan Prather
* Purpose: Display the findings for a particular host that are not assigned to any checklist
* Created: Jan 31, 2014
*
* Portions Copyright (c) 2012-2015, Salient Federal Solutions
* Portions Copyright (c) 2008-2011, Science Applications International Corporation (SAIC)
* Released under Modified BSD License
*
* See license.txt for details
*
* Change Log:
* - Jan 31, 2014 - File created
*/
include_once 'config.inc';
include_once 'database.inc';
include_once 'helper.inc';
$db = new db();
if (!isset($_REQUEST['tgt'])) {
print "Need to know what host you want to look at";
exit;
}
$tgt = $db->get_Target_Details($_REQUEST['ste'], $_REQUEST['tgt'])[0];
$findings = $db->get_Finding($tgt, null, null, true);
set_time_limit(0);
?>
<!DOCTYPE HTML>
<html>
<head>
<title><?php print $tgt->get_Name(); ?> - Orphan Findings</title>
<style type='text/css'>
#tooltip {
display: none;
z-index: 1000;
background-color: #FFE681;
color: #000;
font-size: 16px;
padding: 4px;
line-height: 1em;
position: absolute;
}
.hidden {
display: none;
}
</style>
<script src='../style/5grid/jquery-1.10.2.min.js'></script>
<script src='../script/default.js'></script>
<script>
function pdi_popup(pdi_id, orphan_id) {
$('#pdi_popup').attr('src', '../data/pdi.php?pdi=' + pdi_id + '&orphan=' + orphan_id);
}
</script>
</head>
<body onload='javascript:initTip();'>
<div id='tooltip'></div>
<table border=1>
<thead>
<tr>
<th>Orphan ID</th>
<th>VMS ID</th>
<th>Cat</th>
<th>IA Controls</th>
<th>Short Title</th>
<th>Possible Matches</th>
</tr>
</thead>
<tbody>
<?php
foreach ($findings as $key => $finding) {
$pdi = $db->get_PDI($finding->get_PDI_ID());
$nessus = null;
$cve = null;
$iavm = null;
$gd = $db->get_GoldDisk_By_PDI($pdi->get_ID());
$stigs = $db->get_STIG_By_PDI($pdi->get_ID());
if (!is_a($stigs, 'stig')) {
die("Can't find the STIG for PDI {$pdi->get_ID()}");
}
if (count($gd) == 1) {
$gd = $gd[0];
}
else {
$gd = null;
}
$ia = $db->get_IA_Controls_By_PDI($pdi->get_ID());
print "<tr>" . PHP_EOL .
"<td onmouseout='hideTip();' onmouseover='showTip(event, " . $pdi->get_ID() . ");'>" . $stigs->get_ID() . "<div class='hidden' id='" . $pdi->get_ID() . "'>" . nl2br($finding->get_Notes()) . "</div></td>" . PHP_EOL .
"<td>" . (!is_null($gd) ? $gd->get_ID() : '') . "</td>" . PHP_EOL .
"<td>" . $pdi->get_Category_Level_String() . "</td>" . PHP_EOL .
"<td>" . "</td>" . PHP_EOL .
"<td>" . $pdi->get_Short_Title() . "</td>" . PHP_EOL;
if (preg_match('/\d{5,6}/', $stigs->get_ID())) {
$nessus = $db->get_Nessus($stigs->get_ID());
}
elseif (preg_match('/CVE\-\d{4}\-\d{4}/', $stigs->get_ID())) {
$cve = $db->get_CVE($stigs->get_ID());
}
elseif (preg_match('/\d{4}\-[ABT]\-\d{4}/', $stigs->get_ID())) {
$iavm = $db->get_IAVM($stigs->get_ID());
}
else {
}
$matches = $db->get_Matching_PDIs($pdi, $nessus, $cve, $iavm);
print "<td>";
foreach ($matches as $key => $match) {
$short_desc = nl2br(htmlentities(substr($match['desc'], 0, 500)));
$short_cont = nl2br(htmlentities(substr($match['check_content'], 0, 1000)));
print "<div class='hidden' id='" . $match['pdi_id'] . "'>" .
$short_desc .
(strlen($match['desc']) > 500 ? " <b>(truncated)</b>" : "") . "<br />" .
$short_cont .
(strlen($match['check_content']) > 1000 ? " <b>(truncated)</b>" : "") .
"</div>";
print "<a onmouseout='hideTip();'
onmouseover='showTip(event, " . $match['pdi_id'] . ");'
href='javascript:void(0);'
onclick='javascript:pdi_popup(" . $match['pdi_id'] . ",\"" . $stigs->get_ID() . "\");'>" .
$match['pdi_id'] .
"</a> (" . $match['score'] . ") " . $match['title'] . "<br />";
}
print "</td>";
print "</tr>" . PHP_EOL;
}
?>
</tbody>
</table>
<iframe id='pdi_popup' class='box' style='width: 80%; height: 80%; top: 10%; left: 10%;'></iframe>
</body>
</html>

524
ste/stats.php Normal file
View File

@ -0,0 +1,524 @@
<?php
/**
* File: stats.php
* Author: Ryan
* Purpose: Testing page for the new target details page
* Created: Sep 1, 2016
*
* Copyright 2016: Cyber Perspectives, All rights reserved
* Released under the Apache v2.0 License
*
* See license.txt for details
*
* Change Log:
* - Sep 1, 2016 - File created
* - Jan 30, 2017 - Formatting and added popup for note updates (not complete)
* - Jan 10, 2018 - Renamed from new-ops.php to stats.php and finalized functionality
* - Jan 15, 2018 - Added notes back in (first note line) and follow-up lines in popup,
Moved Scans and Checklists column after Assessed percentage column,
Fixed error with footer not displaying
*/
$title_prefix = "Stats";
set_time_limit(0);
include_once 'config.inc';
include_once 'database.inc';
include_once 'helper.inc';
$db = new db();
$ste_id = filter_input(INPUT_POST, 'ste', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
if (!$ste_id) {
$ste_id = filter_input(INPUT_COOKIE, 'ste', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
}
$task_status = $db->get_Task_Statuses();
$cats = [];
$action = filter_input(INPUT_POST, 'action', FILTER_SANITIZE_STRING);
if ($action) {
if ($action == 'move_to') {
$sel_tgts = json_decode(html_entity_decode(filter_input(INPUT_POST, 'selected_tgts', FILTER_SANITIZE_STRING)));
$db->move_Tgt_To_Cat($sel_tgts, filter_input(INPUT_POST, 'move_to_cat', FILTER_VALIDATE_INT));
}
elseif ($action == 'save_cat') {
$existing_cat = filter_input(INPUT_POST, 'selected_cat', FILTER_VALIDATE_INT);
$new_cat_name = filter_input(INPUT_POST, 'new_cat_name', FILTER_SANITIZE_STRING);
$analyst = filter_input(INPUT_POST, 'analyst', FILTER_SANITIZE_STRING);
$cat = new ste_cat($existing_cat, $ste_id, $new_cat_name, $analyst);
$sources = filter_input(INPUT_POST, 'scan_sources', FILTER_VALIDATE_INT, FILTER_REQUIRE_ARRAY);
if (is_array($sources) && count($sources)) {
foreach ($sources as $src_id) {
$cat->add_Source($db->get_Sources($src_id));
}
}
$db->save_Category($cat);
}
elseif ($action == 'add_cat') {
$name = filter_input(INPUT_POST, 'new_cat', FILTER_SANITIZE_STRING);
$sources = filter_input(INPUT_POST, 'scan_sources', FILTER_VALIDATE_INT, FILTER_REQUIRE_ARRAY);
$ste_cat = new ste_cat(null, $ste_id, $name, null);
if (is_array($sources) && count($sources)) {
foreach ($sources as $idx => $id) {
$ste_cat->add_Source($db->get_Sources($id));
}
}
$db->save_Category($ste_cat);
}
elseif ($action == 'update_auto' || $action == 'update_manual' ||
$action == 'update_data' || $action == 'update_fp_cat1') {
$sel_tgts = json_decode(html_entity_decode(filter_input(INPUT_POST, 'selected_tgts', FILTER_SANITIZE_STRING)));
$new_status = filter_input(INPUT_POST, 'new_status', FILTER_SANITIZE_STRING);
$db->update_Task_Status($action, $sel_tgts, $new_status);
}
elseif ($action == 'assign') {
$cat_id = filter_input(INPUT_POST, 'cat_id', FILTER_VALIDATE_INT);
$analyst = filter_input(INPUT_POST, 'analyst', FILTER_SANITIZE_STRING);
$db->assign_Analyst_To_Category($cat_id, $analyst);
}
elseif ($action == 'autocat') {
$db->auto_Catorgize_Targets($ste_id);
}
elseif ($action == 'import_host_list') {
$file = filter_input(INPUT_POST, 'file', FILTER_SANITIZE_STRING, FILTER_NULL_ON_FAILURE);
if (file_exists(TMP . "/$file")) {
$fh = fopen(TMP . "/$file", "r");
$header = array_flip(array_map('strtolower', fgetcsv($fh)));
if ((isset($header['hostname']) || isset($header['name'])) && isset($header['ip']) && isset($header['os']) && isset($header['category'])) {
while ($row = fgetcsv($fh)) {
if (count($row) >= 4) {
$tgt_id = 0;
if (isset($header['name'])) {
$tgt_id = $db->check_Target($ste_id, $row[$header['name']]);
}
if (empty($tgt_id) && isset($header['hostname'])) {
$tgt_id = $db->check_Target($ste_id, $row[$header['hostname']]);
}
if (empty($tgt_id) && isset($row[$header['ip']])) {
foreach (explode(",", $row[$header['ip']]) as $ip) {
if ($tgt_id = $db->check_Target($ste_id, $ip)) {
break;
}
}
}
if (!empty($tgt_id)) {
continue;
//$tgt = $db->get_Target_Details($ste_id, $tgt_id)[0];
}
else {
$tgt = new target((isset($header['name']) ? $row[$header['name']] : $row[$header['hostname']]));
$tgt->set_STE_ID($ste_id);
}
$os_regex = $db->get_Regex_Array('os');
if (substr($row[$header['os']], 0, 7) == 'cpe:2.3') {
$os = array(0 => new software(null, $row[$header['os']]));
}
elseif (substr($row[$header['os']], 0, 3) == 'cpe') {
$os = array(0 => new software($row[$header['os']], null));
}
else {
$os = software::identify_Software($os_regex, $row[$header['os']]);
}
$os = $db->get_Software($os);
if (is_array($os) && count($os) && isset($os[0]) && is_a($os[0], 'software')) {
$tgt->set_OS_ID($os[0]->get_ID());
$tgt->set_OS_String($os[0]->get_Shortened_SW_String());
}
else {
$sw = new software("cpe:/o:generic:generic:-", "cpe:2.3:o:generic:generic:-:*:*:*:*:*:*");
$os = $db->get_Software($sw)[0];
$tgt->set_OS_ID($os->get_ID());
$tgt->set_OS_String($os->get_Shortened_SW_String());
}
foreach (explode(',', $row[$header['ip']]) as $ip) {
$tgt->interfaces[$ip] = new interfaces(null, null, null, $ip, null, $row[$header['hostname']], (isset($header['fqdn']) ? $row[$header['fqdn']] : null), null);
}
if (!empty($row[$header['category']])) {
$ste_cat = $db->get_STE_Cat_List($ste_id, $row[$header['category']]);
if (is_array($ste_cat) && count($ste_cat) && isset($ste_cat[0]) && is_a($ste_cat[0], 'ste_cat')) {
$tgt->set_Cat_ID($ste_cat[0]->get_ID());
}
else {
$ste_cat = new ste_cat(null, $ste_id, $row[$header['category']], null);
$ste_cat->set_ID($db->save_Category($ste_cat));
$tgt->set_Cat_ID($ste_cat->get_ID());
}
}
$db->save_Target($tgt);
}
}
}
fclose($fh);
unlink(TMP . "/$file");
}
}
}
if ($ste_id) {
if ($db->get_Unassigned_Targets($ste_id)) {
$unassigned = new ste_cat(0, $ste_id, 'Unassigned', null);
$db->get_Cat_Count($unassigned);
$cats[] = $unassigned;
}
$ste_cats = $db->get_STE_Cat_List($ste_id);
$cats = array_merge($cats, $ste_cats);
}
$scan_srcs = $db->get_Sources();
include_once "header.inc";
?>
<script type='text/javascript' src='/ste/ste_script.js'></script>
<script type="text/javascript">
var sel_tgts = [];
function open_echecklist(id) {
$('#echecklist').attr('src', 'echecklist_iframe.php?ste=<?php print (isset($ste) ? $ste : 0); ?>&cat=' + id);
$('#echecklist').animate({'opacity': '1.00'}, 300, 'linear');
$('#echecklist').css('display', 'block');
view_box();
}
function toggle_hostname_ip() {
$('.host').toggle();
$('.ip').toggle();
if ($('#toggle_host_ip').val() == 'Show IP')
$('#toggle_host_ip').val("Show Name");
else
$('#toggle_host_ip').val("Show IP");
}
function delete_host() {
if (!confirm("Are you sure you want to delete the selected target(s)")) {
return;
}
$.ajax('/ajax.php', {
data: {
action: 'delete-host',
selected_tgts: JSON.stringify(sel_tgts)
},
success: function (data) {
if (data.error) {
alert(data.error);
}
else if (data.success) {
$('.tgt-sel:checked').parent().parent().slideUp(500);
$('.tgt-sel:checked').parent().parent().remove();
}
},
error: function (xhr, status, error) {
console.error(error);
},
timeout: 5000,
method: 'post',
dataType: 'json'
});
}
$(function () {
$('.button,.button-delete').on('mouseover', function () {
$(this).addClass('mouseover');
});
$('.button,.button-delete').on('mouseout', function () {
$(this).removeClass('mouseover');
});
});
</script>
<style type='text/css'>
.name, .os {
width: 122px;
padding: 0 3px;
}
.scans, .checklists {
width: 135px;
text-align: center;
}
.cat1, .cat2, .cat3, .nf, .na, .nr {
width: 40px;
}
.comp, .assessed {
width: 50px;
text-align: center;
}
.note {
width: 346px;
}
#wrapper, #main-content {
overflow: auto;
}
.title {
width: 1179px;
background-color: #808080;
font-size: 14pt;
font-weight: bolder;
font-style: italic;
text-align: left;
padding-left: 20px;
color: black;
margin-top: 5px;
border: solid 1px black;
}
.data-row {
display: inline-block;
vertical-align: top;
margin: 5px;
}
#cat-filter {
height: 118px;
border: solid 1px black;
text-align: left;
}
.ip {
display: none;
}
.header {
display: table-cell;
background-color: #31363C;
color: #fff;
}
.left_cat_header span {
text-align: center;
min-width: 25px;
display: inline-block;
padding: 0 3px;
}
.right_cat_header {
width: 200px;
float: right;
}
.cat_icons {
background-size: 20px 20px;
vertical-align: middle;
width: 20px;
height: 20px;
padding-right: 2px;
}
.checklist_image {
width: 32px;
vertical-align: middle;
}
#waiting {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background: #000;
opacity: 0.0;
filter: alpha(opacity=0);
z-index: 1000;
display: none;
}
#loading {
display: none;
}
.ui-tooltip {
width: 500px;
font-size: 10pt;
}
.target-notes {
padding: 0 5px;
}
</style>
<div id='wrapper'>
<div id='main-wrapper'>
<div class='12u' id='main-content'>
<div class="5grid-layout" style="text-align: right;">
<?php include_once 'ops-top.inc'; ?>
<div id='target-header'>
<div class='table-header' style='border: 0;'>
<span class='header name' style='text-align:left'>Name</span>
<span class='header os' style='line-height:1.25em;'>OS</span>
<span class='header cat1' title="Category I Findings">I</span>
<span class='header cat2' title="Category II Findings">II</span>
<span class='header cat3' ttile="Category III Findings">III</span>
<span class='header nf' title="Not a Finding">NF</span>
<span class='header na' title="Not Applicable">NA</span>
<span class='header nr' title="Not Reviewed">NR</span>
<span class='header comp' title="Compliant Percentage (NF + NA) / (total - NR)">C</span>
<span class='header assessed' title="Assessed Percentage (total - NR) / total">A</span>
<span class='header scans'>Scans</span>
<span class='header checklists'>Checklists</span>
<span class='header note'>Notes</span>
</div>
</div>
<?php
if (count($cats)) {
foreach ($cats as $cat) {
print $cat->getSTECatRow();
}
}
else {
print "<div style='text-align:center;font-size:18pt;'>No ST&amp;E selected</div>";
}
?>
</div>
</div>
</div>
</div>
<div class="backdrop"></div>
<div id='tgt-notes' class="box">
<input type='hidden' id='tgt-id' />
<textarea id='notes' style='width:100%;height:75%;'></textarea>
<input type='button' id='save-tgt-notes' value='Save' />
</div>
<div id="move_to" class="box">
<form method="post" action="#">
<input type='hidden' name='selected_tgts' id='move_selected_tgts' />
<input type='hidden' name='action' value='move_to' />
<input type='hidden' name='ste' id='move_ste' value='<?php print (isset($ste_id) ? $ste_id : ''); ?>' />
Move to category:
<select name='move_to_cat' onchange="$('#move_selected_tgts').val(JSON.stringify(sel_tgts));
this.form.submit();">
<option value=''>-- Select Category --</option>
<?php
if (is_array($cats) && count($cats)) {
foreach ($cats as $cat) {
print "<option value='{$cat->get_ID()}'>{$cat->get_Name()}</option>";
}
}
?>
</select>
</form>
</div>
<div id="edit_cat" class="box">
<form method="post" action="#">
<input type="hidden" name="selected_cat" id="selected_cat" />
<input type="hidden" name="action" value="save_cat" />
New Name: <input type="text" name="new_cat_name" id="new_cat_name" /><br />
Analyst: <input type='text' name='analyst' id='analyst' /><br />
<select name='scan_sources[]' id="scan_sources" multiple size='8'>
<?php
if (is_array($scan_srcs) && count($scan_srcs)) {
foreach ($scan_srcs as $src) {
print "<option id='src_{$src->get_ID()}' value='{$src->get_ID()}'>{$src->get_Name()}</option>";
}
}
?>
</select><br />
<input type="submit" name="submit" value="Update Category" />
</form>
</div>
<div id="add_cat" class="box">
<form method="post" action="#">
<input type='hidden' name='action' value='add_cat' />
<input type='hidden' name='ste' id='add_ste' value='' />
Category Name: <input type='text' name='new_cat' value='' /><br />
<select name='scan_sources[]' multiple size='8'>
<?php
if (is_array($scan_srcs) && count($scan_srcs)) {
foreach ($scan_srcs as $src) {
print "<option value='{$src->get_ID()}'>{$src->get_Name()}</option>";
}
}
?>
</select><br />
<input type='submit' name='submit' value='Add Category' />
</form>
</div>
<div id="import_host_list" class="box">
<script type="text/javascript" src="/script/dropzone/dropzone.min.js"></script>
<link type="text/css" href="/script/dropzone/dropzone.min.css" rel="stylesheet" />
<link type="text/css" href="/script/dropzone/basic.min.css" rel="stylesheet" />
<script type="text/javascript">
Dropzone.options.dropzone = {
maxFilesize: 10,
success: function (file, res) {
},
error: function (xhr, status, error) {
console.error(xhr);
console.error(error);
},
acceptedFiles: ".csv"
};
Dropzone.prototype.submitRequest = function (xhr, formData, files) {
$('#host-list-file').val(files[0].name);
var dt = new Date(files[0].lastModifiedDate);
xhr.setRequestHeader('X-FILENAME', files[0].name);
xhr.setRequestHeader('X-FILEMTIME', dt.toISOString());
return xhr.send(formData);
};
Dropzone.autoDiscover = false;
$(function () {
var mydz = new Dropzone('#dropzone');
});
</script>
<form class="dropzone" action="/upload.php" id="dropzone">
<div class="fallback">
<input type="file" name="file" multiple />
</div>
</form>
<form method='post' action='#' style='margin-left: 20px;'
onsubmit="$('#submit').attr('disabled', true);return true;">
<input type='hidden' name='file' id='host-list-file' style='display:none;' />
<input type='hidden' name='action' value='import_host_list' />
<input type='hidden' name='ste' value='<?php print ($ste_id ? $ste_id : ''); ?>' />
<input type='submit' name='submit' id='submit' value='Import Host List' />
</form>
</div>
<div id="add_import" class="box">
<div style='margin-left: 20px;'>
<input type='text' id='location' placeholder='Physical Location...' /><br />
<input type='button' id='add-scan' value='Add Scan Result' onclick='add_scans();' /><br />
<label for='ignore_hidden' id='ignore_label'>Ignore Hidden Tabs in Excel eChecklists</label>
<input type='checkbox' name='ignore_hidden' id='ignore_hidden' value='1' checked />
</div>
</div>
<iframe id='echecklist' class='box' style='width: 80%; height: 80%; top: 10%; left: 10%;'> </iframe>
<div id="waiting"></div>
<div id="loading"></div>
<?php
include_once 'footer.inc';

631
ste/ste_script.js Normal file
View File

@ -0,0 +1,631 @@
/**
* File: ste_script.js
* Author: Ryan Prather
* Purpose: To store all JavaScript for use by any script in this directory
* Created: ?
*
* Portions Copyright 2016-2017: Cyber Perspectives LLC, All rights reserved
* Released under the Apache v2.0 License
*
* Portions Copyright (c) 2012-2015, Salient Federal Solutions
* Portions Copyright (c) 2008-2011, Science Applications International Corporation (SAIC)
* Released under Modified BSD License
*
* See license.txt for details
*
* Change Log:
* - ? - File created
* - Sep 1, 2016 - Updated copyright and added other functionality
* - Oct 24, 2016 - Updated get_hosts and display_hosts function to use JSON instead of XML
* - Nov 21, 2016 - Removed timeout for retrieving hosts from a category and added spinner
* - Jan 30, 2017 - Formatting, added auto-categorization AJAX
* - Feb 15, 2017 - Removed style tag for 0 border around targets after retrieving from DB
* - Mar 4, 2017 - Changed AJAX to use /ajax.php instead of /cgi-bin/ajax.php
* - Apr 6, 2017 - Updating edit_cat code to simplify UI
* - Apr 7, 2017 - Finished edit category functionality
* - May 13, 2017 - Added export_ckl method to export CKL files from category header or target details page
* - May 19, 2017 - Simplified target selection code
* - May 26, 2017 - Added supporting code to delete target from category after clicking "Delete Host", also specified location where CKL files are placed upon export.
* - Jan 10, 2018 - Added new methods for /ste/stats.php and cleaned up
* - Jan 15, 2018 - Moved colums around, added target notes,
Added getColorForPercentage method for sliding color scale
*/
/**
*
*/
var opts = {
lines: 15,
length: 18,
width: 9,
radius: 61,
scale: 2,
corners: 1,
color: '#000',
opacity: 0.2,
rotate: 13,
direction: 1,
speed: 0.5,
trail: 50,
fps: 20,
zIndex: 2e9,
className: 'spinner',
top: '50%',
left: '50%',
shadow: false,
hwaccel: false,
position: 'absolute'
};
var sel_tgts = [];
/**
* Perform a couple checks onces the page completely loads
*/
$(function () {
var target = document.getElementById('loading');
var spinner = new Spinner(opts).spin(target);
$('.close, .backdrop').click(function () {
close_box();
});
$('.notes').click(function () {
$(this).siblings('span').show();
});
$('.toggler').click(collapse_expand);
$('.target-notes').click(get_target_notes);
$('#save-tgt-notes').click(save_target_notes);
});
/**
* Function to update a hidden element with the ID's of the selected targets
*
* @param chk
*/
function update_tgt_chk(chk) {
if ($(chk).is(':checked'))
sel_tgts.push($(chk).val());
else {
sel_tgts.splice($.inArray($(chk).val(), sel_tgts), 1);
}
}
/**
* Open the move to popup
*/
function open_move_to() {
if ($('#ste').val() < 1) {
alert("Please select an ST&E");
return;
}
if ($(":checkbox:checked").length < 1) {
alert("Please select a device to move");
return;
}
$('#move_to').animate({
'opacity': '1.00'
}, 300, 'linear');
$('#move_to').css('display', 'block');
view_box();
}
/**
* Function to open the edit category lightbox
*
* @param {number} cat_id
*/
function edit_cat(cat_id) {
if ($('#ste').val() < 1) {
alert("Please select an ST&E");
return;
}
for (var x in $('#scan_sources option')) {
$('#scan_sources option').eq(x).attr('selected', false);
}
var cat_name = $('#cat_name_' + cat_id).text();
var matches = cat_name.match(/\s+\(([\d]+)\)\s+\(([^\d][ \w]+)\)|\s+\(([\d]+)\)/i);
cat_name = cat_name.replace(/\s+\(([\d]+)\)\s+\(([^\d][ \w]+)\)|\s+\(([\d]+)\)/i, '');
$('#new_cat_name').val(cat_name);
$('#selected_cat').val(cat_id);
if (matches && typeof matches[2] !== 'undefined')
$('#analyst').val(matches[2]);
else
$('#analyst').val('');
var srcs = JSON.parse($('#cat_sources_' + cat_id).val());
for (var x in srcs) {
$('#src_' + srcs[x]).attr('selected', true);
}
$('#edit_cat').animate({
'opacity': '1.00'
}, 300, 'linear');
$('#edit_cat').css('display', 'block');
view_box();
}
/**
*
*/
function merge_target() {
$('#merge_target').animate({
'opacity': '1.00'
}, 300, 'linear');
$('#merge_target').css('display', 'block');
view_box();
}
/**
* Open the delete category popup
*
* @param id
*/
function delete_cat(id) {
if ($('#ste').val() < 1) {
alert("Please select an ST&E");
return;
}
if (!confirm("Are you sure you want to delete this category? Currently assigned targets will be set to the 'Unassigned' category.")) {
return;
}
$.ajax('/ajax.php', {
data: {
action: 'delete-cat',
ste_id: $('#ste').val(),
cat_id: id
},
success: function (data) {
if (data.error) {
alert(data.error);
}
else {
alert(data.success);
location.reload();
}
},
error: function (xhr, status, error) {
console.error(error);
},
dataType: 'json',
method: 'post',
timeout: 3000
});
}
function del_target() {
if (!confirm("Are you sure you want to delete the target? This will also delete all findings and interfaces for the selected targets and is irreversible")) {
return;
}
}
/**
* Open the add category popup
*/
function add_cat() {
if ($('#ste').val() < 1) {
alert("Please select an ST&E");
return;
}
$('#add_ste').val($('#ste').val());
$('#add_cat').animate({
'opacity': '1.00'
}, 300, 'linear');
$('#add_cat').css('display', 'block');
view_box();
}
/**
* Function to get category data from database
*
* @param cat_id
*/
function get_category(cat_id) {
$.ajax('/ajax.php', {
data: {
action: 'get_category_details',
'cat_id': cat_id
},
success: function (data) {
$('#new_cat_name').val(data.name);
for (var x in data.sources) {
$('#src_' + data.sources[x].id).attr('selected', true);
}
},
datatype: 'json',
method: 'post'
});
}
/**
* Reset the backdrop and visible boxes
*/
function close_box() {
$('.backdrop, .box').animate({
'opacity': '0'
}, 300, 'linear', function () {
$('.backdrop, .box').css('display', 'none');
});
}
/**
* Set the backdrop so it's visible
*/
function view_box() {
$('.backdrop').animate({
'opacity': '.5'
}, 300, 'linear');
$('.backdrop').css('display', 'block');
}
/**
* Function to validate that targets were selected
*
* @param chk
* @returns {Boolean}
*/
function update_Status(chk) {
if ($(chk).val() < 1)
return false;
if ($(":checkbox:checked").length < 1) {
alert("Please select a device to update");
return false;
}
return true;
}
/**
* Function to collapse or expand the category group
*/
function collapse_expand() {
var id = $(this).data('id');
if ($('#cat_' + id + '_dl').val() == '0') {
if (location.href.match(/\/ste\/$|index\.php/)) {
get_hosts(id);
}
else {
get_new_hosts(id);
}
}
$(this).toggleClass('fa-minus-square fa-plus-square');
$('.cat_' + id).toggle(300);
}
/**
* Function triggered when a target checkbox is clicked
*
* @param id
*/
function select(id) {
$('.cat_' + id + ' input[type=checkbox]').each(function () {
this.checked = !this.checked;
update_tgt_chk(this);
});
}
/**
* Function to prompt the user for the analyst to assign to a category
*
* @param id
*/
function assign(id) {
var analyst = prompt('Who do you want to assign this category to?\n\nEnter "none" to clear out assignment');
if (analyst) {
$('#analyst_' + id).val(analyst);
$('#assign_' + id).submit();
}
}
/**
* Function to upload a host list file
*/
function upload_host_list() {
if ($('#ste').val() < 1) {
alert("Please select an ST&E");
return;
}
$('#import_host_list').animate({
'opacity': '1.00'
}, 300, 'linear');
$('#import_host_list').css('display', 'block');
view_box();
}
/**
* Function to retrieve the hosts within a specific category
*
* @param cat_id
*/
function get_hosts(cat_id) {
$.ajax('/ajax.php', {
data: {
action: 'get_hosts',
'cat_id': cat_id
},
beforeSend: function () {
$('#loading,#waiting').show();
$('#waiting').animate({'opacity': '0.5'}, 300, 'linear');
},
success: display_hosts,
error: function (xhr, status, error) {
console.error(error);
},
complete: function () {
$('#loading,#waiting').hide();
$('#waiting').animate({'opacity': '0'}, 300, 'linear');
},
dataType: 'json',
method: 'post'
});
}
/**
*
* @param {type} id
* @returns {undefined}
*/
function get_new_hosts(id) {
$.ajax('/ajax.php', {
data: {
action: 'new-get-hosts',
'cat-id': id
},
beforeSend: function () {
$('#loading,#waiting').show();
$('#waiting').animate({'opacity': '0.5'}, 300, 'linear');
},
success: function (data) {
if (data.error) {
console.error(data.error);
}
else {
var cat_id = data.cat_id;
var cat = $('#cat_' + cat_id);
var odd = true;
for (var x in data.targets) {
$(cat).after(
"<div class='" + (odd ? "odd_row" : "even_row") + " cat_" + cat_id + "'>" +
"<span class='cat-cell name' style='text-align:left'>" +
"<input type='checkbox' class='tgt-sel' value='" + data.targets[x].id + "' onclick='javascript:update_tgt_chk(this);' />" +
"<a href='target.php?ste=" + data.targets[x].ste_id + "&tgt=" + data.targets[x].id + "' class='host' target='_blank'>" + data.targets[x].name + "</a>" +
"<a href='target.php?ste=" + data.targets[x].ste_id + "&tgt=" + data.targets[x].id + "' class='ip' target='_blank'>" + data.targets[x].ip + "</a>" +
"</span>" +
"<span class='cat-cell os' style='line-height:1.25em;'>" + data.targets[x].os + "</span>" +
"<span class='cat-cell cat1 cat_I' title='Cat I Findings' style='text-align:center;'>" + data.targets[x].cat_1 + "</span>" +
"<span class='cat-cell cat2 cat_II' title='Cat II Findings' style='text-align:center;'>" + data.targets[x].cat_2 + "</span>" +
"<span class='cat-cell cat3 cat_III' title='Cat III Findings' style='text-align:center;'>" + data.targets[x].cat_3 + "</span>" +
"<span class='cat-cell nf' title='Not a Finding' style='text-align:center;'>" + data.targets[x].nf + "</span>" +
"<span class='cat-cell na' title='Not Applicable' style='text-align:center;'>" + data.targets[x].na + "</span>" +
"<span class='cat-cell nr' title='Not Reviewed' style='text-align:center;'>" + data.targets[x].nr + "</span>" +
"<span class='cat-cell comp' title='Percentage Compliant' style='text-align:center;background-color: " +
getColorForPercentage(data.targets[x].comp)+ ";'>" + (data.targets[x].comp.toFixed(2) * 100) + "%</span>" +
"<span class='cat-cell assessed' title='Percentage Assessed' style='text-align:center;background-color: " +
getColorForPercentage(data.targets[x].assessed) + ";'>" + (data.targets[x].assessed.toFixed(2) * 100) + "%</span>" +
"<span class='cat-cell scans'>" +
(data.targets[x].scans ? data.targets[x].scans : "&nbsp;") +
"</span>" +
"<span class='cat-cell checklists'>" +
(data.targets[x].chk ? data.targets[x].chk : "&nbsp;") +
"</span>" +
"<span class='cat-cell note'>" + data.targets[x].notes +
"<i class='fas target-notes fa-pen-square' data-id='" + data.targets[x].id + "'> </i>" +
"</span>" +
"</div>"
);
odd = !odd;
}
$('#cat_' + cat_id + '_dl').val(1);
$('.target-notes').click(get_target_notes);
$('.fa-ellipsis-h').tooltip({
classes: {
'ui-tooltip': 'highlight'
}
});
}
},
error: function (xhr, status, error) {
console.error(error);
},
complete: function () {
$('#loading,#waiting').hide();
$('#waiting').animate({'opacity': '0'}, 300, 'linear');
},
dataType: 'json',
method: 'post'
});
}
function get_target_notes() {
var id = $(this).data('id');
$('#tgt-id').val(id);
$.ajax('/ajax.php', {
data: {
action: 'get-target-notes',
'tgt-id': id
},
success: function (data) {
if (data.error) {
alert(data.error);
}
else {
$('#notes').val(data.notes);
view_box();
}
$('#tgt-notes').animate({
'opacity': '1.00'
}, 300, 'linear');
$('#tgt-notes').css('display', 'block');
},
error: function (xhr, status, error) {
console.error(error);
},
dataType: 'json',
method: 'post'
});
}
function save_target_notes() {
$.ajax('/ajax.php', {
data: {
action: 'save-target-notes',
'tgt-id': $('#tgt-id').val(),
'notes': $('#notes').val()
},
success: function (data) {
if (data.error) {
alert(data.error);
}
else {
alert(data.success);
close_box();
}
},
error: function (xhr, status, error) {
console.error(error);
},
dataType: 'json',
method: 'post'
});
}
/**
* Function to display retrieved hosts from AJAX call
*
* @param data
*/
function display_hosts(data) {
var cat_id = data.cat_id;
var cat = $('#cat_' + cat_id);
var odd = true;
for (var x in data.targets) {
$(cat).after(
"<div class='" + (odd ? "odd_row" : "even_row") + " cat_" + cat_id + "'>" +
"<span class='cat-cell' style='width:102px;text-align:left'>" +
"<input type='checkbox' class='tgt-sel' value='" + data.targets[x].id + "' onclick='javascript:update_tgt_chk(this);' />" +
"<a href='target.php?ste=" + data.targets[x].ste_id + "&tgt=" + data.targets[x].id + "' class='host' target='_blank'>" + data.targets[x].name + "</a>" +
"<a href='target.php?ste=" + data.targets[x].ste_id + "&tgt=" + data.targets[x].id + "' class='ip' target='_blank'>" + data.targets[x].ip + "</a>" +
"</span>" +
"<span class='cat-cell' style='width:104px;line-height:1.25em;'>" + data.targets[x].os + "</span>" +
"<span class='cat-cell' style='width:102px;'>" +
(data.targets[x].location ? data.targets[x].location : "&nbsp;") +
"</span>" +
"<span class='cat-cell task-" + data.targets[x].auto.toLowerCase() + "' style='width:63px;text-align:center;'>" + data.targets[x].auto + "</span>" +
"<span class='cat-cell task-" + data.targets[x].man.toLowerCase() + "' style='width:63px;text-align:center;'>" + data.targets[x].man + "</span>" +
"<span class='cat-cell task-" + data.targets[x].data.toLowerCase() + "' style='width:63px;text-align:center;'>" + data.targets[x].data + "</span>" +
"<span class='cat-cell task-" + data.targets[x].fp.toLowerCase() + "' style='width:63px;text-align:center;'>" + data.targets[x].fp + "</span>" +
"<span class='cat-cell' style='width:147px;'>" +
(data.targets[x].scans ? data.targets[x].scans : "&nbsp;") +
"</span>" +
"<span class='cat-cell' style='width:147px;'>" +
(data.targets[x].chk ? data.targets[x].chk : "&nbsp;") +
"</span>" +
"<span class='cat-cell' style='width:346px;'>" +
(data.targets[x].notes ? data.targets[x].notes : "&nbsp;") +
"</span>" +
"</div>"
);
odd = !odd;
}
$('#cat_' + cat_id + '_dl').val(1);
}
/**
* Function to make AJAX call for system to autocategorize targets based on OS
*/
function auto_cat() {
$.ajax('/ajax.php', {
data: {
ste: $('#ste').val(),
action: 'auto-categorize'
},
beforeSend: function () {
$('#loading,#waiting').show();
$('#waiting').animate({'opacity': '0.5'}, 300, 'linear');
},
success: function (data) {
location.reload();
},
error: function (xhr, status, error) {
console.error(error);
},
complete: function () {
$('#loading,#waiting').hide();
$('#waiting').animate({'opacity': '0'}, 300, 'linear');
},
dataType: 'json',
timeout: 5000,
method: 'post'
});
}
function export_ckl(cat_id, tgt_id) {
if (!cat_id) {
$.ajax('/ajax.php', {
data: {
ste: $('#ste').val(),
tgt: tgt_id,
action: 'export-ckl'
},
complete: function (xhr) {
alert("Exporting target CKL files to document_root/tmp/ckl");
},
method: 'post'
});
}
else {
$.ajax('/ajax.php', {
data: {
ste: $('#ste').val(),
cat: cat_id,
action: 'export-ckl'
},
complete: function (xhr) {
alert('Exporting CKL files to document_root/tmp/ckl');
},
method: 'post'
});
}
}
// Mister @Jacob's Anwser
var percentColors = [
{ pct: 0.0, color: { r: 0xff, g: 0x00, b: 0 } },
{ pct: 0.5, color: { r: 0xff, g: 0xff, b: 0 } },
{ pct: 1.0, color: { r: 0x00, g: 0xff, b: 0 } } ];
var getColorForPercentage = function(pct) {
for (var i = 1; i < percentColors.length - 1; i++) {
if (pct < percentColors[i].pct) {
break;
}
}
var lower = percentColors[i - 1];
var upper = percentColors[i];
var range = upper.pct - lower.pct;
var rangePct = (pct - lower.pct) / range;
var pctLower = 1 - rangePct;
var pctUpper = rangePct;
var color = {
r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper),
g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper),
b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper)
};
return 'rgb(' + [color.r, color.g, color.b].join(',') + ')';
// or output as hex if preferred
}

1136
ste/target.php Normal file

File diff suppressed because it is too large Load Diff