Mã độc có thể đánh cắp tiền của bạn như thế nào!

Trong khoảng thời gian vừa qua, tại một số hội nhóm trên mạng xã hội Facebook , diễn đàn trực tuyến, nổi lên các bài viết của một số người dùng, liên quan đến vấn đề lừa đảo trực tuyến. Điểm chung của những bài viết này đều kể rằng họ là nạn nhân bị lừa đảo, họ bị dẫn dụ cài các ứng dụng mã độc,  dẫn đến mất tiền trong tài khoản ngân hàng.

Những kẻ lừa đảo thường tiếp cận những người dùng này theo nhiều cách khác nhau như đóng giả thành nhân viên, nhắn tin với người dùng rằng họ cần nhanh chóng hoàn thiện một số thủ tục hành chính còn thiếu hoặc sửa lại các thông tin công dân bị sai lệch thông qua một ứng dụng có tên tệp tin là “Dichvucong.apk”, tải xuống và cài đặt từ một số website có tên miền như “dichvucong.lgov.net”, “dichvucong.dancuquocgia.net”,…

Ứng dụng giả mạo này sử dụng logo có hình quốc huy của quốc gia Việt Nam và tên là “DỊCH VỤ CÔNG” nhằm đánh lừa thị giác của người dùng.

Chúng tôi đã thực hiện kiểm thử và phân tích mã dịch ngược từ tệp tin “Dichvucong.apk” được tải xuống từ website “dichvucong.lgov.net”.

Từ mã dịch ngược của tệp tin “Dichvucong.apk”, trong những phân vùng code  thực hiện khởi tạo, chúng tôi phát hiện ra một string là “virbox”.

“VIRBOX” là một cái tên khá nổi tiếng trong khoảng thời gian gần đây. Đây là một công nghệ bảo vệ ứng dụng, bao gồm các chức năng: anit-debug, anti-repacking, code obfuscation, code encryption, string encryption,… Công nghệ này đang được sử dụng bởi malware nổi tiếng khác như GoldDigger.

Mã dịch ngược của tệp tin “Dichvucong.apk” không thực hiện trực tiếp bất kì hành vi nguy hại nào ngoài việc khởi tạo môi trường cần thiết và tải động một thư viện đặt trong thư mục “assets” của ứng dụng.

Tùy vào kiến trúc mà thư viện được tải sẽ có suffix tương ứng trong tên, trên thiết bị mà chúng tôi sử dụng, ứng dụng sẽ tải động thư viện “l4eee8b4d_a32.so”

Tiến hành đọc file “index.html”, “kqkticwjgzy.dat” không thu lại được kết quả gì ngoài những chuỗi byte vô nghĩa. Tiếp theo, tiến hành dịch ngược thư viện, như kết quả dự đoán, phần lớn mã nguồn đã bị obfuscated và encryption, rất khó để reverse.

Để có thể đọc được mã nguồn ứng dụng “một cách rõ rang”, chúng ta cần dumped memory của tiến trình ứng dụng tại thời điểm ứng dụng đã được khởi chạy, khi đó mã nguồn thực sự đã được deobfuscated và decryption, các class java của ứng dụng được load vào memory.

Tiến hành dump các class trong memory của tiến trình ứng dụng:

Ta thu được mã nguồn dịch ngược như sau:

Từ mã nguồn dịch ngược, có thể nhận thấy ứng dụng khai báo một Accessiblity Service. Các dịch vụ trợ năng (Accessiblity Service) của Android nhằm hỗ trợ người dùng khuyết tật vận hành thiết bị của họ. Các dịch vụ này cung cấp các khả năng như đọc màn hình, phóng to, điều khiển dựa trên cử chỉ, chuyển giọng nói thành văn bản, phản hồi xúc giác và các tính năng khác.

Một số Trojan ngân hàng như Gustuff, Gigabud và GoldDigger  đã và đang lợi dụng  tính năng này để thực hiện các hành vi độc hại trên thiết bị của người dùng.

Tính năng này cho phép ứng dụng Trojan được cấp quyền Accessibility có thể quay lại màn hình, đọc được các đoạn thành phần văn bản trên màn hình, ghi chép lại thao thác gõ phím (keylogger), tự động điền văn bản,…

Ứng dụng độc hại có thể thu thập thông tin người dùng, quan sát số dư tài khoản ngân hàng, đánh cắp thông tin đăng nhập, ghi lại thông tin văn bản mà người dùng đã nhập,…

com.yiwuzhibo.controller.TouchAccessibilityService

Máy chủ mà ứng dụng tương tác để lấy một số thông tin chung về các ngân hàng ở Việt Nam:

com.yiwuzhibo.BuildConfig

Một số API endpoint của máy chủ trên giúp ứng dụng lấy được các thông tin liên quan đến ngân hàng và người dùng ngân hàng Việt Nam:

k1.a

Kiểm tra một số endpoints nhận thấy máy chủ vẫn còn đang hoạt động và thông tin trả về liên quan đến các ngân hàng của Việt Nam.

Ứng dụng có các hành vi tiến hành tự động mở khóa màn hình:

com.yiwuzhibo.controller.LockManager$swipeUp$1

Tự động mở khóa màn hình

Khai báo các lớp nhằm thu thập các mật khẩu:

com.yiwuzhibo.controller.PasswordCapture2

Ứng dụng khai báo các lớp nhằm thực hiện tự động hóa các thao tác click các đối tượng trên màn hình thiết bị:

Ứng dụng khai báo các lớp nhằm điều khiển ứng dụng từ xa cũng như gửi dữ liệu thu thập đến máy chủ thông qua tcp:

com.yiwuzhibo.controller.RemoteCommandClient

com.common.want.WantCommonService

com.common.want.WantCommonService

Gửi một số thông tin thu thập được từ thiết bị tới máy chủ C&C

Ứng dụng khai báo các lớp hỗ trợ quay video màn hình:

com.yiwuzhibo.record.ScreenRecordService

Phần kỹ thuật đến đây thì cũng đã khá dài, vậy người dùng cuối cần làm gì???

Người dùng phải nâng cao nhận thức của bản thân, không cài đặt ứng dụng từ nguồn thứ ba không đáng tin cậy, luôn cập nhật thiết bị lên phiên bản mới nhất và chú ý ứng dụng đòi hỏi những permissions nào khi khởi chạy. 

Hãy luôn cẩn trọng trước các lời mời gọi cài đặt app lạ!!!

SharePoint Server và câu chuyện về research. Phần 2: Trái đắng và quả ngọt

Tiếp tục về SharePoint… Sau “cú dup” với CVE đầu tay, tôi tiếp tục đi sâu hơn vào chức năng này và tìm ra một flow khá hay ho. Đặc biệt hơn, flow này hoàn toàn dựa vào quá trình parse XML config để khởi tạo workflow – xin đính chính lại một chút là workflow config có định dạng là XAML.

Phân tích

Sau quá trình validate XAML config (đã nhắc đến ở phần 1) thì SharePoint sử dụng hàm WorkflowMarkupSerializer.Deserialize để tạo workflow. Không giống như XML đơn thuần, XAML cho phép sử dụng “compact format attribute”, các attribute này sẽ được bắt đầu bằng ký tự “{” và kết thúc bằng ký tự “}”.

1. ValueType với compact format

Hàm DeserializeFromCompactFormat được sử dụng để xử lý trường hợp này. Đây là một hàm rất dài, tôi sẽ tóm tắt chức năng như sau:

  • Lấy kiểu dữ liệu của SomeType, kiểm tra xem kiểu dữ liệu này có nằm trong allow list hay không. Nếu không thì throw exception.
  • Đọc và parse các argument thành một mảng các chuỗi [“Arg1”, “Arg2”, “Arg3”].
  • Sử dụng reflect để tìm kiếm một constructor của SomeType với số lượng tham số và kiểu dữ liệu phù hợp (3 tham số chuỗi).
  • Tạo và trả về instance của SomeType.

Trace bằng dnSpy chúng ta sẽ được flow:

Nội dung của các hàm sẽ như sau.

2. Hàm DeserializeSimpleMember
3. Hàm DeserializeFromCompactFormat
4. Hàm GetValueFromMarkupExtension

Hơi dài dòng và khó hiểu nhưng tóm gọn lại thì nếu SomeType kế thừa MarkupExtension thì ValueType = (new SomeType).ProvideValue(), ngược lại thì ValueType = new  SomeType.

Như đã nếu ở phần 1, ValueType sẽ mang giá trị là chuỗi System.Resources.ResourceSet. Như vậy thì chia ra 2 trường hợp. Một là SomeType phải là System.String, điều này khá khó thực hiện vì System.String không tồn tại constructor nào có tham số là chuỗi cả. Hai là SomeType.ProvideValue phải trả về một chuỗi. Sau khi xem xét toàn bộ các kế thừa của MarkupExtension thì tôi phát hiện một case khá thú vị – TypeExtension. Theo như document mặc định thì markup này chỉ trả về một Type (kiểu dữ liệu Type). Nhưng trong SharePoint thì không.

5. Lớp TypeExtension

Dễ dàng thấy được hàm ProvideValue trả về một chuỗi tại dòng 36 hoặc 38. Ngoài ra lớp này còn có constructor thỏa mãn điều kiện nêu phía trên. Do đó đây có thể coi là một ứng viên tiềm năng cho công cuộc bypass.

