Như đang hứa sinh sống cuối phần 1 thì trong phần 2 này mình sẽ nói tới các lỗ hổng: PHP Type Juggling, Hard Coded, giải pháp xử lý dữ liệu đặc biệt quan trọng tại Client side, thực hiện bộ sinh số đột nhiên không an toàn,...

Bạn đang xem: Cách lập trình viên xử lý password của người dùng

Mình vẫn đang lấy những challenge vào Secure Coding CTF làm cho ví dụ phân tích. Vừa tiện có ví dụ trực quan, vừa tiếp tục là write up cho các challenge luôn.

Giờ thì tiếp tục với Secure Coding thôi

3. PHP Type Junggling

Lỗ hổng typle junggling xẩy ra do PHP hỗ trợ 2 phương thức đối chiếu bằng: so sánh tương đối (Loose comparisons)so sánh tuyệt vời nhất (Strict comparisons)

So sánh tuyệt đối hoàn hảo được áp dụng với 3 dấu bằng ===. Kiểu so sánh này chỉ trả về TRUE khi 2 thay đổi được đối chiếu giống nhau về cả kiểu dữ liệugiá trị.

So sánh kha khá được sử dụng với 2 dấu bởi ==. Kiểu so sánh này linh hoạt hơn, nhưng lại cũng dễ tạo nên các lỗ hổng mà lập trình viên không còn biết. Đó là do khi tiến hành so sánh, PHP sẽ cố gắng đưa 2 đổi thay về 1 kiểu tài liệu chung. Trường hợp 2 đổi mới được đối chiếu giống nhau về cả kiểu dữ liệu cùng giá trị thì triển khai không không giống gì đối chiếu tuyệt đối.

Tuy nhiên, lúc kiểu dữ liệu của 2 biến không giống nhau thì trong quá trình chuyển về kiểu dữ liệu chung, quý hiếm của chúng hoàn toàn có thể bị ráng đổi. Việc này hoàn toàn có thể tạo ra đa số sai lệch tác dụng không muốn muốn. Nếu có thể lợi dụng được vấn đề này thì kẻ tiến công có khả năng:

Vượt sang một số bước xác thựcThay đổi luồng hoạt động vui chơi của chương trình theo ý muốnLàm chương trình xẩy ra lỗi logic.

Để rõ hơn thế thì mọi người có thể tham khảo thêm trong bài viết của bạn mình trên đây. Tiếng thì chúng ta sẽ nhìn qua 2 ví dụ nắm thể

3.1. Ví dụ như 1: Junggling 1

Thông tin:

Tuần: 1Bài: Junggling 1Ngôn ngữ lập trình: PHP

Chúng ta chỉ cần chăm chú đến đoạn code PHP trong file mã nguồn là được:

require "settings.php"; if (isset($_GET<'password'>)) $actualPass = "999"; if ($_GET<'password'> === "999") $_GET<'password'> = "=P"; //hahaha if ($_GET<'password'> == $actualPass) echo $flag; else echo "Nope"; Trong code vẫn ghi rõ password là 1 trong những xâu: 999. Tuy vậy nếu chúng ta nhập vào 999 thì khi chạm mặt đoạn if thứ nhất, đối chiếu === sẽ đổi ngay đầu vào của họ thành =P . Còn nhằm echo ra được flag thì nên bypass đoạn if trước tiên và vào được if sản phẩm 2, hay nói cách khác là cần tìm input thỏa mãn nhu cầu đồng thời 2 đk sau:

Không được là 999So sánh tương đối với xâu 999 phải trả về FALSE

Để dễ tìm được input thỏa mãn nhu cầu thì họ nên coi 3 bảng đối chiếu trong tài liệu về đối chiếu trong PHP

Mình đã ghi lại luôn trên bảng so sánh tương đối để xem dễ hơn:

*

Việc đối chiếu string 1 cũng như khi so sánh string 999 nên tôi đã khoanh cả dòng này lại bằng color xanh. Những trường hợp có thể xảy ra TRUE là hướng chúng ta cần tra cứu để thỏa mãn được đoạn if sản phẩm công nghệ 2. Trong số ấy cần loại bỏ trường đúng theo được khoanh vàng luôn luôn vì trường phù hợp này có khả năng sẽ bị chặn tại phần if thứ nhất ("1" == "1" trả về TRUE và "1" === "1" cũng trả về TRUE).

