PFCLObfuscate – Protect Your PL/SQL

Do you write code in PL/SQL?

Do you or your employer sell your applications written in PL/SQL?

Do you deploy your applications written in PL/SQL to customers sites or servers/databases or internally?

If you do write in PL/SQL then you should consider the effort and value in your PL/SQL work and think about protecting it. Wouldn’t it be great to be able to protect the intellectual property (IPR) in your PL/SQL code from others prying eyes, in other words stop someone from understanding what you have written in your PL/SQL, your algorithms, secrets and more.

And wouldn’t it also be great to apply license restrictions to your PL/SQL. For instance deploy a trial version of your PL/SQL package to a customer to allow them to test before they license (BUY) or deploy a set of PL/SQL packages and code but only allow the customer to use the PL/SQL code under your terms. For instance you maybe want to license your PL/SQL (your IPR) to a customer but for a fixed term or to a fixed number of databases. It would be great to have a customer activate your PL/SQL code in their database but under your controls and settings.

These sorts of protections are available in the C programming Win32, Win64, .NET and other worlds. Writers of .NET or C binaries intended to be used on Windows can buy products or even use free facilities in Visual Studio to acheive some of the protections of IPR loss and also adding license type protections. i.e. time limit, locked to hardware etc but all of this type of functionallity is not available for PL/SQL until now.

The goal for us with PFCLObfuscate is to provide  multi-layered security for your PL/SQL. We want to:

  1. Protect your PL/SQL from being understood – obfuscation, compaction, removal of comments, wrap and wrap protection (if needed)
  2. Protect your PL/SQL code from being run outside of your controlled licensed conditions. i.e. add technical license protections to your PL/SQL to control its use, and add those protections automatically.
  3. Protect your PL/SQL from being stolen. We cannot stop someone stealing it (well we can help reduce the risk but thats part of our normal Oracle security audit and PFCLScan business and not directly PFCLObfuscate) but we can stop it working in another database with PFCLObfuscate

To achieve all of this we developed the first version of PFCLObfuscate which allowed PL/SQL to be obfuscated nicely and also we developed Wrapprotect to stop 9iR2 and earlier unwrappers from working so that where necessary layerded protection of your PL/SQL can be implemented. The first version of PFCLObfuscate provides good protection but it was obvious we could get better obfuscation and also to achieve some of our goals such as adding license protection or tamperproofing (checking if the PL/SQL has been modified by an attacker to avoid protections) we needed a better PFCLObfuscate.

!!Yesterday!! we released the brand new version 2.0 of PFCLObfuscate. All current customers should have now received an email to download their new build of version 2.0.

Version 1.0 allowed us to do comprehensive obfuscation but version 2.0 brings “dynamic obfuscation”. This means that as we parse your PL/SQL to protect it with obfuscation we also run a configurable set of dynamic obfuscations at various “hook” points in your PL/SQL code. These “hooks” are at the start of a declaration block, the end of a declaration block, the start of a block, the end of a block and when any pre-defined PL/SQL is found. “Dynamic obfuscation” allows us to programatically (the user can define the rules) modify the PL/SQL to achieve much better obfuscation and also to automatically add license protection and tamperproof protection. The core enhancement with version 2.0 is the dynamic obfuscation engine that will allow us to do much more in terms of securing PL/SQL on many levels.

Let’s see a simple example of protecting two PL/SQL procedures and adding license protections to them to allow our code to be run by a customer for 30 days.

I have two simple PL/SQL files, p1.sql and p2.sql; p1.sql is a simple PL/SQL procedure DEMO_RUN that runs another procedure TEST_PROC in p2.sql. The public interface DEMO_RUN is to be retained but the name of the internal procedure TEST_RUN can be obfuscated.

Here is the original source code:

p1.sql

-- test the interface with TEST_PROC in p2.sql
create or replace procedure DEMO_RUN(pv_input in varchar2)
is
lv_one number:=1;
lv_two number:=3;
begin
dbms_output.put_line('Start of Test');
dbms_output.new_line();
test_proc(lv_one,pv_input,lv_two);
dbms_output.put_line('End of Test');
end;
/

p2.sql

