Art of Vulnerability Discovery

Pham Van Toan
tradahacking
Published in
9 min readFeb 27, 2019

“Hacking: art of Exploitation” đó là cách mà mình bắt đầu cách đây hơn gần 10 năm, vài năm trước khi bắt đầu nghĩ một cách nghiêm túc về quá trình tìm kiếm và khai thác lỗ hổng phần mềm dẫn mình tới một số thứ thú vị không lường trước.

Ở đây, mình phân biệt sự khác nhau giữa tìm kiếm và khai thác, phần khai thác có nhiều sách vở đã bàn tới và vô số các blog, presentation khắp nơi mà các bạn hoàn toàn có thể tìm đọc, tuy nhiên việc tìm kiếm ít ai đề cập tới tương tự khi bắt đầu một bài viết về bug tìm được, chúng ta hay được đọc “ Phần mềm X với các tính năng ABC, trong tính năng A nhận input từ user và xử lí ….” hay một phiên bản khác “ Đề bài CTF cho chúng ta một binary với các tính năng sau….”. Hiếm có ai viết rằng: “ Sau khi xem xét toàn bộ các software trên hệ điều hành X, vì lí do ABC tôi chọn Y để đào sâu hơn… “

Mình suy nghĩ về việc này và nhận ra rằng ở một khía cạnh nào đó việc đi tìm lỗ hổng phần mềm hoàn toàn không khác việc các nhà khoa học tìm ra/phát minh một điều gì đó mới, khoa học đi tìm hiểu và giải đáp những bí ẩn của tự nhiên, người săn tìm lỗi tìm kiếm những sai sót trong phần mềm.

Điểm khác nhau căn bản là tự nhiên gần như vô hạn và được tạo ra bởi vô số quy luật, có những thứ ngoài tầm hiểu biết của nhân loại, phần mềm thì không, nó được tạo ra và phục vụ cho mục đích của con người.Nhìn chung công việc của chúng ta sẽ nhẹ nhàng hơn khoa học gia nhưng không phải mọi lúc đều như vậy.

Một điểm khác, lỗ hổng phần mềm cũng như quy luật của tự nhiên, chúng ta không biết có thực sự tồn tại hay không, đối mặt với sự bất định này là một gánh nặng tâm lí vô cùng lớn đè nặng trong suy nghĩ của người săn tìm lỗi và đánh bại số đông kể cả người kiên trì nhất, vì vậy mình nghĩ tới việc cần thiết khi có một số guidelines cho việc này.

May mắn cho mình, một người khác đã làm việc này. https://en.wikipedia.org/wiki/Jack_Oliver_(scientist)

Bản gốc của sách ở đây:

https://ecommons.cornell.edu/handle/1813/83

Nếu có thời gian các bạn có thể đọc để nắm rõ hơn, ở bài viết này mình chỉ dùng những ý chính trong sách còn lại sự diễn giải và ví dụ đều xuất phát từ nhìn nhận và kinh nghiệm của bản thân, mình làm vậy vì không muốn phát minh lại bánh xe và quan trọng hơn, tin rằng kiến thức của mình như hạt cát so với tác giả, hi vọng nó sẽ hữu ích cho những ai đã và sẽ đi săn tìm lỗi. Hoặc xa hơn, nếu các bạn muốn trở thành người khám phá, hãy bỏ thời gian đọc sách, nó được viết bởi một trong những nhà khoa học hàng đầu trong lĩnh vực của ông với hàng chục năm kinh nghiệm thực tế.

Như sách, mình sẽ chia làm 2 phần, phần đầu nói về chiến lược chung chung phần sau nói về chiến thuật cụ thể.

“Chiến lược (tiếng Anh: Strategy) là một tập hợp các lựa chọn được sử dụng để đạt được mục tiêu tổng thể trong khi chiến thuật (tiếng Anh: Tactics) là những hành động cụ thể được sử dụng khi áp dụng những lựa chọn chiến lược đó.”

Chiến lược:

Không chạy theo số đông

