feat: add content

+2 -2
.github/workflows/deploy.yaml
···
on:
push:
branches:
-
- change-to-main-if-you-want-to-deploy-to-deno-deploy
+
- main
jobs:
deploy:
runs-on: ubuntu-latest
···
- name: Deploy to Deno Deploy
uses: denoland/deployctl@v1
with:
-
project: change-project-name
+
project: finxol-blog
entrypoint: https://deno.land/std@0.140.0/http/file_server.ts
root: .output/public
-2
app/app.vue
···
const isDark = useDark();
const toggleDark = useToggle(isDark);
-
console.log(config.title)
-
useHead({
title: config.title,
meta: [
+8
app/plugins/simpleanalytics.client.js
···
+
import SimpleAnalytics from "simple-analytics-vue";
+
+
export default defineNuxtPlugin((nuxtApp) => {
+
nuxtApp.vueApp.use(SimpleAnalytics, {
+
skip: process.env.NODE_ENV !== "production",
+
domain: "sa.finxol.io"
+
});
+
});
+11 -9
blog.config.ts
···
import { defineBlogConfig } from "./globals";
export default defineBlogConfig({
-
tableOfContents: true,
-
sharingProviders: ["bluesky", "clipboard", "native"],
-
title: "Template blog",
-
author: "Your name",
+
title: "finxol's blog",
+
author: "finxol",
meta: [
{
name: "description",
-
content: "This is a template blog",
+
content: "finxol's blog",
},
{
name: "fediverse:creator",
-
content: "your fediverse handle",
+
content: "@finxol@mas.to",
+
},
+
{
+
name: "fediverse:creator",
+
content: "@User038418@mamot.fr",
},
],
links: [
{
name: "bluesky",
-
url: "https://bsky.app/profile/yourhandle",
+
url: "https://bluesky.app/profile/finxol.io",
},
{
name: "github",
-
url: "https://github.com/yourusername",
+
url: "https://github.com/finxol",
},
{
name: "mastodon",
-
url: "https://mastodon.social/@yourhandle",
+
url: "https://mas.to/@finxol",
},
],
});
+10 -2
content/pages/about.md
···
-
This is the about page.
+
I'm Colin Ozanne, aka finxol. On this blog I write about tech stuff I find interesting.
+
I also have a [travel blog](https://colinswanderlustchronicles.com/) I've written a fair bit for.
-
Edit the content of `content/pages/about.md` to make changes.
+
I'm still a student so I don't have heaps to show for myself yet, but some good stuff is yet to come.<br>
+
Among the few things I can share, I've built a complete [carpool platform for students](https://github.com/unicovoit/unicovoit).
+
+
Staying on the topic of carpool platforms, I'm currently building a federated carpool platform called [Karr](https://karr.mobi/?utm_source=finxol-blog&utm_content=about-page).
+
It's still in very early days though, so there isn't much to show off yet.
+
+
Last potentially interesting thing is my [portfolio](https://colinozanne.fr).
+
I've kept it up to date, but haven't actively worked on it in a couple of years but it still looks decent.
+3 -4
content/pages/index.md
···
## Hi!
-
This template can be edited as you wish.
-
Have a look at the blog config in `blog.config.ts` to adjust settings.
-
-
Change this front matter in `content/pages/index.md`.
+
My name is Colin Ozanne, known online as finxol.
+
I am a French and British software developer and CS student at Université de Rennes,
+
currently building [Karr](https://karr.mobi/?utm_source=finxol-blog&utm_content=homepage).
+135
content/posts/blog-rewrite.md
···
+
---
+
title: I rewrote my blog and it was harder than I expected
+
description: The last time I changed anything on my previous blog was almost exactly 2 years ago. Wayyy too long. So I rewrote it completely.
+
date: 2024-11-14
+
authors:
+
- name: finxol
+
tags:
+
- code
+
- rants
+
published: true
+
---
+
+
I never was never quite satisfied by how my blog looked and felt.
+
When I first set it up I didn't want to bother much with it so I took the first template I found in a language and framework I knew: Nuxt.js.
+
_Spoiler: I went for Nuxt again, but for different reasons this time._
+
+
## Version one was not good
+
+
If you're curious, I'm keeping the original version up and running for a bit on [v1.finxol.io](https://v1.finxol.io/)
+
+
The starter package I used to get my blog up and running was [some random npm package](https://www.npmjs.com/package/@jsilva-pt/nuxt-content-theme-blog)
+
I found god knows where that's barely maintained.
+
Last published version was _4 years ago_, which means it was already 2 years old when I used it.
+
+
Another problem with it is that it's an npm module, so I can't fork or customise it easily.
+
+
I mentioned it was built with Nuxt, which is perfectly fine in itself, but the problem is with the version.
+
You see, Nuxt 3 was officially released almost exactly 2 years ago, so basically when I had last committed on this blog.
+
I started it only a few months before, so Nuxt 3 was already at the Release Candidate stage, yet I stuck with Nuxt 2 despite the much closer EOL to come.
+
+
Nuxt 3 is a complete rewrite, so the API changed A LOT, enough for lazy me to stick with the soon-to-be-killed framework.
+
It admittedly caused quite a mess in a number of production codebases.
+
+
Anyway, all this to say I made a bad choice when I initially built it, so I decided to start over.
+
+
## Building a new blog
+
+
I had a few requirements before starting my quest to find a suitable heir to Nuxt.
+
It has to:
+
+
1. Accept markdown.
+
I don't want to have to rewrite all my (6) previous blog posts.
+
2. Customisable — _to some extent_.
+
I'm after a simple theme, but I want to have things like external links in the nav bar, a list of posts on the home page, and an about page.
+
I don't consider these to be unreasonable asks — _please let me know if any of these sound outrageous._
+
3. Not TOO hard to setup.
+
I'll get to it in a minute, but some "easy" options are a nightmare to customise properly.
+
4. Generate to static files.
+
I don't want to bother with manual hosting, copying the files by hand everytime I make a little change,
+
but I also don't want to have a full Node server running on an expensive VPS just for a simple blog.
+
+
With these more-or-less well defined requirements in mind, I started looking at things I'd heard good things about before.
+
+
### Researching my options
+
+
#### Eleventy
+
+
I'd heard amazing things about 11ty, especially
+
[from](https://bell.bz/eleventy-excellent-truly-is-excellent/)&nbsp;
+
[Andy](https://bell.bz/importing-eleventy-content-into-wordpress/)&nbsp;
+
[Bell](https://github.com/Andy-set-studio/personal-site-eleventy).
+
I kept reading it was a solid option for static site generation.
+
So I gave it a shot.
+
+
Well let me tell you it is definitely not for the weak.
+
The syntax is quite weird in the `.njk` files.
+
+
To be fair though, it does seem fairly straightfoward to use only with markdown files and a template.
+
But unfortunately that doesn't fill in my second requirement...
+
+
#### Hugo
+
+
My starting point with Hugo was the same. I'd seen a few of my [peers](https://blog.itarow.xyz/)
+
and university friends use it, and it seemed a solid option too.
+
For some reason I deliberately chose to stay clear of it in the past, but I don't remember why.
+
+
Having tried it again, it was a fairly good call.
+
I think it's mostly the unfamiliar syntax that put me off, and I'm not a fan of TOML.
+
It's not a bad format, it's quite readable, but somehow I can't wrap my head around it and use it properly.
+
+
I was quite surprised by the nuber of themes available though: 181 themes listed under "blog" on the official themes website.
+
I managed to find one that was close enough to what I wanted, but I really struggled to customise it and make it work with my info.
+
+
#### Deno blog
+
+
Lately, I've been using and loving Deno quite a bit, so when I saw [\*the\* Deno guy's](https://tinyclouds.org/) blog was built with a [simple Deno lib](https://deno.land/x/blog@0.7.0),
+
I had to try it out.
+
+
Much to my disappointment, it didn't work with the current version of Deno.
+
I guess version 2.0 broke a few things.
+
+
Looking at it again now, it doesn't seem very customisable, if at all, so I suppose it wouldn't've been a good fit anyway.
+
+
#### VitePress
+
+
Next one I tried was VitePress. I'd barely heard of that one before, only in passing, but it's built on Vue, which I really like and know decently well.
+
+
It's supposed to be built rather for documentation websites, but I came accross a few tutorials on how to make a blog out of it,
+
so I tried that one out.
+
+
Turns out I couldn't break free from the default "docs" style template — even though I quite liked it visually,
+
so that's a no go.
+
+
#### Nuxt (again)
+
+
I can picture Nuxt looking at me laughing while I come running back to it after trying out other option.
+
+
Nuxt is a solid choice for Static Site Generation (SSG), it comes with all sorts of bells and whistles,
+
is super extensible, while still being really fast.
+
+
First I set out to find a minimalist blog template or starter to kick things off.
+
However, I couldn't find anything that I really liked during my (not hugely) extensive research.
+
+
The only logical solution is to make my own thing :)
+
+
To be clear, I didn't completely rewrite everything because that's way too time consuming for a little blog like this.
+
I just made the UI and pages, and used [Nuxt Content](https://content.nuxt.com/) along with [Tailwind](https://tailwindcss.nuxtjs.org/).
+
I'll be honest, minimum effort was big criteria in the final choice too.
+
+
### Result
+
+
If you're reading this on the actual website, then you're seeing the result.
+
Not too bad for an afternoon's work!
+
+
The website is really fast and snappy, as expected for a simple blog like this.
+
Hosting is dead simple and pretty fast with Github Pages too.
+
+
And that's some pretty damn good results from PageSpeed Insight.
+
+
![PageSpeed Insight result](/posts/blog-rewrite/pagespeed-insight-result.jpg)
+
+
## Publish it as a blog starter
+
+
I want to help out the comunity along the way, so I'll adjust a few things to make it into a template repo to use as a starter,
+
in case anyone out there is looking to build a simple markdown blog with Nuxt.
+104
content/posts/extending-openauth.md
···
+
---
+
title: Extending OpenAuth
+
description: I needed a self-hostable auth solution for the project I'm working on. OpenAuth's beautiful simplicity looked really promising. There were just a couple things I wanted adjusted, so I spent a weekend fixing then.
+
date: 2025-03-31
+
authors:
+
- name: finxol
+
tags:
+
- code
+
- open source
+
published: true
+
---
+
+
I'm currently building [Karr](https://karr.mobi/?utm_source=finxol-blog&utm_content=openauth-post), an open-source federated carpool platform—it's still very early days, not much there yet.
+
Like basically all apps nowadays, I need an auth system.
+
+
The only strong requirement I have is for it to be self-hostable.
+
Since I'm building a federated platform for companies, I don't want instance admins to have to rely on some arbitrary external auth service.
+
+
This limited my options a fair bit.
+
I considered a few other options, but I soon landed on OpenAuth.
+
+
## OpenAuth
+
+
If you haven't already heard of it, [OpenAuth](https://openauth.js.org/) is a pretty new open-source authentication library by the authors of [SST](https://sst.dev/).
+
+
The intent is for it to be "Universal, Self-hosted, Standards-based, and Customizable".
+
Promising stuff.<br/>
+
They also mention right on the home page that it can be "embed it into an existing application".
+
Perfect.
+
+
There's more. OpenAuth is built with Hono, and so is my API.
+
That means I can integrate it directly into my existing API!
+
+
There is however a slight half-truth in there.
+
Running OpenAuth from anything other than the root path (`/`) isn't supported yet, but I really wanted to avoid making a whole other Docker container or crazy path rewrites with the reverse proxy, so I went and implemented it myself.
+
+
## Sub-paths
+
+
Apparently, I'm not the first one to run into this issue.
+
Some people have already been [thinking of solutions](https://github.com/toolbeam/openauth/issues/125) for a couple months.
+
+
However, their approach didn't seem very robust and maintainable to me.
+
It involved looking through the codebase and finding every redirect, and adding the base path to them.
+
+
To me that sounds: 1. super tedious, and 2. hardly maintainable.
+
It would involve all future contributors and maintainers remembering to add the base path to each local url.
+
It seems to me like a mistake could easily slip through.
+
+
So instead, I went for a middleware approach.
+
+
If a base path is specified, all local redirect reponses will be rewritten to include it.
+
For example, a redirect to `/github/authorize` will be rewritten as `/auth/github/authorize` if OpenAuth is mounted at `/auth`.
+
+
All that was left to do was include the base path in the issuer, and remove it when building well-known routes.
+
I managed to get it working 45-ish lines of actual code—the rest is docs and tests—so it's a pretty minimal solution!
+
+
### Spec compliance
+
+
The first spec they mentioned in the issue, [RFC 5785](https://www.rfc-editor.org/rfc/rfc5785.txt), states that all Well-Known URIs must be at the root, so at `/.well-known/`.
+
+
[RFC 8414](https://www.rfc-editor.org/rfc/rfc8414.txt) also states that the Well-Known URI is obtained by "inserting a well-known URI string into the authorization server's issuer identifier between the host component and the path component, if any", e.g. if the issuer is `https://example.org/auth`, the well-known paths would be under `https://example.org/.well-known/*`
+
+
This means there needs to be some sort of rewrite/redirect from the root well-known URIs to the path where OpenAuth is mounted.
+
+
This is an annoying caveat, but I don't see any way to manage it directly inside OpenAuth since the whole point of this base path stuff is to not have it manage the root path.
+
It needs to be handled externally by whatever manages the root path, whether it be by a reverse proxy, a router, or a switchboard operator.
+
+
Best I could do is put a massive warning in the docs next to the `basePath` option.
+
+
Now I just need to wait for feedback [on my PR](https://github.com/toolbeam/openauth/pull/236) and hopefully a merge.
+
+
+
## Storage Adapters
+
+
The second annoyance I had with OpenAuth was the built-in storage adapters.
+
All they offered was either DynamoDB, Cloudflare KV or in-memory with a `Map` object.
+
+
Obviously, the latter isn't usable in a real production environment,
+
but the other 2 aren't any good to me either for the same reason as my self-hosted auth requirement.
+
I can't have instance admins rely on AWS or Cloudflare just for an auth KV.
+
+
So again, I went and did an adapter myself.
+
+
Of course, I didn't make a whole KV solution for Node.
+
I simply made a wrapper around [unstorage](https://unstorage.unjs.io/).
+
As of writing this, they have 21 drivers of all sorts.
+
The one I find particularly interesting is the SQL driver, although still experimental.
+
+
Building the adapter was simply a case of copy-pasting OpenAuth's `MemoryAdapter` and replacing the `Map` function calls with those of unstorage.
+
Very straightforward and automatable stuff.
+
+
There was however one slight snag.
+
+
When calling `.setItem(key, value)`, the key is used as it is.
+
However, when calling `.getKeys(base)`, the base is treated as a prefix and gets normalized, aka. it gets appended a semicolon.
+
+
This is a problem for use in OpenAuth.
+
The Storage API here has its own `joinKey(key)` method which joins the keys with `String.fromCharCode(0x1f)` as a separator, not a semicolon.
+
+
This difference means the keys won't be found when calling `.getKeys(base)`, so for the purposes of OpenAuth, unstorage needs a small patch to remove the semicolon addition for its internal `normalizeBaseKey(base)` function.
+
+
Since unstorage opens up a lot of possibilities for storage, I also [opened a PR](https://github.com/toolbeam/openauth/pull/235) for this one.
+
+
While I wait for my PRs to be merged, I'm just using both with pnpm patches.
-21
content/posts/first-post.md
···
-
---
-
title: This is the first post
-
description: Write a short description for the post to show it on the home page and at the top of the post.
-
date: 2025-05-26
-
authors:
-
- name: Your name
-
tags:
-
- post
-
published: true
-
---
-
-
Here is where you can write your post content.
-
-
All markdown is supported, including [links](https://example.com), **bold**, *italic*, and `code`.
-
-
Find out more about MDC syntax [in the Nuxt Content documentation](https://content.nuxt.com/docs/files/markdown).
-
-
## Headings
-
-
By default, headings will generate a table of contents at the top of the page.
-
You can disable this behavior by setting `tableOfContents: false` in the blog config.
+115
content/posts/gdpr.md
···
+
---
+
title: All You Need To Know About GDPR
+
description: GDPR is a series of laws and regulations adopted in May 2016 by the European Parliament and Council to enable EU citizens to have better control over their data online.
+
image: /blog/european_union_padlock.png
+
date: 2020-11-15
+
authors:
+
- name: finxol
+
tags:
+
- GDPR
+
- Thoughts
+
published: true
+
---
+
+
The GDPR, or General Data Protection Regulation, is a series of laws and regulations adopted in May 2016 by the European
+
Parliament and Council to enable European Union citizens to have better control over their data online.
+
It has been in effect from 25 May 2018.
+
+
To all non-european readers, this article is mainly intended to europeans, but you can still read the first two parts to
+
know more about GDPR.
+
You're not directly affected by it, but this initiative has sparked other data protection laws like
+
the [Consumer Privacy Act in California](https://www.osano.com/articles/gdpr-vs-ccpa).
+
+
## What is GDPR ?
+
+
The intent of GDPR was to gives european citizens more control over what data about them is stored and for how long.
+
+
That way, european citizens are legally backed up by the EU in terms of data protection and people or organisations who
+
use digital services are obliged to state what data they keep about you and what they do with it.
+
+
The other great point about GDPR is that it applies to everyone operating in the EU, so european citizens aren't only
+
protected on websites but also at work or even on the streets !
+
+
But it's also enforceable for companies and corporations.
+
+
## What it has already done
+
+
Over the 4 and a half years since it has been acted, it has enabled several Courts of Justice within the EU to deliver
+
some, sometimes very expensive, fines to tech companies, but not only.
+
+
You can't really draw up a typical profile for people who received the 410 fines given out so far.
+
Some were given to companies, others to individuals, political parties, restaurants, universities, airports,
+
institutes...
+
+
Recently, H&M got fined 35,258,707.95€ in Germany for tracking its employees, and British Airways got fined 22,000,000€
+
for being hacked as British Information Commissioner ICO said this hack was preventable.
+
The Dutch National Credit Register BKR was also fined 830,000€ by the Dutch Data Protection Authority for making their
+
customers pay to access their private information.
+
Even an individual person was hit by an 8,000€ fine for having CCTV cameras monitoring public space in Greece.
+
+
The largest fine given so far was by French Data Protection Authority CNIL to Google, who had to pay 50,000,000€.
+
The smallest was given by the Estonian Data Protection Authority to a police officer in Estonia, who was fined 48€.
+
+
Although not directly linked to
+
GDPR, [the EU also fined Google 1,490,000,000€](https://www.theguardian.com/technology/2019/mar/20/google-fined-149bn-by-eu-for-advertising-violations)
+
as part of its war on GAFAM.
+
+
## How to use your rights
+
+
These laws also directly give you some power over your data.
+
+
Your rights are :
+
+
- The right to request reading and retrieval of your data
+
- The right to request rectification of your data
+
- The right to request deletion of all or part of your data
+
+
In short, GDPR theoretically gives you complete access and control over your personal data.
+
But sadly, reality is a little more complex, as some website and services use what are
+
called ['dark patterns'](https://www.wired.com/story/how-to-spot-avoid-dark-patterns/) to try and discourage you from
+
using your rights.
+
+
Concretely, they offer these options (because they are legally obliged to) but hide them in lots of different sub-menus
+
and complicated access paths to make it as hard as possible to use them.
+
And that isn't illegal.
+
+
Still, we're not going to go into much detail about that problem in this article, so let's move on to how to use your
+
rights.
+
+
To help you use your rights, many websites have been created. Here are a useful links :
+
+
- With [JustDeleteMe](https://justdeleteme.xyz/), you can find information on how easy it is to delete your account
+
on many websites, but also details and links to help you do so.
+
- You can download all the data from your Google account with help from
+
[this Google help page](https://support.google.com/accounts/answer/3024190).<br>
+
Before you do so, you should know that this procedure will download everything you have ever saved with Google
+
services,
+
so if you've had your account for a long time the file will be very big, and you will need a lot of time ahead of you
+
to read everything !
+
- You can download all the data from your Facebook account with help
+
from [this article from FossBytes](https://fossbytes.com/download-facebook-data-copy/).
+
As for Google this will download everything, so if you use social media a lot — not only posts, but also comments,
+
likes, conversations... — the file will be big.
+
+
For other online services or companies which don't directly offer a retrieval or deletion option from their website, you
+
can email them asking to do so.
+
You can find help for writing this letter on
+
the [ICO's website](https://ico.org.uk/your-data-matters/your-right-to-get-copies-of-your-data/preparing-and-submitting-your-subject-access-request/)
+
.
+
+
They should answer favourably to your request, but if they don't reply after several enquiries or refuse to comply with
+
your request, you are entitled to start a legal challenge against them.
+
You should only go that far if the data is very sensitive or if the company isn't too big, as that kind of procedure is
+
often very long and costly.
+
+
Alternatively, you get in touch with a consumer association.
+
They can usually talk with companies more easily than individuals, or group together the requests of several people to
+
have more weight against larger companies.
+
+
<br><br>
+
+
*External resources :
+
[GDPR Information from the European Commission website](https://ec.europa.eu/info/law/law-topic/data-protection/data-protection-eu_en)
+
,
+
[Every GDPR fine since 2018](https://www.privacyaffairs.com/gdpr-fines/),
+
[What counts as personal data ?](https://www.which.co.uk/consumer-rights/advice/what-counts-as-personal-data-according-to-gdpr)*
+23
content/posts/tiny-auth-server.md
···
+
---
+
title: I made a small auth server template for Deno Deploy
+
description: I've fallen in love with Deno and its Deploy service, but also OpenAuth, so I made a simple template to deploy OpenAuth to Deno Deploy, using Deno KV for storage.
+
date: 2025-05-26
+
authors:
+
- name: finxol
+
tags:
+
- auth
+
- open source
+
published: true
+
---
+
+
I'm currently messing around with Deno Deploy to build a tiny little service for myself, and I needed authentication—all apps need auth nowadays, url scanners are out of control.
+
+
I didn't really want to have the auth server coupled with the main service, so I just made it into a [separate repository](https://github.com/finxol/auth).
+
The advantage here is that it's very minimal, so it runs for free no problem.
+
+
It's just a very basic wrapper around OpenAuth, using Deno KV for storage. It took me an afternoon to put together properly,
+
but if you need a little auth server and not bother too much, this might be a good starting point.
+
+
With that, I can now use my own domain to authenticate users, and I only need my url and client id key.
+
+
So go crazy, [follow the instructions](https://github.com/finxol/auth#deploy) in the README, and deploy it to Deno Deploy!
+43
content/posts/unicovoit-initial-release.md
···
+
---
+
title: UniCovoit's intial release!
+
description: After four and half months, countless hours of work and 872 commits, the carpool app made for students by students is finally out!
+
image: /blog/unicovoit.png
+
date: 2022-09-04
+
authors:
+
- name: finxol
+
tags:
+
- Launch
+
- Release
+
- UniCovoit
+
published: true
+
---
+
+
I often use carpooling applications to get home to my parents.
+
At my university, there is a student group chat that allows students to exchange and in particular to get in touch with travelers for carpooling.
+
+
The process is quite cumbersome, only works if the driver sees the message before it gets lost in other conversations, and only reaches a small group of people.
+
+
An idea then crossed my mind.
+
It would be much easier to have an app like BlaBlaCar,
+
but only between students and without the heavy fees charged by the company.
+
+
So began the IUCovoit project, a contraction of the words IUT and Carpooling, later renamed UniCovoit, more inclusive of any university.
+
+
I started working on the project a couple of weeks after getting the idea, just the time to let it settle in my head.
+
I was also motivated by the fact that I had to isolate for a week after testing positive for Covid-19.
+
Though times, they were...
+
+
During that week, I spent basically every woken hour learning how to use Nuxt 2 and Vuetify.
+
I chose these technologies for the very simple reason that someone at my university had used them extensively to build a website to access our timetables easier, which meant I had an exit strategy in case I got hopelessly stuck.
+
I've got to say that was a pretty good idea for the beginning, it came in handy a couple times.
+
+
When I finally got out, I continued working on the project, just not so intensively.
+
+
I had to pause the work a few times as well because of uni work, ugh 😒.
+
+
Then came the summer break, which weren't much of a break for the most part, as I was working tirelessly on UniCovoit.
+
I wanted to be ready for a big launch at the beginning of September when we go back to university.
+
+
While working over the summer was definitely worth it and I managed to finish everything on time, I am absolutely exhausted for September.
+
+
Nonetheless, I am very proud to announce that UniCovoit is now open for business! (not literally business, I don't actually make any money)
+83
content/posts/writeup-404ctf-osint-aube-d-un-echange.md
···
+
---
+
title: 404CTF Write-Up À l'aube d'un échange
+
description: Write-up for the OSINT challenge "À l'aube d'un échange" @ 404CTF 2022
+
image: /blog/404ctf.png
+
date: 2022-06-08
+
authors:
+
- name: finxol
+
tags:
+
- writeup
+
- 404ctf
+
- OSINT
+
published: true
+
---
+
+
## 404CTF
+
+
The [404CTF](https://404ctf.fr) is a CTF organized by the Direction Générale de la Sécurité Extérieure (DGSE), Télécom SudParis and
+
its association Hackademint.
+
This 2022 edition marked the double anniversary of "the 80th anniversary of the BCRA, the secret service of the Free France and
+
the 40th anniversary of its heir, the DGSE".
+
+
### Description
+
+
*This is a translation of the original description in French.*
+
+
New recruit! We need you around here.
+
One of our agents has just intercepted a short telephone conversation between two Hallebarde agents.
+
An important exchange of confidential documents is to take place and to indicate the location of the meeting,
+
one of the enemy agents has sent the following picture to his colleague with the following message:
+
+
<blockquote
+
style="border-left: 4px solid #e0e0e0; padding: 0 0 0 1rem;border-radius: 0.1rem; margin: 1rem 2rem;line-height: 1.5rem"
+
>
+
What a beautiful sunrise, isn't it? I'll be waiting in the street between the building in the foreground and those in the background.
+
See you tonight, 10pm.
+
</blockquote>
+
+
We have less than a day to find out the name of the street and prevent the exchange!
+
+
Flag format: 404CTF{md5 of the full street name}.<br>
+
The street name must be in lower case, include the type of street (e.g. avenue, street, boulevard...),
+
without accents, without abbreviations, and all spaces must be replaced by dashes.
+
For example: if the street is Avenue de Saint-Mandé in Paris, the correct flag is `404CTF{129af9edde5659143536427f9a5f659a}`.
+
+
Author : **Artamis**
+
+
![Place to find](/posts/writeup-404ctf-osint-aube-d-un-echange/Lieu.jpg)
+
+
+
## Solution
+
+
Before starting this OSINT investigation, lets analyse the image provided.
+
+
We can immediately check that there is no useful exif data.
+
According to the instructions, it is a rising sun, so we can assume that the picture was taken facing east.
+
Three prominent buildings can also be clearly seen in the background.
+
+
Before going further, we will assume that this is a French city and look for a list of the tallest buildings in France.
+
+
We then come across the Wikipedia page on [France's tallest skyscrapers](https://fr.wikipedia.org/wiki/Liste_des_plus_hauts_gratte-ciel_de_France).
+
Looking at the images associated with the towers, we notice that the third one looks remarkably similar to the one in our photo.
+
+
![Liste des plus hauts gratte-ciel de France](/posts/writeup-404ctf-osint-aube-d-un-echange/wiki_liste_gratte_ciel.png)
+
+
By simply reading the Wikipedia description of the Tour Incity, we find a link to the Part-Dieu district page.
+
Fortunately for us, the viewpoint of the description image is very similar to the one of our photo.
+
The description also states that this photo was taken "from Fourvière".
+
+
![Page Wikipédia de la Part-Dieu](/posts/writeup-404ctf-osint-aube-d-un-echange/wiki_part_dieu.png)
+
+
We can now start to search with [Google Earth](https://earth.google.com/web/@45.7589869,4.82472116,199.71703945a,1402.6169008d,35y,9.91010942h,69.22260348t,0r) for places around Fourvière or further west,
+
probably higher than the rest of the city.
+
We can then see that the Fourvière district is located on a hill.
+
+
![Quartier de Fourvière Google Earth](/posts/writeup-404ctf-osint-aube-d-un-echange/google_earth_fourviere.png)
+
+
Exploring the surroundings, we soon find a building on the East side of the hill which looks like the one in the background of our photo.
+
+
![Bâtiment Montée Saint Barthélémy](/posts/writeup-404ctf-osint-aube-d-un-echange/google_earth_montee_st_barth.png)
+
+
The street below this building is called the *Montée Saint Barthélémy*.
+
We can then format and hash this street name with `echo -n "montee-saint-barthelemy" | md5sum`,
+
which gives us the flag `404CTF{eb66c65861da9fe667f26667b3427d2c}`.
+82
content/posts/writeup-404ctf-web-fiche-js.md
···
+
---
+
title: 404CTF Write-Up Fiché JS
+
description: Write-up for the web challenge "Fiché JS" @ 404CTF 2022
+
image: /blog/404ctf.png
+
date: 2022-06-04
+
authors:
+
- name: finxol
+
tags:
+
- writeup
+
- 404ctf
+
- web
+
published: true
+
---
+
+
## 404CTF
+
+
The [404CTF](https://404ctf.fr) is a CTF organized by the Direction Générale de la Sécurité Extérieure (DGSE), Télécom SudParis and
+
its association Hackademint.
+
This 2022 edition marked the double anniversary of "the 80th anniversary of the BCRA, the secret service of the Free France and
+
the 40th anniversary of its heir, the DGSE".
+
+
### Description
+
+
*This is a translation of the original description in French.*
+
+
After several months of digging into Hallebarde's past, we found an old file hosting platform that they used up until 2010.
+
That's 12 years ago now!
+
Security practices have changed radically since then and what seemed unbreakable then may not be so at all anymore.
+
+
Your move: find a way to bypass the existing protection system and recover the files still hosted on this site!
+
+
Author : **Artamis**
+
+
## Solution
+
+
At first, we only find a page containing a number pad.
+
+
![Landing page](/posts/writeup-404ctf-web-fiche-js/page-web.png)
+
+
From there, we can open our browser's developer console in order to find what is hidden behind this numpad.
+
+
In the "Debugger" tab, we immediately notice a javascript file named `index.js`.
+
After a quick read, we realise that this is the part that controls the number pad.
+
+
There are several places that can be used to validate an entry code.
+
Around line 129, there is an alternative that reacts to a key press on the keyboard.
+
+
```js
+
switch (e.keyCode) {
+
case 8:
+
backspaceOnPin();
+
break;
+
case 13:
+
confirmPin(STATE.enteredPin);
+
break;
+
default:
+
break;
+
}
+
```
+
+
The `keyCode` 13 corresponds to the enter key.
+
We can therefore set a breakpoint here by clicking on line number 129 to examine the behaviour of the `confirmPin()` function.
+
Once the breakpoint is set, we can simulate a validation by pressing the enter key.
+
+
The execution then halts correctly just before the `confirmPin()` function is called.
+
We can then do F11, or *Step Into*, which brings us to what looks like a small file.
+
+
```js
+
/* FONCTIONNEMENT */
+
var key = $(".keypad").keypad(function (pin) {
+
if (pin == "240801300505131273100172") {
+
document.location.href = "./nob03y_w1lL_Ev3r_fiNd_th15_PaGe.html";
+
}
+
});
+
```
+
+
The code check is just a simple comparison, but it is not the code that we are interested in here.
+
Indeed, if the code is correct, we are redirected to a supposedly hidden page.
+
+
It is indeed on this mystery page that we find the flag, as well as the list of all the agents of Hallebarde.
+
+
![Flag](/posts/writeup-404ctf-web-fiche-js/flag.png)
+80
content/posts/writeup-heroctf-prog-ssh.md
···
+
---
+
title: HeroCTF Write-Up SSHs
+
description: Write-up for the programming challenge "SSHs" @ HeroCTF 2022
+
image: /blog/heroctf.jpg
+
date: 2022-05-30
+
authors:
+
- name: finxol
+
tags:
+
- writeup
+
- HeroCTF
+
- prog
+
published: true
+
---
+
+
### Description
+
+
Every user can read the private rsa key of the next user. You just have to grab it, and ssh as the next. But... there
+
are 250 ?!?<br>
+
Let's automate it ! (The last user has a *flag.txt* at the root of his home directory)
+
+
The base credentials are:
+
+
<code-group>
+
<code-block label="Username" active>
+
+
user1:password123
+
+
</code-block>
+
<code-block label="Host">
+
+
Host : xxxx.heroctf.fr
+
Port : xxxx
+
+
</code-block>
+
</code-group>
+
+
Format : **Hero{flag}**<br>
+
Author : **Log_s**
+
+
+
## Solution
+
+
Before doing anything else, let's just login as the base user to have a look around.
+
+
With a simple `ssh user1@xxxx.heroctf.fr` and using `password123` as the password,
+
we can get ssh access to the machine as `user1`.
+
+
Once logged in, we can see that in the home directory, there is an executable file called `getSSHKey`,
+
which simply returns the SSH key of the next user as plaintext.
+
We also know from the description of the challenge that there are 249 users.
+
+
With this information, we can now write a simple bash script to automate the retrieval of the SSH keys and, in turn, the flag.
+
(sorry not sorry Windows users)
+
+
The use of `sshpass` instead of the plain old `ssh` for the first login enables us to give the password
+
directly as a command argument instead of being prompted to enter it manually.<br>
+
The use of `1>` at the end of each command redirects the standard output (stdout not stderr) to a specified file;
+
here the file is used to save the key.
+
+
```bash
+
# Log into the first user and save the key of the next user to a file named id1
+
sshpass -p password123 ssh user1@chall.heroctf.fr -p 10045 "./getSSHKey" 1> id1
+
+
# For each user, log in using the previously fetched key, and save the next key in a file name idX,
+
# where X is the number of the current iteration
+
for i in {2..249}
+
do
+
prev=id$(expr $i - 1)
+
# Set the correct permissions for the ssh key
+
chmod 600 $prev
+
# Retrieve the next ssh key
+
ssh -i "${prev}" user${i}@chall.heroctf.fr -p 10045 "./getSSHKey" 1> id${i}
+
done
+
+
# For the last user, instead of calling getSSHKey, we simply print the contents of flag.txt
+
ssh -i id249 user250@chall.heroctf.fr -p 10045 "cat flag.txt"
+
```
+
+
Et voilà!
+
We can now simply wait for the programme to execute and the flag will magically appear a few seconds later!
+90
content/posts/writeup-midnightflag-osint-will-the-big-wheel.md
···
+
---
+
title: MidnightFlag CTF Write-Up Will the big wheel
+
description: Write-up for the OSINT challenge "Will the big wheel" @ 404CTF 2022
+
image: /blog/infektionctf.png
+
date: 2022-04-24
+
authors:
+
- name: finxol
+
tags:
+
- writeup
+
- MidnightFlagCTF
+
- OSINT
+
published: true
+
---
+
+
## 404CTF
+
+
The [MidnightFlag CTF](https://midnightflag.fr/) is a CTF organised by students from [ESNA](https://www.esna.bzh/)
+
+
### Description
+
+
Our intelligence services have just received a message from one of our agents in the USSR and according to the first elements,
+
we must quickly find him to exfiltrate him.
+
Your mission is to decode his message and return the extraction location to us.
+
+
![Message Recover](/posts/writeup-midnightflag-osint-will-the-big-wheel/MessageRecover.png)
+
+
Author: **A0d3n**
+
+
## Solution
+
+
First of all, let's check the metadata from the image we were given.
+
With a simple `exiftool MessageRecover.png`, we get the following information *(some information was removed for clarity)* :
+
+
```
+
ExifTool Version Number : 12.38
+
File Name : MessageRecover.png
+
Directory : .
+
File Size : 23 KiB
+
MIME Type : image/png
+
Image Width : 532
+
Image Height : 284
+
Bit Depth : 8
+
Color Type : RGB with Alpha
+
Compression : Deflate/Inflate
+
Filter : Adaptive
+
Resolution Unit : inches
+
Y Cb Cr Positioning : Centered
+
Copyright : MidnightFlag
+
Exif Version : 0232
+
Components Configuration : Y, Cb, Cr, -
+
User Comment : WzUxLjQwMzA5LCAzMC4wNDQwMXw1MS40MDc4OSwgMzAuMDU1NjR8NTEuNDAwODksIDMwLjA2NDA4XSwgSSB3SUxsIHdBSXQgWW9VIGFUIHRIZSBjRW50RVIu
+
Flashpix Version : 0100
+
Owner Name : A0d3n
+
Image Size : 532x284
+
```
+
+
One line that catches our eye is the "User Comment".
+
This looks like it could be some base64-encoded text.
+
Let's try to decode it with
+
```sh
+
echo -n "WzUxLjQwMzA5LCAzMC4wNDQwMXw1MS40MDc4OSwgMzAuMDU1NjR8NTEuNDAwODksIDMwLjA2NDA4XSwgSSB3SUxsIHdBSXQgWW9VIGFUIHRIZSBjRW50RVIu" | base64 --decode
+
```
+
+
And we get
+
+
```
+
[51.40309, 30.04401|51.40789, 30.05564|51.40089, 30.06408], I wILl wAIt YoU aT tHe cEntER.
+
```
+
+
These look like coordinates.
+
The first one seems to be in the north of Ukraine, and the other ones are close by.
+
+
![First GPS Coordinate](/posts/writeup-midnightflag-osint-will-the-big-wheel/first_gps_point.png)
+
+
The decoded message also says "I will wait you at the center".
+
We can assume from this sentence that the agent will be waiting at center of these three coordinates.
+
+
With a quick search about averaging GPS coordinates, we land a javascript programme [on Github Gist](https://gist.github.com/tlhunter/0ea604b77775b3e7d7d25ea0f70a23eb).
+
We can then tweak an example case to match our coordinates, and we get a result!
+
+
![Calculating the average coordinate](/posts/writeup-midnightflag-osint-will-the-big-wheel/average_coord.png)
+
+
By plotting these coordinates on a map, we land [near the amusement park](https://www.google.com/maps/place/Pripyat+amusement+park/@51.4053954,30.0488085,2337m/data=!3m1!1e3!4m13!1m7!3m6!1s0x0:0x8b035e1594d47a36!2zNTHCsDI0JzE0LjMiTiAzMMKwMDMnMTYuNSJF!3b1!8m2!3d51.403957!4d30.0545768!3m4!1s0x472a7c5de9f5c0fb:0x87aa178315dd0d18!8m2!3d51.4078925!4d30.055647)
+
where the wheel in the picture can be found.
+
+
We then look at the nearest point of interest, and we find **Чорнобиль**, which means Tchernobyl.
+
+
![Average coordinate on a map](/posts/writeup-midnightflag-osint-will-the-big-wheel/flag.png)
+
+
We then format the word with `echo -n "Чорнобиль" | md5sum` and get the flag `MCTF{3687016d7a89edc046069933f208e8c8}`.