create or replace procedure TEST_PROC( PV_NUM in NUMBER,
PV_VAR in VARCHAR2, PV_VAR3 in out INTEGER) IS
L_NUM NUMBER:=3;
L_VAR NUMBER;
J NUMBER:=1;
procedure NESTED( PV_LEN in out NUMBER) is
X NUMBER;
begin
X:= PV_LEN * 5;
end;
begin
case L_NUM
when 1 then
L_VAR:=3;
DBMS_OUTPUT.PUT_LINE('This is a header');
DBMS_OUTPUT.PUT_LINE('The number is ' ||  L_VAR);
DBMS_OUTPUT.PUT_LINE('The case var is ' ||  L_NUM);
when 2 then
L_VAR:=4;
DBMS_OUTPUT.PUT_LINE('This is a header');
DBMS_OUTPUT.PUT_LINE('The number is ' ||  L_VAR);
DBMS_OUTPUT.PUT_LINE('The case var is ' ||  L_NUM);
when 3 then
L_VAR:=6;
DBMS_OUTPUT.PUT_LINE('This is a header');
DBMS_OUTPUT.PUT_LINE('The number is ' ||  L_VAR);
DBMS_OUTPUT.PUT_LINE('The case var is ' ||  L_NUM);
else
DBMS_OUTPUT.PUT_LINE('wrong choice');
end case;
if ( ( J = 1) and ( J = 3)) then
DBMS_OUTPUT. PUT_LINE('here is IF');
elsif ( ( J = 2) or ( J != 3)) then
DBMS_OUTPUT.PUT_LINE('The elsif clause');
else
DBMS_OUTPUT.PUT_LINE('else clause');
end if;
J:=4;
NESTED( J);
DBMS_OUTPUT.PUT_LINE('nested=:' ||  J);
for J in reverse 1.. PV_NUM loop
if MOD( J,2) = 0 then
DBMS_OUTPUT.PUT_LINE('for loop with reverse');
end if;
end loop;
end;
/

Now install the code into the database and test that it works:


Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

SQL> @p2.sql

Procedure created.

SQL> @p1.sql

Procedure created.

SQL> set serveroutput on
SQL> exec demo_run('Hello');
Start of Test
This is a header
The number is 6
The case var is 3
The elsif clause
nested=:4
End of Test

PL/SQL procedure successfully completed.

SQL>

The code works fine. So now let’s protect the code using version 2.0 of PFCLObfuscate and add license protection automatically to allow the code to run for 30 days. The system date of my database is:


SQL> select sysdate from dual;

SYSDATE
---------
23-MAR-14

SQL>

We need to do some simple configuration for PFCLObfuscate before we can run it; let us run through the configuration. If this is the first time that you execute PFCLObfuscate you need to generate the reserved words configuration file using the provided gr.sql script:

running gr.sql


Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

SQL> @gr
SQL>
SQL> exit

This created the reserved.txt configuration file for us. Now enable version 2.0 in your configuration file (I am just showing the version 2.0 settings not all of the obfuscation settings available):

Part of ob.conf file

############################################################################
# Version 2.0 Settings
############################################################################
#
# The function and string hide file. This file specifies a package to "hide" or
# strings to hide and then specifies the code to add new PL/SQL processing to
# deal with this and also PL/SQL substitute for the actual located string. This
# is detailed in the help
#
functionfile=functionfile.txt
#
# This parameter is  the file extension used for the intermediate files. This
# can be changed.
#
intermediatefile=.imm
#

Now add the public interface name DEMO_RUN to the omit.txt configuration file:

omit.txt file

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type omit.txt
DEMO_RUN
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

The last thing to do is edit a license.txt file to create the simple settings for your license protection. The current system date for my database is 23-MAR-2014 and I want to license for 30 days so I will set the start date to 22-MAR-2014 and the end date to 22-APR-2014 and the number of days to 30. Note that the lifetime and the expiry date are mutually exclusive and the most restrictive always acts first.

Here is the simple license file for this example:

license.txt

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type license.txt
expire_days=30
expire_date=22-APR-2014
start_date=22-MAR-2014
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Now we can obfuscate the code:

execution of PFCLObfuscate


