Chuyện Híu kể,  Tôi đi hack dạo

Reboot router từ xa bằng kỹ thuật HTTP Request Smuggling

Một ngày nọ, vị thiền sư đang cầm con Timuuu ra mid solo với thanh niên Daxu hàng hiệu. Cuộc chiến vốn dĩ rất ngang tài ngang sức thì bỗng từ đâu, thầy tu mù lao ra sút cái đụi một phát. Cơ hội ngàn năm có một, Daxu tung tuyệt kỹ Trăn trối. Hắn ta lao vút lên, chém túi bụi vào chiếc Timuuu bé nhỏ đáng thương. Vị thiền sư choáng váng, cắm đầu lao thẳng về trụ. Tưởng đâu pha này vào nồi lẩu rồi, vậy mà tôi chưa lên bảng đếm số anh em ạ. Gã Daxu kia đứng yên một chỗ, còn tôi thì tiếp tục chạy sâu vào trụ. Hí ha hí hửng cho đến khi nhận ra có gì đó sai sai. Daxu hàng hiệu ăn trọn 3 hit trụ nhưng không hề hấn gì. Và một dòng thông báo hiện lên

Dòng thông báo này chắc hẳn rất quen thuộc với cộng đồng “thọt thủ”. Thật kém may mắn khi mình phải đối mặt với nó thường xuyên. Đôi lúc thì do router bị lag gì đó, lúc thì do… chưa đóng tiền mạng nên bị cắt ?? 😀 ?? Khổ nỗi từ chỗ mình ngồi thiền đến cục router khá là lòng vòng thành thử ra cũng lười. Nhưng dù sao cũng cảm ơn anh em đã chịu khó đọc câu chuyện tôi vừa bịa ra. Nhưng vụ cục router là thật nha. Bắt đầu nào!

HTTP Request Smuggling

HTTP Request Smuggling (HRS) là một kỹ thuật theo dõi và phân tích các request giữa một trang web với máy chủ. Sau đó chúng ta có thể debug hoặc mô phỏng lại Request để ra lệnh cho máy chủ mà không cần thông qua giao diện. Nói cách khác là chúng ta theo dõi và tạo ra các yêu cầu giả mạo. Nếu anh dev back-end cho máy chủ cứng tay thì có thể phát hiện ra và ngăn chặn. Còn không thì 🐧 anh em hiểu rồi đấy.

Trong bài viết này, mình sẽ ghi lại quá trình theo dõi, bắt gói tin và bắt chước request để gửi lệnh khỏi động lại lên router. Thực tế kỹ thuật trong bài chính xác hơn là Cross-Site Request Forgery (CSRF) hoặc XSS. Còn khái niệm HRS nó rộng hơn nhiều.

Trang web lạ mỗi khi reboot cục wifi

Cục wifi nhà mình mỗi lần khởi động lại sẽ tự động hiện lên một trang web thông báo không có mạng (Viettel ZTE F606).  Và cho phép khởi động lại. Mình biết lúc này router đang đăng ký với nhà mạng, ở đây là Viettel để được cấp IP. Sau khi ISP xác thực và cấp địa chỉ IP là chúng ta có thể vào được mạng. Vậy nên không cần phải nhấn nút khởi động lại ở đây.

Theo dõi và bắt chước cách trình duyệt gửi lệnh đến router

Sau vài lần thử nghiệm, mình phát hiện trang web trên không xác thực quyền truy cập. Nghĩa là ai cũng có thể truy cập và khởi động lại router nhà mình nếu họ biết trò này. Cách phòng chống là mua cục router xịn lắp vào hoặc kiếm bản cập nhật mới. Mà thôi kệ, trò này chỉ gây khó chịu một chút chứ cũng không quá nguy hiểm. Nhưng phát hiện này khiến mình nghĩ ra một trò hay ho. Ta sẽ tận dụng lỗ hổng này và viết tool giúp khởi động lại router nhanh. Không cần tác động vật lý hoặc mở trình duyệt rồi đăng nhập các kiểu.

Inspect để xem source HTML

Đầu tiên mình sẽ dùng Dev Tool của trình duyệt để xem thử nút Reboot của trang web trên có gì đặc biệt không. Rất may mắn là nhà sản xuất gọi hàm JS DevStartSubmit() trực tiếp bằng sự kiện onclick trong thẻ HTML nên mình nhanh chóng xác định được hàm JS cần soi.

Bên cạnh đó, có một thẻ <input> ẩn có tên là _SESSION_TOKEN. Chỉ bằng nửa ánh mắt như cách tôi nhìn đứa mình ghét, ký ức về những ngày còn học môn Web-based Java Applications (PRJ321) của hoangvd7 bỗng ùa về. Đó quả là một cực hình khi trường F bắt mình phải code mấy cái web xàm xí bằng … cái bàn phím bị lờn nút ;. Mình vẫn nhớ như in cái cảm giác tuyệt vọng khi làm bài thi final. Gặp trúng câu hỏi về cái hidden input field này mà phải nhắm mắt trả lời bằng trí tưởng tượng.

