Classic stack-based buffer overflow in SLMail 5.1 showing how early mail servers could be compromised through oversized SMTP and POP3 commands.
Classic stack-based buffer overflow in SLMail 5.5 showing how early mail servers could be compromised through oversized SMTP and POP3 commands.
This repository is part of the material I use when teaching memory corruption exploitation (in addition to my regular work, I also teach in different cybersecurity courses where I help train the next generation of reverse engineers).
CVE-2003-0264 is one of the first cases I introduce when teaching vanilla stack-based buffer overflows over a network protocol. It is clean, well-documented, and the exploitation path is direct, no SEH, no egghunter, no space constraints. The student sends a payload, overwrites EIP, lands on a JMP ESP gadget, and gets a shell. That clarity is exactly what makes it useful as a starting point.
SLMail 5.5 is a legacy Windows mail server. The vulnerability is in the POP3 service, specifically in the PASS command handler, which copies user input directly into a fixed-size stack buffer without any length validation. What makes this case particularly useful for teaching is how few moving parts it has:
This combination, network-facing, unauthenticated, direct EIP overwrite, no modern mitigations, makes CVE-2003-0264 one of the cleanest real-world examples of a vanilla stack overflow that still runs on modern Windows versions.
SLMail is a Windows mail server that provides SMTP, POP3, and administration services. The POP3 service listens on TCP port 110 and handles standard mail retrieval commands. The vulnerability is in the PASS command handler, which processes the password argument sent by a connecting client.
Key technical details:
SLMail's POP3 service processes the PASS command by copying the supplied password argument into a fixed-size stack buffer using an unsafe function with no length check. A simplified version of the vulnerable logic looks like this:
char password_buffer[256];
strcpy(password_buffer, pass_argument);
Sending a sufficiently long string as the PASS argument causes the copy to write past the end of the buffer, corrupting the stack until the saved return address is overwritten. When the function returns, the CPU loads the attacker-controlled value from the stack into EIP and jumps to it.
The crash can be reproduced by sending an oversized PASS argument over POP3. No valid credentials are required. Example using Python:
import socket
HOST = '127.0.0.1'
PORT = 110
payload = b"A" * 3000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.recv(1024)
s.send(b"USER username\r\n")
s.recv(1024)
s.send(b"PASS " + payload + b"\r\n")
s.close()
When executed under a debugger, the crash shows EIP overwritten with user-controlled data:
EIP = 41414141
confirming that the saved return address has been corrupted by the overflow.
The goal of this repository is not only to demonstrate the crash, but to walk through the complete exploitation process step by step, from fuzzing to a working reverse shell.
To keep the main README clean, the detailed exploitation notes, scripts, and debugger steps are placed inside the Vulnerability 📂 folder of this repository.
There you will find the complete workflow used to exploit this CVE, including: