Skip to main content

Command Palette

Search for a command to run...

I Spent 3 Weeks Exploiting a Patched Vulnerability

Updated
8 min read
I Spent 3 Weeks Exploiting a Patched Vulnerability
Y

I am a computer science and programming enthusiast with a passion for problem-solving and web development. As a software engineer, I am constantly striving to improve my knowledge, skills, and tackle new challenges.

As an authorized junior developer I was assigned a pentesting task. Something new with not much expertise, however problem-solving from computer science field got my back.

Spoiler: the vulnerability was already patched. I just didn't know it yet.


The Beginning (Feels Easy)

Things were vague in the beginning. I started by information gathering, like any software engineer would:

  1. Have access to the target network (LAN or over the internet)

  2. Know the services - domain finding and IP address scanning

  3. Quick scan known ports against couple of servers

  4. Identify services and corresponding versions

  5. Map vulnerabilities by service/open port

  6. Select highest CVE score vulnerability

Scanner finds Netatalk 3.1.8 on port 548. CVE-2018-1160. CVSS score 9.8. Pre-authentication remote code execution.

I thought: "Nice. This will be easy."

It was not!


What is Netatalk?

Netatalk is a Free and Open Source file server that implements the Apple Filing Protocol (AFP) over TCP/IP. It lets Apple devices talk to Linux/Unix servers. Synology NAS uses it so Mac users can access their files.

Simple enough. Now let's look at the bug.


The Vulnerability (Looks Simple on Paper)

CVE-2018-1160 is a heap overflow in dsi_opensess.c. Here's the vulnerable code:

/* parse options */
while (i < dsi->cmdlen) {
  switch (dsi->commands[i++]) {
  case DSIOPT_ATTNQUANT:
    memcpy(&dsi->attn_quantum, dsi->commands + i + 1,
            dsi->commands[i]);  // <-- THE BUG
    dsi->attn_quantum = ntohl(dsi->attn_quantum);
  case DSIOPT_SERVQUANT:
  default:
    i += dsi->commands[i] + 1;
    break;
  }
}

See the problem? dsi->attn_quantum is a 4-byte integer, but dsi->commands[i] controls how many bytes get copied. Attacker controls that value. Send a big number, overflow the buffer, overwrite the commands pointer, redirect execution to your shellcode.

Classic heap overflow. Tenable published a working exploit. Should be straightforward.

Should be.


Setup and Replication (The First Layer)

The main target was a Synology running DSM 6.2.4-25556. I needed to replicate the environment.

Problem: Synology isn't just software. It's hardware with a custom OS. You can't just download an ISO.

I searched:

  • "Synology 6.2.4-25556 iso"

  • "Synology docker"

  • "Synology virtualbox"

Results were confusing. I had to zoom out and understand what I was even looking at.

NAS: Network Attached Storage - the general category
Synology: A popular brand that makes NAS hardware
DSM: DiskStation Manager - the web-based OS that runs on Synology devices

To run DSM without Synology hardware, you need XPenology - a community project that creates bootloaders to run DSM on regular PCs/VMs.

This is where the pain started.


The Virtualization Nightmare

Attempt 1: VirtualBox

Created a VM. Downloaded a bootloader. Configured the virtual disk.

Boot. Black screen. Nothing.

Tried different settings. Different SATA controllers. Different network adapters.

Boot. Black screen. Still nothing.

The e1000 network adapter wasn't being recognized properly. XPenology forums mentioned this. Solutions were vague. "Try VMware instead."

Attempt 2: VMware Workstation

New VM. Same bootloader.

Boot. Actually got somewhere this time. Bootloader menu appeared.

Selected the option. Loading... loading...

Kernel panic.

I tried them all:

  • Jun's Loader 1.03b - wouldn't boot

  • Jun's Loader 1.04b - booted but couldn't find DSM

  • RedPill - complex setup, failed

  • ARPL (Automated RedPill Loader) - promising but version incompatibility

  • TinyCore RedPill - finally something worked

I rebuilt that VM probably 6-10 times. Each time thinking "this configuration will work."

Each time: it didn't.

Finding the right DSM .pat file was its own adventure. I searched:

  • Official Synology archive (missing old versions)

  • XPenology forums (half the links were dead)

  • Web Archive (saved my life multiple times)

  • Random forum posts from 2019

Lost count of how many 404s I hit. Every promising link led to a dead end. Some files were corrupted. Some were wrong versions. Some required registration on forums that no longer existed.


Plot Twist: The Real Synology

At some point I thought: "Maybe I should just buy the hardware."

I got my hands on a real DS920+. Used, from previous owner.

Problem: it had data on it. Previous owner's data. Couldn't just wipe it without complications.

Back to the VM.


Finally: A Working Environment

After weeks of VM failures, I got DSM 6.2.2-24922 running in VMware. Not the exact version I wanted (25556), but close enough. Same Netatalk version. Should be vulnerable.

Time to exploit.


The Exploit Attempts (The Second Layer)

I read Tenable's writeup. Downloaded the Exploit-DB code (EDB-46034). Studied the DSI protocol.

