Tấn công Rootkit trong Oracle

Một phần của tài liệu Tấn công rootkit trong oracle AT8A HVKTMM (Trang 22 - 46)

Chương 2 Tấn công Rootkit trong Oracle

2.2. Tấn công Rootkit trong Oracle

Oracle database và OS khá tương đồng với nhau về mặt cấu trúc. Cả database và OS đều có user, process, Job, executable và symbolic link. Vì vậy, hacker có thể lợi dụng sự tương đồng này để triển khai các rootkit cũng như các mã độc khác như virus từ phạm vi của OS sang lãnh địa của Oracle database.

Một số tương đồng về command và object giữa Oracle và OS*Nix

*NIX command/object

Oracle command/object

Ps SELECT *FROM V$PROCESS

Kill

<processnumber>

ALTER SYSTEM KILL SESSION ’12,55’

Executable View, package, function and procedure

Execute SELECT * FROM MY_VIEW EXEC

PROCEDURE

Cd ALTER SESSION SET

CURRENT_SCHEMA=USER01

Rm Delete bal…(put in correct sytax)

fdisk Drop tablespaces

Bảng 2.4. Tương đồng giữa database và OS

Thông thường có một thủ thật của rootkit OS thế hệ đầu tiên khi ẩn một tài khoản. lệnh ở trong OS*Nix như ps, who và top đã bị thay thế bằng phiên bản của Trojan, liệt kê tất cả trừ tài khoản của kẻ xâm nhập. Hướng tiếp cận này cũng có thể được áp dụng đối với DB. Rootkit database cũng cần che giấu các hành tung của nó, cụ thể là các process, job, login. Bằng cách tác động vào nơi sẽ lưu trữ và cung cấp các thông tin này cũng như tác động vào các base table và các data dictionary view là sys.user$, v$pwfile_users…Vì vậy attacker cần can thiệp vào source code của các view này.

Đầu tiên, chúng ta thử tìm hiểu một số datadictionary view mà cung cấp thông tin về user cũng như thông tin về các tiến trình có liên quan tới hoạt động của user trong DB. Và tìm hiểu một số PL/SQL package sẵn có của Oracle được sử dụng cho việc tấn công của attacker.

2.2.1. Tìm hiểu 1 số data dictionary view DBA_JOBS

View dba_jobs lưu thông tin về tất cả jobs trong database. Thông tin về các cột trong view này:

Column Comments

Job Xác định một job. Không thay đổi nó dù thực hiện import hay export nhiều lần

Log_user Khi user xác nhận job thì sẽ được ghi lại

Priv_user User có quyền mặc định được áp dụng cho job này Schema_user Schema mặc định được gán cho job khi thực thi Last_date Thời điểm gần nhất mà job được thực hiện thành cng Last_sec Tương tự như last_date

This_date Thời điểm mà job được bắt đầu thực hiện(là null nếu ko thực thi)

This_sec Tương tự this_date. Thời điểm lần thực thi cuối cùng được bắt đầu

Next_date Thời điểm kế tiếp mà job sẽ được thực hiện

Next_sec Tương tự next_date. Thời điểm được thực hiện kế tiếp Total_time Tổng thời gian sử dụng hệ thống của job, tính theo giây Brocken Nếu là Y, nghĩa là không có một cố gắng chạy job này.

Nếu là N có một cố gắng để chạy job Interval Lập lịch chạy job lần tiếp thep

Failures Số lần khởi động job và không thành công kể từ lần thành công gần nhất

What Body của block anonymous PL/SQL mà job này thực hiện

Nls_env Tham số phiên mô tả biến môi trường nls của job Misc_env Tham số phiên khác áp dụng cho job

instance ID của instance chạy hoặc có thể chạy job. Mặc định là 0 Bảng 2.6. View dba_jobs

DBA_JOB_RUNNING

View Dba_job_running liệt kê thông tin về tất cả job đang chạy

Column_name Comments

Failures Số lần job được khởi hoạt và thất bại kể từ lần thành công sau cùng

instance ID của instance chạy job

Job ID của job đang chạy