Nguyên tắc này khá đơn giản, nếu chúng ta làm theo những gì số đông đang làm, tức là cái mà một số người đã tìm ra lỗi, cái mà họ đã viết rất chi tiết, nghĩa là chúng ta sẽ phải cạnh tranh với những người đã bỏ ra vô số thời gian để hiểu và tìm lỗi đó, vì vậy cái giá để tìm hiểu cặn kẽ và kiếm ra thứ mà những người đi đầu chưa tìm được là rất cao hay gần như không thể. Vì vậy cách tốt nhất là không theo đám đông, tự chọn cho mình một lối đi riêng thông qua việc đọc tất cả documentation về phần mềm đó, luôn tìm hiểu kĩ những tính năng mới được cập nhật, theo dõi Changelog trong lúc đó dành thời gian tìm hiểu kiến trúc chung chung, những lỗi hay mắc phải, những nền tảng, 3rd party mà phần mềm đó sử dụng, lịch sử của phần mềm đó để ngay khi có hướng mới chúng ta ngay lập tức hiểu được phải làm gì. Mình report 10 CVE Adobe Reader 2 năm trước xuất phát từ tính năng hỗ trợ người khiếm thị được Adobe thông báo cách đó ít tháng, đồng thời Windows cũng thông báo cách để kích hoạt chức năng đó lên.

Luôn duy trì rèn luyện và chờ đợi :

Công việc hàng ngày của một người tìm lỗi không phải luôn luôn thú vị hấp dẫn, duy trì cho mình một sự ổn định, đọc mã nguồn, dịch ngược phần mềm, ghi chú lại những thứ mà các bạn đã hiểu, cần tìm hiểu thêm, những thứ hay ho về khoa học máy tính, cập nhật những nghiên cứu, tìm hiểu mới từ khắp nơi để không bỏ sót kĩ thuật mới, các đột phá ở những nơi khác thậm chí cả các ngành khác mà các bạn có thể học. Ngay khi nhận thấy cơ hội đến, cố gắng hết sức dùng những kiến thức kĩ năng mình có để đạt được mục đích. Mình trong 1 số lần theo dõi Changelog của JavascriptCore/Safari phát hiện ra 1 tính năng mới của Javascript, lần theo commit của Dev cho tính năng đó dựa vào kiến thức đã có về kiến trúc xử lí của JavascriptCore đã đọc rất nhiều trước đó, về cách Alloc Memory, cách truyền tham số mà tìm ra những bug do người mới không nắm rõ cách làm việc sẵn có từ đó gây ra lỗi.

Luôn cố gắng để mở rộng sự may mắn cho bản thân

Sự may mắn có thể đến từ sự ban phát của tự nhiên hoặc do chính chúng ta chuẩn bị kĩ lưỡng, điều này bao gồm cả điểm bên trên và nhiều thứ khác, các bạn có thể tuỳ vào hoàn cảnh mỗi người mà suy nghĩ về nó.

Tránh đi quá sâu vào những thứ không cần thiết

Luôn giữ cho mình một cái nhìn toàn diện và đầy đủ về target, một người săn tìm lỗ hổng rất dễ bị cuốn sâu vào những thứ khác và dễ bị phân tán bởi những thứ không cần thiết cho việc họ đang làm, thường xuyên cập nhật kiến thức, học hỏi những công cụ mới, những cách thức mới nhưng luôn phải tập trung phục vụ vào mục đích và target bản thân đang hướng đến.

Học về máy tính và Khoa học máy tính

Sau tất cả, chúng ta vẫn là người làm việc trong ngành khoa học máy tính, sự bao la của nó hẳn ai cũng hiểu, lỗi bảo mật có thể phát sinh ở khắp mọi nơi, từ Router,Switch cho tới Web Application, Browser, Hypervisor, CPU hay cả trong Algorithm. Hiểu biết càng rộng, góc nhìn của chúng ta càng nhiều, dưới nhiều lăng kính khác nhau, phần mềm sẽ thể hiện ra những điểm yếu/mạnh khác nhau, mang tới vô số cơ hội để tìm và khai phá những thứ chưa ai từng đụng tới đem đến thành công ngoài mong đợi cho các bạn.

Đặt ra những câu hỏi đúng

Sau khi đã chọn ra mục tiêu để tìm lỗi, Thông qua việc quan sát:

  • Dynamic: bằng cách chạy thử, debug
  • Static: bằng cách đọc source code, reverse engineering

Chúng ta sẽ cần đặt ra những câu hỏi:

  • Nó hoạt động như thế nào?
  • Nó bao gồm các thành phần gì?
  • Các thành phần này tương tác với nhau ra sao?
  • Tại sao khi tác động vào A lại dẫn tới B.

Tập hợp những câu hỏi này sẽ rất rộng và phức tạp, đôi khi câu trả lời sẽ có ngay, đôi khi phải tốn thêm nhiều bước nữa trước khi đến được câu trả lời, hoặc sẽ không có câu trả lời trong giới hạn khả năng của bản thân hay của công cụ hỗ trợ. Việc chọn đúng câu hỏi và tìm kiếm câu trả lời là một bước rất quan trọng trong tiếp cận và phân tích phần mềm để tìm ra lỗi, đôi khi một câu hỏi đúng chỗ sẽ dẫn chúng ta tới kết quả mà không phải tốn nhiều công sức.

