Post

VULNHUB | Orasi

VULNHUB | Orasi

Mô tả

Hint : just one useless little dot

SETUP

Tải file nén của bài lab về và import vào Virtual box, chỉnh chế độ mạng thành Host Only và gán vào vboxnet0 ta được kết quả như sau:

Nhấn start để bắt đầu bài lab:

SOLVE

Enum

Vì đã biết máy ảo được gắn vào card mạng vboxnet0 nên dùng arp-scan để xác định IP của bài lab. Thu được kết quả như sau:

Từ kết quả trên xác định được địa chỉ IP của thử thách này là 192.168.56.103
Sử dụng nmap để quét các cổng mở trên địa chỉ IP này thì thu được kết quả như sau:

Từ kết quả trên thu được các thông tin sau:

  • Có 4 port đang mở là 21, 22, 80 và 5000
  • Script của Nmap quét ra được tại port 21 cho phép đăng nhập ẩn danh

Truy cập vào trang web tại cổng 80 và 5000 thì thu được kết quả như sau:

Thực hiện dò quét các đường dẫn bằng gobuster thì không thu thập được thêm đường dẫn ẩn nào, nên ta nhắm mục tiêu khai thác đến cổng 21 vì cho phép đăng nhập ẩn danh.

Sau khi truy cập vào port 21 với chế độ ẩn danh thì kết quả là ta có thể truy cập vào thư mục pub và có quyền đọc file url nên mình lưu về máy để tiến hành phân tích:

Thực thi file và tìm các chuỗi trong file thì không thu thêm được thông tin gì:

Vì phân tích cơ bản không thu được thông tin gì nên mình tiến hành import file này vào ghidra để tiến hành phân tích chi tiết:

Tìm đến hàm main thì nhận thấy chương trình có gọi đến hàm insert 1 số kí tự như sau:

Chuyển các kí tự sang dạng chuỗi thì thu được kết quả như sau:

Nhìn vào kết quả ta nhận thấy chuỗi kí tự ghép lại trông giống như 1 đường dẫn url /sh4d0w$s. Thử đường dẫn này trên lần lượt 2 port 80 và 5000 thì response tại port 5000 xuất hiện kết quả như sau:

Chuyển method của request sang dạng POST thì nhận thấy server không xử lý request này nên có thể kết luận là input được truyền vào thông qua query của url:

Tuy nhiên ta không biết được giá trị key của query là gì. Và khi truyền vào 1 giá trị key bất kì thì server vẫn trả ra phản hồi là no input:

Thử fuzzing với các wordlist phổ biến thì không thu thập được thêm kết quả gì nên mình nghĩ đến việc tạo wordlist thủ công. Để ý thì ở trang web nằm tại port 80 có 1 chuỗi kí tự khá là đặc biệt là 6 6 1337leet có format khá là giống với đầu vào cho câu lệnh crunch dùng để tạo wordlist nên mình thử tạo wordlist với câu lệnh như sau:

Sử dụng ffuf để fuzzing với wordlist vừa tạo thì thu được kết quả như sau:

Lưu ý: do no input có độ dài là 8 nên mình filter đi các response có kích thước phản hồi là 8 để loại bỏ đi các giá trị không chính xác.

SSTI

Khi thử payload <script>alert(1)</script>, response xác nhận tồn tại lỗ hổng XSS. Tuy nhiên, trong bài lab này không có sự xuất hiện của bot hay tương tác từ người dùng khác nên hướng khai thác XSS phía client-side không mang lại tác động đáng kể. Nhìn vào phân HTTP response header, server đang sử dụng Werkzeug/1.0.1 trên Python 3.7.3 nên có khả năng đầu vào được xử lý thông qua template engine của Python.

Kiểm chứng với payload sau thì xác nhận có lỗ hổng SSTI:

Sử dụng payload RCE thì xác nhận có thể thực thi lệnh hệ thống:

Tiến hành tạo reverse shell để truy cập vào máy chủ:

Tiến hành nâng cấp lên shell hoàn chỉnh để thuận tiện hơn cho việc thao tác:

