Chào mọi người, đây sẽ là phần cuối cùng khép lại series dài kỳ về chiếc ip camera nào đó …

Trước khi vào phần chính, mình có đôi lời muốn chia sẻ. Nếu bạn không muốn đọc, vui lòng bỏ qua.

Nếu đọc qua 2 bài trước của đàn anh của mình, bạn có thể thấy con camera này đúng là thủng lỗ chỗ. Nó có 1 service cho phép mình RCE luôn. Vậy nhiều người sẽ đặt ra câu hỏi nếu RCE được rồi thì xong rồi còn gì, còn sinh ra cái part 3 này làm gì nữa. Thì mình trả lời là mục đích của mình khi vọc con camera này để học hỏi là chính, nên việc tìm thấy feature khiến mình không thỏa mãn, mình cần tìm được 1 bug thật sự, 1 bug RCE.

Rồi, và giờ là phần chính. Phần này trình bày 1 bug về Buffer Over Flow của service Noodles.

Đầu tiên là phần RE và quá trình tìm bug.

Phần RE thì 2 bài trước đàn anh của mình đã nói khá kĩ rồi, nên phần này mình sẽ tập trung vào quá trình tìm bug. Mình tập trung vào những hàm dễ có khả năng dẫn đến buffer over flow như recv, strcpy, strncpy, fscanf, fgets, sprintf, … Lướt qua các hàm đó theo đúng thứ tự như trên thì mình thấy hầu như các hàm khi dùng, size của buffer được check rất kĩ nên sẽ không có lỗi buffer over flow. Duy nhất chỉ có 1 điểm có thể gây ra lỗi, code đoạn đó như sau:

Hàm gây ra lỗi là hàm sprintf, tham số thứ 3 truyền vào hàm bị thiếu do nó được lấy trực tiếp từ giá trị thanh ghi r2 được khởi tạo ở caller của hàm sub_9730 này, nên hexray decompiler không nhận ra được. Trace lên caller thì đó là hàm ứng với lệnh UPLOAD, tức cho phép mình đọc được file bất kì từ trên con ip camera. Giờ cùng tìm xem r2 của nó là gì.

Nhìn vào đây thì thấy r2 là tham số thứ 2 được truyền vào hàm sub_C054, qua RE ta thấy hàm sub_C054 này được dùng để kiểm tra command người dùng gửi lên có match với tag name được truyền vào ở tham số thứ nhất không, nếu có thì extract nội dung trong tag đó ra và lưu vào tham số thứ 2. Vậy nên mình hoàn toàn có thể control được data lưu ở buffer r2. Và 2 điều kiện quyết định nữa để dẫn tới buffer over flow đó là buffer s được truyền vào hàm sprintf được cấp phát với size là 0xA0 byte ([bp – 0xA0]) trong khi size tối đa của data bên trong command mình truyền vào là 0x100 > 0xA0 và trong stack không có canary bảo vệ. Để kiểm chứng lại, mình sẽ setup môi trường debug bằng qemu và gdb-multiarch.

Như hình trên, bằng việc gửi 1 payload đơn giản, mình đã control được pc = 0x62626262. Bây giờ chỉ cần tìm địa nào đó thích hợp thay cho 0x62626262 nữa thôi. Nhờ quá trình debug, mình nhận ra rằng sau khi control pc xong, sp đang trỏ vào đúng cái data nằm trong cặp tag name truyền vào, nên mình đã chọn địa chỉ sau để nhảy về.

Hàm sub_D738 là hàm wrapper của hàm system, gọi hàm system với tham số là tham số thứ nhất truyền vào hàm sub_D738 đó. Vậy nên khi control pc = 0x9E5C, mình có thể control được tham số truyền vào hàm system.

1 lưu ý là phiên bản của firmware con IP camera này đang dùng và phiên bản mình tải được trên mạng khác nhau, nên địa chỉ các hàm cũng khác nhau luôn. Vậy nên để lấy được địa chỉ đúng, cần phải tải được file noodles trên IP camera rồi dùng IDA phân tích.

Dưới đây là quá trình exploit thực tế trên con IP camera. Để dễ dàng, mình đã telnet vào con camera rồi tự khởi chạy service noodles bằng tay.

Bài của mình đến đây là hết. Cảm ơn các bạn đã theo dõi, và hẹn gặp lại các bạn ở các bài sau.

d4rkn3ss

FROM VNPT ISC.

Trung tâm An toàn thông tin

1.810 lượt xem