Chúng ta sẽ phân tích kỹ hơn về cách hoạt động của hàm này. Đầu tiên là thuộc tính typeName sẽ là chuỗi bất kỳ (đã nếu phía trên). Tại dòng 23-24, chương trình sẽ kiểm tra ký tự “:” trong typeName sau đó chia thành 2 phần (tương tự như namespace trong XML). Ví dụ: typeName là “abc:SomeType” thì text2 là “abc” còn text là “SomeType”. Dòng 28 sẽ kiểm tra và lấy ra kiểu dữ liệu từ config, nếu tồn tại thì sẽ trả về kiểu dữ liệu tìm được. Nhưng cái chúng ta cần thì ngược lại, dòng 28 phải trả về null mới có khả năng bypass. Lưu ý là tất cả namespace đều được kiểm tra tính hợp lệ. Cú pháp của namespace sẽ như sau.

Để ý kỹ hơn dòng 36, hàm chỉ đơn giản là trả về namespace + “.” +  text. Như vậy thử tưởng tượng rằng, nếu chúng ta có một namespace hợp lệ, ví dụ như System và text là Resources.ResourceSet. Vậy điều cần thiết ở đây là làm thế nào cho dòng 28 trả về null. Rất đơn giản, chúng ta chỉ cần để một assembly khác. Trong ví dụ này, tôi để mục assembly là System.Workflow.ComponentModel và code ở dòng 28 thực chất chỉ là tìm kiếm System.Resources.ResourceSet trong thư viện System.Workflow.ComponentModel. Điều này đương nhiên sẽ trả về null vì không tồn tại kiểu dữ liệu này, sau đó trả về chuỗi tại dòng 36. Như vậy sau một quá trình dài dòng thì chúng ta đã gán được ValueType là System.Resources.ResourceSet.

Quay trở lại với quá trình validate config, TypeExtension nằm trong allow list cho nên việc này hoàn toàn khả thi. Payload hoàn chỉnh của chúng ta sẽ là:

Ở đây tôi không dùng x:Type mà thay vào đó là ns1:TypeExtension, điều này để chắc chắn việc gọi hàm ProvideValue không bị nhảy vào markup mặc định.

Kết luận

Thật ra tôi đã phát hiện ra flow này trước khi tìm được bug ở phần 1. Nhưng nói gì thì nói, trong giang hồ vẫn tồn tại một ý niệm là có CVE thì lời nói uy tín hơn, và việc này cũng làm cho timeline hợp lý hơn vì theo đánh giá cá nhân, đây không phải là một bug “xàm”… Timeline thật sự sẽ như sau:

  1. Tìm ra và report bug phần 2.
  2. Microsoft chuyển qua Online Service và không đánh CVE (Trái đắng).
  3. Cay cú, tiếp tục tìm bug để có chỗ đứng trên “đấu trường danh vọng”.
  4. Tìm ra và report bug phần 1 (có CVE đầu tay).
  5. Quả ngọt – Microsoft quyết định trao bounty và bonus vì những báo cáo chuẩn mực của bug phần 2 😊.

Tôi không rõ lý do việc microsoft từ chối đánh CVE cho bug này, có thể là do dup mà chưa patch hết. Nhưng dù thế nào đi nữa, con số 26 như một happy ending cho chuỗi ngày dài đau khổ cùng SharePoint.

SharePoint Server và câu chuyện về research. Phần 1: CVE đầu tay

Thời điểm giữa năm 2021, cộng đồng bảo mật xôn xao vì hàng loạt lỗ hổng 0-day của Exchange được công bố. Người người đi diff, nhà nhà có poc, chẳng cho mình là ngoại lệ, tôi cũng nhảy vào nghiên cứu phân tích cho bằng bạn bằng bè. Tuy nhiên đời không như là mơ, trong khi anh em đã ra lỗi thì bản thân lại đang quanh quẩn ở một phase nào đấy chẳng chút liên quan. Không há miệng chờ poc, tôi bắt đầu nghiêm túc với công việc gọi là research này. Chọn một mục tiêu mà bản thân nghĩ sẽ nhẹ nhàng hơn cũng như để tích lũy kinh nghiệm về .NET – SharePoint Server là ứng cử viên sáng giá.

Công cuộc tìm kiếm CVE đầu tay bắt đầu, mặc dù gặp nhiều khó khăn nhưng sau vài tháng thì tôi cũng có thành quả với lỗ hổng Store XSS (CVE-2022-24472). Vẫn chưa bằng lòng với kết quả này, suy nghĩ của tôi lúc đó là “Các thứ khác có hay không không quan trọng, CVE đầu tay phải là RCE”. Vì vậy tôi đã không để acknowledgement và tiếp tục dấn thân sâu hơn vào con đường này. Ông trời không phụ lòng người, sau hơn nhiều tháng tìm kiếm và chờ đợi, ngày 13 tháng 12 năm 2022, lỗ hổng được vá và đánh số CVE-2022-44693.

Phân tích

Đây là một biến thể của CVE-2021-34520 tồn tại trong chức năng Workflow của SharePoint. Mọi người có thể tham khảo phân tích của lỗ hổng này tại đây. Có thể tóm tắt như sau:

  • Workflow là một luồng công việc được thực hiện một cách tự động, bao gồm nhiều bước.
  • Các bước này sẽ chúa một hoặc nhiều hoạt động (activity) và các điều kiện (rule).
  • SharePoint có một danh sách các activity/rule được đánh dấu là an toàn (allow list) và người dùng chỉ có thể tạo workflow (dưới định dạng XML) với các activity/rule đó. Quá trình kiểm tra đều dựa trên định dạng XML.
  • SetVariableActivity (nằm trong danh sách an toàn) có chứa thuộc tính ValueType. Nếu thuộc tính này mang giá trị là chuỗi System.Resources.ResourceSet thì có thể dẫn đến remote code execution.
  • Lỗ hổng được vá bằng cách kiểm tra giá trị của các thuộc tính với allow list. Nếu thỏa mãn thì sẽ thực thi và ngược lại.
  • Payload sẽ như sau:

1. Payload cho CVE-2021-34520

Trong qua trình kiểm tra workflow config, hàm IsGoodWorkflowCore trong thư viện Microsoft.SharePoint.dll được gọi với xmlReader chính là file config và authorizedTypes là allow list đã quy định từ sẵn.

2. Hàm IsGoodWorkflowCore trong bản vá tháng 10 năm 2022

Đây là một hàm rất dài, chức năng của nó là đọc lấy giá trị của từng node và thuộc tính sau đó đem so sánh với allow list, cuối cùng là trả về true/false nếu thỏa mãn/không thỏa mãn. Cũng vì sự dài dòng nên tôi đã chăm chăm vào việc tìm chỗ bypass logic mà không để ý đến những dòng code cuối. Nếu quá trình đọc xảy ra bất kỳ exception nào thì chương trình sẽ ghi log lại và … return true. Do đó ta chỉ cần tìm một đoạn code có khả năng gây exception thì sẽ bypass hoàn toàn được cơ chế này. Chúng ta sẽ đi tiếp vào hàm IsAuthorizedType, hàm này được gọi bởi IsGoodWorkflowCore. Nó có tác dụng đọc và so sánh thuộc tính từ workflow config.

3: Hàm IsAuthorizedType trong bản vá tháng 10 năm 2022

