Gọi là “hack” nghe cho nguy hiểm, thật ra việc này gần với Reverse Engineering và Protocol Analysis hơn (về sau tôi mới biết các khái niệm này). Đây là một nhiệm vụ được công ty giao, không gây thiệt hại cho bất cứ ai hay tổ chức nào vì… đọc hồi sau sẽ rõ!
Sau khi tốt nghiệp, tôi gia nhập phòng R&D của công ty cung cấp giải pháp IoT về năng lượng.
Ngày đó, chúng tôi có một hệ thống đang chạy. Do một số vấn đề khách quan trong quá trình chuyển giao và lưu trữ. Không còn đủ thông tin để xác định nó đang chạy trên phiên bản nào (chúng tôi có khá nhiều phiên bản tùy biến). Hơn nữa, cũng chưa có một công cụ nào có thể giao tiếp hiệu quả với các hệ thống dạng này.
Tôi được giao một source code mà không chắc có trùng khớp với hệ thống kia hay không. Nhiệm vụ của tôi là cố gắng hiểu nó đang chạy thế nào và giao tiếp để lấy được thông tin, ít nhất là số hiệu phiên bản.
Tôi nhận source code và bắt đầu nghiên cứu, xem ra cũng khá phức tạp, hệ thống này là một server giao tiếp với các thiết bị IoT thông qua socket.
Giao thức giữa server và client được định nghĩa trên các mảng byte. Mỗi vị trí byte ẩn chứa một ý nghĩa riêng: một số vị trí là mã lệnh, một số là checksum, một số là payload. Toàn bộ gói tin được mã hóa.
Tôi bắt đầu dựng lab và viết một chương trình giả lập thiết bị IoT để giao tiếp với source code kia.
Trải qua hơn một tuần thử và sai, tìm và thiết lập hàng trăm hàm mã hóa, đặt hàng nghìn breakpoint. Cuối cùng, tôi đã có thể giao tiếp và lấy được thông tin, bao gồm cả số hiệu phiên bản.
Tôi hớn hở báo lại với sếp, chuyển sang giao tiếp với server thật thay vì lab đã dựng. Và… không nhận được bất kỳ phản hồi nào.
Có thể là server kia đang chạy một phiên bản khác chăng? Hoặc…?! À, tôi nhớ ra là cần NAT port, giao thức này yêu cầu server phải chủ động kết nối ngược lại client, và nếu máy tôi nằm sau Router mà không NAT port thì gói tin phản hồi sẽ “mất tích” ngoài cửa ngõ.
Nhưng… thử nhiều cách, tôi vẫn không thể giao tiếp được với server kia như tôi đã làm được với lab.
Tôi chấp nhận rằng mọi chuyện không đơn giản như vậy. Chỉ dựa vào lượng thông tin ít ỏi tôi có để tìm cách giao tiếp với server kia là không thể.
Không có gì đảm bảo phiên bản source code tôi có, hàm mã hóa và giao thức tôi reverse thành công là trùng khớp với phiên bản đang chạy.
Dẫu vậy, công cụ tôi phát triển để giao tiếp với server kia vẫn rất hữu ích, nó mở ra nhiều thứ. Nhờ đó, chúng tôi giao tiếp với các server và thiết bị IoT khác một cách linh hoạt hơn.
Sau lần này, tôi học được nhiều kiến thức mà lúc đi học ở trường không dạy, cả về chuyên môn lẫn kỹ năng giải quyết vấn đề.
Tôi bắt đầu có hứng thú với bảo mật, mã hóa và các loại giao thức. Những kiến thức này giúp ích cho tôi nhiều và như một kim chỉ nam của tôi trong quá trình thiết kế các hệ thống phần mềm về sau.
Dù kết quả cuối cùng không như mong đợi ban đầu, nhưng những gì học được đối với tôi là vô giá.
Tôi nhận ra rằng, để thiết kế một hệ thống thực sự an toàn, cần phải thấu hiểu tường tận cơ chế vận hành của nó ở mọi cấp độ và đặc biệt là tại các điểm giao thoa. Đó không chỉ là việc bắt lỗi logic ở tầng Application, mà còn là sự am tường về cách Framework vận hành, cách các giao thức kết nối, cách các Middleware xử lý yêu cầu, cho đến tận lớp Infrastructure bên dưới.
Cách tốt nhất để bảo vệ hệ thống chính là hiểu được cách mà nó có thể bị tấn công. Mà cách nhanh nhất để hiểu, không gì bằng tự mình nghiên cứu và thử nghiệm thực tế vào từng ngóc ngách của hệ thống.
Cũng từ đó mà tôi mắc “bệnh nghề nghiệp”, mỗi khi được nhờ test một hệ thống nào đó, tôi lại không nhịn được mà “chọc ngoáy” một chút, để xem có vô tình kích hoạt được “tính năng ẩn” nào không 😆.
Đỉnh điểm là có lần, mải test vui quá, tôi lỡ “can thiệp” hơi sâu và ẵm luôn giải Nhất game nội bộ công ty. Đúng là ranh giới giữa một người làm kỹ thuật và một “hacker” đôi khi chỉ cách nhau bởi… cái mục tiêu ban đầu!