Path.Combine() sự thật nhỏ bé

TL;DR

 CHÀ, mới ăn tết đây thôi mà giờ đã cuối tháng ba rồi, thời gian bây giờ cảm giác trôi nhanh hơn chó chạy ngoài đồng ấy! Thời tiết tháng ba ở Hà Nội thật không thể chê vào đâu được, dư vị lạnh của mùa đông kết hợp ánh nắng ấm áp sắp chuyển hạ, khoảng thời gian này nên đi thăm thú, du lịch, ... Mà mình chả có xe ở đây nên cũng lười, ngay cả tàu trên cao cũng chưa đi, định bụng đợi dịch covid-19 lắng xuống xíu đi cho an toàn =)). Đằng nào giờ đang rảnh, thôi thì ngồi xuống viết đôi dòng tâm sự mỏng. À, mình còn chả nhờ viết blog về kỹ thuật gần nhất là khi nào nữa. 😑😑

Nhiều lần gặp những kỹ thuật tấn công đỉnh cao, hay những kiến thức thú vị cũng đôi lần nghĩ đến viết đôi dòng qua góc nhìn tư duy của mình, nhưng thời gian dành cho dự án ở công ty và sự lười nhác đã ngăn cản sự việc xãy ra. Haha :v 

Chém gió nhiêu thế đủ rồi, lúc trước mình chuyên thực hiện pentest bằng phương pháp Gray-box + Black-box. Sau khi chuyển sang công ty mới được tiếp cận White-box liên tọi, review code hằng ngày giúp góc nhìn về lỗ hổng dần trở nên hấp dẫn hơn, nó giống cảm giác đây là một cô gái quá đỗi bí ẩn mình phải khám phá ngay thôi :v, mặc dù khá chật vật lúc đầu làm quen.

Như tiêu dề bài viết, gần đây mình có thực hiện pentest dự án AspNetCore và phát hiện được vài sự thật thú vị về hàm Path.Combine()

---------------------------

Phía dưới chỉ nói về vấn để kỹ thuật

---------------------------

Phía dưới là chức năng đọc tài liệu từ thư mục Uploads/

Mình tìm được khá nhiều bug đọc file tùy ý trên server rồi nên nhìn phát biết ngay khả năng cao sẽ khai thác được, nhưng hôm nay code nó lạ lắm, những trường hợp mình gặp trước đây đều là cộng chuỗi filepath như: string filePath = "Uploads/" + path; nhưng đây là lần đầu mình gặp Path.Combine() hoặc gặp rồi mà éo nhớ :D (Kiểm điểm lại bản thân thôii)

Đoạn code đại khái như sau:

public DownloadFile(string path)
	{
	//code here ...
	string filePath = Path.Combine(AppSettings.Instance.UploadDir, path);
	bool check = File.Exists(filePath);    
	if (check == false) return null;
	var memory = new MemoryStream();
	using (var stream = new FileStream(filePath, FileMode.Open)
	{
		await stream.CopyToAsync(memory);
	}
	memory.Position = 0;
	return memory;
    }

Thế là mình cũng hớn hở dùng payload path traversal để đọc file appsettings.json ở webroot 


Sau một vài payload path traversal để tìm kiếm sự khác biệt khi đọc file ở trong và ngoài thư mục Uploads/ thì có kết quả như sau:
Dùng ../ thoát thư mục Uploads/ rồi truy cập vào lại thì vẫn cứ là ok ➡ Nguyên nhân??



Thế là mình lại viết code để xem
Ơ, quả mơ, nó vẫn nối chuỗi vào mà nhỉ??

Thế là chả còn cách nào khác ngoài việc đọc định nghĩa method từ chính Microsoft thôi: tại đây
This method is intended to concatenate individual strings into a single string that represents a file path. However, if an argument other than the first contains a rooted path, any previous path components are ignored, and the returned string begins with that rooted path component. As an alternative to the Combine method, consider using the Join or TryJoin methods.
Okayy! Thử ngay và luôn
Nó trả về C:\a.txt --> vậy đã đúng lý thuyết =))

True story: Mình phát hiện sự thú vị bé xíu này của Path.Combine() là lúc mình đang ăn trưa ở công ty, lúc đó mình có nói thật lớn (có lẽ đang phê) với một anh cross-check dự án của mình, làm mọi người cười quá trời :)))

Nhận xét

  1. Hy vọng bạn Toản đừng lười biếng viết nhiều blog nho nhỏ bổ ích để đọc nè :)

    Trả lờiXóa
    Trả lời
    1. ok, để mình hỏi bạn LƯỜI BIẾNG trú ngụ trong bản thân đã :))

      Xóa

Đăng nhận xét

Toản Đăng ơi! Có nhật xét mới