C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i p1.sql -o p1.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Thu Apr 17 15:00:50 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2014 Apr 17 14:00:50] obs: Starting PFCLObfuscate...
[2014 Apr 17 14:00:50] obs: Pre-Load Keywords from [key.txt]
[2014 Apr 17 14:00:50] obs: Pre-Load Omit words from [omit.txt]
[2014 Apr 17 14:00:50] obs: Pre-Load StringOmit words from [string.txt]
[2014 Apr 17 14:00:50] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 17 14:00:50] obs: Pre-Load force words from [force.txt]
[2014 Apr 17 14:00:50] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 17 14:00:50] obs: Pre-Load map file list from [map.txt]
[2014 Apr 17 14:00:50] obs: Version 2.0 Initialisation...
[2014 Apr 17 14:00:50] obs: Initialise the file list...
[2014 Apr 17 14:00:50] obs: Initialise the Depth Stack...
[2014 Apr 17 14:00:50] obs: Initialise the FWD Function list...
[2014 Apr 17 14:00:50] obs: Initialise the FUNC function list...
[2014 Apr 17 14:00:50] obs: Initialise the NEW function list...
[2014 Apr 17 14:00:50] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2014 Apr 17 14:00:50] obs: Obfuscating PL/SQL Input File [ p1.sql ]
[2014 Apr 17 14:00:50] obs: Save the transposed variables
[2014 Apr 17 14:00:50] obs: Process intermediate file...
[2014 Apr 17 14:00:50] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i p2.sql -o p2.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Thu Apr 17 15:00:56 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2014 Apr 17 14:00:56] obs: Starting PFCLObfuscate...
[2014 Apr 17 14:00:56] obs: Pre-Load Keywords from [key.txt]
[2014 Apr 17 14:00:56] obs: Pre-Load Omit words from [omit.txt]
[2014 Apr 17 14:00:56] obs: Pre-Load StringOmit words from [string.txt]
[2014 Apr 17 14:00:56] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 17 14:00:56] obs: Pre-Load force words from [force.txt]
[2014 Apr 17 14:00:56] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 17 14:00:56] obs: Pre-Load map file list from [map.txt]
[2014 Apr 17 14:00:56] obs: Version 2.0 Initialisation...
[2014 Apr 17 14:00:56] obs: Initialise the file list...
[2014 Apr 17 14:00:56] obs: Initialise the Depth Stack...
[2014 Apr 17 14:00:56] obs: Initialise the FWD Function list...
[2014 Apr 17 14:00:56] obs: Initialise the FUNC function list...
[2014 Apr 17 14:00:56] obs: Initialise the NEW function list...
[2014 Apr 17 14:00:56] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2014 Apr 17 14:00:56] obs: Obfuscating PL/SQL Input File [ p2.sql ]
[2014 Apr 17 14:00:56] obs: Save the transposed variables
[2014 Apr 17 14:00:56] obs: Process intermediate file...
[2014 Apr 17 14:00:56] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Note: This is a simple example shown long hand but we can actually obfuscate all PL/SQL files in a directory in one command using provided batch scripts with the PFCLObfuscate software and we can also turn off all output using silent, shortening the output completely. PFCLObfuscate is command line and is easy to integrate into existing build processes.

Now we can install the obfuscated and license protected code into the database and test it:

sql installation


Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

SQL> @p2.opf

Procedure created.

SQL> @p2.opf

Procedure created.

SQL> set serveroutput on
SQL> exec demo_run('hello');
Start of Test
This is a header
The number is 6
The case var is 3
The elsif clause
nested=:4
End of Test

PL/SQL procedure successfully completed.

SQL>

So our code is now protected from anyone understanding it and also now has license protection automatically added. The protected code works above as we are in the licensed period for the code but to show that the license protection does work lets change the license so that it has expired already. So I have changed the license to allow this code to be run for 5 days so now the license started on the 12-MAR-2014 and expired on the 19th March. Remember the current database date is 23-Mar-2014 (Don’t ask, its in a VM with the wrong date!):

license.txt

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type license.txt
expire_days=5
expire_date=17-MAR-2014
start_date=12-MAR-2014
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Now re-protect the two source code files:

Running PFCLObfuscate, silently this time:


C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -s -c ob.conf -i p1.sql -o p1.opf

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -s -c ob.conf -i p2.sql -o p2.opf

Now reload the code back into the database and test it:

Loading the files:


Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

SQL> @p2.opf

Procedure created.

SQL> @p1.opf

Procedure created.

SQL> set serveroutput on
SQL> exec demo_run('hello');
BEGIN demo_run('hello'); END;

*
ERROR at line 1:
ORA-20096: invalid license(2)
ORA-06512: at line 1
ORA-06512: at "ORABLOG.DEMO_RUN", line 21
ORA-06512: at "ORABLOG.DEMO_RUN", line 115
ORA-06512: at line 1
SQL>

So it works, we automatically licensed our PL/SQL and you can do the same to your PL/SQL.

This was a simple example of license protecting and obfuscating PL/SQL. We will also support licenses locked to the database and deployed licenses. So that a customer can deploy the code and you can then generate a license that is locked to their database allowing your code to be executed in their database. If the code (and even the license) were removed to another database the stolen code would not run as its locked to their database.

Note: In general the configuration for PFCLObfuscate needs to be done only once at the start of a project for a set of PL/SQL code that needs to be protected and perhaps needs to be updated when changes to the public interfaces are made or new code is added to the protection process.

PFCLObfuscate version 2.0 also provides powerful obfuscation techniques to protect your code. Please contact us for more details by emailing info@petefinnigan.com or by visting the Buy PFCLObfuscate page of this site.