Chú ý là: khi đọc giá trị từ GET request thì input của chúng ta chỉ là một trong những string mà lại thôi, nên sẽ không còn thể truyền giá trị boolean được. Thế thì chỉ còn 1 cách thực hiện khả thi nhất, kia là đối chiếu 1 số với cùng một string. Với cách thực hiện này thì xem giải pháp PHP cách xử lý kiểu vươn lên là khi triển khai so sánh sinh sống bảng sau đây sẽ rõ hơn.

*

Vậy là khi tiến hành so sánh 2 chuỗi cùng nhau thì PHP sẽ gửi hết thanh lịch dạng số, rồi tiến hành so sánh giữa 2 số với nhau.

=> đề xuất tìm 1 chuỗi nhưng mà khác 999, tuy vậy khi đưa sang dạng số tự nhiên thì phải có mức giá trị = 999.

=> Chuỗi chính là 0999:

0999 === 999 => FALSE0999 == 999 => TRUE

*

3.2. Lấy ví dụ 2: Junggling 2

Thông tin:

Tuần: 4Bài: Junggling 2Ngôn ngữ lập trình: PHP

Lần này phần code PHP đối chiếu như sau:

require "settings.php"; if (isset($_GET<'password'>)) if (strcmp($_GET<'password'>, $actualPass) == 0) echo $flag; else echo "

Nope

"; ?>Lần này để lấy được flag đề xuất nhập input sao để cho strcmp($_GET<'password'>, $actualPass) trả về 0. Tôi đã khoanh đỏ những ô như hình dưới vị hàm strcmp chỉ trả về 4 loại giá trị: 0 và null.

*

Để quá qua bảo đảm thì họ cần hàm strcmp trả về 0 hoặc null. Họ chỉ có thể tìm giải pháp làm hàm strcmp trả về null, vì bọn họ không biết mật khẩu đề xuất không thể làm cho strcmp trả về 0 được.

Khi hiểu document về hàm strcmp của PHP, bọn họ dễ dàng thấy một số trường hợp khiến strcmp trả về null.

*

Trong đó, khi so sánh một chuỗi với một mảng thì strcmp sẽ trả về null. Mà bạn có thể nhập vào 1 mảng bằng cách đổi ?password= thành ?password<>=

*

Tóm lại, tuy bao hàm trường hòa hợp lập trình viên chỉ có thể sử dụng so sánh tương đối. Tuy vậy nếu bao gồm thể, hãy luôn luôn sử dụng so sánh tuyệt đối. Của cả khi trông dường như vô hại, đối chiếu tương đối vẫn hoàn toàn có thể làm ngắn gọn xúc tích code vận động sai vì năng lực cho ra các hiệu quả khó đoán.

4. Hard Coded

Hard coded là lỗi do lập trình viên để lộ những thông tin đặc biệt trong code. Khi đoạn code này bằng cách nào đó bị lòi ra và kẻ xấu rất có thể sử dụng các thông tin này nhằm tấn công. Tùy theo độ đặc biệt quan trọng của tin tức mà hậu quả rất có thể từ không tác động gì tới tác động vô cùng nghiêm trọng.

Ví dụ như trường hòa hợp được 4000$ bounty bên trên hackerone này. Starbuck đang để lộ API key của JumpCloud vào public repo bên trên Github. Ví như chăm search trên github thì thỉnh phảng phất cũng thấy một số API key được hard code trong các public repo.

Mình đang từng gặp mặt lỗi này vào thực tế. Đó là trong mã nguồn của một ứng dụng android vẫn còn đó hard code địa chỉ cửa hàng server staging đương nhiên basic authen. Mà thông tin tài khoản chính vẫn rất có thể đăng nhập được vào môi trường thiên nhiên staging luôn.

Ví dụ: Sloth

Thông tin:

Tuần: 1Bài: SlothNgôn ngữ lập trình: Java

Trong code vẫn lộ tin tức đăng nhập như sau:

Lộ username tại dòng 58:

if (username.equals("admin") && md5hash(password).equals(adminPasswordHash))Lộ admin password hash tại cái 29:adminPasswordHash = "0571749e2ac330a7455809c6b0e7af90";Không chỉ lộ tin tức đăng nhập, trường vừa lòng này còn là một lỗ hổng thực hiện hàm băm không an ninh do băm mật khẩu bởi thuật toán MD5. Chỉ cần sử dụng những công cầm cố online, bất cứ ai cũng có thể tìm được mật khẩu gốc.

Xem thêm: Cách Làm Vệ Sinh Máy Lạnh - Hướng Dẫn Vệ Sinh Máy Lạnh Đúng Cách Ngay Tại Nhà

*

Với thông tin đăng nhập là admin/sunshine thì chúng ta có thể đăng nhập cùng lấy được flag

*

Ngoài lấy một ví dụ này, trong ví dụ như về vấn đề lộ git log tại đoạn 1 mình đã và đang đề cập về câu hỏi hard coded credential nhưng tiếp nối đã gỡ thoát ra khỏi code.

Tóm lại, để tránh lộ các thông tin đặc trưng chỉ có 1 cách, sẽ là thật cảnh giác với mỗi thông tin được hard code. Cần chắc hẳn rằng rằng tin tức này không tồn tại giá trị giúp tấn công vào hệ thống thì new hard code. Tiêu giảm tối thiểu việc hard code.

5. Xử trí dữ liệu quan trọng đặc biệt tại Client Side

Lỗi này xảy ra do xây dựng viên thực hiện 1 vài công dụng xử lý tài liệu tại Client, kế tiếp chỉ đưa kết quả lên Server. Câu hỏi này có thể giảm dịu phần nào quá trình Server yêu cầu làm, mặc dù chỉ cần phải biết sử dụng Burp Suite cơ bạn dạng thì bạn cũng có thể dễ dàng chặn và sửa request trước khi gửi lên.

Giả sử trường hợp như sau: trong thời điểm Covid sản phẩm 2, trường X triển khai hệ thống làm bài bác kiểm tra trắc nghiệm online đến học sinh. Sau khi học viên bấm nút "NỘP BÀI" thì sống phía Client sẽ đối chiếu đáp án và chấm điểm luôn, rồi gửi điểm lên Server để lưu kết quả lại. Tôi là học sinh Z học lớp 1F, với tài năng của 1 script kiddie chủ yếu hiệu, tôi đã bật burp suite lên và chặn request, sửa điểm bài xích thi từ bỏ 2.5 thành 10. Thời điểm cuối năm học, ko ngoài dự kiến tôi đã mở màn trường.

Qua trường thích hợp của học viên Z kể trên, hoàn toàn có thể thấy rằng rất nguy khốn khi bọn họ xử lý các dữ liệu quan trọng tại Client Side.

Ví dụ: Client Destroyer

Thông tin:

Tuần: 3Bài: Client DestroyerNgôn ngữ lập trình: PHP, JavaScript

Bài Client Destroyer có một đoạn mã PHP với 1 đoạn mã JS:

PHP:

if (isset($_POST<'password'>)) $password = $_POST<'password'>; if ($password == 'Hel2.4dnx21j.sl/dfsz') include_once "flag.php"; echo $flag; else echo "Sorry, the wrong password"; ?>JS://const button = document.querySelector("#sub");//document.addEventListener(button, validate);function validate() let input = document.querySelector("#in").value; console.log("I am here") đầu vào = input.replaceAll(".", ""); if (input != "Hel2.4dnx21j.sl/dfsz") alert("Given input đầu vào is not correct, try again") return false; return true;Ở đoạn code PHP, bọn họ biết được mật khẩu là Hel2.4dnx21j.sl/dfsz, cơ mà khi nhập vào vẫn bị báo sai mật khẩu. Bài toán này xẩy ra là vị đoạn JS ở dưới chọc ngoáy, nó sẽ xóa cục bộ dấu chấm . đi.