Last_date Ngày gần nhất mà job chạy thành công

Last_sec Tương tự như last_date,đó là lần thực hiện thành công gần nhất

SID ID của tiến trình đang thực hiện job

This_date Ngày mà job bắt đầu thực hiện(thường là null nếu không đang thực hiện)

This_sec Giống như this_date. Đó là lần thực hiện thành công cuối cùng

Bảng 2.7. View dba_jobs_running

VSPROCESS

Lưu thông tin về các process hiện tại đang chạy

Cột Mô tả

addr Địa chỉ của process

Pid Định danh của process

Spid Định danh trên OS của process

Username Process được chạy bằng tài khoản OS nào Trace ID Định danh file trace

Background Nhận diện process có phải tiến trình background không Latchwait Địa chỉ của Latch mà process đang đợi

Latchspin Địa chỉ của latch mà process đang spinning trên Pga_used_mem Vùng nhớ PGA mà process sử dụng

Pga_alloc_mem Vùng nhớ PGA hiện thời được cấp phát cho process

Bảng 2.8. V$Process

V$Session

V$sesion liệt kê các thông tin về mỗi session hiện tại. rootkit cần tìm cách che giấu thông tin về các process ở trong các view này. Một số thông tin trong view v$sesion:

Column Nội dung

Saddr Địa chỉ session

sid Định danh session

Sarial# Số serial của session. Dùng để xác định duy nhất một object của session đảm bảo rằng các câu lệnh được thực thi đúng đối tượng khi session kết thúc và một session khác dùng ID lại định danh của session

Paddr Địa chỉ của process sở hữu session,

Event Tài nguyên hoặc sự kiện mà session đang đợi

Status Trạng thái của session(active, inactive, killed, catched…)

Logon_time Thời gian logon

Username Tên user

Command Các lệnh đang xử lý

Type Kiểu session

Bảng 2.9. V$Session 2.2.2. Khai thác các PL/SQL Package

Package là một schema object nhóm các kiểu, biến và chương trình PL/SQL có liên quan. Package thường có 2 phần: phần đặc tả là phần giao tiếp của package.

Nó khai báo các kiểu, các biến, hằng, ngoại lệ, con trỏ và các chương trình con mà bneen ngoài có thể tham chiều tới. phần body định nghĩa các truy vẫn cho con trỏ và mã cho các chương trình con(các procedure, function…). Phần spec được coi là phần hộp trắng, phần body là hộp đen. Có thể debug,thay đổi phần body mà không ảnh hưởng tới phần spec.

Để tạo package spec, dùng lệnh: Create package. Lệnh Create package body định nghĩa phần body. Phần spec sẽ được public với tất cả các procedure và code

khác bên ngoài pack. Phần body chứa các thực thi và các khai báo riêng, không được hiển thị đối với bên ngoài.

Package DBMS_METADATA

Để thay đổi thông tin mà các view đưa ra, attacker cần phải tác động tới mã nguồn (mã tạo ra) các view, table. Trong các function, procedure được viết để thực hiện ý đồ của mình, attacker sẽ cần phải lấy mã nguồn của cá view, table cần thay đổi sau đó thêm vào phần mã của mình và thực hiện tạo lại view, table. Attacker có thể sử dụng package dbms_metadata của Oracle để lấy mã nguồn (DDL) này.

Thực tế Oracle đưa ra package dbms_metadata nhằm làm đơn giản hóa một số công việc trong database mà cần phải trích (extract) thông tin về các table, index từ Oracle và chueyenr chúng sang hệ thống khác. Việc trích DDL của các schema object từ dictionary sẽ rất hữu ích khi phải chuyển sang hệ thống mới và muốn có lại cá object đó trong tablespace miows. Oracle cung cấp package dbms_metadata giúp các nhà phát triển dễ dàng lấy các metadata về các object từ data dictionary và đưa ra dưới dạng XMI hoặc DDL. Sau đó load XMI hoặc chạy DDL để tạo lại object. Dbms_metadata sử dụng một số object và table được định nghĩa trong schema SYS. Thường gặp nhất là ku$_parsed item và ku$_ddl.