Tại dòng 221, attributeValue được tách ra với ký tự “{” sau đó gán vào mảng array. Còn tại dòng 225, giá trị array[1] được gọi. Ta dễ dàng thấy rằng nếu attributeValue mang giá trị là “” hoặc “{}” thì sẽ gây ra IndexOutOfRangeException vì lúc này mảng array chỉ có duy nhất một phần tử. Tới đây mọi thứ đã quá đơn giản, mặc dù vẫn còn một số vấn đề khác để hoàn thành CVE nhưng nó không ảnh hưởng quá nhiều đến kết quả. Payload cho lỗ hổng như sau:

4. Payload cho CVE-2022-44693

Ở đây tôi chọn thuộc tính Name với giá trị là “{}” do nó là thuộc tính mặc định và có thể nhận bất cứ giá trị nào (quá trình parse XML để chạy workflow sẽ có bước kiểm tra thuộc tính có tồn tại trong acitvity/rule hay không). Bên cạnh đó, thuộc tính xmlns cũng có thể được sử dụng thay vì Name. Ngoài ra, còn rất nhiều vị trí có khả năng gây exception, ví dụ như dòng 243 trong chính hàm IsAuthorizedType.

Kết luận

Mặc dù impact là remote code execution nhưng theo đánh giá của những người anh em xã hội, đây là một bug khá dễ, khả năng bị trùng không nhỏ. Và thật sự nó đã bị “dup”, tuy nhiên đây vẫn là một thành quả không nhỏ, cũng như một bước đệm để tôi tiếp tục với bug workflow ở phần 2.

Phân tích tệp tin ImportTool.exe trên trang https://tiemchungcovid19.gov.vn

Qua giám sát an toàn trên không gian mạng chúng tôi phát hiện thông tin từ một số tài khoản MXH nghi ngờ rằng công cụ được cung cấp trên trang https://tiemchungcovid19.gov.vn là một mẫu mã độc.

Thông tin được một tài khoản MXH chia sẻ

Tập tin trên là công cụ nhỏ được thiết kế dành riêng cho các cơ sở Y tế để chuẩn hóa dữ liệu Excel trước khi nhập vào hệ thống, vì tình trạng dữ liệu nhập vào không đồng nhất, một số địa điểm có đăng ký giấy phải nhập liệu thủ công.

Thông tin được các cá nhân này đưa ra dựa vào một số dấu hiệu sau đây:

  • Windows Defender cảnh báo tệp tin có chứa nội dung nghi ngờ là mã độc
  • Đánh giá 9/65 phần mềm duyệt virus trên thế giới nhận định công cụ này là mã độc (nguồn virustotal)
Đánh giá của Virustotal đối với file ImportTool.exe

Tuy nhiên nếu chỉ dựa vào một số thông tin nêu trên để kết luận đây là một tệp tin độc hại thì hoàn toàn chưa đủ căn cứ. Chính vì thế chúng tôi đã tiến hành kiểm tra và phân tích tệp tin này để có được thông tin chính xác nhất.

Dưới đây là một số thông tin cơ bản về tệp tin ImportTool.exe

Thông tin tệp tin ImportTool.exe

Qua kiểm tra, chúng tôi phát hiện đây là một phần mềm được lập trình bằng ngôn ngữ python và được biên dịch bằng Pyinstaller.

Xác định phần mềm được lập trình bằng ngôn ngữ python

Trước đây, có một số mã độc cũng biên dịch từ python để thành tệp tin thực thi độc hại, dẫn tới vấn đề nhận diện nhầm của trình Antivirus, do Antivirus hoạt động phần lớn dựa trên tập luật. Vấn đề nhận diện sai khi sử dụng Pyinstaller đã được đề cập nhiều trên Github cũng như các diễn đàn về Python. Chi tiết xem tại đây.

Để khẳng định nhận định trên chúng tôi thử biên dịch 1 chương trình sample bằng Pyinstaller sau đó đưa lên Virustotal để kiểm tra thì phá hiện 8/67 vendors đánh giá đây là một tệp tin độc hại (chi tiết tại đây). Qua đó có thể thấy do cấu trúc biên dịch, đóng gói một chương trình từ python sang một tệp thực thi duy nhất có nguy cơ cao bị cảnh báo nhầm thành mã độc.

Mã nguồn của sample
Một mã nguồn python đơn giản được biên dịch bằng Pyinstaller

Một số tệp tin thư viện python được sử dụng trong công cụ ImportTool.exe cũng chính là nguyên nhân dẫn đến các công cụ Antivirus đưa ra nhiều hơn các cảnh báo không chính xác về công cụ này. Ví dụ như:

  • fields.cp37-win32.pyd
  • timedeltas.cp37-win32.pyd

Qua những phân tích trên có thể thấy đây hoàn toàn là do các chương trình Antivirus đã vô tình nhận diện sai công cụ này thành một mã độc, tuy nhiên để an toàn hơn cho người dùng, chúng tôi đã thực hiện phân tích sâu hơn về hành vi của chương trình, cụ thể kiểm tra một số thông tin liên quan đến kết nối internet, và một số hoạt động thay đổi thông tin dữ liệu của máy tính và đưa ra một số kết luận như sau:

  • Công cụ không thực hiện các kết nối độc hại trong quá trình người dùng sử dụng
  • Công cụ không thực hiện thay đổi hay tạo thêm các giá trị trong Registry để thực hiện các hành vi độc hại.
  • Công cụ không tạo ra các tệp tin nghi ngờ là mã độc nào khác.
  • Công cụ không thực hiện chạy các phần mềm khác.

Qua những thông tin trên chúng tôi đưa ra kết luận công cụ ImportTool.exe không phải là mã độc như thông tin được đưa ra bởi một số cá nhân trên mạng xã hội Facebook.

Chúng tôi sẽ phân tích tiếp các dữ liệu và cập nhật thêm thông tin nếu có.

Camera và cuộc sống quanh ta

Camera an ninh hiện nay là một thiết bị rất phổ biến được sử dụng ở rất nhiều nơi. Nó nắm khá nhiều thông tin nhạy cảm của người dùng. Tuy vậy chưa nhiều người quan tâm tới vấn đề bảo mật của các thiết bị này lắm. Vì vậy, nhiều kẻ xấu đã lợi dụng vấn đề này để tấn công chuộc lợi cá nhân.

Ở bài viết này chúng tôi sẽ chia sẻ về quá trình tìm hiểu, nghiên cứu về một chiếc camera không tên, là khởi đầu cho việc nghiên cứu những thiết bị khác khó hơn và nhiều người dùng hơn sau này. Thực ra chúng tôi chọn camera này vì là được một người anh cho để nghiên cứu thử chứ cũng không có ý định target nó từ đầu. Việc này đã được chúng tôi làm từ trước đây rất lâu nhưng bây giờ mới có cơ hội chia sẻ lại với các bạn. Tuy nhiên sau một thời gian ngắn nghiên cứu thì chúng tôi đã làm chết con camera này dẫn đến không thể nghiên cứu sâu hơn cũng như không thể thực hiện lại một số thao tác để có một bài viết đầy đủ và chi tiết hơn. Chính vì vậy nếu bài viết này còn nhiều thiếu xót hoặc chưa đủ hấp dẫn và chi tiết thì tôi xin phép hẹn các bạn vào một bài viết khác, về một thiết bị camera khác.

Một camera không tên tuổi

Tiếp cận thiết bị

Với một camera chưa biết gì thì chúng ta có thể tiến hành dump firmware. Nhưng việc đó cần nhiều hiểu biết về phần cứng, là một người mới bắt đầu tôi không chọn phương án này vì cần phải hàn mạch. Hướng tiếp cận đầu tiên là kết nối thiết bị vào mạng LAN rồi thực hiện dò xét các cổng mở để tìm được hướng tấn công tiếp  theo.

Để thực hiện việc này, đầu tiên sau khi kết nối vào cùng mạng wifi của camera tôi dùng công cụ nmap để quét ra ip của camera, sau đó tìm hiểu các cổng mở cũng như các thông tin liên quan:

Kết quả nmap vùng mạng chứa thiết bị

Sau bước này, ta sẽ xác định được địa chỉ ip của camera là 192.168.50.92. Các port mở là 554, 5000 thường được mở ở các thiết bị camera. Như vậy, không có các cổng thông dụng như HTTP, SSH, …

Tiếp tục thực hiện các lệnh nmap thông dụng :

Kết quả nmap thiết bị

Ta lại biết thêm được một thông tin thú vị về chiếc camera này. Có vẻ như nhà sản xuất là Shenzhen. Lên google search một hồi thì công ty này có các sản phẩm về camera. Lục tìm trong các sản phẩm xem có cái nào giống cái của mình đang nghiên cứu hay không.

Sau một thời gian dài kiên nhẫn, cuối cùng tôi cũng tìm được một con có vẻ khá giống loại mình đang nghiên cứu. Tìm các sản phẩm trên thị trường Việt Nam thì ra rất nhiều loại tương tự. Camera này có số hiệu YOOSEE 720P Z06H được bán với giá 350k trên shopee. Từ đây, mình cũng tìm được app điều khiển loại camera này. Đồng thời mở ra nhiều hướng để nghiên cứu thêm.

Nghiên cứu các cổng mở

Sau bước đầu tiên, tôi phát hiện được 2 cổng TCP đang mở. Các cổng này sẽ được dùng với mục đích gì? 

Cổng 554 được nmap gán với nhãn rtsp (Real Time Streaming Protocol), là một giao thức thường xuyên được sử dụng trong camera. Từ đây, tôi tìm một số công cụ để xem stream với rtsp.

Công cụ đầu tiên thành công xem được video là ONVIF Device Manager. Nó thực hiện các giao tiếp với camera qua cổng 5000 để nhận biết được các thông tin thông số kĩ thuật cũng như luồng stream. Tại thời điểm này, camera đang ở trạng thái không xác định nên tôi không thể dựng lại để viết được. Tool tiếp theo dùng được là  VLC media player. Chọn Open Network Stream  Url. Trong trường hợp này, luồng stream video nằm tại rtsp://192.168.50.92:554/onvif1. Tiến hành bắt request để xem cách thức tool giao tiếp với camera như thế nào

Một số gói tin được trao đổi giữa thiết bị và người quản trị

Đúng như mong đợi, công cụ thực hiện các request tới camera qua cổng 554, tuân theo chuẩn của rtsp.

Sau khi nghiên cứu hai ứng dụng này, tôi chưa phát hiện ra cơ chế xác thực nào của ứng dụng. Chả lẽ chúng ta có thể xem video từ camera một cách tự do thế sao?

Nghiên cứu ứng dụng Yoosee

Camera này có một ứng dụng quản lí trên điện thoại : Yoosee. Chúng ta có thể tải ứng dụng về, tạo tài khoản, đăng nhập và thực hiện các tác vụ quản lí camera trên ứng dụng này. Ứng dụng này cho phép chúng ta thêm thiết bị qua mạng lan, nó sẽ tự động dò quét ip để tìm ra camera, tiếp đến chỉ cần nhập password của camera là có thể quản lí thiết bị. Password mặc định là 123 có vẻ như là phổ biến cho tất cả các thiết bị.

Sau khi thêm thiết bị vào, các ứng dụng tại bước hai sẽ không thể xem video được nữa. Cũng không thể có 1 lúc 2 thiết bị cùng thêm một camera. Vậy là đã có câu trả lời cho bước trước tại sao không cần xác thực mà vẫn xem được video. Tuy nhiên, bằng ứng dụng ONVIF Device Manager, chúng ta vẫn có thể thực hiện các lệnh làm cho camera chuyển động. Tức là vẫn có những hành động mà chúng ta có thể tác động lên con camera này. Điều này mở ra nhiều hi vọng tìm kiếm những chức năng tương tự.

Thực hiện bắt request trên thiết bị android :

Ứng dụng giao tiếp với camera bằng giao thức UDP thông qua cổng 51880. Hmm có vẻ như là một cổng khá lạ, quét bằng nmap không ra. Các gói tin gửi đi cũng khá là vô nghĩa, nên ta khó có thể phân tích được nhiều.

Nghiên cứu firmware

Qua các bước trên, tôi đã có được cái nhìn sơ bộ về cách hoạt động của camera. Nhưng muốn nghiên cứu sâu hơn, cần phải có được mã nguồn firmware của camera. Lượn lờ trên google một hồi tôi cũng tìm được link thú vị này.

Nó cho phép chúng ta update firmware của camera đồng thời đi kèm là các bản firmware.

That’s all we need. Tiến hành upgrade thử một firmware. Tôi lại phát hiện ra một chức năng không cần xác thực nữa. Nếu không cần xác thực thì chúng ta có thể nghĩ cách inject backdoor vào trong firmware rồi update bản cập nhật. Tuy nhiên, dù không xác thực nhưng nó vẫn check MD5 ở đâu đó, nên khả năng chúng ta có thể động vào bản update là không thể.

Đến đây, tôi lại có một câu hỏi : điều gì xảy ra nếu ta thực hiện update các phiên bản chính của nhà phát hành nhưng là phiên bản cũ hơn phiên bản hiện tại. (⊙_⊙)?Phiên bản hiện tại camera mà tôi đang nghiên cứu là 21.00.00.95. Tôi lặng lẽ thử downgrade xuống phiên bản 14.00.00.00. Và rip chiếc camera die luôn. Nhấn nút reset cũng không thấy có phản hồi gì. Rip.

Tại đây, cũng mở ra nhiều hướng tấn công khác như là tìm một phiên bản chứa lỗ hổng bảo mật đã được khai thác, rồi downgrade firmware xuống, thực hiện tấn công trên các lỗ hổng đã có.

Extract firmware

Tiếp đến, extract firmware ra và xem chương trình thực hiện những gì. Extract bằng binwalk ta thu được:

File 23B964.elf là file update firmware. Thư mục jffs2-root chứa một phần firmware update. Tôi sẽ tập trung vào thư mục jffs2-root/fs_1

Trong thư mục này có chứa các file cấu hình của camera cũng như các file .xml dùng cho Onvif. File cần lưu ý nhất là file npc. Nó là chương trình chính điều khiển camera.

Phân tích sơ bộ file npc

File này là một file khá lớn, bị stripped hết nên sẽ tốn rất nhiều thời gian để dịch ngược toàn bộ chức năng của chương trình. Như hình trên có chức năng ẩn là thực hiện mở telnetd , tuy nhiên tôi chưa tìm ra cách để kích hoạt nó. Tôi xem qua ứng dụng cũng không thấy có các chức năng để mở cổng telnetd này. Đây có vẻ là một chức năng ẩn. Câu hỏi đặt ra là chức năng này được tạo ra để làm gì \(〇_o)/

Tiếp đến, tôi sẽ tập trung để tìm các hàm mở các cổng 5000, 554, 51880. Bằng cách lần theo các hàm để tạo socket như bind, connect, recv, send, ….

UDP 8899

Trong bài viết này tôi sẽ tập trung vào tính năng unauthen upgrade đã tìm hiểu ở bước trên. Tôi đã dịch ngược được hai hàm xử lí của 2 port TCP đã mở. Và không có hàm nào xử lí việc upgrade cả. Sau khi bắt request, tôi phát hiện ra tool upgrade giao tiếp với camera qua cổng 8899.

Hàm xử lí request tới cổng 8899 nằm tại địa chỉ 0x18EE64.

Chúng ta có thể chọn các lệnh để thực hiện chức năng thông qua bytes đầu tiên của request. Tại đây, chúng ta cũng có rất nhiều các chức năng unauthen nhưng có khá nhiều tham số mà khó có thể kiểm soát. Bộ nhớ được kiểm soát cũng rất tốt nên không có hàm nào bị buffer overflow ở đây.

Tiếp đến, phân tích request mà tool upgrade gửi tới camera sẽ sử dụng option 7. Đoạn xử lý được thực thi như sau:

Từ đó, ta có thể truyền vào request để xác lập port sẽ nhận bản cập nhật từ server và phương thức upgrade. Hàm xử lí chính của upgrade nằm tại địa chỉ 0x191B70.

Tại đây, ta thấy có rất nhiều lựa chọn upgrade chứ không chỉ upgrade mỗi firmware.

Việc upgrade các file hệ thống không có check md5. Ta hoàn toàn có thể tự tạo request và khiến cho hệ thống này cập nhật những thứ không mong muốn.

Tôi đã tiến hành dựng lại để thiết lập được một tính năng tấn công làm cho camera tự khởi động lại.

Đầu tiên thực hiện gửi request tới cổng 8899 để chọn option 7 cho tính năng upgrade. Thiết lập port và option upgrade. Tôi chọn port 21200 và option 0x2.

Sau đó, tạo server bind cổng 21200 để gửi bản cập nhật. Set các tham số tương ứng để thỏa mãn điều kiện:

Nếu các điều kiện trên đều được thỏa mãn, ta sẽ đến được đoạn:

Như vậy, hàm main sẽ thoát khỏi vòng lặp trên và tiến tới thực thi switch case:

Case 8 sẽ là thực hiện upgrade firmware từ file /mnt/ramdisk/tempRsUpg.bin . Sau đó thiết bị sẽ tiến hành reboot.

Với tính năng này, chúng ta có thể thực hiện reboot liên tục thiết bị gây ra một cuộc tấn công DOS camera.

Kết luận

Qua đây ta có thể thấy chiếc camera này mở rất nhiều cổng dịch vụ khác nhau, trong đó nhiều chức năng không yêu cầu xác thực. Thậm chí nó cho phép chúng ta downgrade phiên bản, tự động reboot,…. Làm hư hại nghiệm trọng tới thiết bị. Mở ra nhiều hướng tiếp cận có thể exploit được. Tuy nhiên do việc làm die con camera quá sớm dẫn đến còn nhiều thứ chưa được thử trên con camera để confirm nên chúng tôi không chia sẻ thêm ở đây. Cuối cùng tôi hi vọng bài viết đơn giản này có thể giúp mang lại cho các bạn cái nhìn khách quan hơn về tìm kiếm lỗ hổng trên các thiết bị camera.

Credit: @hacmao of Zepto Team

Phân tích bản vá tháng 05/2021 trên Sharepoint Server 2013

Dạo này thấy các Security Researcher thi nhau public các bài viết phân tích n-day khiến cộng đồng security trong nước xôn sao. Cũng vì thế mà ae trong team dù đang rất nhiều việc cũng phải tranh thủ nhảy vào nghiên cứu bú fame cho bằng anh bằng em.

Người người phân tích Pre-Auth thì chúng tôi tạm thời phân tích Post-Auth, nhà nhà phân tích Exchange thì chúng tôi phân tích Sharepoint. Chúc anh em đọc có nhiều niềm vui và có thêm thông tin hữu ích.

1. DIFF PATCH

Sau khi tải và cài đặt Sharepoint cùng với các bản patch (phiên bản Foundation 2013 SP1), ta lấy các dll tiến hành diff. Các dll của Sharepoint hầu hết ở 3 thư mục:

  • C:\Windows\Microsoft.NET\assembly\GAC_MSIL
  • C:\Program Files\Common Files\microsoft shared
  • C:\inetpub\wwwroot\wss

Tên file đều có pattern là Microsoft.Sharepoint.*.dll. Có thể sử dụng 7zip với option regex để gom các file này một cách nhanh chóng.

7z.exe a dll.7z -r .\Microsoft.Sharepoint.*.dll

Sử dụng DNSpy export toàn bộ các file dll của cả hai phiên bản ra code C# rồi thực hiện diff bằng WinMerge. Công cụ này có sẵn filter ASP.NET Devel giúp loại bỏ các đoạn code khác nhau không quan trọng (các dòng code bị đảo vị trí hoặc thay đổi về version, …), làm quá trình diff trở nên dễ dàng hơn.

Bảng Filters trong tab Tools – Filters
Kết quả sau khi filter & diff

Có thể nhận thấy hầu như code được thay đổi tại các đoạn gọi hàm Deserialize; các thuộc tính như Binder, Resolver được bổ sung giúp cho việc thực hiện deserialize trở nên an toàn hơn trước input người dùng (chỉ cho phép chuyển đổi các đối tượng với kiểu dữ liệu quy định trước).

Đoạn mã vá lỗi BinaryFormatter trong class Microsoft.SharePoint.Portal.WebControls.ScorecardFilterValuesProviderCollectionProxy
Đoạn mã vá lỗi XmlSerializer trong class Microsoft.SharePoint.ApplicationPages.MetaWeblog.MetaWeblogPage

Các formatter chính được sử dụng là BinaryFormatterXmlSerializer. Đối với BinaryFormatter nếu không chỉ định thuộc tính Binder, ta có thể trực tiếp khai thác bằng cách đưa vào các payload độc hại. Còn XmlSerializer yêu cầu kiểu dữ liệu thích hợp, nên muốn khai thác được thì phải tùy ý điều khiển được kiểu dữ liệu đầu vào.

Các định dạng và điều kiện khai thác của từng formatter
(Blackhat USA 2017 – Friday the 13th: JSON Attacks)

Ta sẽ phân tích đoạn patch về BinaryFormatter do không có yêu cầu đặc biệt về input người dùng. Theo thông tin diff bên trên, trong file Microsoft.Sharepoint.Portal.dll, BinaryFormatter được gọi ở namespace WebControls.ScorecardFilterValuesProviderCollectionProxy vì vậy ta đi sâu hơn vào class này.

2. PHÂN TÍCH

Phân tích file Microsoft.SharePoint.Portal.WebControls.dll, ta nhận thấy BinaryFormater được gọi tới trong hàm ParseQueryString(string queryString). Hàm này thực hiện urldecode đối với query string của người dùng, sau đó decode base64 và truyền vào cho câu lệnh BinaryFormatter.Deserialize() để tiến hành chuyển đổi sang đối tượng. Trong đó giá trị của queryString chính là giá trị của tham số SCFVP trên URL.

Tiếp tục trace code, ParseQueryString() được gọi từ method OnPreRender() trong class KpiDisplayFormControlBase.

KpiDisplayFormControlBase kế thừa class System.Web.UI.UserControl, do đó KpiDisplayFormControlBase có thể được gọi trực tiếp từ một web form page (file aspx) thông qua Register.

Như vậy định hình được flow như sau:

  • Tạo một page aspx có Register gọi đến KpiDisplayFormControlBase.
  • Truy cập page aspx vừa tạo với giá trị của tham số SCFVP là payload thực hiện RCE.

Để có thể tạo được một page aspx trên Sharepoint thì user phải có quyền Add and Customize Pages. Quyền này thường được bật đối với các user trong group Farm Administrators. Request dưới đây sẽ tạo một page có tên là rce.aspx với các thuộc tính:

  • Namespace: Micrsoft.Sharepoint.Portal.WebControls
  • Assembly: Thông tin file dll của namespace trên (có thể lấy bằng DNSpy)
  • Register: Class KpiDisplayFormControlBase.

Sử dụng công cụ ysoserial.net để tạo ra payload với gadget bất kỳ mà BinaryFormatter hỗ trợ, ở đây ta chọn TextFormattingRunProperties.

Request đến page rce.aspx vừa tạo với payload trigger RCE

Lệnh calc được thực thi thành công

Credit: @dieulink81 (Member of Zepto Team)

Chuyện ProxyLogon

Tháng 3 vừa bắt đầu, ngoài cửa sổ những cơn gió xuân vẫn còn thổi mát rượi làm lòng người man mác. Tôi vẫn nhớ đó là một sáng thứ ba đẹp trời ngày 02/03/2021, thời tiết thủ đô chợt làm tôi nghĩ tới vài câu thơ của Nguyễn Đình Thi:

Sáng chớm lạnh trong lòng Hà Nội

Những phố dài xao xác hơi may…

Thế mà bỗng dưng BÒM,4 lỗ hổng bảo mật nghiêm trọng CVE-2021-26855, CVE-2021-26857, CVE-2021-26858 và CVE-2021-27065 liên quan tới Exchange Mail Server được Microsoft công bố, làm chao đảo và dậy sóng giới an toàn thông tin. Cả thế giới cảnh báo nhau, tin tặc đua nhau tìm kiếm và khai thác, nhiều công ty, tổ chức, tập đoàn bị “dính bom”. Ở Việt Nam, NCSC cũng đã ghi nhận nhiều trường hợp các tổ chức, công ty bị tin tặc xâm nhập và khai thác hệ thống thông qua những lỗ hổng này.

Nếu đọc đến đây mà bạn vẫn chưa hiểu gì, thì nhanh chóng đọc một chút ở đây.

Tại thời điểm hiện tại, hoạt động tấn công và khai thác lỗ hổng ProxyLogon cũng đã giảm, phần lớn các hệ thống đã fix lỗi, một số khác chắc đã được các bên thứ 3 remote vào fix hộ :p

Báo viết về proxylogon, nhà nhà cảnh báo proxylogon, người người cầm exploit proxylogon, nhưng chỉ thấy lẻ tẻ vài bài về ứng cứu sự cố tấn công proxylogon. Chúng tôi cũng may mắn được giúp đỡ một số đơn vị, xử lý các sự cố liên quan đến tấn công lỗ hổng bảo mật proxylogon nên có viết một chút về quá trình này.

Điều tra, ứng cứu thì làm gì ???

Thu thập hết log, sử dụng PowerShell command được Microsoft hướng dẫn để rà soát những đoạn log khả nghi. Chúng tôi nhận thấy kẻ xấu đã do thám lỗ hổng từ ngày 28/02/2021, trước khi chi tiết về các CVE được Microsoft công bố vào ngày 02/03/2021. link

Rà soát webshell

Sau khi đã phát hiện được những dấu hiệu tấn công và khai thác ban đầu, chúng tôi tiếp tục rà soát các webshell có trong hệ thống. Sử dụng YARA rule để phát hiện những file nghi ngờ là webshell. Các file khả nghi bao gồm:

  • FrontEnd\HttpProxy\owa\auth\redirServerProxy.aspx 2.
  • owa\auth\15.0.1178\scripts\premium\error.aspx 3.
  • \aspnet_client\error_page.aspx 4.
  • \FrontEnd\HttpProxy\owa\auth\version\themes\resources\home.aspx
Webshell

Dựa vào access log của server, chúng tôi nhận thấy có nhiều kết nối đến webshell từ ngày 04/03/2021.

Song song với quá trình sử dụng YARA rule, chúng tôi sử dụng PowerShell script được Microsoft công bố nhằm so sánh sự khác biệt giữa các file gốc của Exchange với phiên bản hiện tại để tìm ra các file không thuộc hệ thống gốc. Đoạn script có tên Compare Exchange Hashes có thể tìm thấy tại link này.

Run and run
Các file nghi ngờ là webshell

Tiếp đến, chúng tôi thực hiện rà quét những file nén dữ liệu (.7z, .zip, .rar) bất thường mà kẻ tấn công có thể sử dụng để tiếp cận và tải về mã độc. Chúng tôi phát hiện có dấu hiệu exfiltration dữ liệu vào ngày 5/3.

File .zip nghi ngờ được khai thác bởi tin tặc nhằm đánh cắp dữ liệu

Rà soát mã độc

Sử dụng bộ công cụ Windows Sysinternals

  • Process Explorer
  • Autoruns
  • TCPView

Sử dụng DeepBlueCLI để rà soát Windows Event Logs

DeepBlueCLI là một bộ công cụ có chứa các PowerShell script giúp phát hiện những bất thường trong hệ thống dựa vào Windows Event Logs. Bằng DeepBlueCLI, chúng tôi đã phát hiện có sự kiện xoá logs vào các mốc thời gian 7/3 2:50 a.m 11 p.m 9/3 1 a.m; 10/3 1-3 a.m.

Sử dụng ListDLLs để phát hiện các hành vi load DLL khả nghi

Sau khi rà soát bằng các công cụ trên mà không tìm thấy mã độc, chúng tôi cứ ngỡ rằng hệ thống này chưa quá “toang”.

Trực giác của chúng tôi cho thấy có một cái gì đó không đúng ở đây, có thể hacker sử dụng một kỹ thuật nào đó để ẩn đi hành vi của mã độc.

Bằng cách rà soát các DLL được load bởi tất cả các tiến trình (bằng một phiên bản customize “nội bộ NCSC” của công cụ ListDLLs), chúng tôi phát hiện ra một tiến trình load DLL không đúng với “thiết kế của nhà sản xuất”. Rà soát lại tiến trình này cũng như các DLL khả nghi, chúng tôi phát hiện một số mẫu mã độc đã sử dụng kỹ thuật DLL Side-Loading để che dấu hành vi của mình.

Tóm lại là

Timeline sự cố

Phân tích mẫu mã độc

Cuối bài viết chúng tôi sẽ trình bài kết quả phân tích hành vi của một số mã độc đã thu được trong quá trình xử lý sự cố.

Microsoft.Exchage.Client.Event.dll

Miêu tả: File Dll này được viết trên nền tảng .NET, được pack bởi .NET Reactor, các tên hàm và tên biến đều ở định dạng utf-16 nên hơi khó để dịch ngược.

Vậy nên, ta có thể sử dụng de4dot để unpack .NET Reactor bằng command như sau:

Sau khi quá trình unpack kết thúc, ta sẽ nhận được một file dll có tên là Microsoft.Exchange.Clients.Event-cleaned.dll. Load file này vào dnspy thì ta có thể đọc code đơn giản hơn trước khi unpack.

Flow hành vi của file này được miêu tả cơ bản qua hình sau:

MSExchangeHM.exe

Miêu tả: file exe chạy với một tham số là đường dẫn tới file Dynamic-Link Library (DllPath) và khởi chạy dll đó bằng cách Inject vào process có commandline OWAApp như flow sau:

Kỹ thuật Inject được sử dụng trong file này có tên là Inject Dll by APC sử dụng hàm NtCreateThreadEx. Bạn có thể đọc chi tiết hơn về kỹ thuật này tại đây.

File này sẽ có chức năng để load các dll, chúng tôi tìm thấy một dll khác đáng nghi ngờ trong cùng thư mục với file exe này. File đó có tên là MSOARES.dll, khá giống với tên của một file dll của Microsoft là MSOERES.dll

File Dll này thực hiện chức năng hook vào LogonUserEx API, mỗi lần hệ thống gọi đến làm LogonUserEx thì nó sẽ ghi usernamepassword vào file có định dạng là C:\ProgramFiles\Microsoft\ExchangeServer\V15\FIP-FS\Data\Engines\metadata\manifest.{8b26bc7d-829d-4354-9527-(time_date)}.cab

Bạn có thể đọc kỹ hơn về kỹ thuật hook được sử dụng trong file dll này tại đây.

Bài viết cũng đã dài, sẽ viết tiếp phần phân tích các mẫu còn lại trong ngày gần nhất. Đi ngủ phát mai còn đi rà soát mấy con F5 đang bị đào coin :vvvv

Indicators of Compromise (IoC)

Mã hash của các web shell đã được phát hiện:

  • b75f163ca9b9240bf4b37ad92bc7556b40a17e27c2b8ed5c8991385fe07d17d0
  • 097549cf7d0f76f0d99edf8b2d91c60977fd6a96e4b8c3c94b0b1733dc026d3e
  • 2b6f1ebb2208e93ade4a6424555d6a8341fd6d9f60c25e44afe11008f5c1aad1
  • 65149e036fff06026d80ac9ad4d156332822dc93142cf1a122b1841ec8de34b5
  • 511df0e2df9bfa5521b588cc4bb5f8c5a321801b803394ebc493db1ef3c78fa1
  • 4edc7770464a14f54d17f36dc9d0fe854f68b346b27b35a6f5839adf1f13f8ea
  • 811157f9c7003ba8d17b45eb3cf09bef2cecd2701cedb675274949296a6a183d
  • 1631a90eb5395c4e19c7dbcbf611bbe6444ff312eb7937e286e4637cb9e72944

Các đường dẫn đã được biết:

  • C:\inetpub\wwwroot\aspnet_client\
  • C:\inetpub\wwwroot\aspnet_client\system_web\

Trong các đường dẫn cài đặt Microsoft Exchange Server như:

  • %PROGRAMFILES%\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth\ C:\Exchange\FrontEnd\HttpProxy\owa\auth\

Các web shell đã được phát hiện có tên:

  • web.aspx
  • help.aspx
  • document.aspx
  • errorEE.aspx
  • errorEEE.aspx
  • errorEW.aspx
  • errorFF.aspx
  • healthcheck.aspx
  • aspnet_www.aspx
  • aspnet_client.aspx
  • xx.aspx
  • shell.aspx
  • aspnet_iisstart.aspx
  • one.aspx

Hi vọng bài viết sẽ giúp các tổ chức có thể dễ dàng tự rà soát lại hệ thống Exchange của mình hơn.

Để kiểm tra hệ thống của mình đã được fix chưa, thì có thể dùng công cụ này: https://khonggianmang.vn/check-proxylogon

Credit: Zepto Team

DF Cyber Defense Write-Up

Lời đầu tiên chúng tôi xin thay mặt BTC gửi lời cảm ơn đến các đội đã tham gia cuộc thi. Sau một thời gian để các đội tiếp tục tự nghiên cứu và tìm hướng giải cho các thử thách còn lại nhằm nâng cao chuyên môn cũng như kỹ năng nghiệp vụ của mình, hôm nay BTC sẽ công khai lời giải cho các thử thách có ít đội giải được. Đối với các thử thách có nhiều đội giải được các đội nếu có thắc mắc có thể liên hệ BTC thông qua kênh hỗ trợ Discord để được giúp đỡ.

Backdoor Detected (Category: Webshell)

Mô tả của thử thách

Ở thử thách này BTC gửi cho các đội một tập tin bao gồm một file access_log.txt và một thư mục ROOT của web server. Sau khi xem qua các tệp do BTC cung cấp, tệp tin đáng ngờ nhất là tệp tin banking.jsp.

Nội dung file banking.jsp nghi ngờ là webshell

Step 1: Decode UTF-16

Thoạt nhìn qua chúng ta có thể phát hiện đây là một kiểu encode dạng UTF-16, chính vì thế chúng ta cần thực hiện decode UTF-16 để có thể có được một nội dung có thể đọc được.

Decode UTF-16

Sau khi thực hiện decode UTF-16 chúng ta có thể thấy đây là một đoạn mã java, đoạn mã này tiếp tục bị làm rối bằng cách thay đổi tên các biến có khuôn dạng $_$ làm cho việc đọc hiểu đoạn mã trở nên khó khăn hơn.

Mã nguồn được giải mã UTF-16

Step 2: Khôi phục các hàm, biến và string của webshell

Sau khi có được tên webshell là banking.jsp, kết hợp với access_log.txt, bước đầu có thể thấy payload được gửi đến webshell qua POST method và ta hoàn toàn không có trong tay payload, vì vậy flag có thể được giấu đâu đó trong webshell hoặc ở một trong số các tệp còn lại của thư mục ROOT. Để biết được nội dung bị đánh cắp được lưu ở đâu chúng ta cần phải hiểu được cách thức hoạt động của web shell này.

Sử dụng một trang web https://kt.gy để khôi phục nhanh các chuỗi byte thành các string

Khôi phục các chuỗi byte thành string

Dựa vào các string, class và function mặc định được sử dụng ta có thể dự đoán được chức năng chính của các hàm được sử dụng trong web shell

Function Write_File
Function Base64_Decode
Function Base64_Encode_AES_Encrypt
Function AES_Decrypt
Function Exec_Command

Step 3: Khôi phục hàm main của webshell

Thực hiện tương tự như các bước ở step 2 chúng ta có được nội dung hàm main như sau

Hàm main

Có thể viết một cách ngắn gọn lại như sau

Hàm main thu gọn

Có thể nhận thấy sau khi payload được gửi lên, web shell thực hiện giải mã chúng, sau đó thực thi, mã hóa output và ghi vào file 404.html.

Như đã trình bày ở step 2, ta không có payload của kẻ tấn công và payload của kẻ tấn công gửi lên sẽ được giải mã và thực thi trong hàm Exec_Command. Do đó, ta chỉ tiến hành dịch ngược đầy đủ hàm Base64_Encode_AES_Encrypt để có các giá trị, từ đó khôi phục data được giấu trong tệp “404.html

Step 4: Dịch ngược Base64_Encode_AES_Encrypt và giải mã dữ liệu

Sau khi trích xuất được dữ liệu được mã hóa và giấu trong file 404.html, chúng ta cần phải nắm được cách thức mà web shell đã thực hiện mã hóa chúng mà không cần quan tâm payload kẻ tấn công gửi lên được giải mã như thế nào. Chính vì thế chúng ta chỉ cần tập trung vào đọc hiểu hàm Base64_Encode_AES_Encrypt.

Lời gọi hàm Base64_Encode_AES_Encrypt dạng ngắn gọn

Hàm Base64_Encode_AES_Encrypt được gọi

Dựa vào string, class và tham số, biến được sử dụng trong các hàm, ta dịch ngược hàm Base64_Encode_AES_Encrypt.

Hàm Base64_Encode_AES_Encrypt sau khi khôi phục

Có thể thấy các tham số được truyền vào hàm Base64_Encode_AES_Encrypt bao gồm như sau:

  • Param1 = “99wp_B0uNTy_p1Z!”
  • Param2 = “192.168.18.80” chính là remote addr, ip nguồn của kẻ tấn công được lấy từ file access_log.txt
  • data = nội dung được đưa vào để mã hóa

Step 5: Thực hiện giải mã bằng cách viết lại script bằng python.

Script giải mã được viết bằng python

Zerologon 01 (Category: Zerologon)

Mô tả của thử thách

Lỗ hổng Zerologon được khai thác theo flow sau:

Flow khai thác lỗ hổng Zerologon

Vì là zerologon nên ta sẽ tập trung vào giao thức RPC_NETLOGON (trong file pcap được ký hiệu là những packets màu tím). Trong zerologon, có hai lần chúng ta xác thực thành công Netlogon, một là khi ta muốn set password về rỗng, và 2 là khi chúng ta muốn set lại về password ban đầu.

Step 1: Set empty password

Forensic một lượt từ đầu file pcap, tại packet 3816, đây là lần xác thực thành công đầu tiên dựa vào status của packet:

Lần xác thực thành công đầu tiên

Trong packet 3818, là request NetrServerPasswordSet2 -> set password về rỗng. Malformed Packet (được chú thích bên trong packet này) nghĩa là wireshark không thể phân tích nội dung gói tin thêm nữa.

Step 2: Secrets dump

Và một đoạn các gói tin tiếp là là quá trình dump data. Flag cần tìm là NTLM hash ban đầu của account computer, đó cũng là data được lấy ra trong quá trình dump. Tuy nhiên việc đọc được NTLM hash từ dữ liệu thu được trong quá trình dump là không khả thi. Chính vì thế ta cần quan tâm đến bước tiếp theo là bước reinstall password của account computer.

Step 3: Reinstall original password

Tiếp theo là quá trình reinstall original password, mà NTLM hash của nó chính là cái chúng ta cần tìm. Theo dõi tiếp file pcap, sau đoạn dump data và tập trung vào những packet màu tím, ta tìm được đoạn xác thực thành công số hai như hình dưới:

Xác thực không thành công sẽ trả về STATUS_ACCESS_DENIED
Xác thực thành công ở packet 8789

Sau khi xác thực thành công, ta thấy packet NetServerPasswordSet request được sử dụng để cài đặt lại mật khẩu của account computer. Đi sâu vào packet này, ta thấy được Encrypted NTLM Pwd:

Encrypted NTLM Pwd

NTLM dùng thuật toán mã hóa SAM, để decrypt thì chúng ta còn cần thêm key, trong trường hợp này, chính là sessionkey, mà sessionkey được tính toán dựa trên giá trị của server challenge:

Script attack [link]

Tại packet 8787, là response từ server, ta thấy giá trị của server challenge:

Giá trị của server challenge

Sau khi đã có đủ ciphertext + key, ta dùng thư viện có sẵn của python để decrypt và tìm được flag:

Script decrypt NTLM hash [link]

Zerologon02 (Category: Zerologon)

Mô tả của thử thách

Step 1: Tìm kiếm câu lệnh được thực thi

Trong quá trình phân tích file pcap, chúng tôi phát hiện có một số packet chứa nhiều chuỗi được mã hóa base64. Nghi ngờ kẻ tấn công sử dụng script powershell được mã hóa base64 tấn công máy chủ AD. Chúng tôi thực hiện search chuỗi string “powershell -e” hoặc “powershell.exe -e”

Tìm kiếm chuỗi powershell
Dữ liệu nghi ngờ là script tấn công

Thực hiện bóc tách script powershell từ pcap cần lưu ý rằng data bắt đầu từ sau cặp từ “IO” do script được chia thành nhiều packet để gửi đi.

Cần loại bỏ cặp từ “IO” khi bóc tách dữ liệu

Step 2: Dịch ngược script tấn công

Thực hiện decode base64 ta được một đoạn mã powershell được encrypt bằng SecureString

Powershell được encrypt bằng SecureString [link]

Thực hiện decrypt đoạn powershell ở trên bằng script sau:

Script decrypt powershell [link]

Sau khi decrypt ta được một đoạn mã powershell như sau:

Mã powershell được giải mã [link]

Các số ở đầu là index của các string phía sau, chúng ta có thể viết script python convert về script ps ban đầu, hoặc dùng tool PSDecode. Từ đó ta có được đoạn mã powershell như sau:

Mã powershell cuối cùng

Với k là mảng đã biết, host name trong file pcap đã có là ABC-DC-01, dùng xor để tìm được nội dung đã ghi vào file và đó chính là flag.

Malware 02 (Category: Malware)

Mô tả thử thách

Step 1: Phân tích

Phân tích file mã độc được BTC cung cấp ta thấy mã độc thực hiện các hành động sau:

  • decrypt resource để có được shellcode
  • copy file mã độc vào %APPDATA%
  • Ghi key auto run vào registry
  • Thực hiện injection shellcode vào một process phù hợp bất kỳ được tìm thấy
Hàm main của file mã độc
Shellcode được inject vào một process phù hợp
Shellcode được load và thực thi dưới dạng một thread chạy ẩn

Có thể thấy file mã độc này đơn giản chỉ inject shellcode vào một process khác trong máy tính và thực thi. Chính vì thế ta cần tập trung phân tích shellcode này.

Có nhiều hướng để có thể phân tích shellcode trong mã độc này, tuy nhiên chúng tôi sử dụng cách làm tương tự như các bước được mô tả trong bài viết tại đường [link] đối với thử thách này ta có được file dll

Step 2: Phân tích file dll được dump ra

Bắt đầu với DllMain:

Function init() được call bởi DllMain()
Một phần nội dung hàm init()

Trong hàm init có define một số chức năng và mã ảnh hưởng đến thuật toán dùng để encrypt dữ liệu của các hàm như sau:

  • RemoteCommand => cmd = 3
  • Upload => cmd = 5
  • Keylogger => cmd = 2
  • Download => cmd = 4
  • Screenshot => cmd = 1

IP và port mà file kết nối đến:

Thông tin c&c

Parse chức năng của các hàm trên

RemoteCommand

Trong hàm Command, ta thấy một số chức năng mà file thực thi.

Case 0 là tạo process cmd.exe, tạo ra một pipe để nhận lệnh và giao tiếp
Case 1 là write command vào pipe
Case 2 là terminate pipe (terminate process)
Case 3 là copy dữ liệu từ pipe, đọc và gửi data nhận được về c2, data sẽ đi vào hàm flow_send_data để mã hóa trước khi được gửi đi.

Download

Dữ liệu từ file được đọc, sau đó đi qua hàm nén dữ liệu (rice compress) và được mã hóa trong hàm flow_send_data trước khi gửi về c&c.

Function Download

Screenshot

Tương tự như hàm Download, dữ liệu từ ảnh chụp màn hình được nén lại qua hàm rice compress -> mã hóa -> gửi về c&c. Mà yêu cầu của challenge này chính là một trong số các ảnh chụp được gửi đi.

Function Screenshot

Flow send data

Hàm này được sử dụng để xử lý và gửi dữ liệu đến c&c

Hàm xử lý dữ liệu và gửi đến c&c

Sau khi phân tích ta thấy hàm này dựa trên giá trị của cmd để random một số thuật toán mã hóa, và tạo 16 bytes key random. Trong hàm algorithm, chúng ta thấy có 4 thuật toán được sử dụng ở đây

Các option mã hóa

Vì ScreenShot có cmd = 1 thuật toán mã hóa sẽ là random XOR, RC4 hoặc là AES. Cuối cùng, quá trình encrypt dữ liệu screenshot giống như sơ đồ sau:

Flow xử lý dữ liệu chụp màn hình

Step 3: Lấy dữ liệu ảnh chụp màn hình

Đầu tiên, chúng ta cần extract data từ file pcap bằng cách filter theo ip và port, sau đó viết script đơn giản để lấy từng packet send and recv.

Script parse data [link]

Sau khi đã có các packet, phân tích theo struct của các packet như sau (trừ serpent encrypt):

  • 4 bytes đầu là signature
  • 4 bytes sau là insize
  • 1 bytes tiếp là định danh hàm encrypt (0 => XOR, 1 => RC4, 2 =>AES)
  • 16 bytes kế tiếp là key
  • 4 bytes tiếp là outsize
  • Và còn lại là data
Minh họa trên một packet

Viết script đơn giản để decrypt 3 thuật toán mã hóa trên (trừ serpent):

Script decrypt 3 thuật toán [link]

Tiếp đó là decompress rice. Dùng hàm decompress tương tự như [link] để giải nén dữ liệu và ta thu được một số ảnh màn hình gửi đi trong đó có một ảnh có chứa flag.

Flag thu được

Malware 03 (Category: Malware)

Mô tả thử thách

Từ dữ liệu lấy được ở thử thách Malware 02 ta nhận thấy có một số packet sử dụng serpent là thuật toán mã hóa sẽ được parse theo struct sau:

  • 4 bytes đầu là signature
  • 4 bytes sau là insize
  • 1 bytes tiếp là định danh hàm encrypt bằng serpent với giá trị mặc định bằng 4
  • Và còn lại là data

Step 1: Decrypt serpent

Sử dụng hàm như trong [link] để decrypt dữ liệu extract được từ file pcap được mã hóa bằng serpent.

Packet được encrypt bằng serpent

Tại packet số 30, sau khi decrypt ta nhận thấy có signature của file zip và một file có tên là flag2.txt trong đó và một số file Keylogger khác.

File zip được tìm thấy

Thực hiện giải nén file zip này ta thấy có yêu cầu nhập password. Khả năng password được lưu ở đâu đó trong những file Keylogger.

Có thể thấy trong các file Keylogger có một nội dung dạng “Th1s_1s_p4ssw0rd” tuy nhiên đây không phải là password cần tìm vì sử dựng để giải nén không thành công.

Nội dung một file Keylogger

Quay trở lại đọc kỹ hơn hàm Keylogger trong file dll, ta thấy có một hàm hook_keylogger, chính hàm này đã thay đổi giá trị của phím được nhấn trước khi ghi vào file.

Function hook_keylogger

Theo như trên, nó đã thay đổi i -> 1, a -> 4, o -> 0. Từ đó ta có thể suy ra được password chính xác sẽ là: This_is_password

Thực hiện extract zip file với password có được ta có flag như sau:

Flag cần tìm

Credit: @nhiephon, @lanleft

Tản mạn về một cuộc điều tra tấn công DDoS

Xin chào, sau một thời gian chống chọi Covid, Zepto team chúng tôi đã quay trở lại rồi đây =]]

