Ransomware Petya

Trỗi dậy từ đống tro tàn của Wannacry, một hiểm họa mới bắt đầu: Petya. Trong hai năm 2016 và 2017, ransomware Petya và những biến thể của nó đã ảnh hưởng đến hàng nghìn máy tính trên toàn thế giới. Ngay sau khi ransomware Wannacry vừa có dấu hiệu lắng xuống, Petya nỗi lên như một sự thay thế hoàn hảo.

Điểm đặc biệt của loại malware này là nó không mã hóa các tập tin dữ liệu của người dùng mà thay đổi Master Boot Record(MBR) và mã hóa Master File Table (MFT) khiến cho người dùng thậm chí còn không boot được vào hệ điều hành.

Theo các nguồn thông tin, cuộc tấn công của ransomware Petya bắt nguồn từ công ty M.E.Doc, một công ty kiểm toán có trụ sở tại Ukrainian, thông qua phần mềm của M.E.Doc có chứa Petya trong một bản cập nhật. Ngoài ra, Petya còn được chèn trong các file văn bản được gửi có chủ đích tới các cơ quan tổ chức khi người dùng mở lên thì ransomware sẽ lừa người dùng kích hoạt marco có sẵn trong các phiên bản của Office.
Microsoft.com/security/blog/2018/02/05/overview-of-petya-a-rapid-cyberattack/

Stage 1: High level

Trên không gian mạng hiện nay có rất nhiều biến thể của ransomware Petya nhưng trong bài viết này ta sẽ tập trung phân tích mẫu:

Ta dễ dàng nhận ra mẫu ransomware cần phải được unpack trước khi thực thi các lệnh thực. Trong quá trình debug malware có gọi đến các hàm như VirtualProtect và VirtualAlloc để phân bổ và thay đổi quyền của một vùng nhớ mới. Phỏng đoán ràng đây sẽ là vùng nhớ chứa mã thực của malware sau khi unpack. Vậy nên ta chỉ cần đặt breakpoint ở điểm đầu của vùng nhớ mới được tạo ra và đây là kết quả:

Unpack Petya

Như ta thấy trong hình trên, trong cửa sổ hexdump là header của một pe file. Dump toàn bộ section này ra ta thu được một file Setup.dll với đầy đủ import table rất dễ đọc.

Dll file

Đi qua lần lượt các hàm được thực hiện trong file Setup.dll khi được khởi chạy. Đầu tiên, ransomware Petya lấy thông tin ổ cứng của nạn nhân bằng hàm DeviceIoControl để láy vị trí vật lý của một volume trên ổ cứng, thông tin về chủng loại, kích thước, tích chất của phân vùng ổ cứng(bằng IOCTL_DISK_GET_PARTITION_INFO_EX, PARTITION_INFORMATION_EX, ). Dưới đây là pseudocode hàm lấy vị trí vật lý của một volumn trên một hoặc nhiều ổ cứng:

  v1 = this;
  BytesReturned = 0;
  v2 = GetSystemDirectoryA(0, 0);
  v3 = v2;
  if ( !v2 )
    return 0;
  v5 = (CHAR *)sub_239090(v2);
  if ( !GetSystemDirectoryA(v5, v3) )
    return 0;
  *(_DWORD *)FileName = 1546542172;
  v9 = *v5;
  v10 = 58;
  sub_239070(v5);
  v6 = CreateFileA(FileName, 0, 3u, 0, 3u, 0, 0);
  if ( v6 == (HANDLE)-1 )
  {
    CloseHandle((HANDLE)0xFFFFFFFF);
    return 0;
  }
  DeviceIoControl(v6, 0x560000u, 0, 0, &OutBuffer, 0x20u, &BytesReturned, 0);
  // Trong đó 0x560000 là IoControlCode được thay lần lượt là 0x70048, 0x70000 trong các hàm còn lại để lấy thông tin ổ đĩa  
  CloseHandle(v6);
  qmemcpy(v1, "\\\\.\\PhysicalDrive", 17);
  v1[17] = v12 + 48;
  v1[18] = 0;
  return 1;