Nhưng vày đoạn script này được viết tức thì trong file php, nên chúng ta cũng có thể sử dụng Chrome Dev Tools nhằm sửa hàm validate(). Chỉ cần F12 => tab Console => copy paste lại đoạn code JavaScript sinh hoạt trên nhưng xóa dòng input = input.replaceAll("." , ""); đi => Enter để thực hiện thực thi ghi đè hàm.

Sau đó chúng ta có thể nhập mật khẩu cùng lấy được flag.

Như vậy, để đảm bảo an toàn hệ thống hoạt động đúng, cùng với các công dụng quan trọng thì chỉ nên gửi input từ người dùng lên đến Server xử lý.

6. Sử dụng bộ sinh số thốt nhiên không an toàn

Vấn đề về việc áp dụng bộ sinh số hốt nhiên không bình an thường được nói đến với ngôn từ lập trình Java. Java chung cấp 2 tủ sách sinh số ngẫu nhiên là java.util.Random với java.security.SecureRandom

Cả 2 tủ sách trên đều có tác dụng sinh số ngẫu nhiên, tuy vậy java.security.SecureRandom được xem là True Random (Random Number Genarator - RNG) còn java.util.Random ko được review cao, được xem là Pseudo Random - đưa ngẫu nhiên (Pseudo Random Number Genarator - PRNG).

Theo mình hiểu thì có thể xác định tính ngẫu nhiên của cục sinh số bằng phương pháp đánh giá bán 2 yếu tố:

Thuật toán sinh ngẫu nhiênThuật toán mang seed

Về thuật toán sinh thiên nhiên thì mình không xuất sắc thuật toán để có thể đưa ra nhấn xét. Còn về seed thì mình có biết 1 chút. Seed là 1 tham số nhưng mà từ seed này thì thuật toán sinh ngẫu nhiên rất có thể sinh ra hàng số ngẫu nhiên. Với các seed tương tự nhau thì dãy số thiên nhiên được ra đời sẽ giống hệt nhau về cả quý giá từng thành phần và sản phẩm công nghệ tự của chúng.

Các thuật toán RNG được lời khuyên dùng trong các thành phầm yêu ước độ bảo mật cao không chỉ là do bao gồm thuật toán sinh tốt, mà phương pháp thuật toán lấy seed cũng được phức tạp hóa để bảo đảm an toàn giá trị seed là đột nhiên và không tồn trên 2 seed trùng nhau.

Ví dụ: Thunderstruck

Thông tin:

Tuần: 3Bài: ThunderstruckNgôn ngữ lập trình: Java

Vẫn là yêu ước đăng nhâp để mang flag, user name vậy nên admin, còn password thì được sinh bằng hàm generateSecurePassword(). Cơ mà hàm này không an ninh chút nào:

static private String generateSecurePassword() String password = "magicallysecure"; Random rnd = new Random(); // generate a random number between 0 & 20 & based on that, create a password Integer random = rnd.nextInt(20); // let's vì some math on that number // btw, this code can be run on the website lượt thích https://w...content-available-to-author-only...e.com/online-java-compiler // just don't forget lớn import java.util.Random; at the vị trí cao nhất of the code editor random = random * 16578; random = random ^ 654321; for (int i = 0; i password.length(); i++) random += (int) password.charAt(i); // convert every character from password to an integer according to lớn ASCII table and địa chỉ cửa hàng that number to lớn random password = random.toString(); return password;Hàm trên sinh mật khẩu bằng phương pháp lấy thốt nhiên 1 số trong khoảng 0 -> 20, sau đó qua 1 loạt phép tính để tạo ra mật khẩu. Với mức số nhỏ bé như vậy thì chỉ có tầm khoảng 20 mật khẩu rất có thể được tạo nên mà thôi. Họ chỉ bắt buộc thử chạy thuật toán với các giá trị từ bỏ 0 -> 19, tiếp nối thử lần lượt các mật khẩu được tạo.

Và seed = 19 sẽ xuất hiện mật khẩu và đúng là 867281.

*

*

Mình xin chấm dứt phần 2 tại đây. Vào phần tiếp sau mình sẽ hầu hết đề cập đến lỗ hổng OS Command Injection.