Hôm nay chúng tôi sẽ chia sẻ về quá trình điều tra, truy vết nguồn gốc của một chiến dịch tấn công DDoS mà hệ thống giám sát ghi nhận được. Qua điều tra, chúng tôi đã phát hiện đây là một cuộc tấn công DDoS đến từ một hệ thống botnet của một tổ chức chuyên bán các dịch vụ tấn công từ chối dịch vụ. Quá trình điều tra và truy vết như thế nào sẽ được chúng tôi chia sẻ cụ thể ở bên dưới, hi vọng mọi người sẽ cảm thấy hữu ích với bài viết này.

Let’s go

Sau khi nhận được thông tin từ hệ thống giám sát rằng hệ thống đang có hiện tượng bị tấn công từ chối dịch vụ, chúng tôi đã ngay lập tức cử người đến để phối hợp ứng cứu sự cố và điều tra về tấn công này. Việc xử lý và ngăn chặn tấn công DDoS đã được thực hiện ngay sau đó và hệ thống đã quay trở lại hoạt động bình thường. Tuy nhiên mục tiêu chúng tôi đặt ra là làm sao để biết được tấn công này đến từ đâu và hệ thống nào điều khiển cuộc tấn công này thì vẫn còn là một dấu hỏi lớn cần được giải đáp.