Nói đến đây, tự dưng thấy sống mũi nó cay cay anh em ạ. Xin phép thầy hoangvd7 cho em giải thích ở đây luôn để chuộc lỗi với thầy 😭. Các input field ẩn có chức năng đính kèm thông tin vào form để submit mà người dùng không biết. Thông thường, người ta thường sử dụng nó để xác thực form, tránh làm giả, xss. Hoặc đơn giản là dùng để xác định phiên đăng nhập như cách server của router nhà mình sử dụng. Thông thường, các trang web sẽ sử dụng cookie để xác thực người dùng. Thế nhưng có một số trình duyệt không hỗ trợ cookie hoặc người ta cố tình tắt cookie đi. Thì đây là một phương pháp chắc chắn hoạt động được.

Như vậy, ở bước này mình thu thập được 2 thông tin sau: Hàm DevStartSubmit()_SESSION_TOKEN dùng để xác thực phiên đăng nhập.

Tìm hàm tạo và gửi lệnh reboot đến router

Tiếp theo, mình tìm đến hàm DevStartSubmit(). Ở đây, trang web sẽ hiện một hộp thoại để hỏi người dùng có thực sự muốn khởi động lại không. Nếu nhấm confirm thì nó sẽ gọi hàm ajaxRebootRequest(). Thứ mình cần tìm đây rồi. Tại đây, trình duyệt sẽ tạo một HTTP Request đến trang "/ajaxComLogic.gch?pid=1" kèm theo các pay load là IF_ACTION_SESSION_TOKEN với các giá trị tương ứng.

Theo dõi HTTP Request để lấy Session Token

Đầu tiên, mình mở DevTools và chuyển sang tab Network để bắt đầu theo dõi các request đi và đến. Tiếp theo, mình truy cập vào link http://192.168.1.1/dnscheat_nolos.gch như thông thường. Và đây là thông tin của request đó.

Sau khi xem qua HTTP Request Header, mình chẳng thấy gì đặc biệt. Đến đây là chúng ta có thể viết được lệnh gửi Request lên router để lấy _SESSION_TOKEN.

Anh em hãy sử dụng terminal Linux để chạy thử. Lưu ý, đối với MacOS nó không hiệu quả vì mình sử dụng cú pháp của GNU Grep chạy trên các máy Linux, còn Mac sử dụng FreeBSD Grep. Trên Windows anh em cũng có thể cài WSL để chạy cũng oke. Và đây là kết quả khi thực hiện đoạn lệnh trên. 

Thực thi shell script lấy session token từ router

Tiếp tục theo dõi Request yêu cầu reboot router

Vậy là bước đầu thành công, tiếp theo mình sẽ bắt HTTP Request được gửi đi khi nhấn nút Confirm.

Tại đây, chúng ta có thể biết được các field cần cho một reboot request. Như vậy, ta chỉ cần viết một lệnh curl tương tự ở bước trên, với các header và payload như những gì vừa thu thập là được. Thứ duy nhất cản trở là cần thêm một request đầu tiên để lấy token của phiên đăng nhập. Việc này cũng không khó khăn mấy. Đoạn code đầy đủ sẽ như sau:

Chạy thử nghiệm thực tế

Vậy là chúng ta đã có một script hoàn chỉnh để gửi request, yêu cầu router khởi động lại. Nếu anh em nào sử dụng router Viettel ZTE F606 giống mình và đang sử dụng Linux. Hãy thử copy đoạn code trên, lưu vào file reset-zte-f606.sh và chạy thử để xem kết quả.

Cuối cùng, mình dùng terminal trên MacOS, kết nối đến một máy chủ Linux cùng mạng LAN thông qua ssh để chạy chương trình trên. Sau khi chạy chương trình thì máy mình sẽ bị mất kết nối ssh đến máy chủ kia. Điều này có nghĩa là kết nội mạng nội bộ đã mất, router đã được khởi động lại. 😂

Khởi động lại router từ xa

Tổng kết

Nếu bạn đã dành thời gian đọc đến dòng này, mình xin cảm ơn bạn đã kiên nhẫn nghe mình luyên thuyên xàm xí đú nãy giờ. Nếu bạn không tìm được giải pháp để khởi động lại router ở nhà bạn thì hãy thông cảm. Mỗi nhà mạng mỗi thời điểm lại cấp một loại router khác nhau. Đôi khi cùng loại mà không chạy cùng firmware thì cũng không thể ôm nguyên cục code của mình mà xài được rồi. Nhưng hy vọng qua bài viết này, anh em sẽ được bổ sung một số kiến thức hay ho cũng như kỹ thuật bắt và soi gói tin. Cảm ơn anh em đã ủng hộ Blog Hiếu Đá vip pro cute 🐖.

Hãy chọn một người lười biếng để làm một công việc khó. Họ sẽ tìm được phương pháp đơn giản đến không ngờ… hoặc không - Thiền sư Hiếu Đá

Chào bạn, mình là lập trình viên, yêu thiên nhiên và ghiền chụp ảnh. Blog này được tạo nên để lưu giữ những trải nghiệm cũng như ghi chú các kiến thức mình học được. Hy vọng bạn sẽ tìm thấy gì đó hay ho ở đây. 🌸

5 2 votes
Article Rating
Subscribe
Notify of
guest

2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments