Đây là phần tiếp theo của câu chuyện về Liferay,
Đáng ra phần trước là phần đầu và cũng là phần cuối của câu truyện này, …
Nhưng sau đó, vào một ngày đẹp trời nào đó, … vô tình mình lướt twitter … và chợt thấy câu chuyện này mới chỉ là bắt đầu, chưa thể đi đến hồi kết sớm như vậy …

Ngay sau part 1 của câu chuyện này, thì khoảng 10 ngày sau đó (23/1/2019), mình có ghét thăm blog của acunetix để tìm bản update thì vô tình thấy bài này: https://www.acunetix.com/blog/articles/a-fresh-look-on-reverse-proxy-related-attacks/ (bài viết nói về 1 số reverse proxy, red team …).

Và thặc trùng hợp: “feature” của HA Proxy mình abuse trong bài trước cũng có ở đây, và nó là 1 feature thật )).
Ngoài ra có thêm 1 số trick khác, cũng khá là hay, mình suggest các bạn làm red team nên đọc qua, có thể sẽ giúp ích đc thêm cho công việc của các b!
Part 2 này mình vốn đã muốn viết từ trước tết, nhưng vì số lượng công việc + học tập trên trường khá nặng nên mình quên béng mất ).
Vô tình hôm qua có đọc list đồ án của KMA có 1 đề tài về cái này mới nhớ ra và bắt tay vào viết ).
———————————————-
The entrypoint
———————————————-
Theo như phần 1 mình cũng đã có nói qua: với các server có HA Proxy đứng trước thì hoàn toàn có thể bị bypass để access tới “/api/liferay” để gởi payload deserialize.
Nhưng còn với các server có nginx đứng trước thì vẫn chưa có cách nào để bypass được cả,
Và sau đó câu trả lời đã được đề cập ngay trước mắt như vầy:
TL; DR:
Đối với những server khi config với nginx, nếu như thiếu dấu “/” ở cuối như sau:
location /api/liferay/ {
    deny all;
    return 403; }
location / {
    proxy_pass http://liferayserver;
}
Sẽ khác với config có dấu “/” ở cuối path của web server:
location /api/liferay/ {
    deny all;
    return 403; }
location / {
    proxy_pass http://liferayserver/;
}
Những config mà không có dấu “/” ở cuối, proxy sẽ forward thẳng tới mà không thực hiện các filter này nọ!
Thêm vào đó, (cũng là may mắn), kỹ thuật để bypass trong blog post của acunetix cũng hoạt động với server tomcat < 8.x (không hoạt động với đa số loại servlet khác)
Example:
Request bị block khi access 1 cách thông thường:
Bypass request:
Như vậy là ta đã có thể bypass và access tới entrypoint “/api/liferay”, đã đi được 1 nửa chặng đường để RCE ròi .
btw: Đừng hỏi mình tại sao nó lại như thế ), mình chỉ đi học lỏm thôi chứ cái này ko phải là mình nghiên cứu ra …
———————————–
Bypass story
———————————–
Sau khi có thể truy cập tới entrypoint “/api/liferay”, mình đã cố thử sử dụng lại các gadget CC này nọ như trong part 1, nhưng đúng như dự đoán của mình: server đã apply patch trước đó, và các gadget thông dụng kia không còn có thể chạy được trên server này được nữa:
Ròi giờ sao, …
Mình mở lại bài của tenable và ngâm cứu tiếp )) (https://www.tenable.com/security/research/tra-2017-01)
TL;DR:
  • Server này đã được apply security patch và có 1 cái blacklist để chống lại insecure deserialize!
  • CommonCollection đã được update lên latest ver, không còn bị abuse nữa
Và lời giải đáp (bypass) cũng được đề cập ngay phía dưới luôn:
Như vậy, ở đây vẫn có thể sử dụng gadget Beanutil bypass của bác @pwntester để bypass case này (https://github.com/pwntester/SerialKillerBypassGadgetCollection).
Mình có dạo quanh để tìm file compiled, nhưng không có thấy, đành phải bật Eclipse lên và compiles vậy.
¯\_(ツ)_/¯ Cuộc xống mà.
  • Build payload
Do việc build payload hơi lằng nhằng và gặp nhiều lỗi vớ vẩn nên mình quyết định viết lại 1 vài note!
Ngay sau khi import cái project serialkillerbypass kia vào eclipse, sẽ bị ngay 1 lỗi như sau:
Và theo cảm tính của mình, thì mình xóa hết chúng đi, vì ko có j cần thiết cho cái gadget của mình cả, sẽ thêm vào sau cũng được!
Sau đó set cái buildpath, cho thêm file jar của ysoserial vào đó, nhân tiện cũng del hết cái đống thừa thãi màu đỏ này đi:
Sửa lại “new GeneratePayload.ToStringComparator()” thành “new ToStringComparator()” và import package ysoserial.Strings.ToStringComparator vào đây (do gadget của bác này đã quá cũ còn yso thì thay đổi quá nhiều ròi ¯\_(ツ)_/¯ ).
Tada:
Đã hết lỗi và build thành công ))
Và tiếp theo, nếu bạn định chạy thử luôn thì mình dám cá 100% là sẽ fail ngay lập tức )).
Lý do là đây:
Trong dependency của serialkillerbypass thì CommonBeanutil có version là 1.9.2:
Nhưng trong case thực tế của mình, là liferay, CommonBeanutil có version là 1.8.2:
Như vậy sẽ nảy sinh ra 1 vấn đề lớn, đó là khi thực hiện deserialize, nếu phát hiện ra serial bị sai lệch so vs class trên server thực tế, việc deserialize sẽ không thể được thực hiện!
Vậy nên phải modify version trong gadget thành version giống như version trên liferay sử dụng, đó là 1.8.2!
(Rất lấy làm tiếc vì mình đã del mất liferay 6.2 nên không có demo về đoạn check serial này!)
Không chỉ ở serialkillerbypass mà ngay ysoserial cũng phải modify lại với lý do y chang, version của Bean là 1.9.2:
Do đó, tiếp tục phải lấy source của ysoserial (https://github.com/frohoff/ysoserial) về, sửa 1.9.2 thành 1.8.2 và recompile ¯\_(ツ)_/¯ .
Từ đây ta có thể compile được serialkiller và gen payload hoàn chỉnh:
Việc tiếp theo chỉ là gởi payload đến server thông qua path: “/#/../api/liferay
Và đây là cái kết … đừng bao giờ coi thường system admin )
Trong 1 số case thực tế, mình có gặp 1 số trường hợp khá là limit, ko có internet nên đã code thêm 1 số gadget để drop shell dành riêng cho liferay …
.
.
Mình chỉ nói thế thôi, ko public đâu hihi
Cảm ơn các bạn đã đọc hết bài!
Jang (From VNPT Sec!)
Ref:

Jang – Trung tâm An toàn thông tin

1.803 lượt xem