Mục tiêu chúng tôi đặt ra trong trường hợp này như sau:

  • Phát hiện được cách thức tấn công
  • Phát hiện hệ thống điều khiển tấn công
  • Phát hiện kẻ đứng sau thực hiện tấn công.

Điều tra cách thức tấn công

Sau khi phân tích các dữ liệu được cung cấp từ đội ngũ quản trị hệ thống, chúng tôi đã đưa ra kết luận đây là một cuộc tấn công SYN Flood nhằm vào hệ thống máy chủ ứng dụng. Đây là một hình thức tấn công từ chối dịch vụ thông qua việc gửi liên tục các gói tin khởi tạo kết nối SYN đến máy chủ dẫn đến vượt quá khả năng xử lý của máy chủ làm cho hệ thống không kịp phản hồi các kết nối hợp lệ từ người dùng thông thường.

Ngay sau khi phát hiện hình thức tấn công thì các biện pháp khắc phục, xử lý đã được thực hiện để đưa hệ thống trở lại trạng thái hoạt động bình thường.

Điều tra hệ thống điều khiển tấn công

Ghi nhận thông tin hệ thống bị tấn công đồng loạt từ nhiều ip khác nhau (tấn công từ nhiều máy trạm), để làm được điều này kẻ tấn công không thể đến trực tiếp từng máy trạm để thực hiện hành động này. Do đó chắc chắn phải có một hệ thống đứng sau điều khiển tất cả máy trạm thực hiện tấn công đồng loạt vào một thời điểm nhất định.