Lấy ví dụ trong phân tích của mình trên medium về tìm lỗi trong Foxit Reader, câu hỏi đặt ra là: “Nếu buộc các bạn viết một chương trình đọc một file PDF mà trong file PDF đó có một file ảnh khác các bạn sẽ làm thế nào?”

Trước tiên phán đoán xem có bao nhiêu cách để làm được việc đó:

  • Cách thứ 1, cứ mỗi lần cần hiển thị phần nào của cái ảnh bạn sẽ đọc lại file pdf và lấy thông số ra từ đó mà tính toán và hiển thị lên.
  • Cách thứ 2, load dữ liệu của cái ảnh lên 1 lần và sau này cứ đọc vào đó mà lấy ra thông tin cần thiết để tính toán.

Sau đó dùng IDA ( Static Analysis) để kiểm tra phán đoán đồng thời download file PDF về và debug ( Dynamic Analysis ) để xác nhận phán đoán trên , từ đó dẫn tới việc tìm ra vị trí trong binary mà input của chúng ta được lấy lên thao tác, đối với những binary có độ phức tạp thấp và đơn giản ( như trong khi thi CTF ) thì điều này không đem lại lợi thế gì lớn tuy nhiên với real world software, biết được điều này giúp chúng ta hiểu và phân tích target một cách nhanh chóng đồng thời tìm ra bug một cách dễ dàng.

Đánh giá tình hình thông qua góc nhìn dài hạn

Khi theo dõi một target nào đó trong thời gian ngắn thường chúng ta sẽ dễ rơi vào hoàn cảnh không nhìn ra được những sự thay đổi lớn, từ đó sẽ dẫn tới cảm giác mọi thứ không có gì mới mẻ: không tính năng mới, không có commit mới lên github, chỉ fix những bug cũ… Chuyện này sẽ khiến người kiếm lỗi mất phương hướng và dần dần sẽ không còn kiên nhẫn với mục tiêu mình chọn. Vì vậy, cần nhìn mọi thứ với độ dài theo hàng tháng, hàng năm, kết hợp với xu hướng của thế giới để đặt mình vào vị trí trong tương lai xem xét nhiều góc độ khác nhau của target, từ đó chuẩn bị cho mình kĩ năng, công cụ cần thiết ở thời điểm hiện tại nhằm tạo ra hiệu quả lớn nhất khi thời cơ đến.

Ví dụ: Nếu chúng ta đứng ở chục năm trước, Browser không mấy quan trọng, nó chỉ đơn giản là công cụ để thể hiện ra text, hình ảnh, không ai biết rằng client security sẽ quan trọng thế nào ngày hôm nay tuy nhiên vẫn có những dự báo trước về sự bùng nổ này thông qua các tin tức, report, dự đoán của các chuyên gia tại thời điểm đó. Dĩ nhiên điều này nói có vẻ dễ nhưng sẽ luôn có vô số biến cố xảy ra trong tương lai không dự đoán trước, cách duy nhất mình nghĩ có lẽ là chọn 1 số thứ các bạn thích đồng thời được dự đoán sẽ phát triển trong tương lai và dấn sâu vào nghiên cứu, dù sao thì nếu không có cái tương lai đó ít ra chúng ta cũng có một quãng thời gian thú vị khi học và tìm hiểu nó.

Tin tưởng vào trực giác:

Trước tiên, để có được trực giác của một người tìm kiếm lỗi phần mềm theo mình phải làm rất nhiều: reverse 1 file binary, đọc writeup của những người khác, tự mình đào sâu vào một phần mềm, suy nghĩ về cách bypass những phép kiểm tra, những ràng buộc của mọi thứ, software hay không software, luôn nghĩ tới cách khía cạnh khác nhau của cùng một vấn đề …. là cách để rèn cho chúng ta có một trực giác nhạy bén.

Ví dụ: Khi nhìn vào một phần mềm parse file ảnh các bạn có thể nghĩ ngay tới Integer overflow ( lỗi phần mềm xảy ra khi cộng trừ con số vượt quá số lớn nhất).

Khi nhìn vào một phần mềm thay đổi các trạng thái vùng nhớ, đặc biệt là dưới sự điều khiển của người dùng chúng ta cần nghĩ ngay tới các lỗi liên quan đến Heap Corruption như Used after freed, Double Freed….

Khi nhìn vào một phần mềm có nhiều đối tượng, các đối tượng có quan hệ chồng chéo và hoán đổi vai trò cho nhau chúng ta cần nghĩ ngay tới Type Confusion….

--

--