Ta thu thập được thông source code chứa lỗi SSTI như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from flask import Flask, request, render_template_string

app = Flask(__name__)

@app.route("/sh4d0w$s")
def page():

    name = request.args.get('l333tt')

    if request.args.get('l333tt'):
       return render_template_string(request.args.get('l333tt'))
    else:
       return "No input"

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)

Leo thang đặc quyền:

Trong thư mục home có 2 người dùng là iridakori:

Sudo -l thì nhận thấy có thể thực thi lệnh dưới quyền của người dùng kori mà không cần mật khẩu:

Leo lên người dùng kori

Đoạn code jail.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
array_shift($_SERVER['argv']);
$var = implode(" ", $_SERVER['argv']);

if($var == null) die("Orasis Jail, argument missing\n");

function filter($var) {
        if(preg_match('/(`|bash|eval|nc|whoami|open|pass|require|include|file|system|\/)/i', $var)) {
                return false;
        }
        return true;
}
if(filter($var)) {
        $result = exec($var);
        echo "$result\n";
        echo "Command executed";
} else {
        echo "Restricted characters has been used";
}
echo "\n";
?>

Đoạn code tren chứa lỗ hổng command injection tuy nhiên lại filter khá là nhiều keyword.
Để bypass được filter này thì ý tưởng là ta chỉ cần tạo một file exploit chứa payload rce có thể thực thi rồi chạy câu lệnh sudo -u kori /bin/php /home/kori/jail.php sh exploit trong thư mục chứa file exploit là có thể leo thang thành công lên user kori:

Vì payload được ghi vào bên trong file, trong khi đoạn code filter chỉ kiểm tra đối với chuỗi được nhập vào nên ta có thể sử dụng các payload chứa các keyword bị filter trong trường hợp này!

Ngoài ra trong lúc tìm reverse shell mình tìm được 1 chuỗi payload trực tiếp không bị filter bởi đoạn code, mà server cũng có sẵn socat nên có thể leo thang thông qua câu lệnh:

Leo lên người dùng irida

Tiếp tục sudo -l thì nhận thấy kori có thể thực thi copy file apk dưới quyền irida mà không cần mật khẩu:

irida không có quyền ghi vào thư mục của kori nên ta cần cấp quyền ghi vào thư mục cho irida

Sau khi cấp quyền thì copy file thành công:

Tuy nhiên ta lại không có quyền đối với file đó:

Nên để có thể có toàn quyền sở hữu file đó thì ta cần tạo ra file đó với các quyền cần thiết trước khi copy, lúc này ta đã có toàn quyền với file irida.apk:

Tiến hành đưa file ra máy vật lý để tiến hành phân tích:

Mở file apk bằng jadx và tìm kiếm thì mình thấy được 1 đoạn code như sau:

Dựa vào logic code thì ta có thể dễ dàng đoán ra được mật khẩu là eye.of.the.tiger.()

Tuy nhiên SSH lại với mật khẩu trên thì lại không được. Cho đến khi mình đọc được hint của bài lab thì mới biết cần phải bỏ 1 dấu chấm đi. Kết quả mật khẩu chính xác cho người dùng iridaeye.of.the.tiger().

Nhập mật khẩu trên thì kết quả là ssh thành công:

Leo lên root

Đọc file user.txt thì chỉ là một mã hash. Ngoài ra ta có thể thực thi 1 đoạn code python dưới quyền người dùng root:

Sau khi chạy code và nhập input thì có lộ thông báo lỗi chỉ ra rằng đoạn code xử lý đầu vào dưới dạng hex:

Tiếp tục nhập đầu vào dưới dạng hex thì nhận được thông báo lỗi tiếp theo. Ở đây xảy ra lỗ hổng command injection:

Chuyển payload reverse shell sang dạng hex và đưa nó vào input thì nhận được shell root:

Đoạn code python dính lỗ hổng Command injection:

1
2
3
4
5
6
7
8
import os
import base64
import re
import sys

name = input(": ")
name = bytes.fromhex(name).decode('utf-8')
print(exec(name))

Kết quả file root.txt:

This post is licensed under CC BY 4.0 by the author.