Chúng tôi thực hiện lọc trên hệ thống bảo vệ và có kết quả nhận về một số lượng lớn ip vẫn đang có các hành vi thực hiện tấn công vào hệ thống nhưng đã bị chặn. Để tìm được kẻ đứng sau thì chúng tôi quyết định tiến hành điều tra truy vết thông tin từ những địa chỉ ip này.

Danh sách ip bị chặn khi phát hiện tấn công SYN Flood

Qua kiểm tra một số ip thuộc danh sách trên chúng tôi đưa ra hai giả thuyết như sau:

  • Tấn công đến từ hệ thống máy tính bị nhiễm mã độc
  • Tấn công đến từ một hệ thống các thiết bị IoT bị kiểm soát

Sử dụng hệ thống tra cứu thông tin của NCSC Việt Nam, chúng tôi phát hiện số lượng lớn ip bị chặn thuộc các hệ thống botnet.

Các ip bị chặn nằm trong các hệ thống botnet

Như vậy có thể nhận định rằng đây là một cuộc tấn công đến từ một hệ thống botnet. Kiểm tra các ip này phần lớn đang mở các dịch vụ quản trị từ xa của các thiết bị IoT. Có thể nhận định các thiết bị IoT này tồn tại các lỗ hổng bảo mật dẫn đến bị khai thác chiếm quyền điều khiển và đưa vào hệ thống botnet. Tuy nhiên, làm sao để biết được hệ thống botnet này hoạt động như nào và được điều khiển từ đâu lại là một vấn đề phức tạp.

