Xin chào ! Nếu đây là lần đầu tiên bạn đến với diễn đàn, xin vui lòng danh ra một phút bấm vào đây để đăng kí và tham gia thảo luận cùng VnPro.

Announcement

Collapse
No announcement yet.

SQL Injection

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • SQL Injection

    SVTH: Hoàng Minh Tuấn

    2.7 SQL Injection


    2.7.1 Giới thiệu về SQL Injection

    2.7.1.1 Tầm quan trọng của các câu lệnh SQL đối với một hệ thống web
    Cơ sở dữ liệu(database) được coi như là "trái tim" của hầu hết các website. Nó chứa đựng những dữ liệu cần thiết để website có thể chạy và lưu trữ các thông tin phát sinh trong quá trình chạy. Nó cũng lưu trữ những thông tin cá nhân , thẻ tín dụng , mật khẩu của khách hàng , của user và thậm chí là cả của Administrator. Để lấy các thông tin cần thiết từ cơ sở dữ liệu thì các câu lệnh SQL sẽ đảm đương trách nhiệm thực hiện các yêu cầu truy vấn được đưa ra từ phía người sử dụng: khi người dùng đăng nhập vào hệ thống, lấy một thông tin nào đó trên web,… đều cần sử dụng các câu lệnh SQL, hay nói cách khác, các câu lệnh SQL đóng một vai trò rất quan trọng đối với một hệ thống web.

    2.7.1.2 Khái niệm về SQL Injection
    SQL Injection là một kĩ thuật tấn công dựa vào các lỗ hổng lập trình ứng dụng, cụ thể là các ứng dụng có thao tác truy xuất cơ sở dữ liệu, để “tiêm”( inject) vào đó các câu truy vấn bất thường, nhằm đạt được một mục đích cụ thể nào đó như chiếm password, tạo backdoor,…
    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ữ cơ sở dữ liệu có thể gây ra thất thoát lớn về tài chính cho công ty. Thông thường, cơ sở dữ liệu bị tấn công để 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.

    2.7.1.3 Một số thông tin về SQL Injection
    SQL Injection có thể được sử dụng như một phương pháp tấn công DoS( Denied of Service). Vào tháng 1/2008, một nhóm attacker đã phát hiện ra nguy cơ SQL injection trên web site của Recording Industry Association of America( RIAA). Nguy cơ này tạo bàn đạp cho việc tấn công SQL Injection, khiến cho hàng triệu CPU xử lý hàm MD5 trong cơ sở dữ liệu. Bằng cách đưa ra đường link sau:

    và khuyến khích mọi người click vào. Khi click vào, sẽ thực hiện câu lệnh SQL nhằm làm tê liệt hệ thống. Kết quả là với chỉ vài dòng SQL, hệ thống đã bị đánh sập. Câu lệnh SQL đơn giản chỉ với 77 kí tự như sau:

    Vào năm 2007 và 2008, các hacker sử dụng SQL Injection để load malware từ các hệ thống bên trong của nhiều công ty để chiếm lấy hàng triệu credit card. Tháng 10 năm 2008, cục điều tra liên bang Mỹ( FBI) đã đóng cửa một web site đóng vai trò quan trọng trong việc buôn bán các dữ liệu credit card sau 2 năm điều tra và tránh được việc thất thoát 70 triệu USD.
    Vào ngày 8 tháng 11 năm 2008, các hacker đã tấn công vào một ngân hàng và lấy được hơn 9 triệu USD từ 49 thành phố trên toàn cầu chỉ trong vòng 30 phút.
    Theo thống kê về các lỗ hổng bảo mật thường bị tấn công nhất vào năm 2009

    SQL Injection chiếm một tỉ lệ rất cao so với các phương pháp tấn công khác.

    2.7.1.4 Đánh giá mức độ nguy hiểm của SQL Injection
    Theo tài liệu Hacking Exposed Web 2.0 đánh giá:

    Mức độ phổ biến của phương pháp tấn công này rất cao( 8/10), bởi vì nó cũng khá đơn giản để thực hiện( 8/10), và các tác động của SQL Injection tới hệ thống là rất nguy hiểm( 9/10). Chính vì thế, nên tổng thể nguy cơ này được đánh giá 9/10. Đây thật sự là một lỗ hổng về bảo mật rất đáng được quan tâm đến.
    Dựa vào lỗi SQL Injection, hacker có thể làm được những việc sau:
    • Có thể lấy được rất nhiều thông tin quan trọng trong cơ sở dữ liệu của một hệ thống web
    • như account và password của admin của một web site, hay các thông tin quan trọng về thẻ tín dụng của khách hàng trong một ngân hàng nào đó,…
    • Có thể thêm, xóa, sửa cơ sở dữ liệu của đối tượng bị tấn công theo ý muốn
    • Có thể tạo một backdoor cho những lần tấn công sau
    • Có thể đánh sập hoàn toàn một hệ thống
    • Có thể dùng như một phương pháp tấn công DoS


    2.7.2 Tìm hiểu về SQL Injection

    Mặc dù SQL là một chuẩn do ANSI và ISO đưa ra, tuy nhiên, có rất nhiều phiên bản khác nhau của ngôn ngữ SQL. Và phần lớn các chương trình cơ sở dữ liệu cũng có những phần mở rộng thêm vào riêng của họ, so với chuẩn SQL. Do đó, khi tấn công các cơ sở dữ liệu khác nhau hoặc các web site viết trên các ngôn ngữ lập trình khác nhau, thì có thể sẽ phải sử dụng nhiều phương pháp tấn công khác nhau. Tuy nhiên, các câu lệnh cơ bản của các chương trình cơ sở dữ liệu thì phần lớn đều phải theo chuẩn đã được đưa ra.
    Nguy cơ bảo mật về SQL Injection có thể giúp attacker chiếm quyền điều khiển cơ sở dữ liệu thông qua ứng dụng web. Đối với nhiều web site, thì cơ sở dữ liệu có chứa các thông tin quan trọng như thông tin sản phẩm, các đơn đặt hàng, user profile,..
    Câu lệnh SQL thường khá giống so với tiếng Anh. Xét ví dụ sau: để xem được thông tin của tất cả sinh viên được lưu trữ( name, student ID, mailing address, GPA,…) trong bảng Undergraduates thì câu lệnh sẽ là:
    Select * From Undergraduates
    Để xem dữ liệu về sinh viên có họ là Wiley, câu truy vấn sẽ là:
    Select * From Undergraduates Where Last_Name = ‘Hoang’
    Để xem thông tin về sinh viên có họ là Hoang và tên là Tuan, câu truy vấn sẽ là:
    Select * From Undergraduates Where Last_Name = ‘Hoang’ and First_Name = ‘Tuan’
    Câu lệnh and trong câu truy vấn có nghĩa là cả hai điều kiện đều phải đúng( họ là Hoang và tên là Tuan) thì sẽ hiển thị lên. Tuy nhiên, nếu thay đổi and thành or thì câu truy vấn sẽ trở thành:
    Select * From Undergraduates Where Last_Name = ‘Hoang’ or First_Name = ‘Tuan’
    và nó sẽ hiển thị mọi sinh viên có họ là Hoang( Cuong Hoang, Loc Hoang, Tuan Hoang,…) và có tên là Tuan( Tuan Hoang, Tuan Vu, Tuan Nguyen,…). Câu lệnh or trong SQL có nghĩa là chỉ cần một trong hai điệu kiện là đúng thì toàn bộ câu truy vấn sẽ là đúng. Đây chính là mấu chốt cho việc thực hiện tấn công SQL Injection.
    Xét ví dụ: ở một cơ sở dữ liệu của một hệ thống web có lưu trữ một account có ID là Tuan Hoang và password là 12345, khi đăng nhập vào form sau:

    Hình 2.6. Form login




    Nếu nhập đúng thì câu truy vấn SQL sau sẽ được thực hiện:
    Select ID From Users Where UserName = User_Entered_Username and Password = User_Entered_Password
    Câu truy vấn trên sẽ tìm kiếm trong bảng Users với giá trị phải là đúng của cả username( Tuan Hoang) và password( 12345). Tuy nhiên, nếu attacker nhập vào khung password là 123 or 1 = 1 thì câu lệnh SQL đương nhiên trở thành giá trị đúng, và với cách thực hiện như vậy thì sẽ xâm nhập được vào hệ thống một cách vô cùng đơn giản. Và cũng bởi vì khi đã xâm nhập được trực tiếp vào bên trong hệ thống, nên những thao tác như thêm, xóa, sửa cơ sở dữ liệu có thể được thực hiện một cách dễ dàng.
    Tuy nhiên, phương pháp tấn công trên ngày nay đã không còn sử dụng được nữa, bởi lỗi này đơn giản, dễ thực hiện, song cũng rất dễ vá lỗi. Thế nhưng phương pháp tấn công trên thường được sử dụng như một ví dụ kinh điển làm nền tảng việc tìm hiểu về tấn công SQL Injection. Sau này, các hacker đã tìm được rất nhiều lỗ hổng SQL Injection nguy hiểm có thể gây thiệt hại nghiêm đến cơ sở dữ liệu và hệ thống.
    Lỗ hổng SQL Injection giúp attacker điều khiển được cơ sở dữ liệu thông qua Web application. Đối với nhiều Web site, cơ sở dữ liệu đóng vai trò rất quan trọng, nó chứa nhiều thông tin như danh sách các sản phẩm, đơn đặc hàng, user profile, password,… những site xử lý các câu truy vấn cơ sở dữ liệu khi user thực hiện các thao tác cũng bị ảnh hưởng khi thực hiện các câu lệnh truy vấn. Cơ sở dữ liệu có thể bị truy vấn để lấy ra các thông tin có trong đó. Dữ liệu có thể bị thay đổi như gửi một comment tới một thread đang được thảo luận. Các thông tin lạ có thể được đưa vào cơ sở dữ liệu như thêm vào một comment mới trong thread, hay thêm vào một đơn đặt hàng mới. Thông tin lưu trữ trong cơ sở dữ liệu có thể được update, như thay đổi home address hoặc reset password. Cũng có lúc dữ liệu bị xóa đi khỏi cơ sở dữ liệu… Trong mọi trường hợp, web site đều xử lý câu lệnh truy vấn với một mục đích cụ thể nào đó.
    Các lỗ hổng về SQL Injection thay đổi câu lệnh cơ sở dữ liệu thành ra khác hẳn so với ý muốn ban đầu của người tập trình, khiến các câu lệnh có thể được điều khiển bởi attacker. Một câu truy vấn đến một record có thể đổi thành một câu truy vấn cho toàn bộ các record. Một thông tin mới thêm vào có thể xóa toàn bộ các table trong cơ sở dữ liệu. Trong trường hợp nghiêm trọng hơn, việc tấn công vượt ra khỏi cơ sở dữ liệu và tấn công thẳng lên hệ điều hành.
    Lý do mà SQL Injection có thể gây tác hại lớn đến như vậy là do nguy cơ đến từ các ứng dụng Web: các kí tự “dính” vào với nhau tạo thành chuỗi( string concatenation). String concatenation là tiến trình “dính” các kí tự lại với nhau để tạo thành một chuỗi đơn thống nhất- trong trường hợp này là các lệnh truy vấn cơ sở dữ liệu. Do đó, ta có thể lợi dụng cách này để thực hiện câu truy vấn trực tiếp thẳng vào address bar hoặc thêm vào các kí tự bất thường ngay tại khung đăng nhập để “đánh lừa” hệ thống.
    Ví dụ dưới đây sẽ cho thấy, chỉ một yêu cầu truy vấn tới cơ sở dữ liệu nhưng lại có thể viết dưới rất nhiều cách khác nhau:

    SELECT*FROM parties WHERE day='tomorrow'
    SELECT*FROM parties WHERE day='tomorrow'
    SELECT*FROM parties WHERE day=REVERSE('worromot')
    SELECT/**/*/**/FROM/**/parties/**/WHERE/**/day='tomorrow'
    SELECT*FROM parties WHERE day=0x746f6d6f72726f77
    SELECT*FROM parties WHERE(day)LIKE(0x746f6d6f72726f77)
    SELECT*FROM parties
    WHERE(day)BETWEEN(0x746f6d6f72726f77)AND(0x746f6d6 f72726f77)
    SELECT*FROM[parties]WHERE/**/day='tomorrow'
    SELECT*FROM[parties]WHERE[day]=N'tomorrow'
    SELECT*FROM"parties"WHERE"day"LIKE"tomorrow"
    SELECT*,(SELECT(NULL))FROM(parties)WHERE(day)LIKE( 0x746f6d6f72726f77)
    SELECT*FROM(parties)WHERE(day)IN(SELECT(0x746f6d6f 72726f77))
    Khi thử nhiều dòng lệnh như vậy, cần chú ý tới lỗi SQL được đưa ra để biết được những kí tự nào sẽ vượt qua được “bộ lọc”, và kiểm tra các kí tự được mã hóa và phần nào của cú pháp câu truy vấn cần được chỉnh sửa.
    Dưới đây là bảng một số kí tự đặc biệt trong ngôn ngữ SQL và được xem là không an toàn và có thể gây nguy hiểm cho cơ sở dữ liệu

    Hình 2.7. Một số kí tự đặc biệt trong SQL




    Những kí tự trên mang một mối nguy hiểm tiềm tàng đối với cơ sở dữ liệu, xét thêm một ví dụ sau:
    String query = "SELECT id FROM user_table WHERE " +
    "username = '" + username + "' AND " +
    "password = PASSWORD('" + password + "')";

    Đây là một câu truy vấn trong HTML, giả sử attacker nhập username là:
    ' OR 1=1; DROP TABLE user_table; --
    Thì câu truy vấn sẽ trở thành:
    SELECT id FROM user_table WHERE username='' OR 1=1; DROP TABLE
    user_table; -- ' AND password = PASSWORD('x');
    và sẽ thực hiện đồn thời hai lệnh:
    SELECT id FROM user_table WHERE username='' OR 1=1;
    DROP TABLE user_table;
    Bởi vì câu truy vấn trên hoàn toàn là đúng, nên nó sẽ thực hiện lệnh DROP. Điều này rất nguy hiểm đối với một cơ sở dữ liệu.
    SQL Injection bằng cách sử dụng trực tiếp user data khi tạo một câu truy vấn.
    Theo tài liệu Hacking Exposed Web 2.0 đánh giá:


    Đây cũng là một dạng SQL Injection nhưng có phức tạp hơn một chút so với phương pháp SQL Injection thông thường, khi yêu cầu đòi hỏi phải có dữ liệu của user. Mức độ phổ biến của phương pháp này cũng khá cao( 8/10), mức độ đơn giản chỉ ở mức vừa phải( 6/10) nhưng sức phá hoại của nó rất cao( 9/10). Đây cũng là một mối nguy hiểm cần được quan tâm đến( 9/10).
    Xét đoạn code ví dụ sau:
    string query = "SELECT * FROM Users WHERE name='" + userName + "'";
    SqlConnection conn = new SqlConnection(connectionString);
    conn.Open();
    SqlCommand sqlCommand = conn.CreateCommand();
    sqlCommand.CommandText = query;
    SqlDataReader reader = sqlCommand.ExecuteReader();
    /* Process Results Here */
    Đoạn code này có thể bị tấn công bằng phương pháp SQL Injection bởi vì nó xử lý trực tiếp câu truy vấn với dữ liệu của user. Đối tượng SqlConnection tạo kết nối tới cơ sở dữ liệu và SqlCommand đại diện cho một lệnh riêng biệt sẽ được xử lý trong database management system( DBMS). Attacker có thể “tiêm” nhiều lệnh vào câu truy vấn bằng dấu chấm phẩy(;) để phân cách mỗi câu lệnh riêng biệt với nhau.
    Lỗi này có thể dễ dàng tránh được bằng cách sử dụng .NET. Dùng class SqlParameter để insert thông tin vào các câu truy vấn SQL thay vì insert trực tiếp thông qua string concatenation. Bằng cách sử dụng class SqlParameter, các class trong .NET sẽ biết lấy user data từ câu truy vấn và thông tin mà attacker đưa vào sẽ không thực hiện được. Các class của SqlParameter có thể sử dụng có thể sử dụng các phương thức được lưu trữ sẵn và các câu truy vấn chuẩn như câu lện select trong ví dụ trên.
    Để sử dụng một đối tượng SqlParameter với một câu truy vấn, có thể chỉ ra cac biến bằng cách đặt các biến truy vấn vào trong câu query và thêm vào đối tượng SqlParameter thích hợp vào trong SqlCommand. Các biến truy vấn được chỉ ra trong câu truy vấn bằng cách sử dụng @ParameterName với ParameterName là tên của SqlParameter phải cấp cho SqlCommand. Vài hiệu ứng lề có lợi của việc tham số hóa các câu truy vấn là trong vài trường hợp các câu truy vấn lặp sẽ xử lý nhanh hơn và code sẽ trở nên dễ đọc và kiểm soát hơn.
    Ví dụ sau có thể được viết lại để sử dụng SqlParameters:
    SqlCommand sqlCommand = sqlConn.CreateCommand();
    sqlCommand.CommandType = CommandType.Text;
    sqlCommand.CommandText = "SELECT * FROM Contact WHERE
    FirstName=@FirstName";
    SqlParameter nameParam = new SqlParameter("@FirstName", firstName);
    nameParam.SqlDbType = SqlDbType.Text;
    sqlCommand.Parameters.Add(nameParam);
    Câu truy vấn đã được thay đổi và sử dụng đối tượng SqlParameter để phân biệt giá trị cho cột FirstName trong vế WHERE. Cấu truy vấn đã có thể được xử lý an toàn, ko cần lo lắm về việc dữ liệu của user được dùng để tấn công vào cơ sở dữ liệu.
    Kĩ thuật này cũng được dùng khi gọi một stored procedure. Để tránh câu truy vấn dài như exec sp_my_stored_procedure @param1, @param2, thay đổi CommandType của SqlCommand thành CommandType.StoredProcedure. Bằng cách thay đổi kiểu câu lệnh thành StoredProcedure, .Net Framework sẽ hiểu người lập trình muốn gọi một stored procedure và đặt vào câu truy vấn thích hợp.
    Attacker có một vài lợi thế khi tấn công bằng phương pháp SQL Injection trên các ứng dụng ASP.Net. Trước hết, rất nhiều ứng dụng chính của ASP.NET được triển khai trên môi trường Microsoft và sử dụng Microsoft SQL Server. Attacker có thể lưu vài database fingerprinting bằng cách tấn công Microsoft SQL và sử dụng phương pháp tấn công thích hơp. Sau đó, ASP.Net chạy phổ biến nhất trên nền .Net. Kết hợp điều này, attacker có thể tấn công các ứng dụng với thông tin về cách mà các câu truy vấn được đặt như thế nào trong cơ sở dữ liệu. Chỉ cần một ít thông tin đó thôi cũng đủ để các hacker tìm được lỗ hổng SQL Injection.
    Vài năm trước, một kiểu tấn công phổ biết vào các version của SQL Server từ trước đây tới năm 2005 sử dụng phương pháp gọi stored procedure xp_cmdshell. Phương pháp tấn công này chỉ thành công với Microsoft SQL Server và không thành công với các DBMS khác.
    Khi kiểm tra một ứng dụng .Net mới, một trong những điều lưu ý đầu tiên là xem chỗ mà lập trình viên đặt CommandText property trong đối tượng SqlCommand. Thường thì rất dễ liệt kê các phương thức gọi bằng cách tìm trong CommandText hoặc CommandType.Text và quyết định xem lập trình viên ứng dụng đó có tạo đúng mục đích sử dụng của các tham số trong truy vấn SQL hay không.
    Một lưu ý là sẽ một người sẽ có lợi thế trong việc sử dụng các câu truy vấn an toàn nếu họ biết cách sử dụng các hàm trong SQL. Đối với attacker, họ sẽ chú ý tới những điểm mà người lập trình ứng dụng không biết tới hoặc lười kiểm tra khi họ thao tác với ngôn ngữ SQL.

    Mời các bạn đón đọc phần tiếp theo, bài về khai thác lổ hổng...!!!
    Last edited by lamvantu; 26-09-2011, 01:53 PM.
    Lâm Văn Tú
    Email :
    cntt08520610@gmail.com
    Viet Professionals Co. Ltd. (VnPro)
    149/1D Ung Văn Khiêm P25 Q.Bình thạnh TPHCM
    Tel: (08) 35124257 (5 lines)
    Fax (08) 35124314
    Tập tành bước đi....



  • #2
    hay quá...đang chờ phần tiếp theo đây :). phần tiếp theo coi bộ hấp dẫn à, đọc xong chắc vào forum vnpro khai thác thử...hehe

    Comment


    • #3
      hay wa ! anh lamvantu post tiếp cho anh em cùng học hỏi !

      Comment


      • #4
        hi all,
        mình có 1 câu sql như này :
        Select* From (
        select * from suppcd_mst where sup_suppcd in ('yamato', 'IC0001', 'CYD002') order by /*$sortKey*/ asc,lang_cd desc
        ) as T where sup_suppcd = 'yamato'

        /*$sortKey*/ là param truyền vào.Giá trị sortKey ở đây là j để có thể tấn công vào câu sql như trên. Bác nào có cao kiến help
        Last edited by Guest; 07-05-2012, 05:45 PM.

        Comment

        Working...
        X