The exploit strategy:

  1. Send malformed DSI OpenSession packet

  2. Overflow attn_quantum to overwrite commands pointer

  3. Point commands to the AFP dispatch table (afp_switch)

  4. Next command executes from the dispatch table = code execution

First step: find addresses. The binary has no PIE (Position Independent Executable), so addresses are fixed. Good news.

$ checksec usr/bin/afpd
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)  # <-- NICE

Extracted afp_switch address: 0x65b880

Now build the payload. Send it.

Crash.

Okay, wrong offset probably. Adjust. Send again.

Crash.

Different offset. Different approach.

Crash. Crash. Crash.

I wrote more than 10 different exploit scripts. Different offsets, different padding, different techniques.

Every. Single. One. Crashed the server.


The Confusion

The server crashed every time. But here's what was weird:

When I sent a normal DSI OpenSession (option length = 4 bytes), the server responded fine.

When I sent length = 6 or more, instant crash. No response.

My theory: "The exploit is working. I'm just hitting the wrong offset. Maybe ASLR is on somehow?"

I checked ASLR. It was off.

I kept trying different offsets. 16 bytes from attn_quantum. 24 bytes. 32 bytes. 40 bytes.

All crashed.

What was I missing?


The Discovery

After 2-3 weeks of this, I decided to actually look at what the server was doing.

Opened radare2 on the library file:

r2 -A usr/lib/libatalk.so.17.0.0
[0x00011d80]> pdf @ sym.dsi_opensession

Scrolled through the disassembly. Looking for the memcpy. Looking for the vulnerable pattern.

Then I saw it:

0x00029c09      cmp r9b, 1           ; if option_type == 1
0x00029c0d      jne 0x29c24          ; skip if not
0x00029c0f      cmp rsi, 4           ; CHECK: is length == 4?
0x00029c13      jne 0x29d01          ; if NOT 4 → jump to ERROR

Followed the error path:

0x00029d01      ...
0x00029d18      lea r8, str.option__u_bad_length:__zu  
               ; "option %u bad length: %zu"
...
0x00029cfc      call sym.imp.exit    ; exit(1)

There it was.

The "crash" wasn't the vulnerability triggering. It wasn't my payload corrupting memory. It wasn't wrong offsets.

It was a patch.

Synology added a length check. If the option length isn't exactly 4, the server logs an error message and calls exit(1). Clean termination. Not a crash.

The vulnerability was patched before I even started.


The Timeline

  • CVE-2018-1160 disclosed: December 2018

  • Synology patch (DSM 6.2.1-23824-4): December 2018

  • My target (DSM 6.2.2-24922): May 2019

  • Reality: Already patched for 6 months before the build date

I spent 3 weeks trying to exploit something that was fixed before I started.


What I Actually Learned

Here's the thing: I'm not even mad. I learned more from this failure than I would have from a working exploit.

1. Verify the vulnerability exists before exploiting

I trusted the scanner. Scanner said "Netatalk 3.1.8 = vulnerable." Scanner didn't check for vendor patches.

Lesson: Version numbers lie. Synology ships Netatalk 3.1.8 but with backported security fixes. Always verify by looking at the actual code.

2. Read the disassembly FIRST

10 minutes in radare2 would have saved me 3 weeks. I should have looked at dsi_opensession before writing a single line of exploit code.

Lesson: Understand what you're attacking before you attack it.

3. The setup struggle was valuable

All those failed VMs taught me:

  • How bootloaders work (and why they exist)

  • VirtualBox vs VMware networking differences

  • How to extract firmware (.pat files are just compressed archives)

  • How XPenology actually functions

  • That sometimes the "easy path" (buying hardware) isn't easy either

4. Document everything

I wish I had written this article as I went. Half my notes were scattered across terminal history and random text files.


Tools I Used

  • radare2 - Binary analysis (the tool that finally showed me the truth)

  • checksec - Quick binary security check (PIE, ASLR, etc.)

  • file - Identifying file types during firmware extraction

  • VMware Workstation - After VirtualBox failed me

  • Various XPenology bootloaders - TinyCore RedPill eventually worked


What Would I Do Differently?

  1. Check if patched first - Before any exploit development, look at the actual vulnerable function. Compare to patched version.

  2. Document from day one - Every failure, every dead end, every small victory.

  3. Trust but verify - Vulnerability scanners give you leads, not guarantees.


Attack End Goal (That Never Happened)

For the record, here's what CVE-2018-1160 would have allowed:

An unauthorized attacker could gain remote code execution on a Synology DiskStation NAS server. No authentication required. Send malformed packet → execute arbitrary code → own the box.

Critical vulnerability. CVSS 9.8. Would have been a clean kill.

If only it wasn't patched.


Final Thoughts

Failing is part of the process. I went in expecting to pop a shell in a few days. Instead I learned how NAS systems work, how firmware is structured, how to read assembly, and how to properly verify a vulnerability before wasting weeks on it.

The next pentest will go differently. I'll check the code first.

But I wouldn't trade this experience for a quick win. The struggle taught me more than success ever could.


This was an authorized penetration test in a controlled lab environment. Don't hack things you don't have permission to hack.