How I Exploited Oracle Advanced Support to Run Remote SQL via Hidden JavaScript
During an external penetration test I discovered an Oracle Advanced Support service, reverse‑engineered its JavaScript endpoints, crafted GET and POST requests to create and execute named SQL statements, and ultimately extracted database version, user information, and password hashes, highlighting a critical web‑application flaw.
While performing an external penetration test for a client, I used nmap together with EyeWitness to enumerate reachable web services and identified an Oracle Advanced Support endpoint. This service allows remote technical support to log into the Oracle environment, which can be abused if its API is not properly protected.
Initial reconnaissance
I began by searching for obvious vulnerabilities, crawling the application with Burp Suite, enumerating common paths, and inspecting the page source. A directory listing link in the homepage revealed an asset directory, and further browsing exposed a JavaScript file named sql-service.js containing four anonymous functions:
getSqlData
createNamedSql
getNamedSqlList
getSqlNameListTwo of these functions expose GET endpoints ( getNamedSqlList and getSqlNameList) while createNamedSql is a POST endpoint that creates a named SQL query.
Testing the GET endpoints
Sending a request to /rest/data/sql/test returned 404 with the message “Named SQL not found”. By trying the function names as parameters, the request /rest/data/sql/getNamedSqlList succeeded and returned a JSON array of objects, each containing fields such as name, sql, dataSourceJNDI, privileges, and paramList. An example entry is:
{
"id":1,
"name":"sample",
"sql":"SELECT TIME,CPU_UTILIZATION,MEMORY_UTILIZATION FROM TIME_REPORT where TIME > :time",
"dataSourceJNDI":"jdbc/portal",
"privileges":[],
"paramList":[{"id":36,"name":"time","type":"date-time","value":null}]
}Creating a named SQL query
Attempting to call POST /rest/data/sql with an empty JSON body produced a 500 error complaining that the SQL_NAME column cannot be null. Adding a random field also failed, but when I supplied a proper payload with name and sql fields, the server accepted the request:
{
"name":"test",
"sql":"select @@version",
"dataSourceJNDI":"jdbc/portal"
}The response was still a 500 error, indicating the query was stored but not yet executable.
Executing the stored query
Calling the newly created endpoint /rest/data/sql/test returned a successful 200 OK with the result of the SQL statement: [{"@@version":"5.5.37"}] Repeating the process with SELECT USER from dual; yielded the database user SYSMAN, which according to Oracle documentation is an administrator account.
Extracting password hashes
Finally, I created a query to retrieve user credentials:
{
"name":"test3",
"sql":"SELECT name, password FROM sys.user$",
"dataSourceJNDI":"jdbc/portal"
}Fetching /rest/data/sql/test3 returned a JSON array with usernames and password hashes (some redacted for brevity), confirming full database access.
Conclusion
The vulnerability stemmed from an unauthenticated API that allowed arbitrary SQL creation and execution via the Oracle Advanced Support service. After reporting, Oracle patched the issue. The key takeaway is to always review client‑side JavaScript for hidden endpoints that may expose powerful backend functionality.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
