Cài đặt xp_cmdshell trong Database Server MS SQL

Tác giả server360, T.Chín 14, 2014, 11:38:02 SÁNG

« Chủ đề trước - Chủ đề tiếp »

0 Thành viên và 2 Khách đang xem chủ đề.

Cài đặt xp_cmdshell trong Database Server MS SQL


SQL Server là hệ quản trị dữ liệu, khả năng chính của nó là lưu trữ và truy xuất dữ liệu. Tuy nhiên đôi lúc bạn cần thực hiện một số thao tác của windows từ SQL Server, ví dụ khi bạn cần viết sql script để copy file từ folder này sang folder khác; hoặc tự động restore từ file backup mới nhất dựa theo ngày tạo (tên file không biết trước). SQL Server cung cấp thủ tục xp_cmdshell trong master database để làm việc này.

Để có thể gọi đến xp_cmdshell đòi hỏi một vài bước thiết lập.

Nếu bạn là DBA với quyền sysadmin, bạn cần cấu hình lại server để bật xp_cmdshell (khi SQL Server mới cài đặt tính năng này bị tắt):

Mã nguồn [Chọn]
EXEC SP_CONFIGURE 'show advanced option', 1
RECONFIGURE
GO
EXEC SP_CONFIGURE 'xp_cmdshell', 1
RECONFIGURE
GO

Sau đó, với quyền sysadmin bạn có thể dùng xp_cmdshell:

Mã nguồn [Chọn]
EXEC xp_cmdshell 'dir c:\'
Với sysadmin như vậy là xong. Nhưng nếu một người khác (giả sử với sql login là xeko) không có quyền sysadmin mà đăng nhập vào và thử xp_cmdshell, kể cả sau khi bạn đã cấu hình lại server hệ thống vẫn tiếp tục báo lỗi. Có hai vấn đề bạn cần giải quyết.

Thứ nhất, đây là một tác vụ nằm ngoài SQL Server, vì thế mỗi khi có yêu cầu như vậy SQL Server sẽ cần tạo 1 tiến trình trong window để window thực hiện. Tiến trình này cần một window account để có thể chạy, vậy là account nào? Nếu bạn là sysadmin, SQL Server sẽ lấy luôn account đang chạy SQL Service. Nhưng với một non-sysadmin như xeko, SQL Server không đủ tin tưởng để dùng account đó, và như vậy là không có account nào, tất nhiên window sẽ từ chối thực hiện. Để lấp vào khoảng trống đó, bạn cần tạo một proxy account và ánh xạ đến một window account thực, để chỉ thị cho SQL Server khi chạy xp_cmdshell hãy lôi account này ra dùng:

Mã nguồn [Chọn]
EXEC sp_xp_cmdshell_proxy_account 'WinDomain\nobita','password' --thay bằng domain account và password thật
Sau khi chạy lệnh trên, trong Management Studio nếu bạn mở rộng node Security/Credentials, bạn sẽ thấy một dòng ##xp_cmdshell_proxy_account##.

Thứ hai, bạn phải cấp quyền thực hiện thủ tục xp_cmdshell cho xeko:

Mã nguồn [Chọn]
USE master
GO
--Tạo user xeko trong master database nếu chưa có
CREATE USER xeko FROM LOGIN xeko WITH default_schema = dbo
GO
GRANT EXECUTE ON xp_cmdshell TO xeko

Và từ đó xeko có thể chạy xp_cmdshell. Một vài lưu ý sau cùng:

Bạn có thể truyền tham số cho xp_cmdshell như một thủ tục thông thường:

Mã nguồn [Chọn]
    DECLARE @cmd VARCHAR(100), @drive CHAR(2)
    SET @drive = 'C:'
    SET @cmd = 'dir '+@drive
    EXEC xp_cmdshell @cmd

Các lệnh bạn chạy trong xp_cmdshell đều được thực hiện bằng account Windomain\nobita và tuân theo quyền hạn của account này. Ví dụ nếu nobita không có quyền ghi lên ổ D, lệnh sau sẽ trả về thông báo không thực hiện được:

Mã nguồn [Chọn]
EXEC xp_cmdshell 'copy C:\file.txt D:\'
xp_cmdshell tạo ra một lỗ hổng về bảo mật, theo đó hacker nếu chiếm được quyền vào SQL Server và thực hiện xp_cmdshell (tất nhiên phải thông qua một login có quyền exec xp_cmdshell như xeko) có thể tiếp tục phá hoại hoặc đánh cắp dữ liệu nằm ngoài SQL Server. Đây là một đe dọa đáng kể bạn cần lưu ý và cân nhắc giữa sự tiện lợi và an ninh hệ thống. Bạn có thể giảm bớt nguy cơ này bằng cách chỉ bật xp_cmdshell trên các SQL Server không tương tác trực tiếp với web server, và hạn chế tối đa quyền trên mạng cho Windomain\nobita.