Insecure Deserialization Writeup
PortSwigger
Last updated
PortSwigger
Last updated
Pham Quoc Trung
BurpSuite
This lab uses a serialization-based session mechanism and is vulnerable to privilege escalation as a result. To solve the lab, edit the serialized object in the session cookie to exploit this vulnerability and gain administrative privileges. Then, delete the user carlos
.
You can log in to your own account using the following credentials: wiener:peter
Ở đây do đề bài đã cung cấp cho mình tài khoản wiener
, mình sẽ thử đăng nhập xem có gì không
Nhìn vào request sau khi đăng nhập, mình thấy có cookie là session
đã được set thành dạng Base64 của chuỗi O:4:"User":2:{s:8:"username";s:6:"wiener";s:5:"admin";b:0;}
. Đây là dạng serialized của object user. Vì yêu cầu của bài là lấy được quyền admin và xóa tài khoản carlos
, mình sẽ thử sửa b:0
thành b:1
và gửi đi xem sao
Có thể thấy, giao diện của mình hiện đã có thêm nút Admin panel
. Truy cập vào đó và xóa đi carlos
, mình hoàn thành bài lab
This lab uses a serialization-based session mechanism and is vulnerable to authentication bypass as a result. To solve the lab, edit the serialized object in the session cookie to access the administrator
account. Then, delete the user carlos
.
You can log in to your own account using the following credentials: wiener:peter
Tương tự bài trước, mình cứ thử đăng nhập bằng tài khoản mà đề bài đã cho
Lần này thì mình thấy cookie session
có giá trị là O:4:"User":2:{s:8:"username";s:6:"wiener";s:12:"access_token";s:32:"euenp6m85xsb9140zfhbsq7o8zl3rfob";}
, mình không biết access_token
này phải là gì nào để có thể lấy được quyền admin.
Theo như mình nghĩ, một code cơ bản để check access_token
sử dụng deserialization sẽ kiểu như sau
Tuy nhiên, nếu đoạn code kia sử dụng ==
thay vì ===
, hay còn gọi là loose comparison thì ta có thể tìm cách bypass được. Lí do ở đây là ==
chỉ so sánh giá trị chứ không so sánh cả kiểu dữ liệu như ===
. Khi này, nếu mình điền access_token
là 0
, đoạn so sánh sẽ thành 0 == 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
sẽ trả về .
Áp dụng lý thuyết trên, mình sẽ sửa s:32:...
thành i:0
và gửi đi xem sao
Như đã dự đoán, mình đã thành công bypass cách này. Giờ chỉ cần xóa tài khoản carlos
đi là mình sẽ hoàn thành bài lab
This lab uses a serialization-based session mechanism. A certain feature invokes a dangerous method on data provided in a serialized object. To solve the lab, edit the serialized object in the session cookie and use it to delete the morale.txt
file from Carlos's home directory.
You can log in to your own account using the following credentials: wiener:peter
You also have access to a backup account: gregg:rosebud
Với bài này thì sau khi đăng nhập, mình thấy session
có thêm phần về avatar_link
, cũng như ta có thêm chức năng xóa tài khoản
Khi thực hiện xóa tài khoản, request gửi đi sẽ trông như này
Do chỉ có session
để xác định user hiện tại cần xóa nên mình nghĩ trang web sẽ sử dụng avatar_link
để xóa đi avatar của người dùng trên hệ thống khi xóa người dùng. Dựa vào đề bài, mình sẽ thử thay đường link thành s:23:"users/carlos/morale.txt"
xem có thể xóa được file này của user carlos
không
Mã trả về là 302, và mình thử xem response này trên trình duyệt. Tuy nhiên, có vẻ mình đã làm sai ở đâu đó.
Sau khi đọc kĩ lại, mình thấy file cần xóa nằm trong thư mục home
của carlos
. Mình sẽ thử sửa lại thành s:23:"/home/carlos/morale.txt"
Quay lại trình duyệt, lần này bài lab đã được hoàn thành
This lab uses a serialization-based session mechanism and is vulnerable to arbitrary object injection as a result. To solve the lab, create and inject a malicious serialized object to delete the morale.txt
file from Carlos's home directory. You will need to obtain source code access to solve this lab.
You can log in to your own account using the following credentials: wiener:peter
Tương tự các bài trước, khi đăng nhập bằng tài khoản mà đề bài cho, mình sẽ có được một cookie có giá trị session
như sau:
Ở đây khi nhìn vào source code của response trả về, mình thấy có dòng comment sau
Mình thử truy cập vào nó nhưng không thấy gì, có vẻ website đã chạy code php bên trong file này để thực thi việc gì đó. Mình sẽ thử thêm ~
vào sau php
để xem website này có sơ suất trong việc xóa đi các file tạm/backup không. Nếu có, mình có thể xem được nội dung file trên vì php~
không phải là đuôi được website thiết kể để thực thi
Và mình đã xem được nội dung của file /libs/CustomTemplate.php
. Đây là ý nghĩa của nó khi mình dùng ChatGPT
Ở đây ta để ý __destruct()
là một magic method. Nó sẽ xóa file lock_file_path
đi mỗi khi ta khởi tạo một object từ class này. Mục tiêu của bài này là xóa đi file morale.txt
nằm trong thư mục home của carlos
nên mình có thể tạo một object của class CustomTemplate
có thuộc tính lock_file_path
là /home/carlos/morale.txt
. Ở đây session
sử dụng serialization-based nên mình sẽ tạo object như sau
Mình sẽ mã hóa Base64 nó sau đó thay vào session
và gửi request đi xem sao
Quay về trang chủ, mình thấy bài lab đã được hoàn thành
This lab uses a serialization-based session mechanism and loads the Apache Commons Collections library. Although you don't have source code access, you can still exploit this lab using pre-built gadget chains.
To solve the lab, use a third-party tool to generate a malicious serialized object containing a remote code execution payload. Then, pass this object into the website to delete the morale.txt
file from Carlos's home directory.
You can log in to your own account using the following credentials: wiener:peter
Ở đây mình sau khi đăng nhập mình thấy session có dạng rO0....
, có vẻ là nó được serialize bằng Java
Mục tiêu vẫn là xóa đi file morale.txt
. Vì là sử dụng Java và mình không có source code, mình sẽ sử dụng tool ysoserial
để tấn công coi sao.
Cú pháp: java -jar ysoserial-all.jar [payload] '[command]'
Java 16 hoặc hơn (Dùng thử nhưng chưa được) java -jar ysoserial-all.jar --add-opens=java.xml/com.sun.org.apache.xalan.internal.xsltc.trax=ALL-UNNAMED --add-opens=java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED [payload] '[command]'
Có khá nhiều loại payload
Ở đây mình sẽ thử sử dụng như sau
Lấy mã Base64 trên cho vào session
, encode URL và gửi đi, mình thấy response trả về exception
Quay về trình duyệt, mình thấy bài lab đã được hoàn thành
The
URLDNS
chain triggers a DNS lookup for a supplied URL. Most importantly, it does not rely on the target application using a specific vulnerable library and works in any known Java version. This makes it the most universal gadget chain for detection purposes. If you spot a serialized object in the traffic, you can try using this gadget chain to generate an object that triggers a DNS interaction with the Burp Collaborator server. If it does, you can be sure that deserialization occurred on your target.
JRMPClient
is another universal chain that you can use for initial detection. It causes the server to try establishing a TCP connection to the supplied IP address. Note that you need to provide a raw IP address rather than a hostname. This chain may be useful in environments where all outbound traffic is firewalled, including DNS lookups. You can try generating payloads with two different IP addresses: a local one and a firewalled, external one. If the application responds immediately for a payload with a local address, but hangs for a payload with an external address, causing a delay in the response, this indicates that the gadget chain worked because the server tried to connect to the firewalled address. In this case, the subtle time difference in responses can help you to detect whether deserialization occurs on the server, even in blind cases.
This lab has a serialization-based session mechanism that uses a signed cookie. It also uses a common PHP framework. Although you don't have source code access, you can still exploit this lab's insecure deserialization using pre-built gadget chains.
To solve the lab, identify the target framework then use a third-party tool to generate a malicious serialized object containing a remote code execution payload. Then, work out how to generate a valid signed cookie containing your malicious object. Finally, pass this into the website to delete the morale.txt
file from Carlos's home directory.
You can log in to your own account using the following credentials: wiener:peter
Với bài này thì session
của mình sau khi đăng nhập sẽ có dạng như sau
Phần Base64 của token
sau khi decode sẽ là O:4:"User":2:{s:8:"username";s:6:"wiener";s:12:"access_token";s:32:"sezq29lz0lxx45xvsaq7ehcu0a2o91so";}
. sig_hmac_sha1
là chữ ký số cho cookie này
Do format của token là dữ liệu serialized của PHP, mình sẽ sử dụng tool PHPGGC: PHP Generic Gadget Chains để thử làm coi sao. Có khá nhiều lựa chọn:
Để xác định được option cần dùng, mình thử để ý lại response. Mình nhìn thấy dòng sau
Thử truy cập vào đường dẫn trên, mình chưa tìm được gì cho lắm
Giờ mình sẽ thử trigger lỗi bằng cách gửi request có chứa sig_hmac_sha1
sai xem sao
Có thể thấy trong lỗi có trả về luôn framework mà trang web này đang sử dụng là . Dựa vào điều này, mình sẽ sử dụng lệnh sau để tạo ra payload
Thay token
bằng payload phía trên và gửi đi
Ta thấy trang web trả về lỗi vì signature của mình là không đúng, hay sig_hmac_sha1
cho token
mới của mình. Để có thể gen ra cái này thì mình cần có secret key. Để ý ban nãy trong đường dẫn /cgi-bin/phpinfo.php
, mình có tìm được giá trị này như sau
Mình sẽ sử dụng để tạo ra chữ ký mới
Thay chữ ký mới vào sig_hmac_sha1
và gửi đi
Có thể thấy đã không còn lỗi liên quan tới signature nữa. Quay về trang chủ bằng trình duyệt, mình thấy bài lab đã được hoàn thành
This lab uses a serialization-based session mechanism and the Ruby on Rails framework. There are documented exploits that enable remote code execution via a gadget chain in this framework.
To solve the lab, find a documented exploit and adapt it to create a malicious serialized object containing a remote code execution payload. Then, pass this object into the website to delete the morale.txt
file from Carlos's home directory.
You can log in to your own account using the following credentials: wiener:peter
Tương tự các bài trước nhưng lần này session
có vẻ lạ vì không giống format của PHP hay Java
Mình thử hỏi ChatGPT thì nhận được câu trả lời là trang web này sử dụng Ruby on Rails.
Sau một hồi tìm kiếm tool để khai thác deserialization cho Ruby thì mình không tìm ra cái nào cả. Tuy nhiên, mình tìm được bài viết này. Mình sẽ thử dùng đoạn script cuối cùng để gen ra payload. Ở đây mình phải edit một chút như sau
Chạy chương trình và mình có được payload
Mình sẽ thử thay nó vào session
và gửi đi
Quay về trình duyệt, mình thấy bài lab đã hoàn thành
This lab uses a serialization-based session mechanism. If you can construct a suitable gadget chain, you can exploit this lab's insecure deserialization to obtain the administrator's password.
To solve the lab, gain access to the source code and use it to construct a gadget chain to obtain the administrator's password. Then, log in as the administrator
and delete carlos
.
You can log in to your own account using the following credentials: wiener:peter
Note that solving this lab requires basic familiarity with another topic that we've covered on the Web Security Academy.
Trước hết, nhìn vào session
ta có thể dễ dàng nhận ra trang web sử dụng Java
Sau khi thử sử dụng ysoserial
không được, mình nghĩ phải tự tạo ra payload ở bài này. Việc cần làm là phải tìm ra source code của nó cái đã. Mình thử nhìn trong response:
Có vẻ source code sẽ ở trong đường dẫn trên. Thử mở ra và mình thấy code của chức năng tạo token
Tuy vậy, mình chỉ biết là class này sử dụng serialization chứ không có gì thú vị lắm. Mình thử truy cập đường dẫn /backup/
thì thấy có thêm 1 file nữa
Khi mở file ProductTemplate.java
ra, mình thấy nó cũng import thư viện phục vụ serialization nhưng có sự xuất hiện của hàm readObject
Khi có hàm này, Java sẽ sử dụng nó để deserialization thay vì cách mặc định. Để ý thì đoạn query SQL kia truyền trực tiếp giá trị ID vào thay vì dùng prepare statement, nghĩa là có khả năng sẽ có lỗi SQL Injection. Ý tưởng của mình ở đây sẽ là truyền giá trị ID độc hại vào thông qua lỗ hổng về deserialization để khai thác lỗi SQL Injection.
Đầu tiên, mình sẽ tìm cách để tạo ra object của class ProductTemplate
. Mình viết các file code Java như sau. Các package phải giống với code của server
data/productcatalog/Product.java
data/productcatalog/ProductTemplate.java
Main.java
Mình sẽ thử gửi một payload cơ bản của SQL Injection xem có gì xảy ra
Nhìn exception này thì có vẻ ta đã không sai gì đó. Giờ mình sẽ thử tìm ra số column
Có thể thấy lỗi khi ' ORDER BY 9--
, có nghĩa là có 8 column. Giờ mình sẽ tìm xem ô nào có thể in ra kết quả. Do mã lỗi bên trên không in ra lỗi chi tiết nên mình sẽ thử dùng để trigger Blind SQLi
Tìm ra tên bảng
This lab uses a serialization-based session mechanism. By deploying a custom gadget chain, you can exploit its insecure deserialization to achieve remote code execution. To solve the lab, delete the morale.txt
file from Carlos's home directory.
You can log in to your own account using the following credentials: wiener:peter
Với bài này thì mình có session
được serialize sử dụng PHP. Và mình cũng đã thấy một đường dẫn file PHP trong response
Truy cập vào /cgi-bin/libs/CustomTemplate.php~
để xem có đọc được code của nó không
Có khá nhiều các class và các magic method luôn.
This lab does not explicitly use deserialization. However, if you combine PHAR
deserialization with other advanced hacking techniques, you can still achieve remote code execution via a custom gadget chain.
To solve the lab, delete the morale.txt
file from Carlos's home directory.
You can log in to your own account using the following credentials: wiener:peter
Note:
Đối với .NET, chỉ cần thấy có deserialize -> ysoserial .NET
Đối với Java, nếu có deserialize + phiên bản Java cũ -> ysoserial
Đối với PHP:
Nếu muốn RCE hầu như phải có code (whitebox), nếu ko cùng lắm leo được quyền admin trong trang web
Search google "PHP Object Injection" thay vì "PHP Deserialization"
Skills đọc code phải pro vip