Trong dbms_metadata những user thông thường chỉ có thể xem metadata các object mà họ sở hữu, các object họ được gán quyền, các object được public. SYS và user có quyền Select_catalog_role xem được metadata của tất cả các object trong database. Trong các procedure, function và các package định nghĩa quyền, các role như select_cattalog_role không được kích hoạt. Vì thế các chương trình PL/SQL chỉ có thể lấy metadata cho các object ở trong schema của chính nó.

Package dbms_metadata định nghĩa trong schema SYS các object và table như sau:

Table Các column

Sys.ku$_parsed_item Item, values, object_row

Sys.ku$_ddl ddlText,parsedItem

Sys-ku$_Errorline errorNumber, errorText Sys.kus_submitresult Ddl, errorlines

Bảng 2.10. dbms_metadata

Sử dụng các chương trình con trong dbms_metadata để lấy DDL cảu các object hoặc đăng ký dạng XML của các object với database.

Subprogram Nội dung

Add_transform function Xác định 1 transform mà fetch_xxx áp dụng đối với dạng thể hiện XML của object Fetch_xxx Trả về metadata cho object thỏa mãn các

tiêu chuẩn thiết lập bởi open, set_filter, set_count, add_transform

Get_query Trả về dạng text của query mà fetch_xxx sử dụng

Get_xxx Lấy về metadata cho một object cụ thể Open Chỉ ra kiểu của object cần lấy, phiên bản

metadata của nó

Set_count Thiết lập số object được lấy trong một lời gọi fetch_xxx

Set_parse_item Xác định một thuộc tính object được phân tích

Set_filter Đặt các tiêu chuẩn để tìm hiểu object ví dụ tên hay schema

put Gửi dạng XML cho database

Ví dụ để lấy metadata dạng XML của Scottemp:

Set long 2000000 Set pagesize 0

Select dbms_metadata.get_xml(‘table’,’scott’) From dual;

Package DBMS_OUTPUT

Dbms_output package cho phép gửi message từ pl/sql. Thường dùng nhất là kích hoạt package dbms_output và hiển thị nội dung của message buffer. Trong sql*plus điều này có thể thực hiện bằng lệnh: ‘ Set serveroutput on’ hoặc

“Setserverout on”. Dbms_output package thường được dùng trong việc debug.

Procedure put và put_line cho phép đặt thông tin vào buffer để bất kỳ trigger, procedure, package nào cũng có thể đọc được. hiển thị thông tin ở vùng buffer bằng cách gọi procedure get_line và get_lines.

Package dbms_output được chạy bằng scrip dbmsscrip.sql bởi user Sys.Package này được gán Excute cho tất cả user(public)

Subprogram Nội dung

Dbms_output.enable Enable các chương trình con Put, put_line, get_line, get_lines và new_line

Dbms_output.new_line Thêm một end-ò-line vào buffer Dbms_output.get_line(s) Lấy một hoặc nhiều dòng từ buffer Dbms_output.put Chuyển tham số được gọi vào buffer Dbms_output.put_line Thêm một end-of-line vào buffer

Bảng 2.11. dbms_output Package DBMS_JOB

Dbms_job cung cấp một job cho nhiều instance. Mặc định job có thể chạy trên bất kỳ một instance nào, nhưng chỉ có một instance sẽ chạy nó. Không yêu cầu phải có system privilege nào để có thể sử dụng dbms_job. Và cũng không có system privilege nào quản lý dbms_job. Các job không thể bị sửa đổi hay xóa ngoài job sở hữu bởi user đó. Một khi job được start và chạy sẽ không dễ ngừng job lại.

Subprogram Nội dung

Broken Chặn thực hiện job

Change Chỉnh sửa tham số người dùng định nghĩa liên quan tới job

Instance Gán một job cho một instance chạy Next_date Lần thực hiện job tiếp theo

Remote Xóa một job khỏi hàng đợi job

Run Thực hiện chạy job

Submit Đưa một job vào hàng đợi job

