Thực thi các truy vấn do người dùng cung cấp với DBMS_SQL

Một phần của tài liệu Tìm hiểu về PLSQL và tấn công SQL Injection PLSQL trên Oracle (Trang 28 - 32)

X RAW(16); C CLOB;

Thực thi các truy vấn do người dùng cung cấp với DBMS_SQL

Gói mặc định DBMS_SQL cho phép SQL được thực thi động. Thuộc quyền sở hữu của SYS, nó đã được xác định với từ khóa AUTHID CURRENT_USER để nó chạy với các đặc quyền của người gọi. Điều này bảo vệ các thủ tục DBMS_SQL chống lại các cuộc tấn công trực tiếp, nhưng nếu được gọi từ một chương trình PL/SQL khác sử dụng quyền xác định thì nó có thể có vấn đề. Trước khi chúng ta tìm hiểu các thủ tục DBMS_SQL có thể nguy hiểm như thế nào, hãy kiểm tra xem nó hoạt động như thế nào. Hãy xem xét đoạn mã sau DECLARE C NUMBER; R NUMBER; STMT VARCHAR2(200); BEGIN

STMT:=’SELECT 1 FROM DUAL’; C :=DBMS_SQL.OPEN_CURSOR;

R := DBMS_SQL.EXECUTE_AND_FETCH(C);DBMS_SQL.CLOSE_CURSOR(C); DBMS_SQL.CLOSE_CURSOR(C);

END;

Ở đây, một con trỏ, C, được mở bằng hàm OPEN_CURSOR. Sau đó, câu lệnh SQL, 'SELECT 1 FORM DUAL', được phân tích cú pháp bằng cách sử dụng DBMS_SQL.PARSE (C, STMT, DBMS_SQL.NATIVE). Sau khi được phân tích cú pháp, truy vấn được thực thi bằng DBMS_SQL.EXECUTE_AND_FETCH (C). Ngoài ra, hàm DBMS_SQL.EXECUTE (C) có thể được gọi theo sau bởi một lệnh gọi tới DBMS_SQL.FETCH_ROWS (C). Cuối cùng, con trỏ được đóng bằng DBMS_SQL.CLOSE_CURSOR (C).

Bất kỳ truy vấn nào cũng có thể được thực hiện bởi các thủ tục này. Điều này bao gồm các lệnh gọi tới GRANT, CREATE và ALTER. Tuy nhiên, khi cố gắng chạy một truy vấn như vậy bằng DBMS_SQL, một lỗi sẽ được trả về.

ORA-01003: no statement parsed

ORA-06512: at “SYS.DBMS_SYS_SQL”, line 1216 ORA-06512: at “SYS.DBMS_SQL”, line 334

Tuy nhiên, nó đã thành công. Để xem điều này hoạt động, hãy chạy các truy vấn sau: SELECT GRANTEE FROM DBA_ROLE_PRIVS WHERE GRANTED_ROLE = ‘DBA’;

returns GRANTEE --- SYS WKSYS SYSMAN SYSTEM Sau đó chạy DECLARE C NUMBER; R NUMBER; STMT VARCHAR2(200);

BEGIN

STMT:=’GRANT DBA TO PUBLIC’; C :=DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(C, STMT, DBMS_SQL.NATIVE); R := DBMS_SQL.EXECUTE_AND_FETCH(C); DBMS_SQL.CLOSE_CURSOR(C); END; / Kết quả trả vể

ORA-01003: no statement parsed

ORA-06512: at “SYS.DBMS_SYS_SQL”, line 1216 ORA-06512: at “SYS.DBMS_SQL”, line 334 sau đó chạy

SELECT GRANTEE FROM DBA_ROLE_PRIVS WHERE GRANTED_ROLE = ‘DBA’; một lần nữa, lần này trả về GRANTEE --- SYS WKSYS PUBLIC SYSMAN SYSTEM Bây giờ chạy

REVOKE DBA FROM PUBLIC;

Về bảo mật, thủ tục chính là DBMS_SQL.PARSE. Thay vào đó, một tùy chọn an toàn hơn là chạy thủ tục PARSE_AS_USER của gói DBMS_SYS_SQL. Thủ tục này phân tích cú pháp câu lệnh bằng cách sử dụng các đặc quyền của người dùng hiện tại chứ không phải trình định nghĩa của thủ tục. Vì vậy, giả sử SYS đã tạo hai thủ tục P và Q như sau:

CREATE OR REPLACE PROCEDURE P AS C NUMBER;

R NUMBER;

STMT VARCHAR2(200); BEGIN

STMT:=’GRANT DBA TO PUBLIC’; C :=DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(C, STMT, DBMS_SQL.NATIVE); R := DBMS_SQL.EXECUTE_AND_FETCH(C); DBMS_SQL.CLOSE_CURSOR(C); END; /

GRANT EXECUTE ON P TO PUBLIC; CREATE OR REPLACE PROCEDURE Q AS C NUMBER;

R NUMBER;

STMT VARCHAR2(200); BEGIN

STMT:=’GRANT DBA TO PUBLIC’; C :=DBMS_SQL.OPEN_CURSOR;

DBMS_SYS_SQL.PARSE_AS_USER(C, STMT, DBMS_SQL.NATIVE);

DBMS_SQL.CLOSE_CURSOR(C); END;

/

GRANT EXECUTE ON Q TO PUBLIC;

Khi SCOTT thực hiện thủ tục P thì việc cấp thành công, nhưng nếu SCOTT chạy thủ tục Q thì việc cấp sẽ không thành công với

ORA-01031: insufficient privileges

ORA-06512: at “SYS.DBMS_SYS_SQL”, line 1585 ORA-06512: at “SYS.Q”, line 8

Giả sử rằng DBMS_SYS_SQL.PARSE_AS_USER an toàn hơn đã không được sử dụng, mà thay vào đó, DBMS_SQL.PARSE, trong một thủ tục PL/SQL và đầu vào của người dùng được chuyển đến nó, có khả năng bị kẻ tấn công lạm dụng.

Một phần của tài liệu Tìm hiểu về PLSQL và tấn công SQL Injection PLSQL trên Oracle (Trang 28 - 32)

Tải bản đầy đủ (DOCX)

(39 trang)
w