Compare commits
23 Commits
04b6b7e4fe
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 556f377d20 | |||
| b65abf1f6a | |||
| 46a95ff5a4 | |||
| c128870b93 | |||
| 34275b0287 | |||
| 0b3a7114a0 | |||
| aff7154458 | |||
| 72343063cd | |||
| 502b1a241e | |||
| 4bb232c3ce | |||
| fd6123e72c | |||
| a177bec498 | |||
| 5f2cb0d8e0 | |||
| b63e2b61ec | |||
| 20a7eeb659 | |||
| 4788ac1685 | |||
| c47cbeef38 | |||
| 6b38c46be9 | |||
| 85d4df513b | |||
| a60609600f | |||
| 00138d1ed0 | |||
| 0e54866e46 | |||
| e0b6f6bac8 |
@@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
Appliances used to build GNS3 labs.
|
Appliances used to build GNS3 labs.
|
||||||
|
|
||||||
This images are freely inspired from [Chewie's](https://github.com/Chewie/gns3-docker-appliances) ones
|
These images are freely inspired from [Chewie's](https://github.com/Chewie/gns3-docker-appliances) ones
|
||||||
7
beautiful_vuln_rfi/Dockerfile
Normal file
7
beautiful_vuln_rfi/Dockerfile
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
FROM php:8-apache-bullseye
|
||||||
|
COPY src /var/www/html
|
||||||
|
RUN mkdir /hidden_server
|
||||||
|
COPY hidden_server /hidden_server
|
||||||
|
COPY docker/start.sh /start.sh
|
||||||
|
EXPOSE 80
|
||||||
|
ENTRYPOINT ["/start.sh"]
|
||||||
8
beautiful_vuln_rfi/README.md
Normal file
8
beautiful_vuln_rfi/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Unsafe gallery challenge
|
||||||
|
You need to set the `FLAG` environment variable for this challenge to work!
|
||||||
|
|
||||||
|
|
||||||
|
## Run the image
|
||||||
|
```bash
|
||||||
|
docker run --rm --name beautiful_rfi --env FLAG='FLAG{UNSAFE_RFI}' -p 3578:80 -it pierre42100/gns3-appliance-beautiful-vuln-rfi
|
||||||
|
```
|
||||||
1
beautiful_vuln_rfi/build.sh
Normal file
1
beautiful_vuln_rfi/build.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
sudo docker build -t pierre42100/gns3-appliance-beautiful-vuln-rfi .
|
||||||
10
beautiful_vuln_rfi/docker/start.sh
Normal file
10
beautiful_vuln_rfi/docker/start.sh
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
echo Start hidden server
|
||||||
|
cd /hidden_server/
|
||||||
|
php -S 127.0.0.1:4567 &
|
||||||
|
|
||||||
|
cd
|
||||||
|
|
||||||
|
echo Run main server
|
||||||
|
docker-php-entrypoint apache2-foreground
|
||||||
2
beautiful_vuln_rfi/hidden_server/index.php
Normal file
2
beautiful_vuln_rfi/hidden_server/index.php
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<?php
|
||||||
|
echo getenv("FLAG");
|
||||||
1
beautiful_vuln_rfi/src/about.txt
Normal file
1
beautiful_vuln_rfi/src/about.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
I am an old and accustomed developer who wrote too much source code in his life...
|
||||||
7
beautiful_vuln_rfi/src/bootstrap.bundle.min.js
vendored
Normal file
7
beautiful_vuln_rfi/src/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
12
beautiful_vuln_rfi/src/bootstrap.min.css
vendored
Normal file
12
beautiful_vuln_rfi/src/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
3
beautiful_vuln_rfi/src/home.txt
Normal file
3
beautiful_vuln_rfi/src/home.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Welcome to this strong and almost secure website!
|
||||||
|
|
||||||
|
Please use the menu below to access the different parts of the application...
|
||||||
58
beautiful_vuln_rfi/src/index.php
Normal file
58
beautiful_vuln_rfi/src/index.php
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* My home page
|
||||||
|
*/
|
||||||
|
|
||||||
|
$page = "home.txt";
|
||||||
|
|
||||||
|
if (isset($_GET["page"]))
|
||||||
|
$page = $_GET["page"];
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><?= $page ?> - Beautiful RFI</title>
|
||||||
|
<link rel="stylesheet" href="/bootstrap.min.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-expand-lg bg-dark" data-bs-theme="dark">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a class="navbar-brand" href="/">Beautiful VULN RFI</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor02"
|
||||||
|
aria-controls="navbarColor02" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarColor02">
|
||||||
|
<ul class="navbar-nav me-auto">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link <?= $page === "home.txt" ? "active" : "" ?>" href="/?page=home.txt">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link <?= $page === "about.txt" ? "active" : "" ?>" href="/?page=about.txt">About</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link <?= $page === "privacy.txt" ? "active" : "" ?>" href="/?page=privacy.txt">Privacy</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<h1 class="display-4 fw-normal text-body-emphasis" style="color: white !important; text-align: center;">
|
||||||
|
<?= str_replace(".txt", "", $page) ?>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<pre style="max-width: 700px; margin: auto;">
|
||||||
|
<?php echo file_get_contents($page); ?>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<script src="/bootstrap.bundle.min.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
1
beautiful_vuln_rfi/src/privacy.txt
Normal file
1
beautiful_vuln_rfi/src/privacy.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Privacy policy: TODO
|
||||||
11
countries_list/Dockerfile
Normal file
11
countries_list/Dockerfile
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
FROM php:8.3-apache
|
||||||
|
COPY src/ /var/www/html/
|
||||||
|
|
||||||
|
ENV FLAG=CHANGEME
|
||||||
|
|
||||||
|
COPY docker/start.sh /start.sh
|
||||||
|
COPY docker/add_flag.php /add_flag.php
|
||||||
|
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
ENTRYPOINT ["/start.sh"]
|
||||||
8
countries_list/README.md
Normal file
8
countries_list/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Unsafe login challenge
|
||||||
|
You need to set the `FLAG` environment variable for this challenge to work!
|
||||||
|
|
||||||
|
|
||||||
|
## Run the image
|
||||||
|
```bash
|
||||||
|
docker run --rm --name countries_list --env FLAG='FLAG{SQLIMYFRIENDAGAIN}' -p 3767:80 -it pierre42100/countries-list
|
||||||
|
```
|
||||||
1
countries_list/build.sh
Normal file
1
countries_list/build.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
sudo docker build -t pierre42100/countries-list .
|
||||||
12
countries_list/docker/add_flag.php
Normal file
12
countries_list/docker/add_flag.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// First, connect to database
|
||||||
|
try {
|
||||||
|
$db = new PDO('sqlite:/var/www/html/database.db');
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo 'Connection to database failed: ' . $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$stmt = $db->prepare("INSERT INTO secret (flag) VALUES (?)");
|
||||||
|
$stmt->execute(array(getenv("FLAG")));
|
||||||
7
countries_list/docker/start.sh
Normal file
7
countries_list/docker/start.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
echo Add flag to database
|
||||||
|
php /add_flag.php
|
||||||
|
|
||||||
|
echo Run main server
|
||||||
|
docker-php-entrypoint apache2-foreground
|
||||||
3
countries_list/src/.htaccess
Normal file
3
countries_list/src/.htaccess
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<Files ~ "(.db)">
|
||||||
|
Require all denied
|
||||||
|
</Files>
|
||||||
6
countries_list/src/bootstrap.min.css
vendored
Normal file
6
countries_list/src/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
countries_list/src/database.db
Normal file
BIN
countries_list/src/database.db
Normal file
Binary file not shown.
68
countries_list/src/index.php
Normal file
68
countries_list/src/index.php
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// First, connect to database
|
||||||
|
try {
|
||||||
|
$db = new PDO('sqlite:' . __DIR__ . '/database.db');
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo 'Connection to database failed: ' . $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
$filter = isset($_GET["filter"]) ? $_GET["filter"] : "";
|
||||||
|
|
||||||
|
// Get the list of countries
|
||||||
|
$query = "SELECT * FROM countries_list WHERE full_name LIKE '%$filter%'";
|
||||||
|
$stmt = $db->prepare($query);
|
||||||
|
$stmt->execute(array());
|
||||||
|
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
?><!doctype html>
|
||||||
|
<html lang="en" data-bs-theme="auto">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Countries list</title>
|
||||||
|
|
||||||
|
<link href="/bootstrap.min.css" rel="stylesheet"
|
||||||
|
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||||
|
<link href="/style.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="d-flex align-items-center py-4 bg-body-tertiary">
|
||||||
|
<main class="form-signin w-100 m-auto">
|
||||||
|
|
||||||
|
<h1>Countries list</h1>
|
||||||
|
|
||||||
|
<form action="/" method="get" style="margin: 30px 0px">
|
||||||
|
<div class="input-group flex-nowrap">
|
||||||
|
<span class="input-group-text" id="addon-wrapping">Filter by full name</span>
|
||||||
|
<input type="text" class="form-control" placeholder="Filter list by full name" aria-label="Filter by full name"
|
||||||
|
aria-describedby="addon-wrapping" value="<?=$filter?>" name="filter" />
|
||||||
|
<button class="btn btn-outline-secondary" type="submit" id="button-addon2">Filter</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">Full name</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
foreach ($results as $row) {
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<th scope="row"><?= $row["code"] ?></th>
|
||||||
|
<td colspan="2"><?= $row["full_name"] ?></td>
|
||||||
|
</tr><?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
102
countries_list/src/style.css
Normal file
102
countries_list/src/style.css
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin {
|
||||||
|
max-width: 800px;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin .form-floating:focus-within {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin input[type="email"] {
|
||||||
|
margin-bottom: -1px;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin input[type="password"] {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-placeholder-img {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
text-anchor: middle;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.bd-placeholder-img-lg {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.b-example-divider {
|
||||||
|
width: 100%;
|
||||||
|
height: 3rem;
|
||||||
|
background-color: rgba(0, 0, 0, .1);
|
||||||
|
border: solid rgba(0, 0, 0, .15);
|
||||||
|
border-width: 1px 0;
|
||||||
|
box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.b-example-vr {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bi {
|
||||||
|
vertical-align: -.125em;
|
||||||
|
fill: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-scroller {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
height: 2.75rem;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-scroller .nav {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
margin-top: -1px;
|
||||||
|
overflow-x: auto;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-bd-primary {
|
||||||
|
--bd-violet-bg: #712cf9;
|
||||||
|
--bd-violet-rgb: 112.520718, 44.062154, 249.437846;
|
||||||
|
|
||||||
|
--bs-btn-font-weight: 600;
|
||||||
|
--bs-btn-color: var(--bs-white);
|
||||||
|
--bs-btn-bg: var(--bd-violet-bg);
|
||||||
|
--bs-btn-border-color: var(--bd-violet-bg);
|
||||||
|
--bs-btn-hover-color: var(--bs-white);
|
||||||
|
--bs-btn-hover-bg: #6528e0;
|
||||||
|
--bs-btn-hover-border-color: #6528e0;
|
||||||
|
--bs-btn-focus-shadow-rgb: var(--bd-violet-rgb);
|
||||||
|
--bs-btn-active-color: var(--bs-btn-hover-color);
|
||||||
|
--bs-btn-active-bg: #5a23c8;
|
||||||
|
--bs-btn-active-border-color: #5a23c8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-mode-toggle {
|
||||||
|
z-index: 1500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-mode-toggle .dropdown-menu .active .bi {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
26
dns/Dockerfile
Normal file
26
dns/Dockerfile
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
FROM ubuntu:24.04
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y \
|
||||||
|
bind9 \
|
||||||
|
vim \
|
||||||
|
nano \
|
||||||
|
dnsutils \
|
||||||
|
tcpdump \
|
||||||
|
traceroute \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN sed 's/include "\/etc\/bind\/named.conf.default-zones";//g' /etc/bind/named.conf
|
||||||
|
COPY named.conf.local /etc/bind/named.conf.local
|
||||||
|
COPY named.conf.options /etc/bind/named.conf.options
|
||||||
|
|
||||||
|
COPY start.sh /start.sh
|
||||||
|
COPY restart-bind /usr/bin
|
||||||
|
|
||||||
|
RUN mkdir /etc/dns
|
||||||
|
RUN touch /etc/dns/master.conf
|
||||||
|
|
||||||
|
VOLUME /etc/dns
|
||||||
|
|
||||||
|
EXPOSE 53
|
||||||
|
CMD ["/bin/sh", "/start.sh"]
|
||||||
5
dns/README.md
Normal file
5
dns/README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# DNS server container
|
||||||
|
|
||||||
|
## Useful commands
|
||||||
|
* `named-checkconf`: Check Bind9 configuration
|
||||||
|
* `restart-bind`: Restart Bind9
|
||||||
2
dns/build.sh
Executable file
2
dns/build.sh
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
sudo docker build -t pierre42100/gns3-appliance-dns .
|
||||||
1
dns/named.conf.local
Normal file
1
dns/named.conf.local
Normal file
@@ -0,0 +1 @@
|
|||||||
|
include "/etc/dns/master.conf";
|
||||||
32
dns/named.conf.options
Normal file
32
dns/named.conf.options
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
acl "everybody" {
|
||||||
|
0.0.0.0/0;
|
||||||
|
};
|
||||||
|
|
||||||
|
options {
|
||||||
|
directory "/var/cache/bind";
|
||||||
|
|
||||||
|
// If there is a firewall between you and nameservers you want
|
||||||
|
// to talk to, you may need to fix the firewall to allow multiple
|
||||||
|
// ports to talk. See http://www.kb.cert.org/vuls/id/800113
|
||||||
|
|
||||||
|
// If your ISP provided one or more IP addresses for stable
|
||||||
|
// nameservers, you probably want to use them as forwarders.
|
||||||
|
// Uncomment the following block, and insert the addresses replacing
|
||||||
|
// the all-0's placeholder.
|
||||||
|
|
||||||
|
// forwarders {
|
||||||
|
// 0.0.0.0;
|
||||||
|
// };
|
||||||
|
|
||||||
|
//====================================================================== ==
|
||||||
|
// If BIND logs error messages about the root key being expired,
|
||||||
|
// you will need to update your keys. See https://www.isc.org/bind-keys
|
||||||
|
//====================================================================== ==
|
||||||
|
dnssec-validation auto;
|
||||||
|
|
||||||
|
listen-on-v6 { any; };
|
||||||
|
|
||||||
|
//recursion yes;
|
||||||
|
//allow-recursion { everybody; };
|
||||||
|
//allow-transfer { none; };
|
||||||
|
};
|
||||||
3
dns/restart-bind
Executable file
3
dns/restart-bind
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
pkill named
|
||||||
|
/usr/sbin/named -L /var/log/bind.log
|
||||||
5
dns/start.sh
Normal file
5
dns/start.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
|
||||||
|
/usr/sbin/named -L /var/log/bind.log
|
||||||
|
while true; do /bin/bash; done
|
||||||
4
hidden_header/Dockerfile
Normal file
4
hidden_header/Dockerfile
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
FROM php:8.3-apache
|
||||||
|
COPY src/ /var/www/html/
|
||||||
|
|
||||||
|
ENV FLAG=CHANGEME
|
||||||
8
hidden_header/README.md
Normal file
8
hidden_header/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Unsafe login challenge
|
||||||
|
You need to set the `FLAG` environment variable for this challenge to work!
|
||||||
|
|
||||||
|
|
||||||
|
## Run the image
|
||||||
|
```bash
|
||||||
|
docker run --rm --name hidden_header --env FLAG='FLAG{HIDDEN_HEADER}' -p 3865:80 -it pierre42100/gns3-appliance-hidden-header
|
||||||
|
```
|
||||||
1
hidden_header/build.sh
Normal file
1
hidden_header/build.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
sudo docker build -t pierre42100/gns3-appliance-hidden-header .
|
||||||
13
hidden_header/src/index.php
Normal file
13
hidden_header/src/index.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
header("Flag: ".getenv("FLAG"));
|
||||||
|
?><!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>Hello world!</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -11,6 +11,7 @@ RUN apt-get update && \
|
|||||||
iperf3 \
|
iperf3 \
|
||||||
socat \
|
socat \
|
||||||
iputils-ping \
|
iputils-ping \
|
||||||
|
dnsutils \
|
||||||
tcpdump \
|
tcpdump \
|
||||||
traceroute \
|
traceroute \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|||||||
8
js_login/Dockerfile
Normal file
8
js_login/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
FROM python:3.12
|
||||||
|
|
||||||
|
COPY src/ /web
|
||||||
|
|
||||||
|
COPY docker/start.sh /start.sh
|
||||||
|
RUN chmod +x start.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/start.sh"]
|
||||||
8
js_login/README.md
Normal file
8
js_login/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# JsLogin
|
||||||
|
|
||||||
|
Taken from: https://github.com/mazipan/login-page-css/tree/master/src/18-instagram
|
||||||
|
|
||||||
|
## Run the image
|
||||||
|
```bash
|
||||||
|
docker run --rm --name js_login --env FLAG='FLAG{JSLOGIN}' -p 3570:8080 -it pierre42100/unsafe-js-login
|
||||||
|
```
|
||||||
1
js_login/build.sh
Normal file
1
js_login/build.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
sudo docker build -t pierre42100/unsafe-js-login .
|
||||||
13
js_login/docker/start.sh
Normal file
13
js_login/docker/start.sh
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [[ -z "${FLAG}" ]]; then
|
||||||
|
echo "Please set the FLAG environment variable!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo $FLAG > /web/flag.txt
|
||||||
|
|
||||||
|
echo "Starting HTTP server..."
|
||||||
|
|
||||||
|
cd /web
|
||||||
|
python3 -m http.server 8080
|
||||||
52
js_login/src/index.html
Normal file
52
js_login/src/index.html
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="pt-BR">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" href="./styles.css" />
|
||||||
|
<title>Instagram clone</title>
|
||||||
|
<link rel="stylesheet" href="../shared/normalize.css">
|
||||||
|
<link rel="stylesheet" href="../shared/additional.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main class="flex align-items-center justify-content-center">
|
||||||
|
<section id="auth" class="flex direction-column">
|
||||||
|
<div class="panel login flex direction-column">
|
||||||
|
<h1 title="Instagram" class="flex justify-content-center">
|
||||||
|
JsLogin
|
||||||
|
</h1>
|
||||||
|
<form id="loginForm">
|
||||||
|
<label for="email" class="sr-only">Phone number, username or email address</label>
|
||||||
|
<input id="email" name="email" placeholder="Phone number, username or email address" required />
|
||||||
|
|
||||||
|
<label for="password" class="sr-only">Password</label>
|
||||||
|
<input id="password" name="password" type="password" placeholder="Password" required />
|
||||||
|
|
||||||
|
<button type="submit" style="cursor:pointer;">Log In</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="panel register flex justify-content-center">
|
||||||
|
<p>Don't have an account?</p>
|
||||||
|
<a href="#">Sign up</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="foot" style="padding-top:50px">
|
||||||
|
<ul class="flex flex-wrap" style="font-size: .6em">
|
||||||
|
<li><a href="#">About</a></li>
|
||||||
|
<li><a href="#">Blog</a></li>
|
||||||
|
<li><a href="#">Jobs</a></li>
|
||||||
|
<li><a href="#">Help</li>
|
||||||
|
<li><a href="#">API</a></li>
|
||||||
|
<li><a href="#">Privacy</a></li>
|
||||||
|
<li><a href="#">Terms</a></li>
|
||||||
|
<li><a href="#">Top accounts</a></li>
|
||||||
|
<li><a href="#">Hashtags</a></li>
|
||||||
|
<li><a href="#">Locations</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<script src="/script.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
12
js_login/src/script.js
Normal file
12
js_login/src/script.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
const form = document.getElementById("loginForm");
|
||||||
|
form.addEventListener("submit", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const email = document.getElementById("email").value;
|
||||||
|
const password = document.getElementById("password").value;
|
||||||
|
|
||||||
|
if (email === "sesame@ouvretoi.com" && password === "topsecret")
|
||||||
|
location.href = "/flag.txt";
|
||||||
|
else
|
||||||
|
alert("Invalid credentials, please try again!");
|
||||||
|
})
|
||||||
243
js_login/src/styles.css
Normal file
243
js_login/src/styles.css
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
* {
|
||||||
|
border: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #fafafa;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
height: 100vh;
|
||||||
|
margin: auto;
|
||||||
|
max-width: 935px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flex rules
|
||||||
|
*/
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.direction-column {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-content-center {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-items-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-wrap {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #dbdbdb;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#auth {
|
||||||
|
max-width: 350px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mobile img {
|
||||||
|
height: 618px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Login section
|
||||||
|
*/
|
||||||
|
.login-with-fb,
|
||||||
|
form {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.register,
|
||||||
|
form {
|
||||||
|
padding: 30px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-with-fb {
|
||||||
|
padding: 30px 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form .sr-only {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
form input {
|
||||||
|
background-color: #fafafa;
|
||||||
|
border: 1px solid #dbdbdb;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: #808080;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
form input::placeholder {
|
||||||
|
color: #808080;
|
||||||
|
}
|
||||||
|
|
||||||
|
form input:focus {
|
||||||
|
border: 1px solid #808080;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
form button {
|
||||||
|
background-color: #0095f6;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
height: 35px;
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Separator login form from login with fb
|
||||||
|
*/
|
||||||
|
.separator span {
|
||||||
|
background-color: #dbdbdb;
|
||||||
|
height: 1px;
|
||||||
|
width: calc(100% - 10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator .or {
|
||||||
|
color: #808080;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator {
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator span:first-child {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator span:last-child {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Login with fb section
|
||||||
|
*/
|
||||||
|
.login-with-fb a {
|
||||||
|
color: #385185;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-with-fb>a {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-with-fb div a {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-with-fb div {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register section
|
||||||
|
*/
|
||||||
|
.register * {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.register a {
|
||||||
|
color: #0095f6;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.register p {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App download
|
||||||
|
*/
|
||||||
|
.app-download {
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-download p {
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-download img {
|
||||||
|
height: 40px;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Footer
|
||||||
|
*/
|
||||||
|
.foot {
|
||||||
|
margin: 0 auto 30px;
|
||||||
|
max-width: 935px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.foot ul {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.foot ul li {
|
||||||
|
margin: 0 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.foot ul li a {
|
||||||
|
color: #385185;
|
||||||
|
}
|
||||||
|
|
||||||
|
.foot .copyright {
|
||||||
|
color: #808080;
|
||||||
|
}
|
||||||
|
|
||||||
|
.foot ul li a,
|
||||||
|
.foot .copyright {
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Media queries
|
||||||
|
*/
|
||||||
|
|
||||||
|
@media screen and (width <=767px) {
|
||||||
|
main {
|
||||||
|
margin: 30px auto 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.foot .copyright,
|
||||||
|
.foot ul li a {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
4
oh_my_api/Dockerfile
Normal file
4
oh_my_api/Dockerfile
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
FROM php:8.3-apache
|
||||||
|
COPY src/ /var/www/html/
|
||||||
|
|
||||||
|
ENV FLAG=CHANGEME
|
||||||
8
oh_my_api/README.md
Normal file
8
oh_my_api/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Unsafe gallery challenge
|
||||||
|
You need to set the `FLAG` environment variable for this challenge to work!
|
||||||
|
|
||||||
|
|
||||||
|
## Run the image
|
||||||
|
```bash
|
||||||
|
docker run --rm --name oh_my_api --env FLAG='FLAG{BROKEN_ACL}' -p 3569:80 -it pierre42100/gns3-appliance-oh-my-api
|
||||||
|
```
|
||||||
1
oh_my_api/build.sh
Normal file
1
oh_my_api/build.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
sudo docker build -t pierre42100/gns3-appliance-oh-my-api .
|
||||||
1
oh_my_api/src/.htaccess
Normal file
1
oh_my_api/src/.htaccess
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Options -Indexes
|
||||||
131
oh_my_api/src/api.php
Normal file
131
oh_my_api/src/api.php
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$path = isset($_SERVER["PATH_INFO"]) ? $_SERVER["PATH_INFO"] : "/";
|
||||||
|
|
||||||
|
// First, connect to database
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$db = new PDO('sqlite:'.__DIR__.'/database.db');
|
||||||
|
}
|
||||||
|
catch (PDOException $e)
|
||||||
|
{
|
||||||
|
echo 'Connection to database failed: ' . $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for supplied authentication
|
||||||
|
if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']))
|
||||||
|
{
|
||||||
|
$user = $_SERVER['PHP_AUTH_USER'];
|
||||||
|
$pass = $_SERVER['PHP_AUTH_PW'];
|
||||||
|
|
||||||
|
$password_hash = hash("sha512", $pass);
|
||||||
|
|
||||||
|
$query = "SELECT * FROM users WHERE user = ? AND password = ?";
|
||||||
|
$stmt = $db->prepare($query);
|
||||||
|
$stmt->execute(array($user, $password_hash));
|
||||||
|
|
||||||
|
$res = $stmt->fetchAll();
|
||||||
|
|
||||||
|
if(count($res) === 0)
|
||||||
|
{
|
||||||
|
http_response_code(401);
|
||||||
|
echo "The specified credentials are invalid!";
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $res[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Secure maintenance access
|
||||||
|
else if (isset($_GET["dev_user"]))
|
||||||
|
{
|
||||||
|
$user = ["user" => $_GET["dev_user"], "is_admin" => $_GET["dev_user"] === "fake_admin"];
|
||||||
|
}
|
||||||
|
|
||||||
|
header("content-type: application/json");
|
||||||
|
|
||||||
|
// Home page
|
||||||
|
if ($path === "/") {
|
||||||
|
echo "{\"msg\": \"Oh my API\"}";
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get user information
|
||||||
|
else if($path === "/user")
|
||||||
|
{
|
||||||
|
?>{"user": "<?=$user["user"]?>", "admin": <?=$user["is_admin"]?"true":"false"?>}<?php
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the list of articles
|
||||||
|
else if($path === "/articles")
|
||||||
|
{
|
||||||
|
if(!isset($user))
|
||||||
|
{
|
||||||
|
http_response_code(401);
|
||||||
|
?>"Authentication required!"<?php
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract current user information
|
||||||
|
$stmt = $db->prepare("SELECT * FROM articles;");
|
||||||
|
$stmt->execute(array());
|
||||||
|
|
||||||
|
echo json_encode($stmt->fetchAll(PDO::FETCH_CLASS));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert a new article
|
||||||
|
else if($path === "/insert_article")
|
||||||
|
{
|
||||||
|
if(!isset($user))
|
||||||
|
{
|
||||||
|
http_response_code(401);
|
||||||
|
?>"Authentication required!"<?php
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$user["is_admin"])
|
||||||
|
{
|
||||||
|
http_response_code(401);
|
||||||
|
?>"Only an admin can do that!"<?php
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isset($_POST["title"]) || !isset($_POST["content"]))
|
||||||
|
{
|
||||||
|
http_response_code(401);
|
||||||
|
?>"Some fields are missing!"<?php
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $db->prepare("INSERT INTO articles (published, time, title, description) VALUES (0, 0, ?, ?)");
|
||||||
|
$stmt->execute(array($_POST["title"], $_POST["content"]));
|
||||||
|
|
||||||
|
?>"Success!"<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the secret flag
|
||||||
|
else if($path === "/flag")
|
||||||
|
{
|
||||||
|
if(!isset($user))
|
||||||
|
{
|
||||||
|
http_response_code(401);
|
||||||
|
?>"Authentication required!"<?php
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$user["is_admin"])
|
||||||
|
{
|
||||||
|
http_response_code(401);
|
||||||
|
?>"Only an admin can do that!"<?php
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
?>{"flag": "<?=getenv("FLAG")?>"}<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
// 404 not found
|
||||||
|
else {
|
||||||
|
http_response_code(404);
|
||||||
|
echo "\"404 Not Found\"";
|
||||||
|
}
|
||||||
BIN
oh_my_api/src/database.db
Normal file
BIN
oh_my_api/src/database.db
Normal file
Binary file not shown.
BIN
oh_my_api/src/favicon-16x16.png
Normal file
BIN
oh_my_api/src/favicon-16x16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 665 B |
BIN
oh_my_api/src/favicon-32x32.png
Normal file
BIN
oh_my_api/src/favicon-32x32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 628 B |
16
oh_my_api/src/index.css
Normal file
16
oh_my_api/src/index.css
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
html {
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: -moz-scrollbars-vertical;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*:before,
|
||||||
|
*:after {
|
||||||
|
box-sizing: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
21
oh_my_api/src/index.html
Normal file
21
oh_my_api/src/index.html
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<!-- HTML for static distribution bundle build -->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Swagger UI</title>
|
||||||
|
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-PFFSBW3');</script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="index.css" />
|
||||||
|
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||||
|
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PFFSBW3" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||||
|
<div id="swagger-ui"></div>
|
||||||
|
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
|
||||||
|
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
|
||||||
|
<script src="./swagger-initializer.js" charset="UTF-8"> </script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
28
oh_my_api/src/swagger-initializer.js
Normal file
28
oh_my_api/src/swagger-initializer.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
window.onload = function() {
|
||||||
|
const defaultDefinitionUrl = "/swagger.yaml";
|
||||||
|
const ossServices = `petstore3.swagger.io=https://petstore3.swagger.io/api/v3/openapi.json,petstore31.swagger.io=https://petstore31.swagger.io/api/v31/openapi.json,petstore.swagger.io=https://petstore.swagger.io/v2/swagger.json,generator.swagger.io=https://generator.swagger.io/api/swagger.json,generator3.swagger.io=https://generator3.swagger.io/openapi.json,validator.swagger.io=https://validator.swagger.io/validator/openapi.json,oai.swagger.io=https://oai.swagger.io/api/openapi.json,converter.swagger.io=https://converter.swagger.io/api/openapi.json`;
|
||||||
|
const ossServicesTuples = ossServices.split(',').map(ossService => ossService.split('='))
|
||||||
|
const ossServiceMatch = ossServicesTuples.find(([host]) => window.location.host.includes(host))
|
||||||
|
const definitionURL = ossServiceMatch ? ossServiceMatch[1] : defaultDefinitionUrl;
|
||||||
|
|
||||||
|
|
||||||
|
//<editor-fold desc="Changeable Configuration Block">
|
||||||
|
window.ui = SwaggerUIBundle({
|
||||||
|
url: definitionURL,
|
||||||
|
"dom_id": "#swagger-ui",
|
||||||
|
deepLinking: true,
|
||||||
|
presets: [
|
||||||
|
SwaggerUIBundle.presets.apis,
|
||||||
|
SwaggerUIStandalonePreset
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
SwaggerUIBundle.plugins.DownloadUrl
|
||||||
|
],
|
||||||
|
layout: "StandaloneLayout",
|
||||||
|
queryConfigEnabled: true,
|
||||||
|
// validatorUrl: "https://validator.swagger.io/validator",
|
||||||
|
})
|
||||||
|
|
||||||
|
//</editor-fold>
|
||||||
|
|
||||||
|
};
|
||||||
2
oh_my_api/src/swagger-ui-bundle.js
Normal file
2
oh_my_api/src/swagger-ui-bundle.js
Normal file
File diff suppressed because one or more lines are too long
2
oh_my_api/src/swagger-ui-standalone-preset.js
Normal file
2
oh_my_api/src/swagger-ui-standalone-preset.js
Normal file
File diff suppressed because one or more lines are too long
3
oh_my_api/src/swagger-ui.css
Normal file
3
oh_my_api/src/swagger-ui.css
Normal file
File diff suppressed because one or more lines are too long
74
oh_my_api/src/swagger.yaml
Normal file
74
oh_my_api/src/swagger.yaml
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
openapi: 3.0.3
|
||||||
|
info:
|
||||||
|
title: Oh My API
|
||||||
|
description: |-
|
||||||
|
Welcome to my articles services API
|
||||||
|
version: 1.0.0
|
||||||
|
servers:
|
||||||
|
- url: /api.php
|
||||||
|
paths:
|
||||||
|
/:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- default
|
||||||
|
summary: API root
|
||||||
|
description: Get welcome message of API
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
/user:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- default
|
||||||
|
summary: User info
|
||||||
|
description: Get information about current user
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
security:
|
||||||
|
- basicAuth: []
|
||||||
|
|
||||||
|
/articles:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- articles
|
||||||
|
summary: Articles list
|
||||||
|
description: Get the list of articles of the database
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
security:
|
||||||
|
- basicAuth: []
|
||||||
|
|
||||||
|
/insert_article:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- articles
|
||||||
|
summary: Insert a new article
|
||||||
|
description: Insert a new article in the database
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
description: Article title
|
||||||
|
content:
|
||||||
|
type: string
|
||||||
|
description: Article content
|
||||||
|
|
||||||
|
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
security:
|
||||||
|
- basicAuth: []
|
||||||
|
|
||||||
|
components:
|
||||||
|
securitySchemes:
|
||||||
|
basicAuth:
|
||||||
|
type: http
|
||||||
|
scheme: basic
|
||||||
4
unsafe_gallery/Dockerfile
Normal file
4
unsafe_gallery/Dockerfile
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
FROM php:8.3-apache
|
||||||
|
COPY src/ /var/www/html/
|
||||||
|
|
||||||
|
ENV FLAG=CHANGEME
|
||||||
8
unsafe_gallery/README.md
Normal file
8
unsafe_gallery/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Unsafe gallery challenge
|
||||||
|
You need to set the `FLAG` environment variable for this challenge to work!
|
||||||
|
|
||||||
|
|
||||||
|
## Run the image
|
||||||
|
```bash
|
||||||
|
docker run --rm --name unsafe_gallery --env FLAG='FLAG{UNSAFEGALLERY}' -p 3568:80 -it pierre42100/gns3-appliance-unsafe-gallery
|
||||||
|
```
|
||||||
1
unsafe_gallery/build.sh
Normal file
1
unsafe_gallery/build.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
sudo docker build -t pierre42100/gns3-appliance-unsafe-gallery .
|
||||||
1
unsafe_gallery/src/.gitignore
vendored
Normal file
1
unsafe_gallery/src/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uploads
|
||||||
1
unsafe_gallery/src/.htaccess
Normal file
1
unsafe_gallery/src/.htaccess
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Options -Indexes
|
||||||
6
unsafe_gallery/src/bootstrap.min.css
vendored
Normal file
6
unsafe_gallery/src/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
96
unsafe_gallery/src/index.php
Normal file
96
unsafe_gallery/src/index.php
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
// Assign unique session ID to the client
|
||||||
|
if (!isset($_SESSION["id"]))
|
||||||
|
$_SESSION["id"] = uniqid();
|
||||||
|
|
||||||
|
// Specify uploads target directory
|
||||||
|
define('UPLOAD_DIR', __DIR__ . "/uploads/" . $_SESSION["id"]);
|
||||||
|
|
||||||
|
if (isset($_FILES["file"])) {
|
||||||
|
$dest_file_name = (string) time() . "-" . str_replace("/", "", $_FILES["file"]["name"]);
|
||||||
|
|
||||||
|
// Create target directory
|
||||||
|
if (!is_dir(UPLOAD_DIR) && !mkdir(UPLOAD_DIR, 0770, true)) {
|
||||||
|
$error = "Failed to create storage directory!";
|
||||||
|
} else if ($_FILES["file"]["size"] > 500000) {
|
||||||
|
$error = "File is too large (max 500kb)!";
|
||||||
|
} else if (move_uploaded_file($_FILES["file"]["tmp_name"], UPLOAD_DIR . "/" . $dest_file_name)) {
|
||||||
|
$success = "The file was successfully uploaded!";
|
||||||
|
} else {
|
||||||
|
$error = "Error while uploading file!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?><!doctype html>
|
||||||
|
<html lang="en" data-bs-theme="auto">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Safe gallery</title>
|
||||||
|
|
||||||
|
<link href="/bootstrap.min.css" rel="stylesheet"
|
||||||
|
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||||
|
<link href="/style.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="d-flex align-items-center py-4 bg-body-tertiary">
|
||||||
|
<main class="form-signin w-100 m-auto">
|
||||||
|
|
||||||
|
<h1>Gallery manager</h1>
|
||||||
|
|
||||||
|
<div class="alert alert-secondary">
|
||||||
|
<strong>Note</strong> : Une information se cache dans la variable d'environnement <i>FLAG</i>.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if (isset($success)) {
|
||||||
|
?>
|
||||||
|
<div class="alert alert-success">
|
||||||
|
<?= $success ?>
|
||||||
|
</div><?php
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($error)) {
|
||||||
|
?>
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<?= $error ?>
|
||||||
|
</div><?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2>Upload file</h2>
|
||||||
|
|
||||||
|
<form action="/" method="post" enctype="multipart/form-data">
|
||||||
|
<div>
|
||||||
|
<label for="formFile" class="form-label mt-4">Select image to upload</label>
|
||||||
|
<input class="form-control" type="file" id="formFile" name="file" required />
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 10px;">
|
||||||
|
<button type="submit" class="btn btn-primary">Perform upload</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if (is_dir(UPLOAD_DIR)) {
|
||||||
|
?>
|
||||||
|
<h2 style="margin-top: 50px;">Your files</h2>
|
||||||
|
<ul>
|
||||||
|
<?php
|
||||||
|
foreach (scandir(UPLOAD_DIR) as $f) {
|
||||||
|
if ($f === "." or $f === "..")
|
||||||
|
continue;
|
||||||
|
echo "<li><a href='uploads/" . $_SESSION['id'] . "/$f' target='_blank'>" . $f . "</a></li>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</ul><?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
102
unsafe_gallery/src/style.css
Normal file
102
unsafe_gallery/src/style.css
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin {
|
||||||
|
max-width: 800px;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin .form-floating:focus-within {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin input[type="email"] {
|
||||||
|
margin-bottom: -1px;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin input[type="password"] {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-placeholder-img {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
text-anchor: middle;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.bd-placeholder-img-lg {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.b-example-divider {
|
||||||
|
width: 100%;
|
||||||
|
height: 3rem;
|
||||||
|
background-color: rgba(0, 0, 0, .1);
|
||||||
|
border: solid rgba(0, 0, 0, .15);
|
||||||
|
border-width: 1px 0;
|
||||||
|
box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.b-example-vr {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bi {
|
||||||
|
vertical-align: -.125em;
|
||||||
|
fill: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-scroller {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
height: 2.75rem;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-scroller .nav {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
margin-top: -1px;
|
||||||
|
overflow-x: auto;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-bd-primary {
|
||||||
|
--bd-violet-bg: #712cf9;
|
||||||
|
--bd-violet-rgb: 112.520718, 44.062154, 249.437846;
|
||||||
|
|
||||||
|
--bs-btn-font-weight: 600;
|
||||||
|
--bs-btn-color: var(--bs-white);
|
||||||
|
--bs-btn-bg: var(--bd-violet-bg);
|
||||||
|
--bs-btn-border-color: var(--bd-violet-bg);
|
||||||
|
--bs-btn-hover-color: var(--bs-white);
|
||||||
|
--bs-btn-hover-bg: #6528e0;
|
||||||
|
--bs-btn-hover-border-color: #6528e0;
|
||||||
|
--bs-btn-focus-shadow-rgb: var(--bd-violet-rgb);
|
||||||
|
--bs-btn-active-color: var(--bs-btn-hover-color);
|
||||||
|
--bs-btn-active-bg: #5a23c8;
|
||||||
|
--bs-btn-active-border-color: #5a23c8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-mode-toggle {
|
||||||
|
z-index: 1500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-mode-toggle .dropdown-menu .active .bi {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
4
unsafe_login/Dockerfile
Normal file
4
unsafe_login/Dockerfile
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
FROM php:8.3-apache
|
||||||
|
COPY src/ /var/www/html/
|
||||||
|
|
||||||
|
ENV FLAG=CHANGEME
|
||||||
8
unsafe_login/README.md
Normal file
8
unsafe_login/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Unsafe login challenge
|
||||||
|
You need to set the `FLAG` environment variable for this challenge to work!
|
||||||
|
|
||||||
|
|
||||||
|
## Run the image
|
||||||
|
```bash
|
||||||
|
docker run --rm --name unsafe_login --env FLAG='FLAG{EASYINJECTION}' -p 3565:80 -it pierre42100/gns3-appliance-unsafe-login
|
||||||
|
```
|
||||||
1
unsafe_login/build.sh
Normal file
1
unsafe_login/build.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
sudo docker build -t pierre42100/gns3-appliance-unsafe-login .
|
||||||
6
unsafe_login/src/bootstrap.min.css
vendored
Normal file
6
unsafe_login/src/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
unsafe_login/src/database.db
Normal file
BIN
unsafe_login/src/database.db
Normal file
Binary file not shown.
220
unsafe_login/src/index.php
Normal file
220
unsafe_login/src/index.php
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
$user = NULL;
|
||||||
|
|
||||||
|
// First, connect to database
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$db = new PDO('sqlite:'.__DIR__.'/database.db');
|
||||||
|
}
|
||||||
|
catch (PDOException $e)
|
||||||
|
{
|
||||||
|
echo 'Connection to database failed: ' . $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user requested to be signed out
|
||||||
|
if(isset($_GET['sign_out']))
|
||||||
|
{
|
||||||
|
unset($_SESSION["user"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check for authentication
|
||||||
|
if(isset($_POST["user"]) && isset($_POST["password"]))
|
||||||
|
{
|
||||||
|
$username = $_POST["user"];
|
||||||
|
$password_hash = hash("sha512", $_POST["password"]);
|
||||||
|
|
||||||
|
$query = "SELECT * FROM users WHERE user = '$username' AND password = '$password_hash'";
|
||||||
|
$stmt = $db->prepare($query);
|
||||||
|
$stmt->execute(array());
|
||||||
|
|
||||||
|
$res = $stmt->fetchAll();
|
||||||
|
|
||||||
|
if(count($res) === 0)
|
||||||
|
$error = "The specified credentials are invalid!";
|
||||||
|
|
||||||
|
else {
|
||||||
|
$_SESSION["user"] = $res[0]["id"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($_SESSION["user"]))
|
||||||
|
{
|
||||||
|
// Extract current user information
|
||||||
|
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
|
||||||
|
$stmt->execute(array($_SESSION["user"]));
|
||||||
|
$user = $stmt->fetchAll()[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?><!doctype html>
|
||||||
|
<html lang="en" data-bs-theme="auto">
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Safesys</title>
|
||||||
|
|
||||||
|
<link href="/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin {
|
||||||
|
max-width: 330px;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin .form-floating:focus-within {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin input[type="email"] {
|
||||||
|
margin-bottom: -1px;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin input[type="password"] {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-placeholder-img {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
text-anchor: middle;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.bd-placeholder-img-lg {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.b-example-divider {
|
||||||
|
width: 100%;
|
||||||
|
height: 3rem;
|
||||||
|
background-color: rgba(0, 0, 0, .1);
|
||||||
|
border: solid rgba(0, 0, 0, .15);
|
||||||
|
border-width: 1px 0;
|
||||||
|
box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.b-example-vr {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bi {
|
||||||
|
vertical-align: -.125em;
|
||||||
|
fill: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-scroller {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
height: 2.75rem;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-scroller .nav {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
margin-top: -1px;
|
||||||
|
overflow-x: auto;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-bd-primary {
|
||||||
|
--bd-violet-bg: #712cf9;
|
||||||
|
--bd-violet-rgb: 112.520718, 44.062154, 249.437846;
|
||||||
|
|
||||||
|
--bs-btn-font-weight: 600;
|
||||||
|
--bs-btn-color: var(--bs-white);
|
||||||
|
--bs-btn-bg: var(--bd-violet-bg);
|
||||||
|
--bs-btn-border-color: var(--bd-violet-bg);
|
||||||
|
--bs-btn-hover-color: var(--bs-white);
|
||||||
|
--bs-btn-hover-bg: #6528e0;
|
||||||
|
--bs-btn-hover-border-color: #6528e0;
|
||||||
|
--bs-btn-focus-shadow-rgb: var(--bd-violet-rgb);
|
||||||
|
--bs-btn-active-color: var(--bs-btn-hover-color);
|
||||||
|
--bs-btn-active-bg: #5a23c8;
|
||||||
|
--bs-btn-active-border-color: #5a23c8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-mode-toggle {
|
||||||
|
z-index: 1500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-mode-toggle .dropdown-menu .active .bi {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="d-flex align-items-center py-4 bg-body-tertiary">
|
||||||
|
<main class="form-signin w-100 m-auto">
|
||||||
|
<?php
|
||||||
|
if($user === NULL) {
|
||||||
|
?><form method="POST" action="/">
|
||||||
|
<?php
|
||||||
|
if(isset($error))
|
||||||
|
{
|
||||||
|
?><div class="alert alert-danger">
|
||||||
|
<?=$error?>
|
||||||
|
</div><?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h1 class="h3 mb-3 fw-normal">Please sign in</h1>
|
||||||
|
|
||||||
|
<div class="form-floating">
|
||||||
|
<input type="user" class="form-control" id="floatingInput" placeholder="user" name="user" required />
|
||||||
|
<label for="floatingInput">Username</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating">
|
||||||
|
<input type="password" class="form-control" id="floatingPassword" placeholder="Password" name="password" required />
|
||||||
|
<label for="floatingPassword">Password</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-check text-start my-3">
|
||||||
|
<input class="form-check-input" type="checkbox" value="remember-me" id="flexCheckDefault">
|
||||||
|
<label class="form-check-label" for="flexCheckDefault">
|
||||||
|
Remember me
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary w-100 py-2" type="submit">Sign in</button>
|
||||||
|
<p class="mt-5 mb-3 text-body-secondary">© 2025 Safesys</p>
|
||||||
|
</form><?php
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
?><h3>Welcome <?=$user['user']?>! <a href='/?sign_out=1'>Sign out</a></h3><?php
|
||||||
|
|
||||||
|
if($user["is_admin"]) {
|
||||||
|
?><div class="alert alert-success">
|
||||||
|
Hey admin ! You can access the secret value: <?=getenv("FLAG")?>
|
||||||
|
</div><?php
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
?><div class="alert alert-light">
|
||||||
|
You are not an administrator, you cannot access privileged information!
|
||||||
|
</div><?php
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?></main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user