what Thay đổi đặc tả của một job

Bảng 2.12. dbms_jobs Package DBMS_SQL

Package dbms_sql cho phép truy nhập tới dynamic SQL và dynamic PL/SQL từ ben trong chương trình PL/SQL. Dynamic có nghĩa là các câu lệnh SQL trong package sử dụng những tham số chưa được trong chương trình. Chugns là các

chuỗi ký tự được xây dựng tại thời điểm chạy và sau đó được đưa vào SQL engine để thực hiện. package dbms_sql cho phép thực hiện những hành động là không thể trong chương trình PL/SQL bao gồm:

- Executre câu lệnh ddl: câu lệnh ddl như drop table hay create index là không được phép trong native PL/SQL.

- Tạo một ad-hoc query interface: với dbms không cần phải nhọn nhằn gõ các câu lệnh select cho một truy vẫn hay con trỏ. Bạn có thể cho user xác định các thứ tự sắp xếp, các điều kiện và bất kỳ trường hợp nào của các câu lệnh select.

- Execute dynamic các chương trình PL/SQL đã được tạo: trong table, chúng ta lưu tên của procedure thực hiện cho phép tính toán nào đó. Sau đó dùng một front-end cho table đó, để user lực chọn chức năng phù hợp đưa giá trị đầu vào và thực thi thay vì phải thêm vào hàng và tương tác với khá nhiều giao diện

Với sức mạnh sự ảnh hưởng và linh hoạt của dynamic SQL thông thường chỉ nên gán quyền Execute cho những user mà cần thực hiện dynamic SQL. Để che giấu dbms_sql thực hiện lệnh bằng tài khoản sys:

Revoke execute on dbms_sql from public;

Để gán quyền execute cho user nào đó, thực hiện : Grant execute on dbms_sql to User_name;

Khi thực hiện một chương trình dbms_sql từ một anonymous block, chương trình đó được thực hiện với quyền của schema hiện tại. Nếu những chương trình dbms SQL sẽ thực hiện sử dụng quyền của người sở hữu chương trình đó.

Dbms_sql còn được gọi là package ‘run as user’ hơn là ‘run as owner’.

Name Miêu tả

Close(open)_curror Đóng(mở) con trỏ

Column_value Lấy giá trị từ con trỏ vào biến cục bộ

Execute Thực thi con trỏ

Fetch_rows Nhập giá trị row từ con trỏ

Is_open Trả về giá trị true true nếu con trỏ đang mở

Last_row_count Trả về tổng số row được fetch từ con trỏ Last_SQL_function_code Trả về function code cho câu lệnh SQL

Define_column Xác định một column được chọn từ một con trỏ cụ thể

Parse Phân tích cú pháp câu lệnh SQL nếu đó là

DDL thủ tục phân tích sẽ thực thi luôn câu lệnh Variale_value Lấy giá trị một biến trong con trỏ

Bảng 2.13. dbms_sql

Dbms_sql thực sự là một package mạnh nhưng nó cũng là một package khá phức tạp để sử dụng. thông thường chúng ta có thể tạo và thực hiện vào các câu lệnh SQL. Nhưng việc tạo như vậy khá là thủ công và vất vả, phải xác định tất cả các câu lệnh SQL. Nhưng việc tạo như vậy khá thủ công và vất vả, phải xác định tất cả các câu lệnh SQL, với các lời gọi thủ tục, các kiểu, biến…

Quá trình xử lý của Dynamic SQL

- Mở vùng nhớ: trước khi thực hiện bất kỳ sql dynamic nào phải có một con trỏ tới cùng nhớ mà sql dynamic sẽ được quản lý. Khi mở vùng nhớ, Rdbms trả về một integer gán với con trỏ. Chúng ta sẽ sử dụng giá trị này trong các lời gọi sau đó tới các chương trình dbms_sql để thực hiện câu lệnh dynamic này. Có thể sử dụng một con trỏ để thực hiện nhiều câu lệnh SQL. Nội dung của vùng lưu dữ liệu sẽ được rết nếu một câu lệnh mới được phân tích vì thế không phải close và open lại con trỏ.

