This commit is contained in:
Joren 2025-05-31 18:29:56 +02:00
parent 70c43984cc
commit 86ffb3bd40
Signed by: Joren
GPG Key ID: 280E33DFBC0F1B55
48 changed files with 76 additions and 205 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
assets/images/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -26,7 +26,7 @@ banner:
enable: true
label: "Download Resume"
isDownloadable: true
link: "http://cdn.alpin.sbs/resume.pdf"
link: "https://cdn.joren.blog/resume.pdf"
# skill

View File

@ -7,8 +7,6 @@ categories: ["cybersecurity", "event"]
draft: false
---
#### On a Mission with NATO: Cyber Defence on the Frontline
Howests ongoing commitment to world-class cybersecurity training took center stage again as six lecturers from the Cyber Security program joined forces with experts from Latvia, Luxembourg and Belgium in one of NATO's most intensive simulations: the Locked Shields exercise, hosted by the Cooperative Cyber Defence Centre of Excellence (CCDCOE). Now in its fifth year of participation, the Howest team shared their firsthand experiences at a special evening talk at Howest Bruges.
#### The Exercise: Locked Shields

View File

@ -14,7 +14,7 @@ Smart homes are convenient. But with convenience comes risk. If your doorbell ru
---
### Why Segmentation Matters
#### Why Segmentation Matters
Most people treat their home network like a trust zone. All devices are equal. But theyre not. You wouldnt let your robot vacuum log into your online banking, yet they live on the same flat LAN. Thats the fundamental issue.
@ -29,7 +29,7 @@ A compromise is inevitable. The only question is: does that compromise stay loca
---
### VLANs 101
#### VLANs 101
A VLAN (Virtual Local Area Network) logically segments traffic on the same physical infrastructure. Think of it as creating isolated “subnet bubbles” where traffic can be controlled and filtered.
@ -44,7 +44,7 @@ And you dont need enterprise gear to do this. Many consumer-grade routers and
---
### Sample Home Setup
#### Sample Home Setup
Lets say you have a smart home with:
@ -80,7 +80,7 @@ Optional: Use static DHCP leases and force DNS through Pi-hole for logging and f
---
### Real-World Examples
#### Real-World Examples
**Case 1: Smart TV**
@ -100,7 +100,7 @@ On the LAN, it had access to the NAS and router UI. After VLAN isolation, its ac
---
### Caveats & Limitations
#### Caveats & Limitations
* Some IoT devices rely on MDNS or SSDP for pairing/setup. Consider temporarily whitelisting during setup, then blocking.
* Chromecast-style devices need special rules if you want casting from your main network.
@ -111,7 +111,7 @@ Still, the benefits far outweigh the complexity.
---
### Final Thoughts
#### Final Thoughts
If youve ever installed a smart plug and noticed it phones home every few minutes, you're not alone. And if you haven't noticed, maybe you should.

View File

@ -1,6 +1,6 @@
---
title: "Reversing, Rebuilding, and Failing Better: My Cyber Security Challenge Belgium Qualifier Experience"
image: "images/blog/post-2/binexpl.png"
image: "images/blog/blog-2.jpg"
date: "2025-03-15 00:00:00 +0000 UTC"
description: "I tackled buffer overflows, reversed Android apps, cracked crypto puzzles, and solved a 'one-in-a-million' guessing game, but the challenge that stuck with me was rebuilding a fragmented DEX in memory."
categories: ["cybersecurity", "CTF", "education"]

View File

@ -50,4 +50,3 @@ Priced under 150 EUR, the SARV001 offers features typically found in higher-end
The Seiko SARV001 exemplifies the brand's commitment to craftsmanship and value. Its understated design, robust movement, and unique JDM characteristics make it a compelling option for those looking to add a versatile and reliable watch to their collection.
---

View File

