Skip to main content

Command Palette

Search for a command to run...

Zip Symlink attack

Updated
4 min read
Zip Symlink attack
N

Lofi Chill In My Veins

Một người anh từng nói với em Khánh là: “Đừng simp cái 1 cái gì quá ngoại trừ symlink”. vậy thì symlink là gì mà lại có được ngoại lệ đấy??

I. Symlink là gì?

Chắc anh em nào đọc blog này cũng từng có một thời cầm usb mà cứ ngỡ được cầm cả bầu trời, hí hửng copy game về nhà nhưng ai mà ngờ đc nó chỉ là 1 cái shortcut không hơn không kém. Vậy lý do là gì?

Shortcut thực chất là một symbolic link , nó liên kết tới 1 tệp gốc, ở đây shortcut war3.exe được liên kết tới D:\Games\Warrcraft PTR\war3.exe . Nếu chúng ta khởi động war3.exe thì Windows sẽ tìm tới tệp gốc được liên kết và khởi động.

Khi copy shortcut từ quán net vào máy của mình, Windows sẽ cố gắng tìm tệp gốc và khởi động nó; tuy nhiên không hề có điều này lý giải cho việc không thể khởi động game khi chỉ copy shortcut về máy.

Note: từ giờ mình sẽ gọi luôn tên của symbolic link là symlink nhé 🤣

Ở ảnh phía trên mình đã tạo 1 symlink tên symlink_to_test.txt để trỏ tới /home/kali/test . Có thể nhận thấy khi đọc và sửa tệp symlink, tệp gốc sẽ bị thay đổi (Nếu có quyền nhé). Đây là 1 cơ chế khá hay để mình tận dụng vào case study này.

Tuy nhiên khi xóa 1 symlink thì không hề ảnh hưởng đến sự tồn vong của tệp gốc nhé.

II. Symlink Attack

Cùng đặt ra giả thuyết nào?

Vậy điều gì khi chúng ta upload 1 symlink lên trang web ?
Liệu có phải chúng ta upload sym.html link tới /etc/passwd, sau đó truy cập http://server/sym.html là sẽ đọc được /etc/passwd đúng chứ?

Câu trả lời là không phải, Khi upload 1 symlink, browser sẽ cố gắng đọc file gốc(nếu có quyền) và gửi nội dung của file đó lên server. Và lúc này nội dung của file sym.html sẽ là nội dung /etc/passwd của attacker. Điều này chẳng giúp ích được gì 😒

Sự thực thì khi muốn vận chuyển 1 symlink, nó phải được bọc bên trong zip file hoặc thông qua github(cái này mình mới nghe nói, chưa kiểm nghiệm).

Cách tấn công Symlink

Bước 1: chúng ta sẽ nén file symlink link_to_html link tới /var/www/html sau đó upload lên server. Khi server giải nén file link_to_html ra, nó sẽ tìm tới file /var/www/html trên server. => chúng ta có thể dẫn tới việc đọc file trên server

Bước 2: tạo 1 folder link_to_html với file shell.php , nén nó lại rồi upload. Khi server giải nén folder link_to_html, nó sẽ cố gắng tạo folder link_to_html và ghi file shell.php vào folder, thì server nhận ra link_to_html đã tồn tại và đang trỏ tới /var/www/html . Do đó thay vì tạo folder mới, nó sẽ ghi luôn file shell.php vào /var/www/html => dẫn tới RCE server.

III. Code Vulnerability

Vào một ngày trực soc bình dị, mình nhớ đến thịt chó nhưng không có tiền, quyết định chạy lên huntr để đọc 1 con source bất kì thì mình nhận ra đoạn code này

Mình đặt ra câu hỏi là tại sao chỉ có tệp tar đang được phòng thủ path traversal? Điều này 1 phần làm kích thích challenge bypass trong mình.


Tản mạn về đoạn code xử lý tệp tar

Giả sử dest_dir = /home/kali/test.extract , bảng dưới đây mô tả cách hoạt động từng dòng code ứng với mỗi giá trị member.name được truyền vào.

Có thể nhận thấy đoạn code này phòng thủ zip slip khá tốt (zip slip là kĩ thuật chèn path traversal vào file name các file trong tệp zip). Tuy nhiên với symlink thì không. Tất cả tại vì os.path.normpath sẽ cố gắng lấy ra name hiện tại(name của symlink) chứ không phải tên của tệp được trỏ tới.

Điều kiện cần - dùng symlink bypass và đủ - app cho phép upload tar file và giải nén ngay lập tức => Bắt tay vào khai thác

IV. Exploit

Để không phải upload file tar 2 lần. Mình quyết định nghĩ ra 1 cách là nén symlink vào trước, sau đó nén file cùng tên với symlink vào sau với nội dung bất kì. Khi giải nén, chúng ta sẽ ghi đè được file trên server tùy ý. (Nếu chưa hiểu cảm phiền mọi người đọc lại mục II một chút😘)

Ở đây mình đã tạo được 2 file cùng tên với file symlink được nén vào trước, file thường nén vào sau.

Để tránh quá nhiều thông tin trong 1 bài viết 😘. Mình quyết định bỏ qua việc trace code để tìm hàm upload.


Một chút hình ảnh minh họa

POC

╰(*°▽°*)╯
Mong đây là cái CVE đầu tay 😂. Cảm ơn mọi người đã đọc