- Phân tích câu lệnh: sau khi đã xác định con trỏ tới vùng nhớ, để liên kết nó với câu lệnh sql cần phải phân tích (parse) câu lệnh bằng lời gọi tới thủ tục parse. Nó xác định các câu lệnh này có đúng cấu trúc không và liên kết các câu lệnh với con trỏ. Lưu ý khi phân tích một câu lệnh DDL, nó cũng ngay tức khắc được thực thi và rdbms cũng thực hiện một lệnh commit ngầm định.

- Ràng buộc tất cả giá trị host: câu lệnh mà chúng ta thực hiện ở dạng chuỗi tại thời điểm chạy. Khi sử dụng dynamic sql, tại thời điểm compile chúng ta chưa biết giá trị vì thế phải chuyển qua giá trị vào câu lệnh sql tai thời điểm chạy. Có 2 cách để thực hiện: móc nối(concatenation) và ràng buộc(binding). Với móc nối, chuyển tất các thành phần tròn câu lệnh sql thành chuỗi và nối chúng lại. Với ràng buộc chúng ta nên chèn nơi lưu trữ (placebolder) vào chuỗi với dấu ‘:’ đặt trước. nếu câu lệnh sql chứa tham chiếu tới các biến PL/SQL, chúng ta phải chỉ ra nơi đặt các biến đó trong câu lệnh sql bằng cách đặt dấu ‘:’ trước tên. Sau đó gán giá trị thật cho biến đó trong câu truy vấn

Nếu nối giá trị vào một chuỗi thì không cần phải gọi các thủ tục bind_varalable hay bind_array. Ví dụ:

DBMS_SQL_PARSE (the_cursor,

SELECT COUNT(*) freq FROM call WHERE call_date =:call_date’|| ‘AND call_type_cd = :call_type’,

DBMS_SQL.V7);

DBMS_SQLBIND_VARIABLE(the_cursor,’call_date’,:call.last_date_called );

DBMS_SQL_BIND_VARIABLE(the_cursor,’call_type’,:call.call_status);

Để tránh phải tạo các lời giọ riêng rẽ tjoiws bind_variable có thể đưa các giá trị này vào câu lệnh tại thời điểm phân tích. Ví dụ trên có thể viết thành:

DBMS_SQL.PARSE (the_cursor,

‘SELECT COUNT(*) freq FROM call WHERE call_date=’’’||

TO_CHAR(:call.last_date_called ||

“AND call_type_cd = ‘’’||:call.call_status ||’’’, DBMS_SQL.V7);

Các dấu ‘’’ được nhóm lại thành cùng nhau (3 dấu ‘’’ ở cuối chuỗi sẽ trở thành một dấu ‘ ở cuối giá trị được đưa vào câu lệnh sql, móc nối hay kiểu giá trị.

- Định nghĩa các cột trong lệnh select: mỗi cột trong danh sách mà câu lệnh sql liệt kê với các biến PL/SQL nhận giá trị đó. Bước này chỉ dành cho câu lệnh select.

- Thực thi câu lệnh: thực thi tại vùng nhớ đã chỉ ra-tức là câu lệnh tại vùng nhớ đó. Nếu câu lệnh sql là insert, update hay delete, lệnh execute sẽ trả về số các hàng được xử lý. Còn lại, chúng ta có thể bỏ qua giá trị trả về - Lấy các hàng từ truy vấn sql dynamic: nếu thực thi truy vấn, sau đó phải

lấy các hàng từ vùng nhớ. Tuy nhiên, không lấy trực tiếp vào các biến PL/SQL cục bộ

- Tìm hiều các giá trị việc thực thi sql dynamic: nếu câu lệnh SQL là một truy vấn, tìm kiếm các giá trị trả về của lệnh select bằng column_value.

- Đóng con trỏ: giải phóng vùng nhớ liên quan tới con trỏ.

Utl_tcp

Một phần của tài liệu Tấn công rootkit trong oracle AT8A HVKTMM (Trang 22 - 46)

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

(50 trang)
w