SoWhat
VIP Members
-
07/02/2017
-
17
-
14 bài viết
[Part 4] - Embedded devices hacking
Ở các phần trước mình đã giới thiệu các kiến thức cơ bản và cách thức để dump được firmware của thiết bị ra để tiến hành phân tích. Do đối với mỗi nên tảng, mỗi thiết bị có thể có những cách thực hiện khác nhau. Khi nghiên cứu vào một nền tảng hay thiết bị cụ thể nào đó chúng ra sẽ có những phương pháp cụ thể.
Bài này mình xin phép demo trên thiết bị router TPLinks Sử dụng ZynOS. Chúng ta sẽ sử dụng phương thức kết nối qua các giao thức không đồng bộ UART của thiết bị như mình đã trình bày ở bải trước để các bạn dễ hình dung hơn.
Sử dụng chế độ debug để dump bộ nhớ của thiết bị.
Sau khi kết nối với máy tính. Khi khởi động thiết bị, dữ liệu nhận được là thông tin về firmware, phần cứng....v.v. ở đây người dùng có thể truy cập vào chế độ debug trong vòng ba giây sau khi khởi động bằng một phím bất kỳ.
Hình 3: Dữ liệu nhận được khi khởi động thiết bị trên HyperTerminal.
Trong chế độ debug hỗ trợ một số câu lệnh. Nhưng hầu hết để không hữu ích. Chỉ có câu lệnh “ATDUx,y” là câu lệnh có ích nhất dùng để dump bộ nhớ từ địa chỉ x đến địa chỉ y.
Hình 4: Các câu lệnh được sử dụng trong chế độ debug.
Ở lệnh ATENx,(y) là lệnh đặt cờ debug mở rộng với y là password. Sau khi thực hiện lệnh này thì chế độ debug sẽ được mở rộng thêm nhiều câu lệnh hữu ích khác. Để lấy được password thì chúng ta phải dump bộ nhớ ra và thực hiện dịch ngược. Code xử lý sử dụng ngôn ngữ MIPS big endian. Có thể sử dụng IDA (6.6) để thực hiện disassembly.
Hình 5: Đoạn dữ liệu chứa các đoạn text thông báo.
Đoạn mã tạo password trong ngôn ngữ C có dạng:
Trong đó “A11F5AC6” là giá trị đặc biệt được sử dụng cố định, mã seed là mã tạo password được sinh ra sau mỗi lần khởi động thiết bị, Có thể xem mã seed bằng câu lệnh “ATSE”. Và sử dụng byte cuối cùng trong địa chỉ MAC, cũng là byte cuối cùng của mã seed. Sau khi sử dụng lênh “ATENx,(y)” sẽ mở rộng thêm nhiều dòng lệnh hữu ích.
Hình 7: Danh sách các câu lệnh sau khi mở rộng chế độ debug.
Do chế độ debug chỉ được chọn ở ba giây đầu, khi vào chế độ debug thì thiết bị chỉ load phần code xử lý debug. Khi bỏ qua chế độ debug hoặc sử dụng lệnh “ATGR” để boot vào router thì phần code xử lý chính của router mới được load vào bộ nhớ flash. Nhưng khi bỏ qua chế độ debug thì không thể sử dụng các câu lệnh debug trên. Để giải quyết vấn đề này ta tiếp tục phân tích đoạn mã load và thực thi code xử lý chính của router.
Hình 8: Code xử lý giải nén bộ xử lý chính và thực thi.
Ở đây có thể sử dụng một thủ thuật nhỏ là để phần bộ nhớ này được giải nén ra nhưng không thực thi được và tiền hành dump phần bộ nhớ này ra để phân tích. Để thực hiện điều này chúng ta có thể ghi đè lên tại địa chỉ thực thi là 0x8000CA90 (khi dump bộ nhớ từ địa chỉ 0x80000000) bằng câu lệnh debug “ATWL 8000CA90, ae30001c”, ghi đè vào đoạn mã nhảy đến địa chỉ thực thi bằng đoạn mã assembly “ae30001c” disassembly thành ngôn ngữ MIPS là “sw [imath]s0, 0x1C([/imath]s1)”. Câu lệnh “jalr [imath]s0” được thay thế bằng là “sw[/imath]s0, 0x1C([imath]s1)”, thay vì nhảy đến địa chỉ bắt đầu bộ nhớ vừa được load, địa chỉ trong thanh ghi[/imath]s0 này sẽ được gán vào địa chỉ 0x8001FF1C.
Khi sử dụng lệnh để boot vào router bộ nhớ xử lý chính sẽ được load và trả về thông báo lỗi “error” và chúng ta vẫn ở lại trong chế độ debug. Bằng cách gán địa chỉ [imath]s0 vào địa chỉ 0x8001FF1C, bây giờ chúng ta sử dụng lệnh “ATRL 8001FF1C” để đọc địa chỉ[/imath]s0 và thực hiện dump bộ nhớ từ địa chỉ này.
Vừa rồi mình có demo về chức năng debug thông qua cổng giao tiếp không đồng bộ của thiết bị router TPLink. Có thể có nhiều đoạn các bạn chưa hiểu. Hãy cùng thảo luận ở dưới nhé.!
Bài này mình xin phép demo trên thiết bị router TPLinks Sử dụng ZynOS. Chúng ta sẽ sử dụng phương thức kết nối qua các giao thức không đồng bộ UART của thiết bị như mình đã trình bày ở bải trước để các bạn dễ hình dung hơn.
Sử dụng chế độ debug để dump bộ nhớ của thiết bị.
Sau khi kết nối với máy tính. Khi khởi động thiết bị, dữ liệu nhận được là thông tin về firmware, phần cứng....v.v. ở đây người dùng có thể truy cập vào chế độ debug trong vòng ba giây sau khi khởi động bằng một phím bất kỳ.
Hình 3: Dữ liệu nhận được khi khởi động thiết bị trên HyperTerminal.
Trong chế độ debug hỗ trợ một số câu lệnh. Nhưng hầu hết để không hữu ích. Chỉ có câu lệnh “ATDUx,y” là câu lệnh có ích nhất dùng để dump bộ nhớ từ địa chỉ x đến địa chỉ y.
Hình 4: Các câu lệnh được sử dụng trong chế độ debug.
Ở lệnh ATENx,(y) là lệnh đặt cờ debug mở rộng với y là password. Sau khi thực hiện lệnh này thì chế độ debug sẽ được mở rộng thêm nhiều câu lệnh hữu ích khác. Để lấy được password thì chúng ta phải dump bộ nhớ ra và thực hiện dịch ngược. Code xử lý sử dụng ngôn ngữ MIPS big endian. Có thể sử dụng IDA (6.6) để thực hiện disassembly.
Hình 5: Đoạn dữ liệu chứa các đoạn text thông báo.
Đoạn mã tạo password trong ngôn ngữ C có dạng:
Mã:
U32 generate_passwd(U32 seed, U8 last_mac_octet)
{
U32 b = seed & 0x00FFFFFF;
U32 r = ROR(b + 0xA11F5AC6, last_mac_octet & 7);
return r^b;
}
Trong đó “A11F5AC6” là giá trị đặc biệt được sử dụng cố định, mã seed là mã tạo password được sinh ra sau mỗi lần khởi động thiết bị, Có thể xem mã seed bằng câu lệnh “ATSE”. Và sử dụng byte cuối cùng trong địa chỉ MAC, cũng là byte cuối cùng của mã seed. Sau khi sử dụng lênh “ATENx,(y)” sẽ mở rộng thêm nhiều dòng lệnh hữu ích.
Hình 7: Danh sách các câu lệnh sau khi mở rộng chế độ debug.
Do chế độ debug chỉ được chọn ở ba giây đầu, khi vào chế độ debug thì thiết bị chỉ load phần code xử lý debug. Khi bỏ qua chế độ debug hoặc sử dụng lệnh “ATGR” để boot vào router thì phần code xử lý chính của router mới được load vào bộ nhớ flash. Nhưng khi bỏ qua chế độ debug thì không thể sử dụng các câu lệnh debug trên. Để giải quyết vấn đề này ta tiếp tục phân tích đoạn mã load và thực thi code xử lý chính của router.
Hình 8: Code xử lý giải nén bộ xử lý chính và thực thi.
Ở đây có thể sử dụng một thủ thuật nhỏ là để phần bộ nhớ này được giải nén ra nhưng không thực thi được và tiền hành dump phần bộ nhớ này ra để phân tích. Để thực hiện điều này chúng ta có thể ghi đè lên tại địa chỉ thực thi là 0x8000CA90 (khi dump bộ nhớ từ địa chỉ 0x80000000) bằng câu lệnh debug “ATWL 8000CA90, ae30001c”, ghi đè vào đoạn mã nhảy đến địa chỉ thực thi bằng đoạn mã assembly “ae30001c” disassembly thành ngôn ngữ MIPS là “sw [imath]s0, 0x1C([/imath]s1)”. Câu lệnh “jalr [imath]s0” được thay thế bằng là “sw[/imath]s0, 0x1C([imath]s1)”, thay vì nhảy đến địa chỉ bắt đầu bộ nhớ vừa được load, địa chỉ trong thanh ghi[/imath]s0 này sẽ được gán vào địa chỉ 0x8001FF1C.
Khi sử dụng lệnh để boot vào router bộ nhớ xử lý chính sẽ được load và trả về thông báo lỗi “error” và chúng ta vẫn ở lại trong chế độ debug. Bằng cách gán địa chỉ [imath]s0 vào địa chỉ 0x8001FF1C, bây giờ chúng ta sử dụng lệnh “ATRL 8001FF1C” để đọc địa chỉ[/imath]s0 và thực hiện dump bộ nhớ từ địa chỉ này.
Vừa rồi mình có demo về chức năng debug thông qua cổng giao tiếp không đồng bộ của thiết bị router TPLink. Có thể có nhiều đoạn các bạn chưa hiểu. Hãy cùng thảo luận ở dưới nhé.!
Chỉnh sửa lần cuối bởi người điều hành: