switched theme

This commit is contained in:
2026-04-02 13:14:18 +03:00
parent 0c26d89eae
commit e31dbbb16c
192 changed files with 215173 additions and 1463 deletions
+3 -3
View File
@@ -1,7 +1,7 @@
+++
title = "Posts"
template = "posts.html"
page_template = "post.html"
sort_by = "date"
insert_anchor_links = "left"
template = "posts.html"
page_template = "page.html"
paginate_by = 10
+++
+1 -1
View File
@@ -10,6 +10,6 @@ tags = ["obsidian", "entropy", "notes"]
Take control of your artifacts
In my endless endevours to find the perfect note taking app led me to obsidian, a note taking software that uses markdown files as the file format. All software is ephemereal in nature and yoour artifacts need to survive the decline of your favorite app. The files you create should be available to you and shouldt rrequire specialized software to access.
In my endless endevours to find the perfect note taking app led me to obsidian, a note taking software that uses markdown files as the file format. All software is ephemereal in nature and yoour artifacts need to survive the decline of your favorite app. The files you create should be available to you and shouldt rrequire specialized software to access.
Your data shouldt be locked behind a paywall or an authentication system that is not under your control.
+1 -1
View File
@@ -13,7 +13,7 @@ Cognitive inertia is the reason changing our habits can be difficult. If you wan
## Metawork
I will define this as the things we do before getting the "real" work doe. Its things like choosing the best IDE or text editor, setting up your coding environment, choosing the best note taking app, or even the 'best' operating system. They are the prerequisites of the actual work.
I will define this as the things we do before getting the "real" work doe. Its things like choosing the best IDE or text editor, setting up your coding environment, choosing the best note taking app, or even the 'best' operating system. They are the prerequisites of the actual work.
I had been stuck on this loop, always trying to craft the perfect workflow. Setting up the best personalized linux distro, switching note taking apps, trying out multiple layouts, stylings and technologies for my blog, the list is endless.
@@ -1,5 +1,5 @@
+++
title ="Install PostgreSQL on Arch | Manjaro | Garuda Linux"
title = "Install PostgreSQL on Arch | Manjaro | Garuda Linux"
description = "Getting PostgreSQL up and running on Arch Linux-based distros"
date = 2023-02-16T15:34:14.160Z
author = "mockingspectre"
+21 -26
View File
@@ -4,7 +4,7 @@ description = "Integrating netlify cms"
date = 2022-11-24T15:34:14.160Z
author = "mockingspectre"
[taxonomies]
tags = ["blog", "hugo", "netlify","netlify-cms","github"]
tags = ["blog", "hugo", "netlify", "netlify-cms", "github"]
+++
Migrating to a better content management system through Netlify CMS
@@ -83,32 +83,27 @@ backend:
# This line should *not* be indented
publish_mode: editorial_workflow
media_folder: "static/images/uploads" # Media files will be stored in the repo under static/images/uploads
public_folder: "/images/uploads" # The src attribute for uploaded media will begin with /images/uploads
media_folder: 'static/images/uploads' # Media files will be stored in the repo under static/images/uploads
public_folder: '/images/uploads' # The src attribute for uploaded media will begin with /images/uploads
collections:
- name: "post" # Used in routes, e.g., /admin/collections/blog
label: "posts" # Used in the UI
folder: "content/post" # The path to the folder where the documents are stored
- name: 'post' # Used in routes, e.g., /admin/collections/blog
label: 'posts' # Used in the UI
folder: 'content/post' # The path to the folder where the documents are stored
create: true # Allow users to create new documents in this collection
slug: "{{year}}-{{month}}-{{day}}-{{slug}}" # Filename template, e.g., YYYY-MM-DD-title.md
slug: '{{year}}-{{month}}-{{day}}-{{slug}}' # Filename template, e.g., YYYY-MM-DD-title.md
fields: # The fields for each document, usually in front matter
- { label: "Layout", name: "layout", widget: "hidden", default: "blog" }
- { label: "Title", name: "title", widget: "string" }
- { label: "Draft", name: "draft", widget: "boolean", default: true }
- { label: "Publish Date", name: "date", widget: "datetime" }
- { label: "Last Modified", name: "lastmod", widget: "datetime" }
- { label: "Body", name: "body", widget: "markdown" }
- { label: "Keywords", name: "keywords", widget: "list" }
- { label: "Tags", name: "tags", widget: "list" }
- { label: "Categories", name: "categories", widget: "list" }
- { label: "Comments", name: "comment", widget: "boolean", default: true }
- {
label: "Table of Contents",
name: "toc",
widget: "boolean",
default: true,
}
- { label: 'Layout', name: 'layout', widget: 'hidden', default: 'blog' }
- { label: 'Title', name: 'title', widget: 'string' }
- { label: 'Draft', name: 'draft', widget: 'boolean', default: true }
- { label: 'Publish Date', name: 'date', widget: 'datetime' }
- { label: 'Last Modified', name: 'lastmod', widget: 'datetime' }
- { label: 'Body', name: 'body', widget: 'markdown' }
- { label: 'Keywords', name: 'keywords', widget: 'list' }
- { label: 'Tags', name: 'tags', widget: 'list' }
- { label: 'Categories', name: 'categories', widget: 'list' }
- { label: 'Comments', name: 'comment', widget: 'boolean', default: true }
- { label: 'Table of Contents', name: 'toc', widget: 'boolean', default: true }
```
**Step 5**
@@ -137,10 +132,10 @@ Lastly, we will add the following script before the closing `<body>` tag of our
```html
<script>
if (window.netlifyIdentity) {
window.netlifyIdentity.on("init", (user) => {
window.netlifyIdentity.on('init', (user) => {
if (!user) {
window.netlifyIdentity.on("login", () => {
document.location.href = "/admin/";
window.netlifyIdentity.on('login', () => {
document.location.href = '/admin/';
});
}
});
+18 -18
View File
@@ -30,7 +30,7 @@ module.exports = function add(a, b) {
// export an object
module.exports = {
name: "Alice",
name: 'Alice',
age: 25,
};
```
@@ -40,11 +40,11 @@ To import a module in Node.js, you can use the require function and pass the pat
```javascript
// main.js
// import a function
const add = require("./my-module.js");
const add = require('./my-module.js');
console.log(add(2, 3)); // 5
// import an object
const person = require("./my-module.js");
const person = require('./my-module.js');
console.log(person.name); // Alice
console.log(person.age); // 25
```
@@ -53,7 +53,7 @@ Note that Node.js will cache the modules that are imported with require, so if y
## How to export modules in ES6?
ES6 is the version of Javascript that introduced many new features, including a native module system. ES6 modules use the `import` and `export` syntax.
ES6 is the version of Javascript that introduced many new features, including a native module system. ES6 modules use the `import` and `export` syntax.
To export a module in ES6, you can use the `export` keyword followed by the declaration of the value that you want to export. You can also use the export keyword with curly braces to export a list of named values. For example:
@@ -74,7 +74,7 @@ export class Person {
// export an object
export const person = {
name: "Alice",
name: 'Alice',
age: 25,
};
```
@@ -84,17 +84,17 @@ To import a module in ES6, you can use the `import` keyword followed by the name
```javascript
// main.js
// import a function
import { add } from "./my-module.js";
import { add } from './my-module.js';
console.log(add(2, 3)); // 5
// import a class
import { Person } from "./my-module.js";
const person = new Person("Bob", 30);
import { Person } from './my-module.js';
const person = new Person('Bob', 30);
console.log(person.name); // Bob
console.log(person.age); // 30
// import an object
import { person as Alice } from "./my-module.js";
import { person as Alice } from './my-module.js';
console.log(Alice.name); // Alice
console.log(Alice.age); // 25
```
@@ -138,7 +138,7 @@ module.exports = function add(a, b) {
// export an object
module.exports = {
name: "Alice",
name: 'Alice',
age: 25,
};
@@ -158,17 +158,17 @@ To import a default export, you can use the import keyword without curly braces
```javascript
// main.js
// import a default export
import add from "./my-module.js";
import add from './my-module.js';
console.log(add(2, 3)); // 5
// import another default export
import person from "./my-module.js";
import person from './my-module.js';
console.log(person.name); // Alice
console.log(person.age); // 25
// import another default export
import Person from "./my-module.js";
const person = new Person("Bob", 30);
import Person from './my-module.js';
const person = new Person('Bob', 30);
console.log(person.name); // Bob
console.log(person.age); // 30
```
@@ -178,17 +178,17 @@ To import a module.exports value, you can use the require function and assign an
```javascript
// main.js
// import a module.exports value
const add = require("./my-module.js");
const add = require('./my-module.js');
console.log(add(2, 3)); // 5
// import another module.exports value
const person = require("./my-module.js");
const person = require('./my-module.js');
console.log(person.name); // Alice
console.log(person.age); // 25
// import another module.exports value
const Person = require("./my-module.js");
const person = new Person("Bob", 30);
const Person = require('./my-module.js');
const person = new Person('Bob', 30);
console.log(person.name); // Bob
console.log(person.age); // 30
```
+18 -19
View File
@@ -6,14 +6,13 @@ date = 2025-08-03
tags = ["ctf", "rev", "web", "forensics"]
+++
Over the weekend, I had the opportunity to participate in the mmuctf 2025. It was an individual jeopardy style CTF targeted towards beginners and intermediate people in cybersecurity. This is a write-up to explore some challenges I did, or at least almost did.
Over the weekend, I had the opportunity to participate in the mmuctf 2025. It was an individual jeopardy style CTF targeted towards beginners and intermediate people in cybersecurity. This is a write-up to explore some challenges I did, or at least almost did.
## Welcome
>Through the shadows of the cave, at the door I had a zeal to get a welcome flag, but I couldn't see it though
I could hear it calling for me to get it. Happy hacking
{: .prompt-info }
> Through the shadows of the cave, at the door I had a zeal to get a welcome flag, but I couldn't see it though
> I could hear it calling for me to get it. Happy hacking
> {: .prompt-info }
This was a sanity check flag. I believe competitions pose such challenges that you can't get zero points. It's the same as flags in Discord servers, a flag after completing the feedback form, or just other free points.
@@ -22,12 +21,12 @@ The challenge description talked about the `door`, my first instinct was to view
```zsh
┌──(mockingspectre㉿blackout)-[~/ctf/mmuctf2025]
└─$ echo -n "bW11Y3Rme3dlbGNvbWVfZmxhZ19hZGlvc19NdWNoQGNob30=" | base64 -d
mmuctf{welcome_flag_adios_Much@cho}
mmuctf{welcome_flag_adios_Much@cho}
```
## My First App
>Our intern dev swears this app’s secure...
> Our intern dev swears this app’s secure...
This was a web challenge with an account creation form. Let's fire up Burp. The account creation request didn't seem suspicious for now, so I sent it to the repeater to abuse it some more. The response seemed interesting, the user id was in the query parameter: `GET /profile.php?id=5 HTTP/1.1`. This was a nice candidate for an Insecure Direct Object Reference(IDOR). I tried repeating the request with values from 0-4. The flag was at 1, the admin user's account.
@@ -37,7 +36,7 @@ mmuctf{1d0r_4dm1n_4cc3ss_1s_c0mpr0m1s3d}
## Ledilect
>Sometimes the path you take is just a jump away.
> Sometimes the path you take is just a jump away.
This was a simple one, I knew what the challenge wanted, but I couldn't get myself to exploit it, definitely a skill issue. The webapp had a landing page that had a button that made this request:
@@ -59,9 +58,9 @@ Looking at that, I suspected an open redirect vulnerability, but I don't know an
## Meet my X
>In the�days оf cοmfort i met this girl at the Jobless соrner. Аt the�doоrs and windows of iddleness i approached, oops she smiled and thats how i knew she was the one. I guess thatsss whyyy i learned on getting Flags because be warned she later left me at first it feels like a green flag i guess no life was there on blood(heart_break)
> In the�days оf cοmfort i met this girl at the Jobless соrner. Аt the�doоrs and windows of iddleness i approached, oops she smiled and thats how i knew she was the one. I guess thatsss whyyy i learned on getting Flags because be warned she later left me at first it feels like a green flag i guess no life was there on blood(heart_break)
This challenge involved homoglyphs, a character or a sequence of characters that looks very similar or identical to another character or sequence of characters, but has a different meaning, encoding, or origin.
This challenge involved homoglyphs, a character or a sequence of characters that looks very similar or identical to another character or sequence of characters, but has a different meaning, encoding, or origin.
A sentence might look normal, but if you copy it into a text editor that shows Unicode details or a specialized homoglyph detector, you'll see different underlying character codes.
@@ -73,8 +72,8 @@ mmuctf{oops_twitter_steg_1s_fun}
## Shadow
>Look beyond the appearance, perhaps their numerical essence will guide you to the flag.
Can you reveal what lurks in the shadow?
> Look beyond the appearance, perhaps their numerical essence will guide you to the flag.
> Can you reveal what lurks in the shadow?
This was another stego challenge; there is an image with what looks like a color palette. The description hints at 'numerical essence', so it might be something to deal with the hex values of the colors. I used this site <https://imagecolorpicker.com/> to extract the hex values.
@@ -99,7 +98,7 @@ mmuctf{4lw4y5_h1dd3n_1n5d3_m3}
## Revealme
>We found this mysterious executable on an old USB stick... Can you figure out how to get it to reveal the flag?
> We found this mysterious executable on an old USB stick... Can you figure out how to get it to reveal the flag?
The provided file is an ELF executable binary.
@@ -173,7 +172,7 @@ mmuctf{r3v3rs1ng_st4rt3r}
## Flicker
>An ordinary looking Android app... or is it?
> An ordinary looking Android app... or is it?
The provided app is an Android APK. Let's fire up jadx-gui. The package name is `com.example.blink`. There is an interesting class `r2d2`. In the onCreate method, there is an image string variable that seems to contain base64 image data.
@@ -190,8 +189,8 @@ CTF{PUCKMAN}
## Open_Secrets
>Someone trusted the wrong site and network didn’t forget. Can you piece together what was left behind?
Some people still think locks are optional on digital doors.*
> Someone trusted the wrong site and network didn’t forget. Can you piece together what was left behind?
> Some people still think locks are optional on digital doors.\*
The provided file was a network capture pcap file. For people who don't know, pcap (a packet capture) consists of an application programming interface (API) for capturing network traffic.The challenge title and filename hint at unencrypted traffic. Open up Wireshark and apply an HTTP filter. There is an HTTP stream that leaks the flag:
@@ -229,7 +228,7 @@ usb.transfer_type == 0x01
usb.transfer_type == 0x01 && usb.dst == "host" && !(usb.capdata == 00:00:00:00:00:00:00:00)
```
Crafting a tshark command to get the leftover capture data for the above filters and redirect it into a file
Crafting a tshark command to get the leftover capture data for the above filters and redirect it into a file
```zsh
tshark -r log.pcap -Tfields -Eseparator=, -e thekey.pcapng -Y 'usb.transfer_type == 0x01 && usb.dst == "host" && !(usb.capdata == 00:00:00:00:00:00:00:00)' | sed 's/://g' > usb.capdata
@@ -238,9 +237,9 @@ tshark -r log.pcap -Tfields -Eseparator=, -e thekey.pcapng -Y 'usb.transfer_type
```zsh
┌──(mockingspectre㉿blackout)-[~/ctf/mmuctf2025]
└─$ tshark -r thekey.pcapng -Tfields -Eseparator=, -e usb.capdata -Y 'usb.transfer_type == 0x01 && usb.dst == "host" && !(usb.capdata == 00:00:00:00:00:00:00:00)' | sed 's/://g' > usb.capdata
┌──(mockingspectre㉿blackout)-[~/ctf/mmuctf2025]
└─$ cat usb.capdata
└─$ cat usb.capdata
0000190000000000
00000c0000000000
00000c1000000000
+1 -1
View File
@@ -4,7 +4,7 @@ description = "Syncing Obsidian in Windows with Windows Task Scheduler with git"
author = "mockingspectre"
date = 2023-10-01
[taxonomies]
tags = ["obsidian", "git","sync", "windows", "cron", "task scheduler", "powershell"]
tags = ["obsidian", "git", "sync", "windows", "cron", "task scheduler", "powershell"]
+++
Syncing Obsidian in Windows with Windows Task Scheduler and git
File diff suppressed because one or more lines are too long
@@ -1,10 +1,10 @@
+++
title= "Semantic Versioning(SemVer) and Conventional Commits"
title = "Semantic Versioning(SemVer) and Conventional Commits"
description = "Adopting best practices in your git and build workflows."
date= 2023-01-24T15:34:14.160Z
date = 2023-01-24T15:34:14.160Z
author = "mockingspectre"
[taxonomies]
tags= ["git", "semver","workflow", "conventional commits"]
tags = ["git", "semver", "workflow", "conventional commits"]
+++
Adopting best practices in your git and build workflows.
@@ -31,7 +31,7 @@ Semantic versioning is based on three numbers that indicate the versions of the
#### React(v18.2.0)
![react](/images/uploads/react.png "React versioning")
![react](/images/uploads/react.png 'React versioning')
- **Major -> 18**
- **Minor -> 2**
+4 -7
View File
@@ -1,10 +1,10 @@
+++
title= "Subresource Integrity"
title = "Subresource Integrity"
description = "Understanding Subresource Integrity"
date= 2023-04-29
date = 2023-04-29
author = "mockingspectre"
[taxonomies]
tags= ["subresource integrity", "csp", "cors"]
tags = ["subresource integrity", "csp", "cors"]
+++
Understanding Subresource Integrity
@@ -43,10 +43,7 @@ Using Subresource Integrity (SRI) involves a few steps, but it is relatively str
- Add the hash as an attribute to the tag that loads the external resource. For example, for a JavaScript file, you would add the integrity attribute to the `<script>` tag like this:
```html
<script
src="https://example.com/example.js"
integrity="sha256-ABC123XYZ456"
></script>
<script src="https://example.com/example.js" integrity="sha256-ABC123XYZ456"></script>
```
> An integrity value may contain multiple hashes separated by whitespace. A resource will be loaded if it matches one of those hashes.
@@ -0,0 +1,78 @@
+++
title = "The Single Byte That Kills Your Exploit: Understanding Endianness"
date = 2025-11-09
description = "Problem: Computers speak different languages, like people"
[taxonomies]
tags = ["blog"]
+++
If you’ve ever crafted a perfect shellcode and ROP chain only to have your exploit immediately crash with a SIGSEGV(a signal sent by the operating system to a program when it attempts to access a protected or invalid memory location) or EIP(a 32-bit CPU register in the x86 architecture that holds the memory address of the next machine instruction to be executed) pointing to garbage, you’ve likely met the silent killer of beginners: Endianness.
Endianness is fundamental; it defines the order in which a multi-byte value (like a 4-byte integer or an 8-byte memory address) is stored in a machine’s memory. For us in the pwn game, this translates directly to whether the addresses we pack into our exploit payloads are interpreted correctly by the target program. A single misplaced byte means the difference between a shell and a stack smash(stack buffer overflow**)**.
## Little vs. Big: The Two Orders
There are two primary byte orders
Little-Endian (LE): The Least Significant Byte (LSB) is stored first, at the lowest memory address. This is the byte order used by the vast majority of personal computers, including all modern Intel/AMD (x86/x64) architectures.
Big-Endian (BE): The Most Significant Byte (MSB) is stored first, at the lowest memory address. This is often called Network Byte Order (NBO) and is common in network protocols, as well as some older or embedded architectures like PowerPC, MIPS, and SPARC.
## Cross-architecture exploitation (LE <-> BE)
If you’re attacking an embedded device, router, or IoT target, it might be Big-Endian. Always confirm the target architecture and ABI. Common mistakes when cross-compiling or reusing gadgets:
Using x86/x86_64 gadgets and packers on a MIPS/PowerPC target (different endianness and instruction set) will not work.
pwntools and other frameworks allow you to set `context.arch` and `context.endian` So packers and disassemblers behave correctly.
## How to detect the target’s endianness quickly
Run the small C program above on the target if you have code execution. Use `readelf`, `file`, or `objdump` On binaries from the target filesystem, some formats indicate endianness.
In GDB, examine the memory representation of a known constant or pointer. Put a known value in a register or memory, and inspect the byte order with `x/4xb address`.
```gdb
(gdb) p/x 0x41424344
$1 = 0x41424344
(gdb) set {int}0x601000 = 0x41424344
(gdb) x/4xb 0x601000
0x601000: 0x44 0x43 0x42 0x41 # little-endian: ‘DCBA’
```
## Debugging tips when an exploit “looks right” but crashes
Print the raw payload bytes you are sending, compare with what the target receives (packet capture or logging), and what the target’s memory shows in a debugger.
Verify pointer size. Are you packing 32-bit or 64-bit addresses?
Check alignment and padding. Are there extra bytes inserted by the protocol or `scanf`/`fgets` behavior?
Confirm endianness on the target; don’t assume x86 for embedded devices.
Use tool packing (`struct.pack`, `pwntools`) instead of hand-reversing where possible.
If attacking over the network, confirm whether fields are consumed in network byte order.
## Short checklist for exploit authors
- Confirm target architecture (x86, x86_64, MIPS, ARM, PowerPC).
- Confirm endianness (LE or BE).
- Use correct pointer width (`p32` vs `p64`) and pack accordingly.
- Use library packing (`struct`, `pwntools`) to avoid manual reversal mistakes.
- For network services, encode multi-byte protocol fields in network (big-endian) byte order unless the protocol documentation says otherwise.
- Check struct padding and alignment on the target.
- Inspect the target’s memory with a debugger to verify the actual byte layout.
## Final thoughts
Endianness is simple in concept but vital in practice. For most modern exploit work, you’ll be on x86*64 (Little-Endian), so make it a habit to pack addresses in reverse byte order relative to how you read them in a disassembler. Use `pwntools`, `struct`, or equivalent to do the packing for you, but keep in mind \_why* bytes are reversed; that understanding is what will let you debug the next crash quickly and confidently.
Recommended reading:
- <https://betterexplained.com/articles/understanding-big-and-little-endian-byte-order/>
- <https://medium.com/coderscorner/byte-ordering-e4737416d906>
- <https://devopedia.org/byte-ordering>
- <https://www.geeksforgeeks.org/dsa/little-and-big-endian-mystery/>
Disclaimer: This article was written with AI assistance, for a bit of brainstorming and proofreading.
+21 -20
View File
@@ -4,12 +4,13 @@ description = "Tailwindcss in vuejs "
author = "mockingspectre"
date = 2021-06-12
[taxonomies]
tags = ["javascript", "vuejs" , "tailwindcss"]
tags = ["javascript", "vuejs", "tailwindcss"]
+++
A guide on how to use [Tailwind CSS](https://tailwindcss.com/) in your Vue project.
>**Note**
> This article was originaly published on my old medium blog. I moved it here for archival purposes.
> **Note**
> This article was originaly published on my old medium blog. I moved it here for archival purposes.
Tailwind is a utility-first CSS framework for rapidly building custom user interfaces. It is an un-opinionated framework which means that it doesn't come with custom configurations like Bootstrap or Bulma(Yeah, I know, no one should tell you how to live your life).
@@ -59,7 +60,7 @@ module.exports = {
extend: {},
},
plugins: [],
}
};
```
It will also create a `postcss.config.js` file that includes tailwindcss and autoprefixer already configured.Postcss is needed to process tailwind:
@@ -71,7 +72,7 @@ module.exports = {
tailwindcss: {},
autoprefixer: {},
},
}
};
```
## Configure Tailwind to remove unused styles in production
@@ -80,17 +81,17 @@ In your tailwind.config.js file, configure the purge option with the paths to al
```js
// tailwind.config.js
module.exports = {
purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}
module.exports = {
purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
};
```
## Include Tailwind in your CSS
@@ -112,11 +113,11 @@ Finally, ensure your CSS file is being imported in your `./src/main.js` file:
```js
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
import { createApp } from 'vue';
import App from './App.vue';
import './index.css';
createApp(App).mount('#app')
createApp(App).mount('#app');
```
You're finished! Now when you run npm run dev, Tailwind CSS will be ready to use in your Vue app! You can now proceed to create awesome stuff
+149
View File
@@ -0,0 +1,149 @@
+++
title = "What is pwn?"
date = 2025-09-03
description = "No not that one"
[taxonomies]
tags = ["blog"]
+++
> Binary Exploitation is a broad topic within Cyber Security which really comes down to finding a vulnerability in the program and exploiting it to gain control of a shell or modifying the program's functions ~ctf101
In most challenges, you’ll be given a Linux binary to exploit, and occasionally a Windows executable. The goal is to find a way to get the program to run in a way that was not intended.
Over the course of this series, we will look at the basics of a binary from simple to advanced concepts. This will be a multipart post covering the concepts over a couple of months. I’ll also use it as a reference to track my own progress.
> This assumes that the reader has some significant experience with programming, i will not be explaining how to write software. The tutorials will be in C, simple enough while being low level for some of the things well do. I recommend reading :
>
> _[The C Programming Language](https://www.amazon.com/Programming-Language-2nd-Brian-Kernighan/dp/0131103628)_[, 2nd Edition, by Brian W. Kernighan and Dennis M. Ritchie (Prentice Hall, 1988).](https://www.amazon.com/Programming-Language-2nd-Brian-Kernighan/dp/0131103628)
---
## Concepts to Cover
This roadmap will take you from _“I don’t know how the stack works”_ to _“I can write exploits for CTFs and understand real-world CVEs.”_
### **Episode 1: Getting Started**
- Why binary exploitation matters (CTFs, real-world, research).
- Computer architecture basics (x86/x64 registers, stack vs heap, memory layout).
- Compiling and running simple C programs.
- Intro to ELF binaries.
---
### **Episode 2: Assembly & Tools Crash Course**
- Function calls in assembly (prologue/epilogue, stack frames).
- Common instructions (`mov`, `call`, `jmp`, `ret`).
- Debugging with `gdb`, `gef`/`pwndbg`.
- Disassembly with `objdump`, `radare2`, and `Ghidra`.
---
### **Episode 3: Memory Corruption 101**
- What is a segmentation fault?
- Stack buffer overflows (first crashes).
- Off-by-one errors.
- Writing your first shellcode and executing it locally.
---
### **Episode 4: Exploiting Control Flow**
- Overwriting return addresses.
- NOP sleds and shellcode execution.
- Return-to-libc attacks (ret2libc).
- Environment variables and argument tricks.
---
### **Episode 5: Format String Vulnerabilities**
- How `printf` becomes an exploit primitive.
- Memory leaks via format strings.
- Overwriting memory using `%n`.
---
### **Episode 6: Modern Protections & Bypasses (Part 1)**
- NX (non-executable stack) and its bypass with ROP.
- Intro to ROP gadgets and building small chains.
- Automating with Pwntools and ROPgadget.
---
### **Episode 7: Modern Protections & Bypasses (Part 2)**
- ASLR: how randomization works.
- Leaking addresses to defeat ASLR.
- Stack canaries and partial overwrites.
---
### **Episode 8: Heap Exploitation (Basics)**
- Understanding malloc/free and heap metadata.
- Classic heap overflows.
- Use-after-free and double free.
- Simple heap exploitation demos.
---
### **Episode 9: Heap Exploitation (Advanced)**
- Unlink attacks and unsafe unlink.
- Fastbin dup tricks.
- The “House of” techniques:
- House of Force
- House of Spirit
- House of Lore
- House of Einherjar
- Tcache poisoning in modern glibc.
---
### **Episode 10: Advanced Exploitation Techniques**
- GOT/PLT overwrites.
- Ret2dlresolve.
- Sigreturn-oriented programming (SROP).
- JOP (Jump-Oriented Programming).
---
### **Episode 11: Kernel & Windows Exploitation (Intro)**
- Userland vs kernel space.
- Exploiting syscalls for privilege escalation.
- Windows basics: SEH overwrites, DEP/ASLR bypass.
- Kernel driver exploitation.
---
### **Episode 12: Modern Defenses & Mitigations**
- Control-Flow Integrity (CFI).
- Shadow stacks & CET.
- Hardened malloc and allocator security.
- Sandboxing & seccomp-bpf.
---
### **Episode 13: Exploit Workflow in Practice**
- Solving a CTF challenge step-by-step.
- Remote exploitation (exploiting over sockets).
- Exploit reliability (stability, bruteforcing).
- Post-exploitation steps (getting a shell, escalating privileges).
---
### **Episode 14: Beyond the Basics**
- Automating exploit discovery with fuzzing (AFL, honggfuzz).
- Symbolic execution with angr.
- Real-world case studies (Heartbleed, Dirty COW, Shellshock).
- Writing weaponized exploits responsibly.