Tạo một buffer chứa link trả tiền chuộc “hxxp://petya5koahtsf7sv[.]onion/[Random]”, “hxxp://petya37h5tbhyvki[.]onion/[Random]” Ransom Note. Và gọi đến hàm CryptGenRandom để tạo ra khóa cá nhân của nạn nhân:

_DWORD *v4; // edi

  v4 = (_DWORD *)phProv;
  *(_DWORD *)phProv = 0;
  if ( !CryptAcquireContextA(&phProv, 0, 0, 1u, 0xF0000000) )
    return -60;
  if ( !CryptGenRandom(phProv, dwLen, pbBuffer) )
    return -60;
  CryptReleaseContext(phProv, 0);
  *v4 = dwLen;
  return 0;

Tiếp đến, ransomware Petya đoc\ghi dữ liệu MBR. Sau đó, ép máy khởi động lại bằng cách dùng hàm NtRaiseHardError:

  v0 = GetCurrentProcess();
  if ( !OpenProcessToken(v0, 0x28u, &TokenHandle) )
    return 0;
  LookupPrivilegeValueA(0, "SeShutdownPrivilege", (PLUID)NewState.Privileges);
  NewState.PrivilegeCount = 1;
  NewState.Privileges[0].Attributes = 2;
  AdjustTokenPrivileges(TokenHandle, 0, &NewState, 0, 0, 0);
  if ( GetLastError() )
    return 0;
  v2 = GetModuleHandleA("NTDLL.DLL");
  v3 = GetProcAddress(v2, "NtRaiseHardError");
  ((void (__cdecl *)(signed int, _DWORD, _DWORD, _DWORD, signed int, char *))v3)(-1073740976, 0, 0, 0, 6, &v5);
  return 1;

Stage 2: Low level

Giờ ta phân tích mã độc được chèn vào MBR của ổ đĩa:
MBR

Từ kết quả dump ra từ \.\PhysicalDrive0 ta có:

Khi máy khởi động đoạn mã của malware sẽ được thực thi:
Entry MBR

Để đọc sector tử ổ đĩa nó sử dụng interrupt 13
Read_Reset_Disk

Tiếp đến, Malware sẽ check xem MBR đã bị mã hóa chưa?
Encrypt_MFT

Nếu chưa mã hóa, Petya sử dụng thuật toán Salsa20 để khóa MFT.

MFT (Master File Table) là thành phần quan trọng nhất trong hệ thống NTFS. MFT chứa thông tin về tất cả các tập tin và thư mục trong ổ đĩa logic.

Sau khi mã hóa xong màn hình chính sẽ được hiển thị
Red_screen
Red_screen_code

Khi người dùng nhập key Petya sẽ kiểm tra định dạng của key:

Mặc dù, ta hoàn toàn có thể bypass check_key bằng cách đổi địa chỉ của một số hàm jump nhưng như vậy cũng không giải mã được MFT. Tuy nhiên, do giới hạn về kích thước của các sector nên malware Petya không hẳn sử dụng salsa20 mà là salsa10. Với độ dài ngắn như vậy ta hoàn toàn có thể brute force được key để giải mã.

Trong quá trình giải mã của Petya ta thấy:

Ta có được bản mã và nonce. Ta hoàn toàn có thể đọc thuật toàn của salsa và tự viết script brute force hoặc sử dụng script được viết bằng golang của một anh bạn rất tốt bụng leo-stone.

Brute_force_key

Tổng kết

Việc tạo ra một ransomware được khởi chạy ở boot sector, mã hóa MBR và MFT là một hướng đi rất thú vị. Tuy nhiên, việc triển khai malware dưới tầng kernel đã tạo ra một vài lỗ hổng trong lúc triển khai thuật toán mã hóa giúp cho chúng ta có thể giải mã mà không cần key. Điều này đã khiến cho Petya phiên bản đầu thể không lây nhiễm rộng rãi. Mặc dù vậy, những mã độc có hướng đi như Petya, ví dụ như Goldeneye, đã tạo cảm hứng cho hacker phát triển những ransomware tấn công vào tầng kernel, đặt ra thách thức cho các nhà bảo mật.