@ -30,12 +30,12 @@ A `.drmd` file is a structured JSON document that defines one or more encrypted
Each item includes:
* **MPD**: A DASH manifest, either a direct URL or a base64-encoded version. If base64-encoded, DRMDTool decodes and temporarily saves it before use.
* **Keys**: A comma-separated list of **KID\:key** pairs (e.g., `abcd1234ef567890:00112233445566778899aabbccddeeff`). These are required for decrypting encrypted media streams and are passed directly to N\_m3u8DL-RE using `--key` flags.
* **Filename**: The name to be used for the final output file.
* **Subtitles**: Comma-separated list of subtitle URLs in `.vtt` format. DRMDTool downloads and converts these to `.srt`, then muxes them into the final file.
* **Metadata**: A semicolon-separated string like `Title;Type;Season` (e.g., `Example Show;serie;1`) used to determine directory structure (`Movies/Title` or `Series/Title/Season`).
* **Description** and **Poster**: Optional fields used only for display in the web UI.
* MPD: A DASH manifest, either a direct URL or a base64-encoded version. If base64-encoded, DRMDTool decodes and temporarily saves it before use.
* Keys: A comma-separated list of **KID\:key** pairs (e.g., `abcd1234ef567890:00112233445566778899aabbccddeeff`). These are required for decrypting encrypted media streams and are passed directly to N\_m3u8DL-RE using `--key` flags.
* Filename: The name to be used for the final output file.
* Subtitles: Comma-separated list of subtitle URLs in `.vtt` format. DRMDTool downloads and converts these to `.srt`, then muxes them into the final file.
* Metadata**: A semicolon-separated string like `Title;Type;Season` (e.g., `Example Show;serie;1`) used to determine directory structure (`Movies/Title` or `Series/Title/Season`).
* Description and Poster: Optional fields used only for display in the web UI.
##### Example `.drmd` Structure
@ -57,11 +57,11 @@ Each item includes:
#### Processing Steps
1. **Detection**: DRMDTool either watches a folder or receives `.drmd` uploads through the web UI.
2. **Validation**: It waits for the file to finish writing (based on file size stability), then parses its contents.
3. **MPD Handling**: If base64-encoded, the MPD is decoded and written to a temp file; otherwise, the URL is fetched or passed as-is.
4. **Command Generation**: Using the MPD, `KID:key` pairs, output paths, and subtitles, DRMDTool builds a command line for N\_m3u8DL-RE.
5. **Execution**: The download is launched with live progress tracking. Users can pause, resume, or abort jobs, and optionally stream console output via WebSocket.
1. Detection: DRMDTool either watches a folder or receives `.drmd` uploads through the web UI.
2. Validation: It waits for the file to finish writing (based on file size stability), then parses its contents.
3. MPD Handling: If base64-encoded, the MPD is decoded and written to a temp file; otherwise, the URL is fetched or passed as-is.
4. Command Generation: Using the MPD, `KID:key` pairs, output paths, and subtitles, DRMDTool builds a command line for N\_m3u8DL-RE.
5. Execution: The download is launched with live progress tracking. Users can pause, resume, or abort jobs, and optionally stream console output via WebSocket.
These files serve as portable job definitions. When DRMDTool detects or receives a `.drmd` file, it parses the items, decodes or downloads the MPD, applies the keys, and builds a download command using N\_m3u8DL-RE. Files are saved in organized directories like `Movies/Title` or `Series/Title/Season`, and subtitles are embedded if available. Pausing, resuming, and aborting downloads is supported per file.

View File