Để giải quyết vấn đề này tôi có đưa ra hai cách khả thi như sau:

  1. Liên hệ nhà mạng (bởi các ip này có nhiều ip thuộc các nhà mạng Việt Nam) để biết được ip này của khách hàng nào. Sau đó liên hệ khách hàng liên quan để lấy thiết bị, tiến hành phân tích thiết bị để tìm kiếm mã độc.
  2. Tìm cách truy cập vào thiết bị từ xa để phân tích, tìm kiếm mã độc.

Có thể dễ thấy cách đầu tiên nêu ra tốn rất nhiều thời gian và nguồn lực, do đó bằng kỹ năng nghiệp vụ và những hệ thống thông tin có sẵn của NCSC, chúng tôi đã quyết định tìm phương án sử dụng cách thứ 2.

Sau khi truy cập thành công vào thiết bị nghi ngờ nằm trong hệ thống botnet, chúng tôi đã phát hiện được một số tiến trình lạ đang chạy trong thiết bị.

Một số tiến trình lạ đang chạy trên thiết bị

Truy cập vào dịch vụ ftp của ip tìm thấy trong command khởi chạy của một tiến trình bất thường chúng tôi phát hiện nhiều mẫu mã độc IoT được lưu tại đó.

Mẫu mã độc IoT được lưu trên server nghi là c&c