Posted in PFCLObfuscate, PL/SQL, Protect PL/SQL, Uncategorized | Comments Off on PFCLObfuscate – Protect Your PL/SQL

Welcome to PFCLObfuscate!

Welcome to the PFCLObfuscate website blog.

PFCLObfuscate is one of the software products designed and created by PeteFinnigan.com Limited. We specialise in securing databases and  have for many years concentrated on the Oracle database. Indeed our founder Pete Finnigan is well known in the community and has written books on the subject of Oracle database security and also has helped many companies protect and secure database through teaching our training courses, performing security audits and recommending what should be fixed to make data secure and also by specialised consulting in the area of data security.

PFCLObfuscate came out of consulting projects that we undertook to secure the Intellectual Property Rights (IPR) of some clients PL/SQL based applications. We wrote some scripts to obfuscate PL/SQL code and SQL*Plus scripts and manually did consulting to help configure and set up the scripts to integrate with build processes. We also manually coded protections for tamperproofing, license type protections and also protections to prevent the PL/SQL code being run elsewhere if stolen from the source database. The core feature was obfuscating variable names, identifiers and to make the code hard to reverse engineer.

There is a cautionary note with any obfuscation in that it  is not possible fully protect PL/SQL code in our case and code in general with obfuscation. The goal with obfuscation is to make it hard for an attacker to reverse engineer the PL/SQL source code or simply to slow him down; this should stop most people but a true reverse engineer will not be put off for ever; it really then comes down to how long he is willing to spend before he moves onto someone elses easier code.

The best options that we could offer were strong obfuscations and additions of tamperproofing and license type code and more but then to also wrap the resultant obfuscated PL/SQL code with Oracles Wrap.exe program. We used the 9iR2 wrap.exe program because it is harder to reverse this. The 10g and 11g wrap.exe output is too easy to reverse indeed there are even websites where you can paste your wrapped code in and have it unwrapped. The 9iR2 wrap.exe output is harder to reverse manually yourself BUT there are also 9iR2 unwrappers out there; not as easy to find and none  where you simply cut and paste to a website (at least as far as I know!) So the final step to protect the code was to stop any known unwrapper from working so this is what we worked out how to do and did it.

So the resulting PL/SQL code that installs into the database and works in exactly the same way as the clear text original was protected with multiple layers;

1) The original PL/SQL scource code was obfuscated to make it hard to reverse engineer and understand.

2) Manual protections were added to the PL/SQL such as tamperproofing with PL/SQL code.

3) The resultant code was wrapped with Oracles wrap.exe program.

4) Finally we added wrap protections to the wrap output to stop unwrappers from being able to unwrap the code

This gives good strength and security to PL/SQL code. A potential thief of your IPR in PL/SQL in this scenario would read the wrapped code and not be able to glean any detail or structure. If the reverser/attacker were to obtain an unwrapper then they would first need to defeat the upwrap protections added and then unwrap the code with their unwrapper and finally they would be presented with the obfuscated code which would need to be reversed.

That gives some background to our first consulting work with securing PL/SQL; what we did around a year ago was re-write the simple scripts in C using lex and yacc so that the tool became a proper parser. Just after doing that we picked up more consulting work so we used the new C / Lex / Yacc version along with some manual consuting for that project. We wrote up some samples for use of the tool and also a 40 page manual on how to use it. All went well. The C version is much more extendable and robust and includes a debug mode so that the scanning of source code can output lexical tokens instead of obfuscated source to aid setup. The C based tool also now included a set of inpput files to control keywords, reserved words, words to omit from obfuscation (public APIs) and also strings to omit and more. We also built in an instrumentation interface to allow support calls to be processed more easily; i.e. the user can run an obfuscation again and turn on trace to aid locating why something didnt work as planned. This version was sucecssfully used with two clients.

We also re-wrote the wrap protection program in C and this was used for one client.

Next came the plan to license the obfuscation tools and we decided to license the obfuscation tool PFCLObfuscation first for end users to buy; the WrapProtect tool will be available later in the year but contact us if you are interested we are happy to use it on consulting projects where we configure it ourselves at this stage.

PFCLObfuscate has been commercialised. The manual was re-written, we created a proper Windows MSI installer for it, added license protection and converted the main tool to use a configuration file for much easier setup and also have a support site for tickets and we have a road map for new features.

OK, thats a little of the history of how PFCLObfuscate came to be and how you will be able to now license PFCLObfuscate for your own use. I will be showing some of its features here soon.

Posted in PFCLObfuscate, Uncategorized | Comments Off on Welcome to PFCLObfuscate!