@ -31,7 +31,7 @@ Blocky handles all local DNS queries, with DoT upstreams, custom mappings, and d
Highlights:
* Local resolution for custom domains like `directme.in`
* Local resolution for custom domains like `joren.blog`
* Cloudflare, Google as upstream resolvers
* Per-IP blocking rules
* Prometheus metrics for monitoring
@ -48,7 +48,7 @@ blocking:
clientGroupsBlock:
default:
- ads
192.168.178.123:
172.16.0.120:
- vtm
```
@ -83,8 +83,6 @@ In this context, PiVPN reduces the friction of managing WireGuard while remainin
---
---
#### IRC: ngIRCd
For real-time messaging, I run a public-facing **ngIRCd** instance accessible over both plaintext (port 6667) and encrypted TLS (ports 6697, 6698). Despite its modest footprint, *ngIRCd* is stable, portable, and well-suited for both LAN and internet-facing deployments.

View File

@ -1,6 +1,6 @@
---
title: "Sniffing on a Budget: Malware Detection with Suricata and Alpine Linux"
title: "Network Sniffing on a Budget: Malware Detection with Suricata"
image: "/images/project/project-4.jpg"
date: "2025-04-15 00:00:00 +0000 UTC"
description: "Setting up Suricata on minimal hardware to passively inspect mirrored traffic for malware and exploits using open threat intelligence rules."

View File

@ -204,12 +204,10 @@
"p-0",
"p-1",
"p-2",
"p-3",
"p-4",
"pb-1",
"pb-2",
"pb-3",
"pb-4",
"pb-5",
"pe-3",
"position-fixed",
@ -221,7 +219,6 @@
"progress-bar",
"progress-item",
"progress-value",
"project-item",
"projects",
"ps-0",
"ps-lg-4",
@ -321,7 +318,6 @@
"name-resolution-chaos",
"navbar",
"offensive-vs-defensive-security",
"on-a-mission-with-nato-cyber-defence-on-the-frontline",
"ourencissec-zip-bombs-and-oeis",
"phone",
"portfolio",

View File

@ -18314,46 +18314,6 @@ html.light .navbar-nav .nav-item a.nav-link:hover {
max-height: 600px;
object-fit: cover; }
.project-item {
display: flex;
flex-direction: column;
height: 100%; }
.project-item > a {
position: relative;
overflow: hidden;
border-radius: 8px;
display: block;
width: 100%;
aspect-ratio: 16 / 9; }
.project-item > a img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
display: block;
transition: transform 0.4s ease; }
.project-item > a:hover img {
transform: scale(1.05); }
.project-item h3, .project-item .h3 {
min-height: 3.5em;
margin-bottom: 1rem;
font-size: 1.125rem;
font-weight: 500; }
.project-item .card-text {
flex-grow: 1;
font-size: 0.95rem;
line-height: 1.6;
margin-bottom: 1rem; }
.project-item .card-btn {
font-weight: 500;
margin-top: auto; }
#blog {
position: relative; }
#blog::before {

View File

@ -1 +1 @@
{"Target":"/css/style.e0f0e604485dadc53beafefb6a6887ddbbfd8348186bc86d1fc9e99ad8162ccd.css","MediaType":"text/css","Data":{"Integrity":"sha256-4PDmBEhdrcU76v77amiH3bv9g0gYa8htH8npmtgWLM0="}}
{"Target":"/css/style.30c2f870a09379db333105ec31b030d3bad723d3ad8e71a83f60db00f48d4f85.css","MediaType":"text/css","Data":{"Integrity":"sha256-MML4cKCTedszMQXsMbAw07rXI9OtjnGoP2DbAPSNT4U="}}

View File

@ -8817,46 +8817,6 @@ html.light .navbar-nav .nav-item a.nav-link:hover {
max-height: 600px;
object-fit: cover; }
.project-item {
display: flex;
flex-direction: column;
height: 100%; }
.project-item > a {
position: relative;
overflow: hidden;
border-radius: 8px;
display: block;
width: 100%;
aspect-ratio: 16 / 9; }
.project-item > a img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
display: block;
transition: transform 0.4s ease; }
.project-item > a:hover img {
transform: scale(1.05); }
.project-item h3, .project-item .h3 {
min-height: 3.5em;
margin-bottom: 1rem;
font-size: 1.125rem;
font-weight: 500; }
.project-item .card-text {
flex-grow: 1;
font-size: 0.95rem;
line-height: 1.6;
margin-bottom: 1rem; }
.project-item .card-btn {
font-weight: 500;
margin-top: auto; }
#blog {
position: relative; }
#blog::before {

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -311,6 +311,7 @@
}
}
.project-item,
.blog-post {
.card {
@ -442,53 +443,7 @@
object-fit: cover;
}
.project-item {
display: flex;
flex-direction: column;
height: 100%;
}
.project-item > a {
position: relative;
overflow: hidden;
border-radius: 8px;
display: block;
width: 100%;
aspect-ratio: 16 / 9;
}
.project-item > a img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
display: block;
transition: transform 0.4s ease;
}
.project-item > a:hover img {
transform: scale(1.05);
}
.project-item h3 {
min-height: 3.5em; // equal height titles
margin-bottom: 1rem;
font-size: 1.125rem;
font-weight: 500;
}
.project-item .card-text {
flex-grow: 1;
font-size: 0.95rem;
line-height: 1.6;
margin-bottom: 1rem;
}
.project-item .card-btn {
font-weight: 500;
margin-top: auto;
}
// -----------------------

View File

@ -1,7 +1,7 @@
{{define "main"}}
<!-- checking blog -->
{{ if or (eq .Section "post") (eq .Section "posts") (eq .Section "blog") (eq .Section "blogs") (eq .Section "news") (eq .Section "categories") (eq .Section "tags") }}
{{ if or (eq .Section "post") (eq .Section "posts") (eq .Section "blog") (eq .Section "blogs") (eq .Section "news") (eq .Section "categories") (eq .Section "tags") (eq .Section "project") }}
<section class="section">
<div class="container">

View File

@ -1,18 +1,40 @@
<div class="project-item mb-4">
<div class="blog-post mb-4">
<article class="card bg-transparent border-0 p-1">
{{ if .Params.image }}
<a href="{{ .RelPermalink | urlize }}" class="overflow-hidden d-block mb-3" data-aos="fade-up">
{{ partial "image.html" (dict "Src" .Params.image "Alt" .Params.title "Class" "rounded-2 w-100") }}
<a href="{{ .RelPermalink | urlize }}" class="rounded-2 overflow-hidden" data-aos="fade-up">
{{ partial "image.html" (dict "Src" .Params.image "Alt" .Params.title "Class" "w-100") }}
</a>
{{ end }}
<div data-aos="fade-up" data-aos-delay="50">
<h3 class="h5 fw-medium text-capitalize mb-2">
<div class="card-body pt-4 px-0">
<div class="post-meta mb-3 mt-2" data-aos="fade-up" data-aos-delay="50">
{{ with .Params.date }}
<div class="post-date mb-1">
<i class="fa-solid fa-calendar-days me-2"></i>{{ . | time.Format "02 Jan 2006" }}
</div>
{{ end }}
{{ with .Params.tags }}
<div class="post-categories">
<i class="fa-solid fa-folder-open me-2"></i>
{{ range $index, $tag := . }}
{{ if $index }}, {{ end }}
<span class="meta-link">{{ $tag }}</span>
{{ end }}
</div>
{{ end }}
</div>
<div data-aos="fade-up" data-aos-delay="100">
<h3 class="h5 card-title fw-normal mb-3">
<a class="text-white" href="{{ .RelPermalink }}">{{ .Params.title | markdownify }}</a>
</h3>
<p class="card-text mb-3">{{ .Params.description | truncate 115 }}</p>
<p class="card-text mb-4">{{ .Params.description | truncate 80 }}</p>
</div>
<a class="card-btn text-primary d-inline-block" href="{{ .RelPermalink | urlize }}" data-aos="fade-up" data-aos-delay="100">
Discover <i class="fa-solid fa-arrow-right-long"></i>
<a href="{{ .RelPermalink }}" class="card-btn text-primary d-inline-block" data-aos="fade-up" data-aos-delay="150">
View Project <i class="fa-solid fa-arrow-right-long"></i>
</a>
</div>
</article>
</div>

View File

@ -259,7 +259,7 @@
</div>
<div class="projects align-items-start overflow-hidden">
{{ range .Pages.ByDate.Reverse }}
{{ range first 6 .Pages.ByDate.Reverse }}
{{ .Render "project-card" }}
{{ end }}
</div>
@ -293,7 +293,7 @@
</div>
<div class="blog-wrapper">
{{ range .Pages.ByDate.Reverse }}
{{ range first 6 .Pages.ByDate.Reverse }}
{{ .Render "blog-card" }}
{{ end }}
</div>

View File

@ -5,38 +5,21 @@
<div class="row">
<div class="col-xxl-11 mx-auto">
<div class="mb-5 pb-2">
{{ if or (eq .Section "categories") (eq .Section "tags") }}
<p class="mb-3">Category</p>
{{ end }}
<h2 class="h3"><span class="text-primary pe-3 small">//</span>{{.Title | title}}</h2>
<h2 class="h3">
<span class="text-primary pe-3 small">//</span>{{ .Title | title }}
</h2>
</div>
<div class="projects align-items-start overflow-hidden">
{{range .Data.Pages}}
<div class="project-item mb-4">
<div class="card bg-dark rounded-3">
{{if .Params.image}}
<a href="{{.RelPermalink | urlize}}" class="overflow-hidden p-3">
{{ partial "image.html" (dict "Src" .Params.image "Alt" .Params.title "Class" `rounded-2`) }}
</a>
<div class="blog-wrapper">
{{ range .Pages }}
{{ .Render "project-card" }}
{{ end }}
<div class="card-body pb-4">
<div class="px-2">
<h3 class="h5 card-title fw-medium text-capitalize">
<a class="text-white" href="{{.RelPermalink}}">{{.Params.title | markdownify}}</a>
</h3>
<p class="card-text mb-3">{{.Params.description | truncate 115}}</p>
</div>
<a class="card-btn text-primary" href="{{.RelPermalink | urlize}}">Discover<i class="fa-solid fa-arrow-right-long"></i></a>
</div>
</div>
</div>
</div>
{{ end }}
</div>
</div>
</div>
</div>
</section>
{{ end }}

0
themes/professors-hugo/layouts/project/single.html Executable file → Normal file
View File