Các mẫu tìm thấy trùng khớp với các tập tin đang được chạy trên thiết bị, từ đó khẳng định một cách chính xác được thiết bị đang bị điều khiển bởi máy chủ mạng botnet.

Thực hiện phân tích mẫu mã độc thu được chúng tôi đã thấy được đây là một mẫu mã độc được sử dụng cho mục đích tấn công DDoS với nhiều chức năng khác nhau được điều khiển thông qua các lệnh được gửi về từ máy chủ c&c. Tìm kiếm trên mạng internet chúng tôi thấy được một số mã nguồn tương tự với mẫu này đã được công bố trên internet:

Phân tích mẫu mã độc tìm thấy trên thiết bị

Mã độc nhận lệnh từ máy chủ c&c (dịch vụ chạy tại port 1111) và thực hiện hành động tấn công DDoS tương ứng.

Thông tin dịch vụ c&c được tìm thấy trong mẫu mã độc

Thực hiện kết nối đến c&c của botnet và nhận các lệnh từ trên c&c gửi về các máy trạm thông qua việc mô phỏng lại một thiết bị IoT nhiễm độc. Chúng tôi thấy rằng hệ thống này vẫn hoạt động bình thường, và các lệnh tấn công vẫn đang được gửi về từ c&c tới mạng botnet.

Các lệnh được gửi về từ c&c

Truy tìm kẻ đứng sau thực hiện tấn công

Ngoài ra chúng tôi còn phát hiện trên thiết bị chạy một mẫu mã độc thực hiện các hành động tấn công dò quét lỗ hổng trên các thiết bị IoT khác nhằm mục đích mở rộng hệ thống botnet.

Mẫu mã độc sử dụng để mở rộng hệ thống botnet
Một trong số các mã khai thác được sử dụng để tấn công các thiết bị khác (CVE-2017–17215)

Qua quá trình điều tra và phân tích các mẫu tìm được, chúng tôi đã phát hiện được 3 c&c:

  • 163[.]172[.]40[.]236 có địa chỉ IP tại Pháp
  • 51[.]77[.]220[.]127 có địa chỉ IP tại Pháp
  • 185[.]132[.]53[.]194 có địa chỉ IP tại Đức
Thông tin liên quan đến máy chủ c&c

Trong số 3 c&c ở trên, có một c&c có chứa nhiều thông tin hơn 2 c&c còn lại, kiểm tra thông tin máy chủ c&c này chúng tôi phát hiện một nhóm chuyên bán các dịch vụ DDoS nextstress[.]pw. Tuy nhiên tại thời điểm điều tra, trang web này không còn hoạt động. Có thể nhóm này đã chuyển sang sử dụng một hệ thống web khác tương tự.

Thông tin liên quan đến máy chủ c&c
Nhóm hacker quảng cáo dịch vụ DDoS trên twitter https://twitter.com/httpg0d1

Kết luận

Từ những kết quả trên chúng ta có thể kết luận rằng kẻ xấu đã thuê dịch vụ tấn công DDoS thuộc một trong các hệ thống tương tự nextstress[.]pw để thực hiện các hành vi tấn công vào hệ thống.

Tấn công DDoS là một dạng tấn công gây tác động lớn đến các hệ thống, và có thể thấy rằng việc thực hiện các hành vi xấu thông qua tấn công DDoS ngày càng dễ dàng thực hiện thông qua việc thuê các dịch vụ từ bên thứ ba. Các dịch vụ cung cấp các tấn công này thì có hệ thống botnet ngày càng phức tạp, và quy mô ngày càng lớn.

Có thể nói an toàn thông tin cho các thiết bị IoT là rất quan trọng, nó vừa đảm bảo an toàn cho hệ thống, vừa ngăn chặn được việc tận dụng thiết bị IoT cho các chiến dịch tấn công DDoS. Có thể nhiều người sẽ thắc mắc những vấn đề sau:

  • Tại sao các thiết bị IoT lại là đối tượng để kẻ xấu tận dụng để xây dựng các hệ thống mạng botnet phục vụ cho các hình thức tấn công DDoS?
  • Tại sao một thiết bị IoT lại có thể trở thành một máy trạm trong hệ thống mạng botnet?
  • Làm sao để đảm bảo an toàn cho các thiết bị IoT?

Có thể những câu hỏi trên sẽ được giải đáp trong những blog tiếp theo của chúng tôi.

Cuối cùng, xin cảm ơn các bạn đã đọc bài viết này và hẹn gặp lại trong blog tiếp theo!

P/s: Do tính chất đặc thù và một số nguyên tắc trong công việc, ngoài ra blog chỉ tập trung vào chia sẻ các kỹ thuật nên nhiều thông tin quan trọng khác chúng tôi xin phép không nêu trong bài viết này.